Compare commits

..
1464 Commits
Author SHA1 Message Date
Félix MalfaitandFélix Malfait fc6aafd3c6 Fix clickhouse migration not in dist (#11709)
Clickhouse migrations were not correctly copied to the dist folder (for
command yarn clickhouse:migrate:prod)
2025-04-23 21:23:31 +02:00
Charles BochetandGitHub 8076ff5b82 Fix broken metadata sync due to index removal (#11706)
Changing strategy regarding disabling index creation with new relation
system
2025-04-23 18:06:19 +02:00
MarieandGitHub 4257f30f12 Permission checks on twentyORM global manager (#11477)
In this PR we are handling permissions when using
twentyORMGlobalManager,
and handling permissions for rest api and api key
2025-04-23 17:57:48 +02:00
Thomas TrompetteandGitHub 28a1354928 Allow webhook only on active versions (#11705)
- webhook call should only be allow on active versions
- fixing exceptions that are wrongly sent to sentry
2025-04-23 17:28:41 +02:00
Charles BochetandGitHub a2d2db441f Improve Filter chip empty state (#11704)
Cases:

<img width="477" alt="image"
src="https://github.com/user-attachments/assets/06da3efc-b878-499f-97de-570317caa9b7"
/>

<img width="477" alt="image"
src="https://github.com/user-attachments/assets/40114c16-2810-489d-a60f-2579e2916691"
/>

<img width="477" alt="image"
src="https://github.com/user-attachments/assets/fa80d7cf-7c2d-4c19-919e-2d4c78a9202b"
/>
2025-04-23 16:54:11 +02:00
Charles BochetandGitHub a4882089b1 Add is relation enabled to default feature flags (#11703) 2025-04-23 16:26:53 +02:00
Paul RastoinandGitHub f2828883ad Fix click outside dropdown content confirmation modal (#11702)
# Introduction
Closes https://github.com/twentyhq/twenty/issues/11674
2025-04-23 14:23:15 +00:00
Thomas TrompetteandGitHub 1333c64d98 Add diff in workflow update events + fix existing (#11700)
Closes https://github.com/twentyhq/twenty/issues/11676.

Diff should be available for objects displaying timeline activities. It
should also fit the existing type.
2025-04-23 15:43:41 +02:00
Félix MalfaitandGitHub e1054b0474 Fix clickhouse migration (#11699)
It looks like Clickhouse Cloud uses a different config var than the docs
2025-04-23 15:09:23 +02:00
Charles BochetandGitHub 457c6ed113 Improve storybook stories (#11694)
## Improvements

### TaskGroups

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/0dbd71fe-3999-4cf5-870e-565b8e2df1b9"
/>

### EventCardMessage

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/b41cddc1-3ff2-411f-9ac6-8d4035579e54"
/>

### Blocklist stories

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/e997a0c1-e7e2-4ea4-9253-f31609ee44df"
/>

### WorkflowEditActionUpdateRecord

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/275dab17-ad33-4174-8671-31ba455c20a4"
/>
2025-04-23 13:20:13 +02:00
Félix MalfaitandGitHub 93c2ba153b Add clickhouse prod migration command (#11695)
Add a missing command to launch clickhouse migrations the same way we
launch postgres migrations
2025-04-23 13:02:00 +02:00
martmullandGitHub b6e8103df7 Mime encode names in email headers (#11691)
# Before
<img width="618" alt="image"
src="https://github.com/user-attachments/assets/e6d7c0ac-10f8-4d2e-abe4-05bf86a2ea9e"
/>

# After
<img width="504" alt="image"
src="https://github.com/user-attachments/assets/db147cb9-be19-4d08-b357-cb554dc2a4ae"
/>

Fixes also Emojis encoding in Subject ->
<img width="540" alt="image"
src="https://github.com/user-attachments/assets/8c27743f-3a50-46eb-b0f3-492219bbd646"
/>

 Works with microsoft accounts
<img width="360" alt="image"
src="https://github.com/user-attachments/assets/d924440f-c107-4c1c-ad4d-b4b27016f102"
/>


Fixes https://github.com/twentyhq/twenty/issues/9194
2025-04-23 11:37:40 +02:00
EtienneandGitHub ea850f323a Fix inline cell interactions (#11686)
@bosiraphael I've slightly updated [your recent
pr](https://github.com/twentyhq/twenty/pull/11654)
- before
<img width="490" alt="Screenshot 2025-04-22 at 17 48 26"
src="https://github.com/user-attachments/assets/604d65df-5433-4524-bdc5-6f5083b3c045"
/>

- after
<img width="488" alt="Screenshot 2025-04-22 at 17 47 41"
src="https://github.com/user-attachments/assets/21273372-538e-454e-947b-09373d9e0d6d"
/>


closes https://github.com/twentyhq/core-team-issues/issues/831 and
https://github.com/twentyhq/core-team-issues/issues/828
2025-04-23 08:46:10 +00:00
Charles BochetandGitHub fa5f758228 Fix storybook / chromatic tests flakyness and integration tests (#11687)
## Storybook flakyness

### Actor Display image flakyness

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/875c0738-5e31-4aba-9231-4ba5f78d1355"
/>

**Fix:** stop using a random usage

### Task Groups broken

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/c67e47a1-a027-43f1-9601-68d61a8052b4"
/>

**Fix:** add missing TabListComponentInstance

## Flaky dates

Add https://github.com/k35o/storybook-addon-mock-date

## Integration tests

Fix broken tests due to relation refactoring
2025-04-23 01:57:36 +02:00
Félix MalfaitandGitHub 8694840b92 Rename webhook and open api urls (#11684)
We want to have fewer base path for routing.

We will have:
- /files
- /webhooks
- /graphql
- /metadata
- /rest
- /auth
- /healthz

I'm moving /open-api under /rest, and centralizing the webhooks
(removing /stripe and /cloudflare)
2025-04-22 22:24:26 +02:00
Paul RastoinandGitHub fba9ae6dfe Fallback undefined recordDataChip record name to empty string (#11685)
# Introduction
Closes #11682 

This seems to always has been quite flaky but this latest
[update](https://github.com/twentyhq/twenty/commit/f0de6d31b7b3b84671c3a5af8fd047ef7432666f#diff-63704155b77d9690a87a1ebd9f364bab7e7bb12afed7cc5a5516561ec3798f29L20)
seems to made the name optional.

As previously `undefined` being transpiles to a string results in
`"undefined"` which not a good thing neither 🙃 but wouldn't throw before
2025-04-22 20:17:44 +02:00
cc29c25176 feat: new relation sync-metadata, twenty-orm, create/update (#10217)
Fix
https://github.com/twentyhq/core-team-issues/issues/330#issue-2827026606
and
https://github.com/twentyhq/core-team-issues/issues/327#issue-2827001814

What this PR does when `isNewRelationEnabled` is set to `true`:
- [x] Drop the creation of the  foreign key as a `FieldMetadata`
- [x] Stop creating `RelationMetadata`
- [x] Properly fill `FieldMetadata` of type `RELATION` during the sync
command
- [x] Use new relation settings in TwentyORM
- [x] Properly create `FieldMetadata` relations when we create a new
object
- [x] Handle `database:reset` with new relations

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-22 19:01:39 +02:00
Paul RastoinandGitHub de1489aabb Time line activity wrong type (#11673)
# Introduction
Closes https://github.com/twentyhq/core-team-issues/issues/874

`TimeLineActivity` fields `` and `` were typed as required whereas in
reality are nullable, resulting in the related sentry error.
Refactored the type then the related components in order to handle
nullable use case
2025-04-22 15:17:08 +00:00
Baptiste DevessierandGitHub efab98a8f8 Get all first depth fields in the table and the board (#11650)
After discussing it with the team, we now want to query all fields in
the table and the board by default. Feeding the cache with exhaustive
data will make the side panel's life easier, as it needs all the record
fields to determine the actions to enable.
2025-04-22 16:45:36 +02:00
Thomas TrompetteandGitHub 0b7024c94a Perform batch update on workflow runs (#11680)
Command times out on workflow versions with too many runs. Performing
batch update instead
2025-04-22 16:07:29 +02:00
EtienneandGitHub 5250d5c8d6 fix subscription item update (#11648)
closes
https://twenty-v7.sentry.io/issues/6550388239/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=issue-stream&stream_index=6
2025-04-22 14:01:36 +02:00
Raphaël BosiandGitHub 87083cb414 834 Design Adjustments for the Record Page Breadcrumb (#11670)
# Design Adjustments for the Record Page Breadcrumb

Closes [834](https://github.com/twentyhq/core-team-issues/issues/834)
and [826](https://github.com/twentyhq/core-team-issues/issues/826)

## Description

- Added the breadcrumb to every object (not just the workflows)
- Fixed spacings
- Changed icon color from primary to tertiary for proper visual
hierarchy
- Displayed pagination information (current/total)
- Close button has been removed to simplify the UI
- Navigate to index page when the breadcrumb is clicked
- Fixed problems when two record title cells were displayed at the same
time (in the header and in the record page)

## Before

<img width="247" alt="Capture d’écran 2025-04-22 à 12 15 34"
src="https://github.com/user-attachments/assets/5ca2aca7-ffb0-49ea-8d3a-4bd621d78f8d"
/>

## After

<img width="233" alt="Capture d’écran 2025-04-22 à 12 15 06"
src="https://github.com/user-attachments/assets/cbcb5dfe-d616-47c9-8017-71dd4d388534"
/>
2025-04-22 13:52:56 +02:00
Raphaël BosiandGitHub 251a7b126b 838 design adjustments on table kanban and inline fields (#11654)
Closes [#838]( https://github.com/twentyhq/core-team-issues/issues/838)
Design adjustments on table kanban and inline fields.

The table row border selection will be done later since it is harder
than initially thought.
2025-04-22 11:15:53 +02:00
Thomas TrompetteandGitHub 33e0794da9 Update workflow statuses in real time (#11653)
Statuses are maintained by an async job. Those are calculations that we
would like to avoid using in both frontend and backend. Using push
updates are an easier way.



https://github.com/user-attachments/assets/31e44a82-08a8-4100-a38e-c965d5c73ee8
2025-04-22 11:03:12 +02:00
Ken LynchandGitHub 3ce3793129 Update glossary.mdx (#11661)
Remove extraneous AI response. :)
2025-04-22 10:17:16 +02:00
Félix MalfaitandGitHub aa2f3438fa Fix email verification (#11660)
Email verification modal had been broken and looked bad

I also added stories to make it more evident if this happens again
2025-04-20 14:18:43 +02:00
Félix MalfaitandGitHub 24873d0c1d Remove versions from package.json (#11658)
Now the source of truth for the version is set during the build process.
We set it as an environment variable from the tags.
We could add it back to the package.json during the build process (from
the git tag), but there is not use for it at the moment since it's not
npm packages.
2025-04-19 23:03:06 +02:00
Antoine MoreauxandGitHub 83434deb22 refactor(auth): optimize work email handling in sign-up flow (#11655)
Extracted isWorkEmail check into a variable for reusability and adjusted
subdomain generation to conditionally include email. This enhances code
readability and maintains logic consistency.
2025-04-19 15:28:41 +02:00
Baptiste DevessierandGitHub 826889715b Fix e2e tests (#11656)
After @bosiraphael's updates on the table, cells are duplicated when
they get the hover/focus. Playwright has a hard time finding which
element to click on.
I dislike my solution because it doesn't mimic how a real user would use
the application, but I couldn't find a better solution that wasn't
flaky.
2025-04-18 18:39:43 +02:00
MarieandGitHub f8b9e4d780 ignoreLock when recomputing rolePermissions when creating datasource (#11657)
[sentry](https://twenty-v7.sentry.io/issues/6545999328/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=issue-stream&sort=date&stream_index=2)

Our workers have failing jobs because they are concurrently creating
datasources on different pods
While the datasources are independent, they read from the same redis
cache, with the same `RolesPermissionsOngoingCachingLock` value in
redis.
<img width="852" alt="Capture d’écran 2025-04-18 à 18 00 20"
src="https://github.com/user-attachments/assets/42ce8479-acc1-462b-af4c-b547cc2bb0b8"
/>
As a consequence they can fail to create a datasource: the first
datasource computes the permissions and sets ongoingCachingLock to true,
then the second arrives, there are still no available permissions in the
cache, but because of the lock it early returns without permissions and
fails. This behavior goes unnoticed on the product and helps
performances, but is annoying for workers as jobs are failing.

Let's remove the cache lock when creating the datasource !
2025-04-18 18:16:34 +02:00
8512904c0a refacto clickoutside componentv2 (#11644)
Switch to ComponentV2

Friday morning refacto & chill with @charles

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-18 17:48:30 +02:00
Félix MalfaitandGitHub cf5649a1df Deprecate Sentry release (#11651)
Let's deprecate Sentry Release and use APP_VERSION instead. 

It'll make it more clear in the interface to use named version for bug
analysis, than commit sha
2025-04-18 15:48:48 +02:00
martmullandGitHub fba4192d4b Fix rest api integration tests (#11645)
as title
2025-04-18 15:23:36 +02:00
16bd0425e0 i18n - translations (#11647)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-18 14:22:25 +02:00
MarieandGitHub fd750c7c0e Fix metadata cache flush (#11646)
Attempt to fix
https://twenty-v7.sentry.io/issues/6545999328/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=issue-stream&sort=date&stream_index=2
2025-04-18 12:02:36 +00:00
Thomas TrompetteandGitHub 8112c3aab3 Fix workflow run executed by empty (#11642)
Workflow run executed by should not be empty when the workflow is
unamed. Adding Workflow as fallback

<img width="1072" alt="Capture d’écran 2025-04-17 à 19 17 12"
src="https://github.com/user-attachments/assets/e4cc3360-06e5-47e8-ba05-28a0eafab994"
/>
2025-04-18 09:26:51 +00:00
Antoine MoreauxandGitHub 8a2a004fb5 feat(settings): add domain validation effect and delete functionality (#11643)
Introduced a new effect component to validate custom domain DNS records
on mount, centralizing logic. Added a button to reset the custom domain
field, improving user control and form handling. Refactored related code
for maintainability and enhanced UI structure.

Fix https://github.com/twentyhq/core-team-issues/issues/853
2025-04-18 08:18:36 +00:00
oliverGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix MalfaitFélix Malfait
53042cc9dc Date field format display (#11384)
## Introduction

This PR enables functionality discussed in [Layout Date
Formatting](https://github.com/twentyhq/core-team-issues/issues/97).

### TLDR;
It enables greater control of date formatting at the object's field
level by upgrading all DATE and DATE_TIME fields' settings from:

```ts
{
    displayAsRelativeDate: boolean
}
```

to:

```ts

type FieldDateDisplayFormat = 'full_date' | 'relative_date' | 'date' | 'time' | 'year' | 'custom'

{
    displayFormat: FieldDateDisplayFormat
}
```

PR also includes an upgrade command that will update any existing DATE
and DATE_TIME fields to the new settings value

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-04-18 07:00:02 +00:00
Raphaël BosiandGitHub dd0ea2366f 839 Table focus refactoring (#11629)
# Table Focus Refactoring

This pull request implements the table focus refactoring requested in
[#839](https://github.com/twentyhq/core-team-issues/issues/839),
dissociating hover and focus behaviors in the table component to improve
keyboard navigation.

## Technical Implementation

- Created separate component states to handle focus and hover
independently.
- Updated all relevant hooks and functions to use the new focus
mechanism.
- Removed deprecated states and hooks.
- Introduced dedicated portal components to improve the table
performance (the table cells are much simpler and the more complex logic
is handled via the portals)

## Key Behavior Changes

- Performance improvements
- Focus is now handled exclusively with keyboard navigation
- Clicking on a cell or inline-cell now sets the focus to that cell
- Hover state is managed separately from focus, improving user
experience and accessibility
- The table scrolls when the focused cell changes

## Video



https://github.com/user-attachments/assets/9966beac-3b0f-4433-a87a-299506d83353
2025-04-17 16:40:24 +00:00
Thomas TrompetteandGitHub 18a89b5152 Set error on number field and prevent form from being submitted (#11637)
<img width="943" alt="Capture d’écran 2025-04-17 à 18 14 46"
src="https://github.com/user-attachments/assets/1208075e-937f-4224-886c-be578264d448"
/>
2025-04-17 18:39:18 +02:00
WeikoandGitHub 19da80d2e4 Fix logs in integration tests for unhandled exceptions without removing logger (#11635)
Setting a global exception filter for unhandled exceptions to avoid the
default Nest ExceptionsHandler being called (and logging exceptions)
2025-04-17 18:35:21 +02:00
WeikoandGitHub 3fe12cd8b5 Fix select default value not in options (#11622)
Also fixing a bunch of places where validation exceptions were not
properly handled
2025-04-17 18:34:31 +02:00
EtienneandGitHub dd1ac4deee Fix mismatching stripe subscription metadata plan/planKey (#11634)
for later : https://github.com/twentyhq/core-team-issues/issues/867
2025-04-17 18:21:35 +02:00
martmullandGitHub e4150ff3cb Fix logs in integration tests (#11632)
## Before
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/3e8be2e0-ac16-4735-8783-69c800bf0aaf"
/>

## After
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/1a83e7ce-d70a-43c4-a6cd-89dd456d80c1"
/>
2025-04-17 15:05:10 +00:00
Lucas BordeauGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
caf44207fd Implemented filter on FULL_NAME sub-fields (#11628)
This PR implements what's missing to have sub-field filtering.

There is a backend modification to save subFieldName, we just add this
field on view filter workspace entity.

This PR adds subFieldName where missing in frontend, notably in
applyFilter calls, that will be refactored soon.

Also fixes a bug in ViewBar where Add Filter button was at the right
side of the ViewBar, while it should be right after the chips section.

Another bug fixed where we wouldn't delete an empty record filter on
dropdown click outside from the view bar, which was already the case
where using the filter chip dropdown.

<img width="512" alt="image"
src="https://github.com/user-attachments/assets/e9a2f8d2-a66f-4800-853a-4df5c6b627a9"
/>

<img width="495" alt="image"
src="https://github.com/user-attachments/assets/7542697b-0689-4095-9c3c-b5e47875355f"
/>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-17 15:03:56 +00:00
Baptiste DevessierandGitHub 1ba0c24071 Set the page hotkey scope only once (#11626)
The `useEffect` in the `PageChangeEffect` component that sets the page's
hotkey scope is run 4-5 times every time the page changes. It should be
executed only once when the location changes. The re-runs are due to
unstable dependencies that shouldn't re-trigger the `useEffect`.

This PR minimizes the re-runs of the `useEffect`. In the following
video, I discuss a more global pattern.

The documentation for the `useEffectEvent` hook:
https://react.dev/learn/separating-events-from-effects#extracting-non-reactive-logic-out-of-effects.


https://github.com/user-attachments/assets/8c0c238b-f1c4-4bbb-b083-0825f7176599
2025-04-17 16:57:49 +02:00
Antoine MoreauxandGitHub 21c3edf8d6 fix(integration-tests): auth with multiworkspace and skip clickhouse … (#11630)
…tests
2025-04-17 14:49:57 +00:00
EtienneandGitHub a7b75c61e8 fix billing command - add workflow subscription item (#11631)
to migrate user with trialing or paused subscription status with trial
end behaviour 'paused'
2025-04-17 16:23:03 +02:00
f40aafb89f fix: reflect on #10521 changes to order-by-input-factory.ts file (#10662)
# This PR

Fixes an error on the FindMany REST API
I was getting the following error:
```
{
  "statusCode": 400,
  "error": "TypeError",
  "messages": [
    "Cannot read properties of undefined (reading 'fields')"
  ]
}
```
Now, it's working as expected
Related to #10521

cc: @Weiko @ijreilly

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-04-17 16:06:53 +02:00
42e060ac74 Ws poc (#11293)
related to https://github.com/twentyhq/core-team-issues/issues/601

## Done
- add a `onDbEvent` `Subscription` graphql endpoint to listen to
database_event using what we have done with webhooks:
- you can subscribe to any `action` (created, updated, ...) for any
`objectNameSingular` or a specific `recordId`. Parameters are nullable
and treated as wildcards when null.
  - returns events with following shape
```typescript
  @Field(() => String)
  eventId: string;

  @Field()
  emittedAt: string;

  @Field(() => DatabaseEventAction)
  action: DatabaseEventAction;

  @Field(() => String)
  objectNameSingular: string;

  @Field(() => GraphQLJSON)
  record: ObjectRecord;

  @Field(() => [String], { nullable: true })
  updatedFields?: string[];
```
- front provide a componentEffect `<ListenRecordUpdatesEffect />` that
listen for an `objectNameSingular`, a `recordId` and a list of
`listenedFields`. It subscribes to record updates and updates its apollo
cached value for specified `listenedFields`
- subscription is protected with credentials

## Result

Here is an application with `workflowRun`


https://github.com/user-attachments/assets/c964d857-3b54-495f-bf14-587ba26c5a8c

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-04-17 16:03:51 +02:00
Thomas TrompetteandGitHub b112d06f66 Fix onClick on forms (#11624)
As title
2025-04-17 13:53:40 +00:00
Charles BochetandGitHub 56874bf84b Fix aggregate bar (#11620)
Closes https://github.com/twentyhq/twenty/issues/10943

Also adds stories:
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/377059b1-f6b5-4d8c-b7d1-e74e70448445"
/>
2025-04-17 15:29:20 +02:00
Thomas TrompetteandGitHub d2881bb4a2 Allow workflow field update when custom (#11619)
- Allow workflow field update when custom
- Also handle the case where object name is not defined in actions
2025-04-17 15:01:18 +02:00
GuillimandGitHub 1401f80081 Messaging : better logging (#11621)
Better error logging for messaging import exception handler.

Goal is to have better info on why Unknown errors are thrown and avoid
such messages `Unknown error occurred while importing messages for
message channel XXXXXXXX in workspace YYYYYYYYYY: Unknown error occurred
while importing messages for message channel XXXXXXXX...`
2025-04-17 14:16:05 +02:00
EtienneandGitHub 71dbd1d66b fix: re-init subscription items when user ends his trial period (#11616) 2025-04-17 13:53:37 +02:00
GuillimandGitHub 6e7956b990 logs removal (#11618)
view with Martin, not necessary any longer
2025-04-17 10:01:05 +00:00
martmullandGitHub 0469aba90b Improve from in send email action (#11581)
## Before
<img width="701" alt="image"
src="https://github.com/user-attachments/assets/77184775-5b06-4777-9276-1338cc457070"
/>

## After
<img width="705" alt="image"
src="https://github.com/user-attachments/assets/9528eb0e-54c3-452c-8297-27796ccc75a1"
/>
2025-04-17 11:34:55 +02:00
Antoine MoreauxandGitHub e457ade362 chore(constants): add TrackAnalytics to excluded operations (#11617)
Included TrackAnalytics in the list of excluded middleware operations.
This ensures consistent handling of operations that bypass middleware
processing.
2025-04-17 11:24:45 +02:00
Vaibhav DevereandGitHub 6023bda579 Drop await usage for now-synchronous encodeFileToken() (#11612)
### Remove unnecessary `await` from `encodeFileToken` calls (now
synchronous) #11611

####  Context

In [PR #11385 – commit
26c17f3](https://github.com/twentyhq/twenty/pull/11385/commits/26c17f3205eb0cf4b93dd37cfec97638596ed263),
`FileService.encodeFileToken()` was updated to be a **synchronous**
method. However, several places in the codebase were still calling it
using `await`.

####  Changes 
This PR cleans up those redundant `await` usages to:
- Improve clarity
- Avoid confusion (no longer awaiting a non-Promise)
- Slightly reduce overhead in affected functions
- Removed `await` from calls to `this.fileService.encodeFileToken(...)`
2025-04-17 10:55:54 +02:00
9e9ba73a43 better handling the function argument without touching it (#11614)
leave intact the `input` argument to avoid side effects on the parent
caller

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-17 08:54:56 +00:00
nitinandGitHub d89474d43b Fix tab icon alignment issue (#11613)
before:
![Screenshot 2025-04-17 at 13 40
00](https://github.com/user-attachments/assets/b29b3e6b-0185-4289-950c-37a24b63cb65)

after:
![Screenshot 2025-04-17 at 13 39
49](https://github.com/user-attachments/assets/af2efe6f-3908-40d6-acde-d2839a5a8ba2)
2025-04-17 10:29:51 +02:00
GuillimandGitHub b5e6600c73 Capitalize labels objectmetadata (#11609)
Capitalize labels singular and plural from objectmetadata

Fixes [#664](https://github.com/twentyhq/core-team-issues/issues/664)
2025-04-16 21:02:12 +00:00
thomasdnGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
3ad110da33 Added support for podman deployment (#11600)
Added files needed to deploy twenty on podman using podman-compose.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-16 22:08:14 +02:00
Antoine MoreauxandGitHub 587281a541 feat(analytics): add clickhouse (#11174) 2025-04-16 16:33:10 +00:00
b6901a49bf Fix-inline-height (#11608)
Follow up from inline height #11553 related to PR #11442


we had some issues with hover styles

Fixes
https://github.com/twentyhq/twenty/issues/11442#issuecomment-2805893663

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-16 17:49:04 +02:00
e1b99a6f39 Fix Account Owner Dropdown to Display Team Member Profile Pictures #11370 (#11385)
#11370  & #11402
### Changes made:
1. Updated search.service.ts to properly handle workspace member avatar
and Person Avatar URLs with authentication tokens
2. Integrated FileService for token generation
3. Added FileModule to SearchModule for dependency injection

### Implementation details:
- Used getImageUrlWithToken to append authentication tokens to avatar
URLs specifically for workspace members

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-04-16 17:46:37 +02:00
MarieandGitHub 4d78f5f97f [permissions] Improve performances using a cache for userWorkspaces roles (#11587)
In this PR we are 

- introducing a cached map `{ userworkspaceId: roleId } `to reduce calls
to get a userWorkspace's role (we were having N+1 around that with
combinedFindMany queries and generally having a lot of avoidable
queries)
- using the roles permissions cache (`{ roleId: { objectNameSingular:
{ canRead: bool, canUpdate: bool, ...} } `) in Permissions V1's
userHasObjectPermission, in order to 1) improve performances to avoid
calls to get roles 2) start using our permissions cache
2025-04-16 17:07:43 +02:00
Félix MalfaitandGitHub ab277476a8 Remove Sentry fingerprint (#11602)
As discussed this @ijreilly, Fingerprinting is probably not needed and
Sentry will do a better job by itself
2025-04-16 16:25:40 +02:00
nitinandGitHub c95a84c8e5 update KeyValuePairType enum and add IS_CONFIG_VAR_IN_DB_ENABLED config var (#11596)
closes https://github.com/twentyhq/core-team-issues/issues/758
2025-04-16 16:23:57 +02:00
Thomas TrompetteandGitHub 78e10b2da5 Update next step ids on step update (#11605)
When inserting a new step between step 1 et step 2, then step 1 should
have the new step as next step id, add stop having step 2.

When deleting a step, we link the parent and next steps together. It may
change in the future
2025-04-16 15:30:05 +02:00
bf704bd1bc Improve CSV import sub-field selection (#11601)
This PR adds a better UX for selecting sub-fields when importing CSV
files.

Before : 

<img width="395" alt="image"
src="https://github.com/user-attachments/assets/5a599e7d-ed07-4531-8306-9d70e7cfa37d"
/>

After : 

<img width="298" alt="image"
src="https://github.com/user-attachments/assets/2be8a1df-d089-4341-970e-6db2b269141e"
/>

<img width="296" alt="image"
src="https://github.com/user-attachments/assets/584285f4-4e71-4abd-9adf-11819cab0dc5"
/>

- A util `getSubFieldOptionKey` has been made to be able to reference
the sub field in the `options` object of the spreadsheet import.
- New components have been created :
`MatchColumnSelectFieldSelectDropdownContent`,
`MatchColumnSelectSubFieldSelectDropdownContent` and
`MatchColumnSelectV2`
- Extracted the hard-coded option do not import into a constant
`DO_NOT_IMPORT_OPTION_KEY`
- Passed `availableFieldMetadataItems` to spreadsheet global options so
it's available anywhere in the hierarchy of components.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-16 15:08:24 +02:00
Baptiste DevessierandGitHub b1c0613514 Fix execution permissions (#11604)
The PR https://github.com/twentyhq/twenty/pull/11400 introduced changes
to the execution permissions of many executable files. These changes
aren't correct and must be reverted.

cc. @charlesBochet
2025-04-16 11:46:37 +02:00
GuillimandGitHub db8a60fe6f more logging to look at calendar errors (#11603)
Adding more logs to look at calendar errors that we have currently

Should help investigation on
https://twenty-v7.sentry.io/issues/5182547220/events/7e8b168887384ede8397e79c15adeb50/?project=4507072499810304
2025-04-16 11:46:02 +02:00
b7cfe89b14 Onboarding doc update (#11599)
Co-authored-by: Weiko <corentin@twenty.com>
2025-04-16 09:55:57 +02:00
madanlal mohanrao nikaljeandGitHub 4c2c9e4273 Refactor webhook event name generation in OpenApiService (#11592)
Fixes - #11589
POT - 
![Screenshot 2025-04-16 at 12 39
11 AM](https://github.com/user-attachments/assets/43802e1a-1ece-4b44-831f-35d70285c5fb)
2025-04-16 08:03:47 +02:00
Charles Bochet 981b1bd767 Fix stories 2025-04-15 23:41:30 +02:00
Charles Bochet 53c6ddb2ad Fix stories 2025-04-15 19:05:14 +02:00
EtienneandGitHub 6f78a51da4 fix query param init before workspace redirection (#11590) 2025-04-15 18:47:26 +02:00
WeikoandGitHub 43af5ceb5e Add object level permission permissions to role page (ReadOnly) (#11568)
## Context
This PR adds the display of object-level permissions. A following PR
will add the ability to update those permissions.
The PR contains the SettingsRoleObjectLevel page but it's not fully
implemented yet (save won't trigger the corresponding mutation)

<img width="616" alt="Screenshot 2025-04-14 at 18 02 40"
src="https://github.com/user-attachments/assets/f8c58193-31f3-468a-a96d-f06a9f2e1423"
/>
2025-04-15 18:46:36 +02:00
Baptiste DevessierandGitHub c23942ce6f Order the workflow run's output properly in the JsonFieldDisplay (#11583)
In this PR:

- Order the workflow run's output in the JsonField Display; the order
should be: error, stepsOutput, flow
- Ensure the special characters are hidden in the JSON visualizer
- Add missing scenarios to Json Tree's stories as it ensures Chromatic
checks them


https://github.com/user-attachments/assets/2ca5ae1d-fdba-4327-bad2-246fd9d23cb9

Closes https://github.com/twentyhq/core-team-issues/issues/804
2025-04-15 18:40:53 +02:00
8bd7b78825 Moved Select Options to External Files (#11400)
This is a minor rework of PR #10738.

I noticed an inconsistency with how Select options are passed as props.
Many files use constants stored in external files to pass options props
to Select objects. This allows for code reusability. Some files are not
passing options in this format.

I modified more files so that they use this method of passing options
props. I made changes to:
- WorkerQueueMetricsSection.tsx 
- SettingsDataModelFieldBooleanForm.tsx 
- SettingsDataModelFieldTextForm.tsx 
- SettingsDataModelFieldNumberForm.tsx 
- PlaygroundSetupForm.tsx 
- ViewPickerContentCreateMode.tsx 

I also noticed that some of these files were incorrectly using
useLingui(), so I fixed the import and usage where needed.

---------

Co-authored-by: Beau Smith <bsmith26@iastate.edu>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-15 18:31:17 +02:00
EtienneandGitHub 797bb0559a create stripe customer before checking out + update on command (#11578)
two distincts fix in this PR

- add billing threshold for current users (in migration command)
- create stripe customer before checking out in order to enable cloud
user to create multiple workspaces (with associated stripe customer -
closes https://github.com/twentyhq/core-team-issues/issues/852)
2025-04-15 18:02:35 +02:00
Charles BochetandGitHub dee779179b Remove user action from waitFor in stories (#11588)
As per title:
- waitFor is a loop that waits for a condition to be filled, it should
be use to expect or in rare case to wait for element to be present in
the page (in most cases, you can use findByXXX)
- user actions should not be in this loop, otherwise they will be
triggered multiple times
2025-04-15 17:34:28 +02:00
Thomas TrompetteGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
c40baf036c Add command to backfill next step id on version and run steps (#11579)
- add next step id on step
- backfill next step id on step, except for the last one
- backfill flow for workflow run, when it exists

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-15 15:26:58 +00:00
GuillimandGitHub d3922a7f5b removing RecordTableEmptyStateByGroupNoRecordAtAll (#11584)
We found out that `RecordTableEmptyStateByGroupNoRecordAtAll` was used
only when `hasRecordGroups` was true in "RecordTableEmptyState"

However the only parent component is RecordTableEmpty and called
RecordTableEmptyState when `hasRecordGroups` was false

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

Meaning never called at all
2025-04-15 16:52:09 +02:00
Charles BochetandGitHub 3c189688d0 Fix stories (#11585)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/f77a006c-9538-4734-b80e-b58b9f5e7835"
/>
2025-04-15 16:11:31 +02:00
Lucas BordeauandGitHub aa399ca91e Fix a bug that overwrites currentRecordFilters when using URL filtered view (#11525)
This PR fixes a bug that happened when navigating to a filtered view
from a record show page related record section, clicking on 'All'.

The problem was that the QueryParamsFiltersEffect effect component was
overwriting the currentRecordFilter of a different object metadata item
than the current view.

Which when we navigated back on the original view, had emptied the
filters, while they shouldn't change if we only navigate without
refreshing the app.

Fixes https://github.com/twentyhq/core-team-issues/issues/657
2025-04-15 15:32:41 +02:00
GuillimandGitHub 5c23b52c0d multiline CSS aligned to the top (#11582)
Updating CSS for inline cells so that multilie works fine and are
aligned to the top

Fixes
https://github.com/twentyhq/core-team-issues/issues/757?issue=twentyhq%7Ctwenty%7C11495
2025-04-15 13:15:37 +00:00
Charles BochetandGitHub 7bab6cab41 Fix storybook and chromatic tests and fix Block editor custom slash menu positioning (#11580)
Storybook / Chromatic fixes:
- fix linaria twenty-ui style loading (since twenty-ui prebuild
refactoring)
- update prefetch view mocks
- add ability to disable hotkeys initialization in storybook to avoid
race condition

Custom slash menu positioning fix
2025-04-15 14:57:35 +02:00
Murali SinghandGitHub 9da2a74d9e Fix inline field height #11442 (#11553)
Screenshots:

![Image](https://github.com/user-attachments/assets/998f2a88-53ab-49ef-8bb5-c7bef9158b0d)


![Image](https://github.com/user-attachments/assets/218c8f4b-f8d1-4d49-8029-8f99113f01ec)


![Image](https://github.com/user-attachments/assets/1dfde61a-62bb-403a-af3d-fb99c16ab29e)

@Bonapara Can you confirm is this what you expected ?
2025-04-15 14:42:21 +02:00
Charles BochetandGitHub d6ae4d59f0 Various fixes charles 3 (#11573) 2025-04-15 13:45:04 +02:00
Antoine MoreauxandGitHub f30070c2c9 feat(auth): enhance logo behavior and simplify billing logic (#11574)
Added default domain redirection functionality to the Logo component,
leveraging UndecoratedLink for navigation when default logos are used.
Removed metered product billing feature flag logic in the billing
webhook subscription service to simplify and streamline the codebase.

Fix https://github.com/twentyhq/core-team-issues/issues/783
2025-04-15 13:43:13 +02:00
GuillimandGitHub e1ce98825b Possiblity to reconnect on Failed unkown (#11576)
Possiblity to reconnect you account on Failed Unkown errors.

This PR triggers a similar flow than the Failed errors for unsufficient
permission already existing in twenty.

Allows our users to force the synchro again even though they have a
strange error. It's been asked by some customers since we have had a
couple of issues in messaging lately

Fixes https://github.com/twentyhq/twenty/issues/11411
2025-04-15 13:39:18 +02:00
e8db0176a1 Remove recoil sync (#11569)
Recoil-sync was causing issues with Firefox, replacing it with a simpler
mechanism to hydrate variables on page load

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-04-15 13:32:12 +02:00
Baptiste DevessierandGitHub 6c2d64dcb2 Fix e2e tests (#11577) 2025-04-15 12:16:38 +02:00
EtienneandGitHub 8b10059e1b fix - remove isMeteredProductBillingEnabled (#11575) 2025-04-15 11:15:02 +02:00
16fb4d406b i18n - translations (#11572)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-14 18:49:45 +02:00
Raphaël BosiandGitHub 8f2dddaa5f Create stories for action display components (#11547)
Create stories for:
- ActionButton
- ActionComponent
- ActionDisplay
- ActionDropdownItem
- ActionListItem
2025-04-14 18:42:49 +02:00
EtienneandGitHub 0249cf3b34 remove feature flag on billing metered product + fixes (#11570)
- remove feature flag
- design fixes
2025-04-14 18:39:19 +02:00
EtienneandGitHub 9a69cd0b61 add billing threshold + specific trial free credits (#11533)
In this PR : 
- set billing thresholds after subscription creation (not possible
during billing checkout)
- add specific free trial workflow credit quantities + set them in
subscription item + check them when receiving stripe alert event

closes : https://github.com/twentyhq/core-team-issues/issues/682
2025-04-14 16:25:07 +00:00
Baptiste DevessierandGitHub 704b18af30 Create FormRichTextField (#11474)
This PR adds a new Form Field for Rich Text V2 fields. The
implementation was relatively simple, thanks to @thomtrp's job on the
back-end side.

## Demo

### Edit mode + insert in database


https://github.com/user-attachments/assets/f44a6442-fad3-4ad9-af50-a7d90e872c90

### Readonly mode


https://github.com/user-attachments/assets/66243ddf-d4a2-4187-894c-356d9c02b2b2

Closes https://github.com/twentyhq/private-issues/issues/229
2025-04-14 18:07:09 +02:00
Baptiste DevessierandGitHub 0be700f376 Fix e2e tests (#11565)
Fixing the e2e tests
2025-04-14 17:47:57 +02:00
GuillimandGitHub 8a3f8ef324 Chip untitled modification (#11498)
Fixes https://github.com/twentyhq/core-team-issues/issues/663
2025-04-14 15:33:41 +00:00
MarieandGitHub d4deca45e8 Read feature flags from cache (#11556)
We are now storing a workspace's feature flag map in our redis cache. 
The cache is invalidated upon feature flag update through the lab
resolver.
2025-04-14 17:31:13 +02:00
Charles BochetandGitHub 15eb96337f Various fixes (#11567)
In this PR:
- Remove SignUpLoading blank screen by an empty dark overlay =>
VerifyEffect
- Add ModalContent from pages themselves instead of using it the Layout.
This allow for empty dark overlay without showing an empty modal with
padding
2025-04-14 17:24:16 +02:00
85d94822b3 Fix the Command menu items right padding #11484 (#11489)
Screenshot:
![Screenshot 2025-04-10 at 1 07
24 AM](https://github.com/user-attachments/assets/1e7ed8e7-594f-4ead-9b04-0c7dab636fbd)

---------

Co-authored-by: guillim <guigloo@msn.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-14 14:12:15 +02:00
Thomas TrompetteandGitHub 69a00eaaf6 Emit message event with actual message object (#11548)
Events were emitted with the wrong object. We were using
messageWithParticipant instead of actual message object
2025-04-14 13:49:19 +02:00
abecdbafc1 Add Edit Rich Text functionality to table view (#11390)
Fixes https://github.com/twentyhq/core-team-issues/issues/729


[recording.webm](https://github.com/user-attachments/assets/ea95d67b-64a3-4fef-91ed-b06318099a78)

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-14 11:46:22 +00:00
Charles BochetandGitHub 8f7a82f177 Fix refactor selectableList broke hotkey onEnter behavior (#11562) 2025-04-14 12:25:54 +02:00
4a123a8eac i18n - translations (#11560)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-14 11:11:30 +02:00
ace515eea7 Fix workflow with manual triggers and no selection not appearing in the command menu (#11544)
Fix workflow with manual triggers and no selection not appearing in the
command menu

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-14 11:03:29 +02:00
Lucas BordeauandGitHub b5a1d1a895 Improving empty filter chip UI (#11537)
This PR is simply removing the : character on the filter chip when the
filter value is empty.

The issue originally was about removing the filter chip when closing the
filter value dropdown with an empty value but it is already the default
behavior.

Fixes https://github.com/twentyhq/core-team-issues/issues/658
2025-04-14 10:43:20 +02:00
EtienneandGitHub 721a34864f create workflow subscription item addition command (#11541)
closes https://github.com/twentyhq/core-team-issues/issues/541
2025-04-14 10:41:37 +02:00
e2b2697fcc refacto dropdown v1>v2 in address input (#11549)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-14 10:37:40 +02:00
0de8140b3a CreateComponentFamilyState -> createComponentFamilyStateV2 (#11546)
Refacto of createComponentFamilyState

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-14 10:31:30 +02:00
Thomas TrompetteandGitHub 27f542e132 Use transformer in workflows (#11497)
We do not manage rich text properly in workflows. This is because API
has a layer called transformer service. Looks a bit as a duplicate of
format data, but this api layer was already there for position anyway.
Using it in workflow record actions.

I hope at some point we merged formatData util and transformer.
2025-04-11 16:31:45 +00:00
Baptiste DevessierandGitHub 897684f995 JSON Visualizer: ensure labels are 24px tall as all other elements (#11535)
## Before

![CleanShot 2025-04-11 at 14 42
15@2x](https://github.com/user-attachments/assets/a4726342-212a-40b3-829f-40cae7724fec)

## After

![CleanShot 2025-04-11 at 14 42
27@2x](https://github.com/user-attachments/assets/e84a4d81-fdcc-422e-b294-55867a4bc5fb)
2025-04-11 18:25:29 +02:00
MarieandGitHub 162c6bcaa3 [permissions] Implement object-records permissions in query builders (#11458)
In this PR we are

- (if permissionsV2 is enabled) executing permission checks at query
builder level. To do so we want to override the query builders methods
that are performing db calls (.execute(), .getMany(), ... etc.) For now
I have just overriden some of the query builders methods for the poc. To
do so I created custom query builder classes that extend typeorm's query
builder (selectQueryBuilder and updateQueryBuilder, for now and later I
will tackle softDeleteQueryBuilder, etc.).
- adding a notion of roles permissions version and roles permissions
object to datasources. We will now use one datasource per roleId and
rolePermissionVersion. Both rolesPermissionsVersion and rolesPermissions
objects are stored in redis and recomputed at role update or if queried
and found empty. Unlike for metadata version we don't need to store a
version in the db that stands for the source of truth. We also don't
need to destroy and recreate the datasource if the rolesPermissions
version changes, but only to update the value for rolesPermissions and
rolesPermissionsVersions on the existing datasource.

What this PR misses
- computing of roles permissions should take into account
objectPermissions table (for now it only looks at what's on the roles
table)
- pursue extension of query builder classes and overriding of their db
calling-methods
- what should the behaviour be for calls from twentyOrmGlobalManager
that don't have a roleId?
2025-04-11 17:34:02 +02:00
martmullandGitHub 82fa71c2cd Update canary package versions (#11543)
as title
2025-04-11 16:48:41 +02:00
WeikoandGitHub 04f9c5a5de Prepare 0.51 (#11542) 2025-04-11 16:00:24 +02:00
Charles BochetandGitHub 3018e3ac89 Fix date picker month/year dropdown (#11539)
Fixes https://github.com/twentyhq/twenty/issues/11524
2025-04-11 15:22:00 +02:00
GuillimandGitHub 2a8defe262 contact/company creations errors (#11540)
Seeing a couple of issues related to company creations in logs, I
suspect this to be the root cause

This should help a lot in all the support we have to do on email
synchronisation
2025-04-11 15:19:03 +02:00
Charles BochetandGitHub 9da5cca82a Fix dropdown width (#11536)
Fix regressions due to dropdown refactoring
2025-04-11 14:59:57 +02:00
Lucas BordeauandGitHub fe98deef4e Fixed command menu hotkey listener refactor (#11534)
This PR fixes a refactor that was done recently to avoid having
clickoutside listeners on the closed command menu.

The useScopedHotkey hook should have stayed in the command menu
container, because it should always listen.

This has been fixed.
2025-04-11 14:59:48 +02:00
03800ce6d0 i18n - translations (#11532)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-11 14:42:45 +02:00
martmullandGitHub 1794b3a611 Remove build lambda at creation (#11531)
Remove useless build call (done at first execution)
2025-04-11 14:40:00 +02:00
Baptiste DevessierandGitHub e8488e1da0 Only display Flow for Workflow Runs and display Output tab for triggers (#11520)
> [!WARNING]
> I refactored a bunch of components into utility functions to make it
possible to display the `WorkflowStepHeader` component for **triggers**
in the `CommandMenuWorkflowRunViewStep` component. Previously, we were
asserting that we were displaying the header in `Output` and `Input`
tabs only for **actions**. Handling triggers too required a bunch of
changes. We can think of making a bigger refactor of this part.

In this PR:

- Only display the Flow for Workflow Runs; removed the Code Editor tab
- Allows users to see the Output of trigger nodes
- Prevent impossible states by manually setting the selected tab when
selecting a node

## Demo

### Success, Running and Not Executed steps


https://github.com/user-attachments/assets/c6bebd0f-5da2-4ccc-aef2-d9890eafa59a

### Failed step


https://github.com/user-attachments/assets/e1f4e13a-2f5e-4792-a089-928e4d6b1ac0

Closes https://github.com/twentyhq/core-team-issues/issues/709
2025-04-11 14:31:34 +02:00
Raphaël BosiandGitHub c8011da4d7 Fix title input hotkey scope (#11530)
Before:


https://github.com/user-attachments/assets/e0be8247-6d3e-49d0-8595-76f9547bf354


After:


https://github.com/user-attachments/assets/ae23b01b-3ad7-4b90-b4ae-ce604d984d73
2025-04-11 14:22:31 +02:00
446919bc72 Remove onboarding flashes + close all dropdowns on CommandMenu close (#11483)
## Remove onboarding flashes

Tested:
- sign in with credentials
- sign in with social oAuth
- sign up with credentials
- multidomain
- single domain
- reset password

No more flashes, and code logic simplified!

## Close all dropdowns on CommandMenu close

Before:


https://github.com/user-attachments/assets/244ff935-3d40-47d5-a097-12d4cc3810dd


After:


https://github.com/user-attachments/assets/1de692f8-5032-404a-be74-025ebca67138

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-11 14:15:14 +02:00
Raphaël BosiandGitHub 637a7f0e64 Fix workflow dropdown hotkey scope (#11518)
The hokey scope was set on focus of the outermost container of the field
inputs. When clicking on a dropdown inside this container, the hokey
scope was set first by the dropdown and then by the focused container.
This led to the previous hotkey scope being overwritten.
The fix consists in moving the hokey scope setter on focus to the inner
container.

Before:


https://github.com/user-attachments/assets/12538c5b-43ab-4b76-a867-7eda6992b1ea


After:


https://github.com/user-attachments/assets/002fedba-010c-41e9-bec6-d5d80cb2dcc5
2025-04-11 09:07:36 +00:00
d34ec7b253 Fix: "Not shared" label not visible due to extra long email subject (#11492)
Closes #11408 

- Added `min-width: 100px` in `EmailThreadNotShared`
- Added `isShared` prop to `StyledSubject` for better subject handling
in shared visibility scenarios

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-11 10:13:33 +02:00
Thomas des FrancsandGitHub 04168e720c Update 0.51.0.mdx (#11517) 2025-04-11 10:12:31 +02:00
nitinandGitHub 0cccb80221 revert: transform -> marginLeft in DefaultLayout motion div (#11522) 2025-04-10 22:33:12 +02:00
Félix MalfaitandGitHub e6bb3d4d51 Change required permission for MS (#11519)
Change User.Read.All to User.Read in docs
2025-04-10 18:33:37 +02:00
Thomas des FrancsandGitHub 5a8006f1dd Update src/content/releases/0.51.0 2025-04-10 18:17:08 +02:00
martmullandGitHub b8406820ee Fix wrong filter for get requests (#11512)
- remove wrong exception filter for GET api requests
- remove messageThreadId requirements on messages for requests done with
API key (no user, only workspace)
- doing the same for calendarEvents
2025-04-10 17:29:53 +02:00
3e1b5d23f5 i18n - translations (#11515)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-10 17:10:55 +02:00
bc8f71fab5 wip: api playground fixes (#11345)
# ISSUE 
- closes #10926 

- [x] fix paddings
- [x] fix page change to playground animation
- [x] fixes multiple skeletons issues

---

- Also was showing multiple skeletons on reloading, **before**: 


https://github.com/user-attachments/assets/0cdef639-c121-4cbb-b056-b89e60862c54

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-10 17:02:55 +02:00
a86317eb71 i18n - translations (#11514)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-10 17:01:13 +02:00
EtienneandGitHub ee5aa2393d fix billingCheckoutSession query param + enable redirect on workspace… (#11509)
… during onboarding



fixes : https://github.com/twentyhq/core-team-issues/issues/668
2025-04-10 16:47:40 +02:00
WeikoandGitHub d69932c6c4 Fix boolean default value update not updating psql default value when false (#11513)
Fixes https://github.com/twentyhq/twenty/issues/11471

## Context
When sending false as a new defaultValue, this was not going through the
migration creation code due to this condition
```typescript
if (updatableFieldInput.defaultValue)
```
2025-04-10 16:23:16 +02:00
Thomas TrompetteandGitHub 6f5118c677 Remove fixed width for dropdown variables, fix optimistic on file upload (#11507)
As title
2025-04-10 16:07:32 +02:00
Lucas BordeauandGitHub f8f11894e8 Introduce generic way to close any open dropdown on page location change (#11504)
In this PR we introduce a generic way to close any open dropdown
idempotently, with the hook useCloseAnyOpenDropdown.

We also introduce a generic hook useExecuteTasksOnAnyLocationChange that
is called each time the page location changes.

This way we can close any open dropdown when the page location changes,
which fixes the original issue of having advanced filter dropdown
staying open between page changes.

Fixes https://github.com/twentyhq/core-team-issues/issues/659
2025-04-10 16:00:50 +02:00
1844c39a99 i18n - translations (#11511)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-10 15:47:28 +02:00
WeikoandGitHub 35c6cb4f4a fix chromatic 1 (#11510) 2025-04-10 15:44:12 +02:00
WeikoandGitHub 63a165666a fix error messages margin (#11508)
## Context
Fixing error messages margin in various places
Reset password
<img width="453" alt="Screenshot 2025-04-10 at 15 17 00"
src="https://github.com/user-attachments/assets/7a0fb090-4029-415f-8733-0c9e3aa3c3f2"
/>
Api key
<img width="543" alt="Screenshot 2025-04-10 at 15 16 21"
src="https://github.com/user-attachments/assets/d8f8a348-84d3-44d7-8cea-863c3ddb02fc"
/>

Also setting overflow on api key label in api keys table
<img width="580" alt="Screenshot 2025-04-10 at 15 16 15"
src="https://github.com/user-attachments/assets/207df981-c906-4926-a56d-38167628267f"
/>
2025-04-10 15:36:59 +02:00
Thomas TrompetteandGitHub b8d5f6d4b0 Center empty state on record table (#11506)
as title
2025-04-10 15:05:49 +02:00
martmullandGitHub 4e4c0ddd3c Add command to update serverless layer (#11500)
New command to add packages to serverless -> Run into your terminal
`npx nx run twenty-server:command serverless:add-packages -p
stripe@17.0.0,@slack/web-api,@slack/oauth`

Will create a new layer folder, add packages in it and update the new
last_layer_version

<img width="1468" alt="image"
src="https://github.com/user-attachments/assets/da8ee77f-e512-4ceb-95bc-cfa979f3439c"
/>

Before
<img width="877" alt="image"
src="https://github.com/user-attachments/assets/35f6bb6c-2ebf-46fe-bd15-4e6352901fc8"
/>

After
<img width="938" alt="image"
src="https://github.com/user-attachments/assets/785af132-5e8c-4a9a-bc57-dffdcaaeec02"
/>
2025-04-10 14:53:59 +02:00
WeikoandGitHub 1802c30995 Fix workspace menu width varies (#11505)
Before


https://github.com/user-attachments/assets/cd386034-bddd-4452-bb7f-2b3749ba74d6

After


https://github.com/user-attachments/assets/07ab40b1-0f8d-4b80-b0db-ad1ea8c584f7
2025-04-10 14:47:40 +02:00
Thomas TrompetteandGitHub 5b1091b19e Store trigger output (#11503)
As title. Trigger output is the workflow payload
2025-04-10 14:36:15 +02:00
cc6043be9f i18n - translations (#11502)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-10 14:11:46 +02:00
145ddba721 fix settings container vertical scroll position (#11464)
@charlesBochet is this flex needed here? we don't use flex-specific
properties.

I did check all scrolls seem to be working fine, could u please check
once more? thanks :)


before:
<img width="1512" alt="Screenshot 2025-04-09 at 12 59 25"
src="https://github.com/user-attachments/assets/1b0066e3-c3f7-4bd8-829b-174d2747ee66"
/>

after:
<img width="1512" alt="Screenshot 2025-04-09 at 12 58 13"
src="https://github.com/user-attachments/assets/06b103ed-d72f-4bc3-b530-7ae25542f568"
/>

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-10 14:11:21 +02:00
db88c93eff Navigation drawer refactor (#11251)
closes #11195
closes #11199

### Context

The yellow dots in the Settings Navigation Drawer (used to indicate
advanced settings) were being hidden due to ScrollWrapper's overflow
handling. This required both a fix for the visibility issue and an
improvement to the component structure.

### Changes
1. Keep scrolling logic of the MainNavigationDrawer and
SettingsNavigationDrawer in one place, and conditionally apply
`<StyledScrollableInnerContainer>` when isSettingsDrawer is true.

2. Fixed Yellow Dots Visibility
Added specific padding in NavigationDrawerScrollableContent to
accommodate yellow dots:
```
  padding-left: ${theme.spacing(5)}; // Space for yellow dots
  padding-right: ${theme.spacing(8)}; // Space for no-padding scroll
  ```
  
  This ensures the yellow dots are visible while maintaining proper scroll behavior

3. Improved Component Composition
Using proper component composition instead of passing components as props
Components are now composed in a more React-idiomatic way:
```
  <NavigationDrawer>
    <NavigationDrawerScrollableContent>
      <SettingsNavigationDrawerItems />
    </NavigationDrawerScrollableContent>
    <NavigationDrawerFixedContent>
      <AdvancedSettingsToggle />
    </NavigationDrawerFixedContent>
  </NavigationDrawer>
  ```

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-10 14:05:10 +02:00
WeikoandGitHub 41674129c3 Fix sign-in-up sso buttons width (#11499)
## Context
An enforced width was introduced recently for error texts but broke
Microsoft sso placement due to its longer text.
I've replaced it by a min-width and introduced the missing one in global
signin/up.

Before
<img width="456" alt="Screenshot 2025-04-10 at 12 14 51"
src="https://github.com/user-attachments/assets/43f29c63-f257-4c1c-9c16-b0170343c43e"
/>

After
<img width="494" alt="Screenshot 2025-04-10 at 12 14 17"
src="https://github.com/user-attachments/assets/17c4362a-1336-4adc-aeb9-76c6dcd059c6"
/>
2025-04-10 13:51:21 +02:00
Raphaël BosiandGitHub b84a31cb8a Create open side panel page action (#11481)
Closes https://github.com/twentyhq/core-team-issues/issues/697
2025-04-10 11:34:34 +02:00
Raphaël BosiandGitHub 4a4ce9a6fe Fix PageHeaderToggleCommandMenuButton (#11496)
This PR fixes a bug introduced by
https://github.com/twentyhq/twenty/pull/11470

Before:


https://github.com/user-attachments/assets/8c1b8114-591f-4b58-a177-551c4f0dfb98

After:


https://github.com/user-attachments/assets/b93aa498-2ae8-4001-b541-372866d24f54
2025-04-10 11:29:45 +02:00
Charles BochetandGitHub a7e6564017 Make token update synchronous on FE (#11486)
1. Removing tokenPair internal variable of ApolloFactory. We will relay
on cookieStorage
2. setting the cookie explicitely instead of only relaying on recoil
cookieEffect which is too late
2025-04-10 01:39:25 +02:00
WeikoandGitHub 7bd68ad176 Fix event propagation after record creation (#11485)
Fixes https://github.com/twentyhq/twenty/issues/11460
2025-04-10 01:37:26 +02:00
Lucas BordeauandGitHub 2b77f598b2 Fixed (#11482)
This PR fixes many small bugs around the recent hotkey scope refactor.

- Removed unused ActionBar files
- Created components CommandMenuOpenContainer and
KeyboardShortcutMenuOpenContent to avoid mounting listeners when not
needed
- Added DEFAULT_CELL_SCOPE where missing in some field inputs
- Called setHotkeyScopeAndMemorizePreviousScope instead of
setHotkeyScope in new useOpenFieldInputEditMode hook
- Broke down RecordTableBodyUnselectEffect into multiple simpler effect
components that are mounted only when needed to avoid listening for
keyboard and clickoutside event
- Re-implemented recently deleted table cell soft focus component logic
into RecordTableCellDisplayMode
- Created component selector isAtLeastOneTableRowSelectedSelector
- Drill down hotkey scope when opening a dropdown
- Improved debug logs
2025-04-09 18:34:31 +02:00
GuillimandGitHub 9f4e8c046f Messaging-unit-tests (#11467)
# Unit test on the Messaging Module

Initially the issue was to create integration test for the messaging
module but after speaking with the core team, we decided to go for an
easier implementation: unit test only,

We decided to focus our test on three main components of the module :  
- message list
- message import
- message save & create contact

Fixes https://github.com/twentyhq/core-team-issues/issues/56
2025-04-09 17:57:43 +02:00
Charles BochetandGitHub e23688cb41 Fix lint issues (#11475) 2025-04-09 17:35:25 +02:00
b6c079f050 Fixed Navbar padding issue #11438 (#11470)
@Bonapara 
Related Issue: Fixes #11438.

Screenshot:
![Screenshot 2025-04-09 at 4 10
41 PM](https://github.com/user-attachments/assets/4c5346b6-4e1c-4441-bd8a-b88aee139b9b)

---------

Co-authored-by: guillim <guigloo@msn.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-09 17:22:49 +02:00
Thomas TrompetteandGitHub 5d9cd257ae Command menu mobile - Prevent overflow on navigation bar (#11480)
Fix https://github.com/twentyhq/twenty/issues/11413
2025-04-09 17:16:46 +02:00
Thomas TrompetteandGitHub 025e50645d Avoid settings object cover image to be reduced on scroll (#11473)
Fix https://github.com/twentyhq/twenty/issues/11420
2025-04-09 16:43:25 +02:00
Raphaël BosiandGitHub 9e0402e691 Action menu refactoring (#11454)
# Description

Closes [#696](https://github.com/twentyhq/core-team-issues/issues/696)

- `useAction` hooks have been removed for all actions
- Every action can now declare a react component
- Some standard action components have been introduced: `Action`,
`ActionLink` and `ActionModal`
- The `ActionDisplay` component uses the new `displayType` prop of the
`ActionMenuContext` to render the right component for the action
according to its container: `ActionButton`, `ActionDropdownItem` or
`ActionListItem`
- The `ActionDisplayer` wraps the action component inside a context
which gives it all the information about the action
-`actionMenuEntriesComponenState` has been removed and now all actions
are computed directly using `useRegisteredAction`
- This computation is done inside `ActionMenuContextProvider` and the
actions are passed inside a context
- `actionMenuType` gives information about the container of the action,
so the action can know wether or not to close this container upon
execution
2025-04-09 13:12:49 +00:00
Lucas BordeauandGitHub 1834b38d04 Fix show page relation record count (#11459)
This PR fixes the incorrect relation count on a show page relation
section title, when there are more than 60 records.

An aggregate COUNT query has been used to rely on the backend.

A new component RecordDetailRelationSectionDropdown has been created to
abstract a chunk of the parent RecordDetailRelationSection component.

Fixes https://github.com/twentyhq/twenty/issues/11032
2025-04-09 14:41:11 +02:00
nitinandGitHub bd3ec6d5e3 rename core-module environment to twenty-config (#11445)
closes https://github.com/twentyhq/core-team-issues/issues/759
2025-04-09 14:11:26 +02:00
MarieandGitHub fe6d0241a8 [permissions] Allow logo update during sign-up (#11468)
Fixes https://github.com/twentyhq/twenty/issues/11410
2025-04-09 13:58:30 +02:00
c6203d8928 i18n - translations (#11469)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-09 11:34:35 +02:00
8582bcccf5 remove billing stripe plan product id from env (#11461)
Fixes https://github.com/twentyhq/core-team-issues/issues/661
remove billing stripe plan product id from env

Co-authored-by: Keshav Gupta <keshavgupta@Keshavs-MacBook-Air.local>
2025-04-09 11:31:38 +02:00
EtienneandGitHub 11fb8e0284 add metered products usage (#11452)
- add metered products usage module on settings/billing page
- add new resolver + logic with meter event data fetching from Stripe

<img width="590" alt="Screenshot 2025-04-08 at 16 34 07"
src="https://github.com/user-attachments/assets/34327af1-3482-4d61-91a6-e2dbaeb017ab"
/>
<img width="570" alt="Screenshot 2025-04-08 at 16 31 58"
src="https://github.com/user-attachments/assets/55aa221a-925f-48bf-88c4-f20713c79962"
/>

- bonus : disable subscription switch from yearly to monthly

closes https://github.com/twentyhq/core-team-issues/issues/681
2025-04-09 09:26:49 +00:00
Thomas des FrancsandGitHub b25ee28c12 Update CONTRIBUTING.md (#11465)
Updated the issue assignment policy for good first issues to prioritize
PRs over Issue assignments.
2025-04-09 11:16:13 +02:00
Thomas TrompetteandGitHub 46bbf02431 Emit event on message creation (#11466)
adding event emitting on message creation
2025-04-09 11:04:43 +02:00
GuillimandGitHub c6be260fec datasource TTL fix (#11444)
Comparing the last date a datasource was used instead of a fixed TTL :
should fix workers issues "error: Error: Connection terminated"

FYI was done in pair prog with @Weiko
2025-04-09 10:08:20 +02:00
ccdc2835a2 i18n - translations (#11463)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-09 01:20:17 +02:00
b6e344e7be Various fixes (#11448)
# Scrollbar fix

Fixes https://github.com/twentyhq/twenty/issues/11403

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/b13fe0f2-8c61-4ea8-9ea1-e61e571a90da"
/>

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-04-09 01:03:43 +02:00
ab63214efa Added Proper theme color for Favorite Input box (#11434)
#11418  The background color changes based on the theme.
 - If the theme is 'light', the background color will be white.
- Otherwise, it will use the theme's background transparent lighter
color.

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
2025-04-08 20:46:36 +00:00
martmullandGitHub f121c94d4a 701 workflow improve webhook triggers (#11455)
as title

Nota bene: I did not filter execution by http method. A POST webhook
trigger can be triggered by a GET request for more flexibility. Tell me
if you think it is a mistake


https://github.com/user-attachments/assets/1833cbea-51a8-4772-bcd8-088d6a087e79
2025-04-08 19:01:22 +00:00
2f7f28a574 i18n - translations (#11457)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-08 18:37:10 +02:00
Baptiste DevessierandGitHub 6521d19238 Use JSON visualizer for JSON fields (#11428)
- Updates on the JSON field input
  - Previously, we were editing json fields in a textarea 
- Now, we display a JSON visualizer and the user can click on an Edit
button to edit the JSON in Monaco
- The JSON field input has a special behavior for workflow run output.
We want the error to be displayed first in the visualizer. Displaying
the error in red was optional but makes the output clearer in the
context of a workflow run record board.
- Made the code editor transparent in the json field input
- Ensure workflow run's output is not considered readonly in
`packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueReadOnly.ts`;
we want the json visualizer to always be displayed in this specific case

## Demo

### Failed Workflow Run


https://github.com/user-attachments/assets/7a438d11-53fb-4425-a982-25bbea4ee7a8

### Any JSON field in the record table


https://github.com/user-attachments/assets/b5591abe-3483-4473-bd87-062a45e653e3

Closes https://github.com/twentyhq/core-team-issues/issues/539
2025-04-08 16:18:36 +00:00
EtienneandGitHub c1d421de06 remove default meter driver (#11456)
Remove default meter driver to prevent metric logs from polluting the
console.
2025-04-08 18:17:58 +02:00
Thomas TrompetteandGitHub dd1d9c32c3 Remove task, note and file tabs for workflows (#11453)
Command menu tries to fetch task, file and notes that are not available
for workflow entities. Hiding those tabs
2025-04-08 17:35:41 +02:00
Thomas TrompetteandGitHub a049cd4a25 Update placeholder on record picker object type update (#11451)
- requires a refacto so several fields can be updated at once
- updating object name on record picker will now update placeholder
- add a min-height to label so fields do not get moved when the label is
deleted
2025-04-08 14:20:15 +00:00
6611fbf9ac Fix : Menu shouldn't be displayed on logged out pages (#11437)
#11414 
Conditionally render MobileNavigationBar based on user authentication
status
- Added useIsLogged hook to check if the user is authenticated.
- Updated MobileNavigationBar component to render only when the user is
logged in.
![Screenshot from 2025-04-08
12-33-04](https://github.com/user-attachments/assets/1b58a5ac-e5ff-418f-a903-b952f37db84d)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-08 11:54:21 +02:00
Charles BochetandGitHub 17474a0e1e Remove cell hotkey scope (#11435)
Remove FieldContext hotkey scope as:
- each Field should set its own hotkey scope (ex:
emails-field-input-{recordId} or emails-field-input for now)
- while opening a fieldInput, we should synchronously set the
corresponding hotkey scope

To cut this refactoring in half, I'm allowing all input to use
TableHotkeyScope.CellEditMode
2025-04-08 11:18:23 +02:00
3d90eb4eb9 Fix broken dropdown auto resize behavior (#11423)
This PR was originally about fixing advanced filter dropdown auto resize
to avoid breaking the app main container, but the regression is not
limited to advanced filter dropdown, so this PR fixes the regression for
every dropdown in the app.

This PR adds a max dropdown max width to allow resizing dropdowns
horizontally also, which can happen easily for the advanced filter
dropdown.

In this PR we also start removing `fieldMetadataItemUsedInDropdown` in
component `AdvancedFilterDropdownTextInput` because it has no impact
outside of this component which is used only once.

The autoresize behavior determines the right padding-bottom between
mobile and PC.

Mobile : 

<img width="604" alt="Capture d’écran 2025-04-07 à 16 03 12"
src="https://github.com/user-attachments/assets/fbdd8020-1bfc-4e01-8a05-3a9f114cdd40"
/>

PC :

<img width="757" alt="Capture d’écran 2025-04-07 à 16 03 30"
src="https://github.com/user-attachments/assets/f80a5967-8f60-40bb-ae3c-fa9eb4c65707"
/>

Fixes https://github.com/twentyhq/core-team-issues/issues/725
Fixes https://github.com/twentyhq/twenty/issues/11409

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-08 11:03:10 +02:00
Félix MalfaitandGitHub 89abf3db4f Remove dead code to backfill record positions (#11439)
Fixes https://github.com/twentyhq/core-team-issues/issues/767
2025-04-08 11:02:40 +02:00
8b5c259c36 i18n - translations (#11441)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-08 11:01:29 +02:00
ea93ac6348 fetch latest version tag from docker hub (#11362)
closes #11352

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-08 08:55:03 +00:00
eliasylonenandGitHub 95eba07f6e Share RICH_TEXT_V2 field value override between REST and GraphQL APIs (#10912)
Fixes issue #10606.

This PR makes `RICH_TEXT_V2` field behavior in REST API matche the
current behavior in GraphQL API:

Currently both `markdown` and `blocknote` fields must be included in the
request, one of them can be `null`. The field with a `null` value will
be filled by the converted value of the other field.

In other words, this works:
```
curl http://localhost:3000/rest/notes \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC0xYzI1LTRkMDItYmYyNS02YWVjY2Y3ZWE0MTkiLCJ0eXBlIjoiQVBJX0tFWSIsIndvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWMyNS00ZDAyLWJmMjUtNmFlY2NmN2VhNDE5IiwiaWF0IjoxNzQxODA1MzQyLCJleHAiOjQ4OTU0MDUzNDEsImp0aSI6ImZlMzU0NTBkLTlhMDMtNGE2ZS04ODVjLTBlNTU3M2Y3YTE0NiJ9.6_g8cwoSE7ZCX1Zzsw44gZIyBdLKNsnDqMOmm1bKik0' \
  --data '{
  "position": 1,
  "title": "a",
  "bodyV2": {    
    "markdown": "test4\n\ntest3\n\n# test1\n",
    "blocknote": null
  },
  "createdBy": {
    "source": "EMAIL"
  }
}'
```

And this does not work:
```
curl http://localhost:3000/rest/notes \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC0xYzI1LTRkMDItYmYyNS02YWVjY2Y3ZWE0MTkiLCJ0eXBlIjoiQVBJX0tFWSIsIndvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWMyNS00ZDAyLWJmMjUtNmFlY2NmN2VhNDE5IiwiaWF0IjoxNzQxODA1MzQyLCJleHAiOjQ4OTU0MDUzNDEsImp0aSI6ImZlMzU0NTBkLTlhMDMtNGE2ZS04ODVjLTBlNTU3M2Y3YTE0NiJ9.6_g8cwoSE7ZCX1Zzsw44gZIyBdLKNsnDqMOmm1bKik0' \
  --data '{
  "position": 1,
  "title": "",
  "body": "",
  "bodyV2": {    
    "markdown": "test4\n\ntest3\n\n# test1\n"
  },
  "createdBy": {
    "source": "EMAIL"
  }
}'
```

---

It would be nice not to require the null value, maybe let's make that a
separate PR?
2025-04-07 23:30:53 +02:00
6bc18960c9 Show Header in RecordTable on empty state and show groups in Group By views (#11416)
Closes #11298

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-07 22:05:59 +02:00
07b25a2aad i18n - translations (#11432)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-07 19:33:05 +02:00
Charles BochetandGitHub 20895f1129 Fix views reordering (#11431)
As per title
2025-04-07 19:18:05 +02:00
Thomas TrompetteandGitHub 17b7e703b4 Refacto form select input (#11426)
- small fixes on form design
- refacto form select input to use the existing select component
2025-04-07 16:56:59 +00:00
WeikoandGitHub ff59658d39 Fix permission check during onboarding (#11429)
## Context
CurrentUser is fetched during onboarding however roles and permissions
are not created yet during that stage so an error was thrown. We only
want to fetch permissions after the onboarding of the workspace.
2025-04-07 18:53:53 +02:00
WeikoandGitHub f403c551d7 Add settings permissions check on FE (#11425)
## Context
Now that we can update role settings permissions, we need to reflect
that on the FE as well (hiding/showing nav items + redirection logic).
Feature flag check here is not really needed because since not having
any setting permission will result in the same behavior as Permission
V1.
This PR updates the resolvers to return settings permissions of the
current user
2025-04-07 17:15:33 +02:00
Charles Bochet d4db399933 Fix Google Icon 2025-04-07 17:14:36 +02:00
0226dec717 i18n - translations (#11427)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-07 17:13:37 +02:00
GuillimandGitHub 6451b7b5e3 Fix-messaging-calendar-issues (#11424)
- fixing Event Calendar bug due to TypeORM limitations
- avoid systematic crash on contact creation jobs, simply logging
2025-04-07 17:13:13 +02:00
Paul RastoinandGitHub 69da046812 Twenty-website copy twenty-ui dockerfile (#11394)
Fixes deployment


https://github-production-user-asset-6210df.s3.amazonaws.com/45004772/430425195-218d6f61-3ab0-4042-8206-52eac22fe599.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAVCODYLSA53PQK4ZA%2F20250404%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250404T143735Z&X-Amz-Expires=300&X-Amz-Signature=489088bc5bf23c371d80d655c83a61e8ba481313b368369785c203b7268dd924&X-Amz-SignedHeaders=host
2025-04-07 17:09:55 +02:00
GuillimandGitHub c798cccba7 Switching plan overflows (#11396)
Swithcing plan overflows the modal soo Bonapara said to go back to
simple switch plan until we have a better version next week with the
stirpe pricing page
2025-04-07 17:09:29 +02:00
Charles BochetandGitHub 59ae978ee3 Fix safari broken table (#11417)
In this PR:
- deprecate usage of useInView (react-intersection-observer) for record
table
- fixes #11254
2025-04-07 16:33:02 +02:00
26504f02a3 i18n - translations (#11422)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-07 15:39:19 +02:00
EtienneandGitHub 361b7682dd add trial period ending banner + server logic (#11389)
Solution : 
- if user reaches his workflow usage cap + in trial period > display
banner
- end trial period if user has payment method (if not, not possible)

<img width="941" alt="Screenshot 2025-04-04 at 10 27 32"
src="https://github.com/user-attachments/assets/d7a1d5f7-9b12-4a92-a7c7-15ef8847c790"
/>
2025-04-07 15:28:02 +02:00
nitinandGitHub a627eff5c2 fix: Use namePlural instead of labelPlural for favorite view URLs (#11407)
closes #11404

Used `namePlural` instead of `labelPlural` for generating favorite view
URLs to ensure proper routing across all languages.
2025-04-07 08:54:43 +02:00
Lucas BordeauandGitHub f365caa365 Fixed ViewBarDetails unnecessary padding-top (#11395)
This PR fixes a recent change in ViewBarDetails that added an
unnecessary padding-top.

Before : 

<img width="876" alt="image"
src="https://github.com/user-attachments/assets/f0152f24-da2c-44f7-b299-a98cb559b2d1"
/>

After : 

<img width="884" alt="image"
src="https://github.com/user-attachments/assets/48a0c9d8-1c22-4eb7-abfa-02963facbcd6"
/>
2025-04-07 07:37:19 +02:00
Charles BochetandGitHub 8fa09e21ec Fix safari broken table (#11399)
Fixes #11254
2025-04-04 19:16:33 +02:00
241d8820d7 i18n - translations (#11398)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-04 17:47:01 +02:00
WeikoandGitHub e1f6c61651 add settings permissions update (#11377)
Fixes https://github.com/twentyhq/core-team-issues/issues/710
2025-04-04 17:40:14 +02:00
6142e193ce i18n - translations (#11397)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-04 17:34:18 +02:00
10e140495c Fixing Singup sequence FLASHING💥 (#11371)
After investiagting the different options ([see related
issue](https://github.com/twentyhq/core-team-issues/issues/660#issuecomment-2766030972))
I decided to add a "Verify Component" and a to build a custom Layout for
this route.

Reason I cannot use the default one is to have all preloaded once the
user changes website and lands on the verify route.

Reason I did not modify the DefaultLayout to match our need is that is
would require many changes in order to avoid preloading states for our
specific usecase.

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

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-04 15:25:15 +00:00
Charles Bochet 609e06fd14 Fix main build 2025-04-04 16:21:23 +02:00
2308091b13 Remove overlay-scroll-bar (#11258)
## What

- Deprecate overlayscrollbars as we decided to follow the native
behavior
- rework on performances (avoid calling recoil states too much at field
level which is quite expensive)
- Also implements:
https://github.com/twentyhq/core-team-issues/issues/569

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-04 16:13:48 +02:00
Thomas TrompetteandGitHub 6b184cc641 Select node by default when pending form action (#11378)
We want the run side panel to be open when the form step is pending



https://github.com/user-attachments/assets/a7a7015e-b0b7-422a-b625-eca8f2614ac1
2025-04-04 15:56:57 +02:00
Lucas BordeauandGitHub 59e8e0633b Fix advanced filter dropdown input components (#11381)
This PR fixes the filter value input components that are used in
advanced dropdown filter, which slightly differ from the classic object
filter dropdown in the view bar.

We notably needed the same experience as other text inputs in the
application, for entering filter values.

## New text and number filter experience : 

<img width="681" alt="image"
src="https://github.com/user-attachments/assets/b373bb6b-dc00-4396-9294-9b866b91fa02"
/>

## New date filter experience : 

<img width="683" alt="image"
src="https://github.com/user-attachments/assets/8aea22e2-6f3b-4641-9f3d-6d7ba537bc27"
/>

To obtain the same experience for date input as in workflow forms, it
would require to duplicate or factorize a lot of complex code that
manipulates dates and user events with the input, it would be better
tackled in another issue related to a larger refactor effort :
https://github.com/twentyhq/core-team-issues/issues/736

Fixes https://github.com/twentyhq/core-team-issues/issues/674
2025-04-04 12:45:21 +00:00
Raphaël BosiandGitHub ad2357a6fd Fix error when workflows aren't enabled (#11388)
Fix Uncaught Error: Workflow is not enabled. If you want to use it,
please enable it in the lab.
<img width="505" alt="erroractionmenu"
src="https://github.com/user-attachments/assets/66e60219-20fb-4b00-90e4-d6bd640be774"
/>

This error was due to using the hook `useWorkflowWithCurrentVersion`
outside of a workflow object. Adding a skip parameter wasn't enough
because the `useFindOneRecord` uses `useObjectMetadataItem` which throws
if workflows aren't enabled.
2025-04-04 14:26:19 +02:00
27256c960e i18n - translations (#11387)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-04 11:33:11 +02:00
Baptiste DevessierandGitHub 9353e777ea Copy JSON values on click (#11382)
https://github.com/user-attachments/assets/1638c196-fb9c-4f2b-910c-6d8b0693a37a

Closes https://github.com/twentyhq/core-team-issues/issues/568
2025-04-04 11:20:57 +02:00
WeikoandGitHub bb40bc9929 Fix update field default value (#11386)
Fixes https://github.com/twentyhq/twenty/issues/11379
2025-04-04 08:58:53 +00:00
Lucas BordeauGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix Malfait
5e43839efb Fix CSV import select field matching (#11361)
This PR fixes a bug that prevented to do the matching of an imported CSV
file that contains a SELECT type column.

Fixes https://github.com/twentyhq/twenty/issues/11220

## Stacking context improvement 

During the development it was clear that we lacked a reliable way to
understand our own z indices for components like modal, portaled
dropdown, overlay background, etc.

So in this PR we introduce a new enum RootStackingContextZIndices, this
enum allows to keep track of our root stacking context component
z-index, and because it is an enum, it prevents any conflict.

See
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Stacking_context
for reference.

## Component cleaning

Components have been reorganized in a SubMatchingSelectRow component

The Dropdown component has been used to replace the SelectInput
component which doesn't fit this use case because we are not in a cell,
we just need a simple standalone dropdown, though it would be
interesting to extract the UI part of the SelectInput, to share it here,
the benefit is not obvious since we already have good shared components
like Tag and Dropdown to implement this specific use case.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-03 16:28:15 +02:00
EtienneandGitHub 752eb93836 disable workflow execution if billing issue (#11374)
closes https://github.com/twentyhq/core-team-issues/issues/404
2025-04-03 14:18:44 +00:00
7eec64b6e0 have footer on emails (#11300)
# ISSUE 

- Closes #9622

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-03 14:26:19 +02:00
EtienneandGitHub cfae440a02 add stripe alert listening and cap on subscriptionItems (#11330)
in this PR :  
- reverting https://github.com/twentyhq/twenty/pull/11319 > at trial
period end, subscriptions switch to 'past_due' status if payment method
not set up
- adding cap on subscriptionItems and updating them when receiving alert
event + refreshing them when beginning a new subscription cycle

closes https://github.com/twentyhq/core-team-issues/issues/606
2025-04-03 13:44:32 +02:00
Baptiste DevessierandGitHub 144a326709 JSON visualizer: Highlight the parent nodes of in-use nodes (#11373)
https://github.com/user-attachments/assets/5f31023d-b24f-40c8-a061-ffc0d02b63b0

Closes https://github.com/twentyhq/core-team-issues/issues/715
2025-04-03 12:11:19 +02:00
Paul RastoinandGitHub 4a4e65fe4a [REFACTOR] Twenty UI multi barrel (#11301)
# Introduction
closes https://github.com/twentyhq/core-team-issues/issues/591
Same than for `twenty-shared` made in
https://github.com/twentyhq/twenty/pull/11083.

## TODO
- [x] Manual migrate twenty-website twenty-ui imports

## What's next:
- Generate barrel and migration script factorization within own package
+ tests
- Refactoring using preconstruct ? TimeBox
- Lint circular dependencies
- Lint import from barrel and forbid them

### Preconstruct
We need custom rollup plugins addition, but preconstruct does not expose
its rollup configuration. It might be possible to handle this using the
babel overrides. But was a big tunnel.
We could give it a try afterwards ! ( allowing cjs interop and stuff
like that )
Stuck to vite lib app

Closed related PRs:
- https://github.com/twentyhq/twenty/pull/11294
- https://github.com/twentyhq/twenty/pull/11203
2025-04-03 09:47:55 +00:00
MarieandGitHub 8c9fcfe5a4 Hot fix for currentWorkspaceMember not found error on blocklist page (#11367)
Fixes
https://twenty-v7.sentry.io/issues/6504066204/?project=4507072563183616
Introduced by https://github.com/twentyhq/twenty/pull/11325

Called it a hotfix as not sure if missing currentWorkspaceMember is an
expected state - maybe it is expected to be temporarily missing ?
2025-04-03 08:44:11 +00:00
MarieandGitHub 0df07a766a Handle no value options in filters (#11351)
Fixes #11323 - see description to reproduce

The issue was that the filter was malformed for no value options: 
<img width="649" alt="Capture d’écran 2025-04-02 à 14 56 25"
src="https://github.com/user-attachments/assets/5287c4f8-7eaf-4488-b692-4d7634236d3d"
/>
causing
<img width="333" alt="Capture d’écran 2025-04-02 à 14 56 43"
src="https://github.com/user-attachments/assets/aa1b7333-50da-4b7d-979b-70dab9a1ab41"
/>


after fix: 
<img width="653" alt="Capture d’écran 2025-04-02 à 14 39 56"
src="https://github.com/user-attachments/assets/1777c068-7231-4e14-bc41-84ef7909cf10"
/>
2025-04-03 10:41:50 +02:00
Thomas TrompetteandGitHub 256a5c1a2b Remove form feature flag (#11369)
As title. Workflows are still in the lab and forms are starting to be
usable
2025-04-03 08:38:19 +00:00
Raphaël BosiandGitHub 1240d39f56 Introduce hooks to retrieve directly the registered actions without using actionMenuEntriesComponentState (#11359)
Introduce two hooks:
- `useRegisteredRecordActions`
- `useRegisteredRecordAgnosticActions`

These hooks will be used to read directly the registered actions
according to the context.
We will stop to rely on `actionMenuEntriesComponentState` to improve
performances and reduce state copies and updates.

This PR is part of
https://github.com/twentyhq/core-team-issues/issues/683, and at this
step, we still save the actions inside
`actionMenuEntriesComponentState`.
2025-04-03 10:25:42 +02:00
Thomas TrompetteandGitHub a062a17229 Add form date field (#11360)
Builder
<img width="498" alt="Capture d’écran 2025-04-02 à 19 02 20"
src="https://github.com/user-attachments/assets/29db9fa9-aae4-4d1f-98f2-0b2371f944f1"
/>

Execution
<img width="837" alt="Capture d’écran 2025-04-02 à 19 02 47"
src="https://github.com/user-attachments/assets/ce1c442c-3c06-4f7e-99d6-3eb8fb1d2428"
/>
2025-04-03 10:10:43 +02:00
GuillimandGitHub 8abec309e0 Phone-onclickoutside (#11350)
Fixes : For phones I have to press "enter" to validate my changes but
for other fields it's saved automatically when I leave the cell

Bug related to onClickOutside on the MultiItemFieldMenuItem component
that shows phones (but also emails...)

Seen with @bonapara : we keep a consitent behaviour meaning
- saving input on click outside when primary item is being edited
- not saving input on click outside when other items are being edited



Fixes https://github.com/twentyhq/twenty/issues/11246
2025-04-03 07:57:02 +00:00
Baptiste DevessierandGitHub bea75b9532 Set failed node's output as red (#11358)
| Error | Success |
|--------|--------|
| ![CleanShot 2025-04-02 at 18 18
45@2x](https://github.com/user-attachments/assets/6674d4d2-344a-4e16-9608-a70cde07a376)
| ![CleanShot 2025-04-02 at 18 20
23@2x](https://github.com/user-attachments/assets/55b5a467-528f-4f07-9166-40ed14943ee2)
|

Closes https://github.com/twentyhq/core-team-issues/issues/716
2025-04-03 08:58:56 +02:00
183dc40916 [FIX] Out of memory while running app localy (#11341)
# Introduction
Lately encountering a lot of out of memory error when running
twenty-front in watch mode with both TypeScript and lint checkers
```ts
Error: Worker terminated due to reaching memory limit: JS heap out of memory
    at new NodeError (node:internal/errors:405:5)
    at [kOnExit] (node:internal/worker:287:26)
    at Worker.<computed>.onexit (node:internal/worker:209:20)
```

The existing configuration looks like this:
```ts
// packages/twenty-front/vite.config.ts
'cd ../.. && eslint packages/twenty-front --report-unused-disable-directives --max-warnings 0 --config .eslintrc.cjs',
```
This is wrong as computing the root eslintrc completely omitting
twenty-front's one ***and its ignorePattern*** so will be checking in
`node_modules` etc checking for project-structure :).
For example this a
[snippet](https://gist.github.com/prastoin/d7f8ad4ef5eb2f7732209b756a38094c)
of the above commands errors. We can see rule that should be disabled by
`eslintrc.react.cjs` extension made from twenty-front `eslintrc` :
```ts
/Users/paulrastoin/ws/twenty-two/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/__stories__/SettingsDataModelFieldSettingsFormCard.stories.tsx
  23:27  warning  Forbidden non-null assertion  @typescript-eslint/no-non-null-assertion
```

## Fixes
- consume the `twenty-front` package eslint configuration within the
vite lint checker
- eslint overrides extends are getting merged based on glob inclusion of
their files declarations
- any linted files should be included in one of our `tsconfig`
- removed redundant and counter-productive negative `ignorePatterns`, as
eslint will naturally only lint files within configuration file
directory by default which will result making it go through local
`node_modules` project structure

## Now
Less cpu usage <3.5 gb and faster
```ts
// from packages/twenty-front
TIMING=1  npx eslint . --report-unused-disable-directives --max-warnings 0 --config .eslintrc.cjs --debug
#...
Rule                                            | Time (ms) | Relative
:-----------------------------------------------|----------:|--------:
project-structure/folder-structure              | 19578.927 |    20.2%
prettier/prettier                               | 13746.156 |    14.2%
no-redeclare                                    |  9546.570 |     9.9%
@nx/workspace-explicit-boolean-predicates-in-if |  8167.805 |     8.4%
@typescript-eslint/no-unused-vars               |  6872.803 |     7.1%
import/no-relative-packages                     |  6577.273 |     6.8%
@nx/enforce-module-boundaries                   |  6520.945 |     6.7%
import/no-duplicates                            |  4987.476 |     5.2%
react/no-direct-mutation-state                  |  2323.082 |     2.4%
react/require-render-return                     |  1155.261 |     1.2%
```

## Conclusion
Please note that `nx linter` might not be as strict as vite config
eslint runner

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-02 18:35:00 +02:00
010b7663c4 i18n - translations (#11357)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-02 18:21:16 +02:00
Raphaël BosiandGitHub 5e905180c8 690 extract shouldberegistered from the useaction hooks (#11355)
Closes https://github.com/twentyhq/core-team-issues/issues/690

This PR is the first part of a refactoring on the actions system
https://github.com/twentyhq/core-team-issues/issues/683. It:
- Removes `shouldBeRegistered` from the useAction hook
- Instead `shouldBeRegistered` becomes a function to which we can pass
parameters which describe the context of the app (the object, the
selected record, information about favorites ...). It returns a boolean.
- `useShouldActionBeRegisteredParams` returns the parameters to pass to
the `shouldBeRegistered`
- Introduces a way to inherit actions from the default config and to
overwrite its properties, closing
https://github.com/twentyhq/core-team-issues/issues/72

Some tests testing if an action was registered correctly have been
removed, we should add them back at the end of the global refactoring.
2025-04-02 17:58:14 +02:00
Antoine MoreauxandGitHub bc57e98949 chore(ci): extend timeout for Danger JS job (#11356)
Increased the timeout for the Danger JS job from 3 to 5 minutes to
prevent premature failures on slower runs. This ensures more reliable
execution of the workflow.

To unlock https://github.com/twentyhq/twenty/pull/11339
2025-04-02 17:26:52 +02:00
Thomas TrompetteandGitHub 7488c6727a Add record picker in form action (#11331)
Record picker becomes a form field that could be used in another context
than workflows.

Settings
<img width="488" alt="Capture d’écran 2025-04-02 à 10 55 53"
src="https://github.com/user-attachments/assets/a9fc09ff-28cd-4ede-8aaa-af1e986cda8e"
/>

Execution
<img width="936" alt="Capture d’écran 2025-04-02 à 10 57 36"
src="https://github.com/user-attachments/assets/d796aeeb-cae1-4e59-b388-5b8d08739ea8"
/>
2025-04-02 17:08:33 +02:00
EtienneandGitHub 2bc9691021 fix stripe subscription deletion (#11353)
when soft deleting workspace, stripe subscription is canceled then
workspace is soft deleted before stripe async web hook event is
received. This webhook event is needed to update billingSubscription
status.
2025-04-02 15:59:09 +02:00
2b14cd5649 i18n - translations (#11354)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-02 15:47:16 +02:00
c03438a02e Support Moved to Security Setting (#11335)
This PR addresses issue #11321 by moving the "Support" section from the
General tab to the Security tab.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-02 13:40:56 +00:00
Félix MalfaitandGitHub e94065fb44 Auto-run migration script on docker entrypoint (#11338)
A small PR but a big step towards making Twenty easier to self-host and
upgrade!

Now changing the tag and pulling a new version should be the only step
to upgrade as migrations script will be ran automatically upon starting
the containers. It was already the case for typeorm migrations, but not
for standard objects migration and data migration scripts. It is still
possible to disable this behavior for the most complex deployments such
as our own cloud.
2025-04-02 15:37:51 +02:00
martmullandGitHub 55eadf1ab4 11312 rest api cant filter enum type columns by null value (#11343)
- Fixes https://github.com/twentyhq/twenty/issues/11312
- Fixes record undefined on webhook deleted events
- Emit destroy event when deleting record via the rest api
2025-04-02 15:07:53 +02:00
Paul RastoinandGitHub 76bbffc315 [FIX] Upgrade command missmatch (#11348)
# Introduction
As we deploy patch from the main branch we've ship the upgrade for the
`0.51` within the `0.50`.
We should only do that when about to release

We should find a way for this not to occur again
2025-04-02 11:58:50 +00:00
EtienneandGitHub da1413c5a1 fix hot reload (#11347) 2025-04-02 11:42:05 +00:00
martmullandGitHub c6afb0d1ba Revert "[4/n]: migrate the RESTAPI GET /rest/* to use TwentyORM direc… (#11344)
…tly (#10372)"

This reverts commit a26b3f54d6.
2025-04-02 13:39:28 +02:00
Lucas BordeauandGitHub e47c19e86f Advanced filter bug bash (#11327)
This PR fixes some bugs on advanced filters dropdown.

See reference master issue :
https://github.com/twentyhq/core-team-issues/issues/648

Fixes https://github.com/twentyhq/core-team-issues/issues/726
Fixes https://github.com/twentyhq/core-team-issues/issues/724
Fixes https://github.com/twentyhq/core-team-issues/issues/655
2025-04-02 10:25:51 +02:00
martmullandGitHub 6e92b19e01 11311 object create webhook should be triggered when object is created via rest api (#11336)
Fixes https://github.com/twentyhq/twenty/issues/11311
2025-04-02 10:22:22 +02:00
GauravandGitHub 9a2f7d8b71 Fix: Timeline responsiveness (#11288)
Fixes #11136


[recording.webm](https://github.com/user-attachments/assets/328afab8-511a-4090-bdb0-e1cdb42565be)
2025-04-02 10:07:05 +02:00
Antoine MoreauxandGitHub 44bf393b06 fix(email-validation): validation email cross workspace (#11261)
- Finish removing captcha guard from validation  email
- Fix an issue where domain validation wasn't working on a multi-domain
setup
2025-04-02 08:06:34 +00:00
44d4e4efaf fix: Display multipicker on Created By source filter (#10543)
fix: #9674 

When the selected filter is Is and the field type is ACTOR, we now show
ObjectFilterDropdownSourceSelect instead of a text input. This ensures
proper selection for actor-based filters. Also previously, when a user
changed the selected option, all default values were getting wiped out
so i have made some changes in updatedSelectedItems

Loom video:
https://www.loom.com/share/8b80a78d5e8c4a5192d69cab96f0c838?sid=5bd76fff-7cd4-4e3c-8c48-d1c9e4e95651

---------

Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-02 09:56:32 +02:00
WeikoandGitHub 3357f93415 Bump 0.51.0-canary (#11329) 2025-04-02 09:23:17 +02:00
MarieandGitHub e6422ad08a Only show a workspace member their own email blocklist (#11325)
Fixes https://github.com/twentyhq/twenty/issues/11320
2025-04-01 16:23:37 +00:00
martmullandGitHub 8e6b175f34 700 fix rest api issues (#11326)
fixes issues listed here
https://github.com/twentyhq/core-team-issues/issues/700
2025-04-01 17:22:24 +02:00
51ea241a1c Fix mobile table styling outside record table (#10407) (#10663)
Fix to issue #10407 now including a fix to `ChipFieldDisplay` [throwing
an error outside a record
table](https://twenty-v7.sentry.io/issues/6350031213/?project=4507072563183616&referrer=github-pr-bot).

This works now, but refactoring is needed before merging.

Fixes #10407

---------

Co-authored-by: ad-elias <elias@autodiligence.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-01 17:11:31 +02:00
WeikoandGitHub 8385e2d08b Fix object metadata collection not found (#11306)
## Context
This fix ensures that even if a datasource creation promise throws and
is cached, subsequent requests won't return that cached exception.
Also adding a TTL on MetadataObjectMetadataOngoingCachingLock, this is
not something that should stay in the cache forever and could
potentially unlock some race conditions (the origin of the issue is
probably due to performances where the lock is not removed as it should
be after metadata computation and caching)
2025-04-01 16:38:43 +02:00
Thomas TrompetteandGitHub 7e07b3f7e9 Fix dropdown height and scroll in workflows (#11324)
Before
<img width="459" alt="Capture d’écran 2025-04-01 à 15 58 41"
src="https://github.com/user-attachments/assets/8f2183b3-cbc4-4e03-97f7-e9edc719af35"
/>

After
<img width="459" alt="Capture d’écran 2025-04-01 à 15 58 28"
src="https://github.com/user-attachments/assets/00ef0ffe-bfc8-429c-942a-c02f6c52d91d"
/>
2025-04-01 14:11:06 +00:00
EtienneandGitHub 1d4fc5ff4a update subscription with metered products at trial ending (#11319)
Context
- Subscription with metered prices can't be 'paused' at the end of
trialing period
- Currently, pausing subscription have been the process we choose at
Twenty

Two solutions : 
- [x] (The chosen one!) Adding metered products when the trial period is
ended.
- [ ] Switching from 'paused' to 'past_due' status at the end of
trialing period. Tricky because we should handle different cases of
'past_due' subscription status, some causing workspace suspension and
some other not.

closes https://github.com/twentyhq/core-team-issues/issues/676
2025-04-01 15:57:01 +02:00
Thomas TrompetteandGitHub e74c8723d0 Add position in run / version + block creation from generated API (#11318)
- Add position during workflow version / creation. It will allow to have
the versions and runs ordered
- Block the creation from generated api for versions. We use workflow
post hooks or create from draft
2025-04-01 15:29:54 +02:00
Félix MalfaitandGitHub aa5da92555 Improve upsert for spreadsheet import (#11283)
Refactor query runner to improve the import method for upserts, we now
take into account any unique field and prevent any conflict upfront.
Previously, we would only update if an `id` was passed.



https://github.com/user-attachments/assets/8087b864-ba42-4b6e-abf2-b9ea66e6c467


This is only a first step, there are other things to fix on the frontend
for this to work.
2025-04-01 15:27:08 +02:00
MarieandGitHub 366106bb2b Fix field metadata creation page (#11285)
in this pr 
1. fixing error helper was no longer showing. unfortunately had to
resort to `formConfig.trigger`...
2. closes https://github.com/twentyhq/twenty/issues/11262
3. closes https://github.com/twentyhq/twenty/issues/11263


https://github.com/user-attachments/assets/11f763bb-3098-4b0e-bc96-8a0de3cb3c19
2025-04-01 14:09:24 +02:00
GuillimandGitHub 9cbc2e3df0 Option-menu-imporovements (#11309)
- icon switching : if switching layout from table to kanban
and if icon is the table icon (the default one) then automatically
update the icon to the kanban icon

- add tooltip on Layout default view to better explain why it's
unavaialble


Fixes [#689](https://github.com/twentyhq/core-team-issues/issues/689)
Fixes [#688](https://github.com/twentyhq/core-team-issues/issues/688)
Fixes [#686](https://github.com/twentyhq/core-team-issues/issues/686)
2025-04-01 10:31:40 +00:00
bc81853095 i18n - translations (#11317)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-01 12:01:27 +02:00
Thomas TrompetteandGitHub 023d071103 Set record position on workflow creation (#11308)
- Migrate record position factory to core-modules 
- set position on record creation
2025-04-01 09:50:43 +00:00
Félix MalfaitandGitHub b2012229f4 Display system objects in Workflow triggers (#11314)
Fixes #11310

Note:
- I changed "system to advanced" because I think we will link that to
the Advanced Mode in the future
- Not sure when to use useCallback / useMemo, AI added some useCallbacks
which I removed but I left some useMemo... Not sure what should be the
rule
- It had to use MenuItem because this sub-menu behavior wasn't available
in the Standard select component. We should probably rename the
"MenuItem" elements to something more generic. I didn't do it in this PR
because I'm not sure about the strategy and it would change a lot of
files.
2025-04-01 11:48:52 +02:00
a26b3f54d6 [4/n]: migrate the RESTAPI GET /rest/* to use TwentyORM directly (#10372)
# This PR

- Addressing #3644
- Migrates the `findOne` and the `findMany` Rest API to use TwentyORM
directly
- Adds integration tests to the migrated methods

---------

Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: martmull <martmull@hotmail.fr>
2025-04-01 11:34:43 +02:00
Raphaël BosiandGitHub a24e96ae0e 685 Move all navigation actions inside the actions configs (#11303)
Move all navigation actions inside the actions configs
2025-04-01 11:23:28 +02:00
Paul RastoinandGitHub f6e4cd45ed [CHORE] Update browserslist (#11304)
# Introduction
```sh
npx update-browserslist-db@latest
```
https://github.com/browserslist/update-db#readme
2025-03-31 18:12:38 +02:00
1c675149f7 i18n - translations (#11305)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-31 18:01:13 +02:00
WeikoandGitHub 06ff16e086 add role update (#11217)
## Context
This PR introduces the new Create and Edit role components, behind the
PERMISSIONS_ENABLED_V2 feature flag.
2025-03-31 17:57:14 +02:00
Paul RastoinandGitHub 3c9bf2294f test(front): fix main failing test due to timezone (#11295)
# Introduction
Due to winter to summer timezone update, it shown that we have some unit
tests flakiness due to both mocked and unmocked date.now invokation
between app bootstrap and test bootstrap

This PR does not refactor this behavior
Just fix the currently failing test

## Note
Removed a duplicated file
2025-03-31 15:39:05 +02:00
Lucas BordeauandGitHub b13be7bd2e Advanced filter fix placeholder and icon in dropdown buttons (#11286)
This PR fixes a UI issue that brings a lot more robustness to the
advanced filter look and feel.

It adds the icon of the field metadata item in the filter field select.

It adds a custom placeholder in the filter input select, depending on
the field metadata item type.

<img width="661" alt="image"
src="https://github.com/user-attachments/assets/8bf2044f-52cf-447d-909d-3312089c0df5"
/>
2025-03-31 08:32:04 +00:00
Lucas BordeauandGitHub 98475ee63e Advanced filter UI fast follow-ups (#11272)
This PR fixes the issue about the easy fast follow-up part on advanced
filter.

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

Changes : 
- Changed horizontal gap to spacing(1) for AdvancedFilterDropdownRow
- Created a DEFAULT_ADVANCED_FILTER_DROPDOWN_OFFSET for all
sub-dropdowns in advanced filter dropdown with a y-offset of 2px.
- Created a DropdownOffset type
- Used a padding-left of spacing(2.25) in
AdvancedFilterLogicalOperatorCell to allign the disabled text with the
text in the Select component
- Added IconTrash and accent danger on
AdvancedFilterRecordFilterGroupOptionsDropdown and
AdvancedFilterRecordFilterOptionsDropdown
- Removed unnecessary CSS properties on
AdvancedFilterRootRecordFilterGroup
- Set dropdownMenuWith to 280 for AdvancedFilterValueInputDropdownButton
- Fixed Dropdown generic clickable component container that was
expanding
- Set IconFilter instead of IconFilterCog in AdvancedFilterChip
- Set AdvancedFilterDropdownButton dropdown content width to 650 instead
of 800
- Refactored generic IconButton component so that it disambiguates
secondary and tertiary variant for the color CSS props
2025-03-31 10:24:52 +02:00
Antoine MoreauxandGitHub eea30828a4 test(user-workspace): add unit tests for UserWorkspaceService + review #11239 (#11256) 2025-03-30 08:37:16 +02:00
GuillimandGitHub ce07d2645c Renaming + remove setRecoilvalue (#11281)
Simple renaming of a hook plus a deletion of a useless setRecoilValue
hook.

pretty strainghtforward
2025-03-28 18:59:47 +01:00
Raphaël BosiandGitHub 352cf3d38e Update previousHotkeyScopeState to be a family state (#11270)
Fixes #11259
2025-03-28 17:59:05 +01:00
3e20134676 Add command to update createdBySource enum values (#11280)
Fixes webhook create workflowRun by WEBHOOK error

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-03-28 16:53:14 +00:00
GuillimandGitHub d9ac662302 Microsoft Throtling error and wrongly types on our side (#11266) 2025-03-28 16:37:46 +00:00
8e39585c0d i18n - translations (#11271)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-28 16:45:59 +01:00
859ed1d8dd Feature: Update record right click menu (#11252)
closes #11193


[recording.webm](https://github.com/user-attachments/assets/2c89f50a-546b-4047-8b5a-69f6588cabe4)

---------

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
2025-03-28 16:31:43 +01:00
EtienneandGitHub da9e078283 fix no billing subscription error (#11257)
closes https://github.com/twentyhq/core-team-issues/issues/625

Context : 
Soft-deleted workspaces no longer have any subscriptions. Computing
inactivity causes an error.
2025-03-28 14:45:13 +00:00
3e5a6d0a5e i18n - translations (#11260)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-28 11:20:53 +01:00
Raphaël BosiandGitHub b1c57edc90 Display a tooltip for actions without short labels (#11243)
- Merge `RecordIndexActionMenuButtons` and `RecordShowActionMenuButtons`
into a single component `PageHeaderActionMenuButtons`
- Display tooltip after 1s for actions without short labels


https://github.com/user-attachments/assets/7649bed8-a1a9-4c1d-8fbe-f1bf3a51db56
2025-03-28 11:01:55 +01:00
Thomas TrompetteandGitHub 8d35454dd8 Form action fast follows (#11242)
- on form action, add trash on hover and fix spacing
- fix dark mode
- second batch of icon fixes

<img width="692" alt="Capture d’écran 2025-03-27 à 18 25 48"
src="https://github.com/user-attachments/assets/963f50d2-12ee-425c-97a3-2ad0c6bb5c57"
/>
2025-03-28 10:11:01 +01:00
Paul RastoinandGitHub 78943b3370 chore(website): start docs (#11253) 2025-03-28 10:02:51 +01:00
vaibhav-devereGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Charles BochetCharles Bochet
8127e4f635 Fix filter button height (#11237)
[#11218](https://github.com/twentyhq/twenty/issues/11218) Fixed Filter
Reset Button height

- Replaced the default button with LightButton to align with Figma
design specs which Restores expected button size and appearance.

- Ensured the correct height, padding, and styling are applied
automatically.

- Wrapped the button inside StyledChipcontainer for consistency.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-03-28 09:28:05 +01:00
c294d967a3 reset main context store viewId and current view type on settings page (#11206)
closes https://github.com/twentyhq/core-team-issues/issues/588

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-28 09:26:59 +01:00
EtienneandGitHub 391392dd87 set up metrics collecting with open telemetry (#11236)
Done :  
- move metrics and health cache services from health module to metrics
module
- refactor metrics counter from specific method to set up from enum keys
- add OpenTelemetry (Otel) instrumentation for metrics
- set up Otel SDK to send metrics to Otel collector

To do later : 
- implement Otel instrumentation for traces + plug Sentry on top
2025-03-28 08:45:24 +01:00
Félix MalfaitandGitHub e9e33c4d29 Refactor spreadsheet import (#11250)
Mostly renaming objects to avoid conflicts (it was painful because names
were too generic so you could cmd+replace easily)

Also refactoring `useBuildAvailableFieldsForImport`
2025-03-28 07:56:51 +01:00
Antoine MoreauxandGitHub 9af2628264 feat(auth): enhance email validation when no workspace available + disable captcha on email validation (#11239)
Implemented fallback logic to associate a user with a workspace when
none is found. Introduced new GraphQL types and mutations for roles and
permissions management. Simplified and refactored URL-building logic for
email verification, improving code maintainability and flexibility.
2025-03-28 07:38:58 +01:00
WeikoandGitHub 976c6afb4b Generate more random subdomains (#11249)
Sorted the 2 existing lists + added a new colors list to generate the
random subdomain to have less collision

<img width="368" alt="Screenshot 2025-03-27 at 19 25 28"
src="https://github.com/user-attachments/assets/6d6d27f1-134b-4ae7-88a6-4af506115317"
/>
2025-03-27 19:40:20 +01:00
Charles BochetandGitHub a683827e4b Fix inline cell height issue and allow field settings update (#11248)
In this PR:
- allow to update settings on fields metadata (regression introduced by
a recent refactoring of fields-metadata update)
- revert changes introduced by
https://github.com/twentyhq/twenty/pull/11221
2025-03-27 19:29:34 +01:00
MarieandGitHub e201da263d Fix sync-workspace log (#11247)
This is now log for every workspace we sync so stopped making sense
2025-03-27 18:17:11 +00:00
Paul RastoinandGitHub 226b8f1b00 [CHORE] Remove preconstruct local patch (#11153)
# Introduction
Please find related parent PR
https://github.com/twentyhq/twenty/pull/11083

Custom TypeScript configuration file should be available on "2.8.12" !
See related changeset version dump PR
https://github.com/preconstruct/preconstruct/pull/619
2025-03-27 18:19:46 +01:00
c19f6c3479 0.50 (#11241)
changelog :)

---------

Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
2025-03-27 18:07:37 +01:00
65bf836e8b i18n - translations (#11240)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-27 17:36:51 +01:00
7508f09ede i18n - translations (#11235)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-27 17:21:26 +01:00
MarieandGitHub d12bbdf9f1 Move MigrationRelations command out of 0.50 -> 0.51 (#11234) 2025-03-27 16:06:52 +00:00
Raphaël BosiandGitHub f145862cf1 Design fixes on show page (#11221)
- Fixes record inline cell height
- Fixes notes body empty state
2025-03-27 17:03:06 +01:00
Thomas TrompetteandGitHub 439ccb0a52 Fix workflow placeholders and icons (#11222)
- allow all form fields that may need a placeholder to set it
- update main icons on versions and runs
2025-03-27 17:01:33 +01:00
4eefa45164 Option-menu-switch-table-kanban (#11167)
New options menu feature: table/kanban switching

This feature is the last one of the Optino Menu v2 update. It is
designed to enable the possibility to switch from table to kanban and
vice-versa.

Only the default tab is not editable for consitency in the UX of the
application as designed by our team

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-03-27 16:49:44 +01:00
Lucas BordeauandGitHub 937a393d74 Fix missing positionInRecordFilterGroup in applyFilter legacy logic (#11230)
This PR fixes a bug where modifying a filter in the advanced filter
dropdown was making it change its position in the filter list.

This is due to the legacy logic of applyFilter(), which outlines the
importance of the needed refactor to remove this logic which requires
duplicating code modification in nearly every component that can modify
a record filter.

This refactor will be addressed over the next sprints, because there are
underlying sub-refactors to tackle first, as outlined by
https://github.com/twentyhq/core-team-issues/issues/559
2025-03-27 16:40:30 +01:00
GuillimandGitHub 3b9e7c38eb better error handling for messaging import in case of unknown error (#11228) 2025-03-27 16:19:57 +01:00
Lucas BordeauandGitHub 645d76fe69 Removing advanced filter feature flag (#11219)
This PR removes the advanced filter feature flag.
2025-03-27 15:25:07 +01:00
d4c40113b1 i18n - translations (#11216)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-27 09:01:24 +01:00
Félix MalfaitandGitHub a545b3adf3 CSV Import translations and dark mode fixes (#11184)
Fixes #11182 and adds missing translations
2025-03-27 08:53:00 +01:00
fad02fa26b i18n - translations (#11215)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-27 00:01:02 +01:00
5bf21a9567 i18n - translations (#11214)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-26 23:45:52 +01:00
Charles BochetandGitHub 22e56339a1 Fix field options not updatable anymore (#11213)
As per title
2025-03-26 23:40:44 +01:00
589b4cf77e fix: View switcher should close after view switch (#11154)
# Issue

- closes #11147

Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
2025-03-26 23:02:05 +01:00
2cc59929b8 Fixed the 'Extra space on GroupBy option menu' (#11179)
#10969 

Fixed!


![image](https://github.com/user-attachments/assets/4784891c-2c49-4098-8d1b-a8b52fdec1f6)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-26 22:59:52 +01:00
d02b5b4086 fix: adjust padding for icon button in Data model visualizer (#11180)
Fixes #10958 


![image](https://github.com/user-attachments/assets/4d9105c9-1bdb-4cb1-801c-56cb1cac0cce)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-26 22:53:51 +01:00
6f7e6e63f8 fix: improve settings menu spacing by moving logout into last section (#11202)
Issue: https://github.com/twentyhq/twenty/issues/11194

- Remove separate navigation drawer section for logout button
- Move logout button into the last section of settings menu
- Fix visual spacing between menu items

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-26 22:10:12 +01:00
4c7d71e325 chore(analytics): remove tinybird (#11146)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-26 21:59:42 +01:00
e64c4b8ab1 Feature/add flexibility to docker image makefile (#11210)
Trying to build the images for different build platforms using the
Makefile isn't possible without changing the code.

This change exposes the PLATFORM and TAG variables to enable the user to
build and tag the images with greater flexibility.

The same TAG variable can be used on the prod-*-run targets too.

Postgres is not built in the same way but is run in the Makefile too, so
the TAG variable applied here too, but not the platform.

---------

Co-authored-by: Paul McKeown <paul@midships.io>
2025-03-26 21:48:47 +01:00
Paul RastoinandGitHub 870069f682 [CHORE] Enable workspace version validation on upgrade for next release (#11211)
# Introduction
- Activate workspace version validation on upgrade command
- Update upgrade command to manager next release starting from `0.44.0`
2025-03-26 21:47:39 +01:00
Charles BochetandGitHub 5bd10d40cb Fix deactivate objects impacts (#11185)
In this PR:
- Remove deactivated objects from ActivityTargetInlineCell record picker
- Prevent users to deactivate createdAt, updatedAt, deletedAt fields on
any objects

Still left:
- write unit tests on the assert utils
- write integration tests on field metadata service
- prevent users to deactivate createdAt, updatedAt, deletedAt on FE
2025-03-26 20:45:46 +01:00
90e884d33f i18n - translations (#11209)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-26 19:37:26 +01:00
151841d3db i18n - translations (#11207)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-26 19:21:48 +01:00
d8ab23046a i18n - translations (#11204)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-26 18:33:33 +01:00
c48fed6173 i18n - translations (#11201)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-26 18:20:15 +01:00
Thomas TrompetteandGitHub b3948d2406 Add selected number to title (#11200)
Fixes https://github.com/twentyhq/core-team-issues/issues/586

<img width="633" alt="Capture d’écran 2025-03-26 à 17 37 10"
src="https://github.com/user-attachments/assets/2215aa95-1f74-4634-b76e-2b9322230fe8"
/>
2025-03-26 18:03:42 +01:00
Raphaël BosiandGitHub 1860768b52 Create 'Hide deleted records' action (#11198)
This PR:
- Makes 'See deleted records' action unavailable when the deleted filter
is active
- Creates 'Hide deleted records'



https://github.com/user-attachments/assets/b45f8ead-d973-418d-afba-a5983ac85172
2025-03-26 17:59:59 +01:00
760a21d8fa i18n - translations (#11197)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-26 17:37:16 +01:00
Raphaël BosiandGitHub 3660bec01d New TitleInput UI component for side panel (#11192)
# Description

I previously introduced the `RecordTitleCell` component, but it was
coupled with the field context, so it was only usable for record fields.
This PR:
- Introduces a new component `TitleInput` for side panel pages which
needed to have an editable title which wasn't a record field.
- Fixes the hotkey scope problem with the workflow step page title
- Introduces a new hook `useUpdateCommandMenuPageInfo`, to update the
side panel page title and icon.
- Fixes workflow side panel UI
- Adds jest tests and stories

# Video



https://github.com/user-attachments/assets/c501245c-4492-4351-b761-05b5abc4bd14
2025-03-26 17:31:48 +01:00
MarieandGitHub 4827ad600d Add workspace constraint on defaultRoleId and activationStatus (#11191)
Part of https://github.com/twentyhq/core-team-issues/issues/526

An active workspace's defaultRoleId should never be null.
We can't rely on a simple postgres NOT NULL constraint as defaultRoleId
will always be initially null when the workspace is first created since
the roles do not exist at that time.
Since a suspended workspace can be active again, we should maintain that
rule during the workspace suspension. The only moment defaultRoleId can
have a null value is during the onboarding. this pr enforces that
2025-03-26 14:43:13 +00:00
fe3dd40034 i18n - translations (#11190)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-26 15:20:30 +01:00
MarieandGitHub 7af90eb4c4 [permissions V2] Custom role deletion (#11187)
Closes https://github.com/twentyhq/core-team-issues/issues/616
2025-03-26 15:08:48 +01:00
WeikoandGitHub 16cb768c5c Do not suspend onboarding workspaces after stripe hook and add cron to delete them after 7 days (#11189)
## Context
When a trial ends, we receive a webhook from stripe to switch a
workspace from its previous status to SUSPENDED.
We also have some workspaces in ONGOING_CREATION that started the flow,
started the trial but did not finish completely the flow which means the
workspace has no data/metadata/schema.
Because of this, we can have workspaces that switch from
ONGOING_CREATION to SUSPENDED directly and ONGOING_CREATION workspaces
that didn't start the trial can stay in this state forever since they
are not cleaned up by the current cleaner.
To solve those 2 issues, I'm adding a new cron that will automatically
clean ONGOING_CREATION workspaces that are older than 7 days and I'm
updating the stripe webhook to only update the activationStatus to
SUSPENDED if it's already ACTIVE (then it will be deleted by the other
cron in the other case)
2025-03-26 14:35:11 +01:00
MarieandGitHub 72b4b26e2c [permissions] Enable permissions V1 for all workspaces (#11172)
Closes https://github.com/twentyhq/core-team-issues/issues/526

(for reminder: 
1. Make defaultRoleId non-nullable for an active workspace
2. Remove permissions V1 feature flag
3. Set member role as default role for new workspaces

About 1.:
An active workspace's defaultRoleId should never be null.
We can't rely on a simple postgres NOT NULL constraint as defaultRoleId
will always be initially null when the workspace is first created since
the roles do not exist at that time.

Let's add a more complex rule to ensure that

About 3.:
In the first phase of our deploy of permissions, we chose to assign
admin role to all existing users, not to break any existing behavior
with the introduction of the feature (= existing users have less rights
than before).

As we deploy permissions to all existing and future workspaces, let's
set the member role as default role for future workspaces.
)
2025-03-26 12:51:34 +00:00
0f7adedc96 i18n - translations (#11188)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-26 13:42:53 +01:00
f55a20addc [ENH] UseActionMenuEntries optimization (#11183)
# Introduction
Dynamically set in remove actions only if map has given key
Thanks @charlesBochet for the class on Recoil !

Related to https://github.com/twentyhq/twenty/issues/11079

## Conclusion
As always any suggestions are welcomed !

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-03-26 13:19:08 +01:00
Félix MalfaitandGitHub c36cfb3af9 Fix no timeline for opportunities (#11186)
Fixes #11176
2025-03-26 12:35:59 +01:00
80074bc21b i18n - translations (#11181)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-26 11:20:43 +01:00
Lucas BordeauandGitHub 8cc9f77417 Advanced filters bug bash (#11178) 2025-03-26 11:06:53 +01:00
7d6573e766 i18n - translations (#11177)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-25 22:31:15 +01:00
Félix MalfaitandGitHub 6ec06be18d Overwrite standard translations (#11134)
Manage overwriting translations for standard fields and standard objects
properties
2025-03-25 22:17:29 +01:00
7a7003d859 i18n - translations (#11175)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-25 19:21:40 +01:00
EtienneandGitHub 934abf1fb3 fix billing issues (#11160)
- first commit : fix quantity update on Enterprise plan
- second commit : fix user with soft deleted workspace trying to
recreate another workspace

closes https://github.com/twentyhq/core-team-issues/issues/634
2025-03-25 19:09:36 +01:00
Antoine MoreauxandGitHub 20f2a251b6 fix(auth): handle missing workspaceId in auth service (#11173)
Add a check to return undefined if workspaceId is not provided. Prevents
unnecessary execution and potential errors during workspace lookup.
2025-03-25 17:58:53 +00:00
Thomas TrompetteandGitHub 3e7ec4f756 Allow empty string for primary link (#11171)
Fixes https://github.com/twentyhq/twenty/issues/11166



https://github.com/user-attachments/assets/72208ac9-c19d-4c19-b305-40d6318310ed
2025-03-25 18:17:38 +01:00
ddd439031f i18n - translations (#11170)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-25 17:21:08 +01:00
nitinandGitHub 2182821fe1 fixed workspace tabs not working in admin panel (#11164)
fixed a regression on user lookup workspace tabs.
regression caused after this merge
https://github.com/twentyhq/twenty/pull/11008
2025-03-25 17:09:17 +01:00
Paul RastoinandGitHub a58831978f [FIX] Compute custom datname in entrypoint.sh (#11148)
Close https://github.com/twentyhq/twenty/issues/10928
2025-03-25 16:29:47 +01:00
Raphaël BosiandGitHub b24046b1bb Various design fixes on side panel (#11165)
- Fix background color
- Fix Menu Item height
- Fix Input design
- Fix show page summary card design
2025-03-25 15:21:10 +00:00
martmullandGitHub 45b8a330c6 Fix lambda iam (#11163)
As title, fix lambda driver for serverless functions
2025-03-25 15:57:04 +01:00
b70aa6f2ee i18n - translations (#11155)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-25 15:21:06 +01:00
GuillimGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
877d6e9304 Option-menu-v2-input (#11116)
Adding the possibility to change the view name and incon from the
Options menu dropdown

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-03-25 15:13:13 +01:00
acead6169c i18n - translations (#11152)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-25 13:52:56 +01:00
Raphaël BosiandGitHub f3f4dd7648 Fix record page title focus (#11145)
Fix record page title focus when creating a new record.

Before:


https://github.com/user-attachments/assets/3f032873-ef5b-4799-a6b7-6459674e4347


After:


https://github.com/user-attachments/assets/7ca4107d-cea8-477d-9e6a-2b74c3121a13
2025-03-25 11:54:29 +01:00
Paul RastoinandGitHub d601213c21 [FIX] twenty-shared build on window even wsl (#11130)
# Introduction
Handles both '/' and '\' by using native path api
2025-03-25 11:44:32 +01:00
GuillimandGitHub 96c61df007 fix MailboxConcurrency And email format without @ (#11133) 2025-03-25 11:40:58 +01:00
Lucas BordeauandGitHub de1f8a4706 Fix created by filter dropdown that appears on other filter types. (#11126)
Fixes https://github.com/twentyhq/twenty/issues/11077

This PR fixes a bug where the actor source filter dropdown input was
showing on other field types filter dropdown input.

It just adds a check to show this particular actor source filter
dropdown input only if the field type is ACTOR.

Sub field name reset and lifecycle will be handled in the incoming work
on sub field filtering.
2025-03-25 11:26:39 +01:00
MarieandGitHub 4680bc740a [permissions V2] Upsert object and setting permissions (#11119)
Closes https://github.com/twentyhq/core-team-issues/issues/639
2025-03-25 11:07:51 +01:00
Antoine MoreauxandGitHub 54e346a2aa fix(auth): prevent workspace creation on signup with password with no authorized user + fix 10982 (#11128)
Updated the method to properly fetch and return workspace data with
related approved access domains. This ensures the correct handling of
workspace lookup and fixes potential issues with undefined returns.

Fix #10982
2025-03-24 20:24:58 +01:00
Raphaël BosiandGitHub fd23a6e5ff Update delete record message (#11132)
Update delete record message
2025-03-24 20:22:05 +01:00
52cf6f4795 Allow to edit labels of standard objects (#10922)
Fixes #10793

This PR is a work in progress.

**Still left to fix:**

- [x] When disabling synchronization of labels / api names, the edited
labels should be set to the English version. Currently the client just
send the localized versions together with the `isLabelSyncedWithName`
change. Could be an easy fix.
- [ ] Sometimes flipping the switch don't trigger the update function,
may be a regression as it seems to affect the custom objects too.
- [ ] There is a frontend problem where the labels inputs don't reflect
the changes made. When enabling back synchronisation after editing
labels, they are correctly back to their base values (backend,
navigation breadcrumb, etc) but the label inputs still have the old
values (switching pages will put them back to normal). I suspect this
could be linked to the above problem.
- [ ] API names are still displayed for standard objects per (kept them
for debugging, trivial fix)
- [ ] `SettingsDataModelObjectAboutForm` have a `disableEdition`
parameter which is now used only for a few fields, not sure if it's
worth keeping because it's a bit misleading since it doesn't "disable"
much?
- [ ] I don't know what these do, but I have seen "Remote" object types.
Not sure if they work with my patch or not (I don't know how to test
them)
- [ ] Make it work with metadata synchronisation


**What should work:**

- Disabling synchronization of standard objects should work, label
inputs should no longer be disabled
- Modifying labels should work
- Enabling back synchronization should reset back the labels to the base
value and disable the label inputs again (minus the mentioned display
bug)
- The synchronisation switch should still work as expected for custom
objects
- Creating custom objects should still work (it uses the same form)

---------

Signed-off-by: AFCMS <afcm.contact@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-03-24 20:19:52 +01:00
Raphaël BosiandGitHub bc1b55ddc3 Add see runs and see workflows actions (#11131)
On default objects:
- Add see workflows

On workflows:
- Add see all runs (no selection)

On workflow runs:
- Add see workflows (no selection)
- Add see linked workflow (single record selection)
- Add see run version (single record selection)

On workflows versions
- Add see all runs (no selection)
- Add see workflows (no selection)
- Add see linked workflow (single record selection)
- Add see linked runs (single record selection)
2025-03-24 18:12:32 +01:00
Thomas TrompetteGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
049a065307 Update workflow run step (#11125)
Currently, when filling the form, values are not saved in the action
settings. This is an issue because we do not see the response in the
node settings, only in the output of the step.

This PR:
- adds a new endpoint to update a step in the run flow output
- updates this flow when a step is updated



https://github.com/user-attachments/assets/2e74a010-a0d2-4b87-bd1f-1c91f7ca6b60

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-03-24 17:42:15 +01:00
Paul RastoinandGitHub 0656b640d7 [FIX] Dockerfile copy prettierrc (#11129)
Now needed to build twenty-shared
2025-03-24 17:28:17 +01:00
Paul RastoinandGitHub da394ffcdc [FIX] Move preconstruct patch into twenty-shared package (#11124) 2025-03-24 15:51:14 +01:00
Paul RastoinandGitHub e23fcb21ae [CD][FIX] Copy twenty-shared patch (#11123)
Copy patches
2025-03-24 15:34:36 +01:00
Raphaël BosiandGitHub 0084946b76 608 fix hotkey scope and dropdown issues in the command menu (#11121)
Closes https://github.com/twentyhq/core-team-issues/issues/608

- Introduces a new hotkey scope `CommandMenuFocused`
- Fixes hotkey scopes issues in the side panel
2025-03-24 14:34:09 +00:00
Charles BochetandGitHub 6898a40ac3 Fix relation from many notes (#11120)
Fixes https://github.com/twentyhq/twenty/issues/3415
2025-03-24 15:19:05 +01:00
Lucas BordeauandGitHub e83e7b3b40 Fix bug and refactored advanced filter field selection dropdown (#11103)
This PR is a first step towards isolating each filter dropdown use case,
here we isolate advanced filter field selection dropdown from view bar
filter field selection dropdown.

## Isolation of advanced filter field selection logic

We reimplement the previously generic logic into
AdvancedFilterFieldSelectMenu and AdvancedFilterSubFieldSelectMenu
components.

For now it contains duplicated code but, the end goal is to factorize
what's common to all object filter dropdowns in small hooks where
possible, at the end of the code path isolation first step, which will
be done for applyFilter and selectFilter logic that will be able to be
deleted after code path isolation.

A new component ObjectFilterDropdownFilterSelectMenuItemV2 has been
created to expose an onClick method instead of computing logic that
tries to guess where it is located, which allows to verticalize what
happens when we select a field in each specific use case, one layer
above.

Created the hook useSelectFieldUsedInAdvancedFilterDropdown which
contains the logic for field selection for advanced filter field select
dropdown specific use case, the first example of a good verticalized and
unique place to handle field selection in the context of advanced
filter.

The naming useAdvancedFilterDropdown was lying and is now
useAdvancedFilterFieldSelectDropdown which is now self-explanatory.

useAdvancedFilterFieldSelectDropdown has been removed from the main
object filter dropdown, thus isolating advanced filters field select
dropdown from the generic object filter field select dropdown.

## Miscellaneous

Removed states that were used in the generic filter dropdown to guess
whether it was in advanced filter context or not.
2025-03-24 15:18:53 +01:00
Paul RastoinandGitHub 8b2a90dea1 [FEAT] Generate barrel export named modules and types (#11110)
# Introduction
In this PR using the Ts AST dynamically compute what to export,
gathering non-runtime types and interface in an `export type`

[Export type TypeScript
documentation](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html)

From
```ts
// index.ts
export * from "submodule"
```
To
```ts
export type { SomeType } from "submodule";
export { SomeFunction, SomeConst } from "submodule";
```


close https://github.com/twentyhq/core-team-issues/issues/644

## Motivations
- Most explicit and maintainable
- Best for tree-shaking
- Clear dependency tracking
- Prevents name collisions

## Important note
Please keep in mind that I will create, very soon, a dedicated
`generate-barrel` package in our yarn workspaces in order to:
- Make it reusable for twenty-ui
- Split in several files
- Setup lint + tsconfig
- Add tests

## Conclusion
As usual any suggestions are more than welcomed !
2025-03-24 15:06:16 +01:00
e6dec51ca6 Display workflow step header in workflow run input and output tabs (#11102)
- Wrap the content of Workflow View, Workflow Edit, and Workflow Run
side panels with a container making them take all the available height
- Remove the `StyledContainer` of code steps as it's redundant with the
global container
- Add the WorkflowStepHeader to the input and output tabs
- Make the JSON visualizer take all the available height in input and
output tabs
- Reuse the WorkflowStepBody component in the input and output tabs as
it applies proper background color

## Demo

![CleanShot 2025-03-21 at 18 30
26@2x](https://github.com/user-attachments/assets/c3fa512b-c371-4d0b-9bf6-a5f84d333dda)

Fixes
https://discord.com/channels/1130383047699738754/1351906809417568376

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-03-24 13:06:26 +00:00
EtienneandGitHub 1c5f3ef5fa clean searchResolvers in server (#11114)
Introduces break in change

- remove search... resolvers
- rename globalSearch to search
- rename searchRecord.objectSingularName > objectNameSingular
closes https://github.com/twentyhq/core-team-issues/issues/643
2025-03-24 13:42:51 +01:00
Charles BochetandGitHub 6e7d2db58f Fix From Many relation for deleted notes crashing (#11117)
In this PR, I'm: 
- fixing the root cause (we should not try to render a RecordChip if the
record is not defined in RelationFromMany Display)
- fixing related typing issues
- we won't be able to catch the issue from TS perspective as
ObjectRecord is a Record of string, any
2025-03-24 13:29:44 +01:00
GuillimandGitHub 3ec72a2bca logging ids to import (#11115) 2025-03-24 09:17:31 +00:00
f9e826d37e fix: Added ScrollWrapper on Settings Sidebar (#11106)
## Description

- this PR fixes issue #11092 
- Added ScrollWrapper and scroll in Settings sidebar while maintaining
the exit Settings fixed.

## Added Behaviour



https://github.com/user-attachments/assets/c8db0f6d-986e-46f3-85d6-bb3028c56e5f

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-03-23 13:02:33 +00:00
Paul RastoinandGitHub 9ad8287dbc [REFACTOR] twenty-shared multi barrel and CJS/ESM build with preconstruct (#11083)
# Introduction

In this PR we've migrated `twenty-shared` from a `vite` app
[libary-mode](https://vite.dev/guide/build#library-mode) to a
[preconstruct](https://preconstruct.tools/) "atomic" application ( in
the future would like to introduce preconstruct to handle of all our
atomic dependencies such as `twenty-emails` `twenty-ui` etc it will be
integrated at the monorepo's root directly, would be to invasive in the
first, starting incremental via `twenty-shared`)

For more information regarding the motivations please refer to nor:
- https://github.com/twentyhq/core-team-issues/issues/587
-
https://github.com/twentyhq/core-team-issues/issues/281#issuecomment-2630949682

close https://github.com/twentyhq/core-team-issues/issues/589
close https://github.com/twentyhq/core-team-issues/issues/590

## How to test
In order to ease the review this PR will ship all the codegen at the
very end, the actual meaning full diff is `+2,411 −114`
In order to migrate existing dependent packages to `twenty-shared` multi
barrel new arch you need to run in local:
```sh
yarn tsx packages/twenty-shared/scripts/migrateFromSingleToMultiBarrelImport.ts && \
npx nx run-many -t lint --fix -p twenty-front twenty-ui twenty-server twenty-emails twenty-shared twenty-zapier
```
Note that `migrateFromSingleToMultiBarrelImport` is idempotent, it's atm
included in the PR but should not be merged. ( such as codegen will be
added before merging this script will be removed )

## Misc
- related opened issue preconstruct
https://github.com/preconstruct/preconstruct/issues/617

## Closed related PR
- https://github.com/twentyhq/twenty/pull/11028
- https://github.com/twentyhq/twenty/pull/10993
- https://github.com/twentyhq/twenty/pull/10960

## Upcoming enhancement: ( in others dedicated PRs )
- 1/ refactor generate barrel to export atomic module instead of `*`
- 2/ generate barrel own package with several files and tests
- 3/ Migration twenty-ui the same way
- 4/ Use `preconstruct` at monorepo global level

## Conclusion
As always any suggestions are welcomed !
2025-03-22 19:16:06 +01:00
Charles Bochet 8a21c19f03 Fix missing record field component instanceId 2025-03-22 18:52:57 +01:00
Mitesh GuptaandGitHub aba55a5a34 fix: update allowed protocols for URL validation in environment variables (#11104)
When using postgres cloud databse connection string with protocol
'postgresql', it throws error "ERROR PG_DATABASE_URL must be a URL
address".

![Screenshot 2025-03-22 at 12 24
25 AM](https://github.com/user-attachments/assets/a5fdcb4e-686c-481a-9f4d-48a65aa44a30)
2025-03-22 13:32:50 +00:00
Charles BochetandGitHub ccf60284cf Various fixes (#11108)
Fixes many bug regarding TableCell and InlineCells
2025-03-22 14:19:10 +01:00
Charles BochetandGitHub 692e08f0d4 Improve AppError boundaries (#11107)
## What

This PR aims to make sure all application exceptions are captured
through react-error-boundaries

Once merged we will have:
- Root Level: AppErrorBoundary at the highest level (full screen) ==>
this one needs to be working in any case, not relying on Theme, was not
working
- Route Level: AppErrorBoundary in DefaultLayout (full screen) ==> this
was missing and it seems that error are not propagated outside of the
router, making errors triggered in CommandMenu or NavigationDrawer
missing
- Page Level: AppErrorBoundary in DefaultLayout write around the Page
itself (lower than CommandMenu + NavigationDrawer)
- Manually triggered: example in ClientConfigProvider

## Screenshots

App level (ex throw in IconsProvider)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/18a14815-a203-4edf-b931-43068c3436ec"
/>

Route level (ex throw in CommandMenu)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/ca066627-14c7-438e-a432-f0999a1f3b84"
/>

Page level (ex throw in RecordTable)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/ffeaa935-02af-4762-8859-7a0ccf8b77e1"
/>

Manually Triggered (clientConfig, ex when backend is not up)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/062d6d84-097a-4ed9-b6ce-763b8c27c659"
/>
2025-03-22 09:19:08 +01:00
Thomas TrompetteandGitHub c50cdd9510 Execute workflow form action (#11099)
- create a form filler component
- send the response on submit
- put back a field name. We need it for the step output
- validate a form is well set before activation

TODO:
- we need to refresh to see the form submitted. We need to discuss about
a strategy
- the response is not saved in the step settings. We need a new endpoint
to update workflow run step



https://github.com/user-attachments/assets/0f34a6cd-ed8c-4d9a-a1d4-51455cc83443
2025-03-21 17:38:14 +00:00
Félix MalfaitandGitHub 07bd2486ca Add enterprise plan in cloud onboarding (#11100)
Adding a way to switch to enterprise plan during onboarding

<img width="409" alt="Screenshot 2025-03-21 at 17 03 19"
src="https://github.com/user-attachments/assets/7a8c9ebd-3d77-4875-a141-c30fa5119eff"
/>
2025-03-21 17:38:13 +01:00
EtienneandGitHub e624e8deee replace search resolvers by global search in front (#11086)
Done
- Replace global search in multi record picker and single record picker

To do
- refactor SingleRecordPicker to match MultipleRecordPicker - next 1:1
- items in this issue
https://github.com/twentyhq/core-team-issues/issues/643



closes https://github.com/twentyhq/core-team-issues/issues/535
2025-03-21 17:25:00 +01:00
Antoine MoreauxandGitHub da527f1780 chore(ci): update Tinybird CI workflow (#11033)
Added a new job to check for changed files before executing the CI
workflow. Integrated Tinybird local service, updated environment
variables, and refined the CI steps for better functionality and
clarity.
2025-03-21 16:32:24 +01:00
nitinandGitHub 3960b0f99d App health check: Optimize pending migration query (#11049)
## Optimization: Efficient Health Check Query

This PR optimizes the workspace health check system by replacing the N+1
query pattern with efficient database queries.

### Key Improvements

- **Eliminated N+1 Query Problem**: Instead of fetching all workspaces
and then querying each one individually for pending migrations (which
caused slowness in production), we now use a single optimized query to
directly identify workspaces with pending migrations

- **Better Performance**: Reduced the number of database queries from
potentially hundreds/thousands (previous implementation) to just 2 fixed
queries regardless of workspace count

- **Full Coverage Instead of Sampling**: Rather than implementing a cap
on workspace checks at 100 (which was a workaround for performance
issues), this solution addresses the root cause by optimizing the query
pattern. We can now efficiently check all workspaces with pending
migrations without performance penalties.

@FelixMalfait This addresses the "always eager-load when you can"
feedback by handling the problem at the database level rather than just
applying a limit. The optimized query should solve both the performance
issues and provide more accurate health status information.
2025-03-21 16:30:38 +01:00
Nabhag MotivarasandGitHub 081f5fa766 Sort menu Incorrect padding bottom #11078 (#11091)
##  Issue
- Closes #11078
- **visual regression** from PR - #9159 that likely might have break
visuals in several other places.
2025-03-21 16:29:30 +01:00
Raphaël BosiandGitHub 3328998e61 Remove hotkey scope from useListenClickOutside (#11098)
The old `useListenClickOutside` API allowed us to pass a hotkeyScope as
a parameter, the click outside was triggered only if the current hotkey
scope matched the parameter. We don't want this anymore. This fixes a
few bugs related to hotkey scopes inside the side panel.
2025-03-21 16:27:58 +01:00
WeikoandGitHub 2c5e3dba60 revert logout button to settings menu (#11097)
## Context
Reverting back the removal of "Log out" button. While it is now
accessible from the workspace picker, suspended workspaces don't have
access to that picker and are locked in the settings pages so I'm adding
back the log out button in the settings menu

<img width="225" alt="Screenshot 2025-03-21 at 15 52 40"
src="https://github.com/user-attachments/assets/d5453868-d043-49e9-9207-2cfdd65838da"
/>
2025-03-21 16:26:06 +01:00
martmullandGitHub 463a2995a9 Fix wrong totalCount in groupBy view (#11094)
Add filters by visibleRecordGroup to compute totalCount
## Before
see https://github.com/twentyhq/twenty/issues/11067

## After

![image](https://github.com/user-attachments/assets/333e8898-e051-4554-b462-9b1d2f10ec05)

- After hiding `New` and `Meeting` columns:
<img width="1280" alt="image"
src="https://github.com/user-attachments/assets/a2ae1728-ea11-4e2d-86e5-02778b3c42c0"
/>

- With filtering
<img width="1275" alt="image"
src="https://github.com/user-attachments/assets/263d8865-9cba-4b46-84a0-e9270b29109b"
/>

- Works also in groupBy view
<img width="1280" alt="image"
src="https://github.com/user-attachments/assets/c1ec171f-6eec-45db-aafc-2bd2d1de8841"
/>
2025-03-21 16:22:24 +01:00
martmullandGitHub 6a412a531f Remove useless skelettonLoader (#11096)
## After

![image](https://github.com/user-attachments/assets/772e9a8c-5df2-4bfd-95ea-5854022e82e0)
<img width="825" alt="Capture d’écran 2025-03-21 à 15 43 14"
src="https://github.com/user-attachments/assets/87818683-9cb0-4264-a6c3-f0420b0ae34d"
/>
2025-03-21 16:19:45 +01:00
Lucas BordeauandGitHub c961d3a60d Reorganized components in advanced filter dropdown (#11089)
This PR essentially focuses on a refactor of the component hierarchy and
naming in advanced filter dropdown, to make it more readable and easy to
maintain.

This refactor was required because this area of the code is recursive,
so it's better to see the same abstract components in the recursion,
instead of trying to guess whether we have the same components than the
level above or not.

Also keep in mind that this refactor is meant to separate the advanced
filter code path from the view bar simple filter code path, while
reusing what's reusable, so here we have a first attempt at finding the
sweet spot, that we'll be able to duplicate on other filter dropdown use
cases.

- We now use AdvancedFilterRecordFilterGroupRow and
AdvancedFilterRecordFilterRow to make it clearer in the advanced filter
dropdown recursion where we are.
- Children component of AdvancedFilterRecordFilterRow have been
abstracted at the same level to make reading easier
- The field selection dropdown is now in a self-explanatory component
that follows the same naming pattern as other dropdowns in the app :
AdvancedFilterFieldSelectDrodownButton, together with
AdvancedFilterFieldSelectDrodownContent.
- The field selection search in the filter dropdown is now a standalone
component : AdvancedFilterFieldSelectSearchInput
- The UI container of a row has been abstracted in a new
AdvancedFilterDropdownRow

Miscellaneous : 
- Renamed a bunch of view filter old naming to record filter naming.
2025-03-21 16:19:19 +01:00
Raphaël BosiandGitHub d7dabe5826 Update timeline empty state in the side panel (#11093)
Fixes https://github.com/twentyhq/twenty/issues/10914

Before:


https://github.com/user-attachments/assets/83764543-06bf-455e-8b07-fa2822691005


After:


https://github.com/user-attachments/assets/09afa15d-6352-4024-a6b9-2cccf5991d8a
2025-03-21 15:30:14 +01:00
Charles BochetandGitHub b49dc57bbf Microsoft mail sync: make sure that message list fetch is using max batch size (#11095)
Fixes https://github.com/twentyhq/core-team-issues/issues/641
2025-03-21 15:20:39 +01:00
WeikoandGitHub 77ee016d6f Fix currency update (#11088)
## Context
Currency picker was not working properly, clicking a value was
triggering the clickOutsideListener of the parent and was closing the
select without saving. We are now toggling the click outside listener
based on the state of the currency picker dropdown
This also means the UX changed a bit, now choosing a value or clicking
outside only closes the select (allowing you to choose the amount as
well) and only enter OR clicking outside will save
2025-03-21 13:56:03 +01:00
Raphaël BosiandGitHub cecb32cd89 Fixes on rich text editor (#11087)
- Update skeleton loader padding and make it take only one line
- Update rich text editor padding to align with the fields inside the
side panel
<img width="163" alt="Capture d’écran 2025-03-21 à 11 57 00"
src="https://github.com/user-attachments/assets/5964404a-3a32-4d7e-b96f-3377949430bf"
/>
2025-03-21 13:49:39 +01:00
Raphaël BosiandGitHub 3af5cde170 Reorder commands (#11084)
Put workflows on top of navigation commands in the command menu.
2025-03-21 11:10:30 +01:00
99438a810c Error invalid link (#10288)
Don't have access to push on
https://github.com/twentyhq/twenty/pull/9942, so close it and open new
PR here

<img width="244" alt="Screenshot 2025-02-18 at 11 09 39"
src="https://github.com/user-attachments/assets/4bc1b436-147a-4d17-88c8-2aff0fffd06a"
/>
<img width="246" alt="Screenshot 2025-02-18 at 11 09 51"
src="https://github.com/user-attachments/assets/3d7b2972-ab7e-4e3b-a177-658325a3bb70"
/>

Ok for RecordInlineCell / RecordTableCell and EmailsFieldInput /
LinksFieldInput.
I think it's too complex for a so small issue (agree with you khuddite)

closes https://github.com/twentyhq/twenty/issues/9778
on top of https://github.com/twentyhq/twenty/pull/9942 from @khuddite

---------

Co-authored-by: khuddite <khuddite@gmail.com>
Co-authored-by: khuddite <62555977+khuddite@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-21 10:18:55 +01:00
bd162da318 Update environment-variables.ts (#11068)
Added rediss protocol.

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-03-20 22:47:38 +01:00
Raphaël BosiandGitHub 70a295641d Fix overscroll behavior on dev environment (#11080)
Before:


https://github.com/user-attachments/assets/c04e8d5d-cfa2-4d62-a4c6-39041c8b61c8


After:


https://github.com/user-attachments/assets/953b31b4-9388-43ed-9279-2bc0a73b24dc
2025-03-20 22:44:43 +01:00
AyushandGitHub 8c982653cf fix/REDIS_URL-has-failed-the-following-constraints-isUrl (#11082)
Added 'rediss' in protocols array so that url doesn't fail isUrl
constraint
2025-03-20 22:38:27 +01:00
nitinandGitHub 8309575a94 Fix option text deletion in select fields by removing error for empty values (#11081)
closes #11013
Fixes the issue where users couldn't delete all text in select field
options. Removed the error throw for empty strings in the
computeOptionValueFromLabel function, allowing proper text deletion.
This error handling was redundant since the form validation already
prevents submission with empty values.
2025-03-20 22:35:48 +01:00
Paul RastoinandGitHub 872c0e97f6 [BUGFIX] GenerateDefaultRecordChipData returns RecordChipData (#11071)
# Introduction
closes https://github.com/twentyhq/twenty/issues/11030, might not fix
the issue as it seems to be related to the passed record to
`identifierChipGeneratorPerObject` about to dig deeper in this generator
code => found nothing revelant doubled check each `RecordChip`
invocation that could provide undefined record
Fixed wrong default generated `RecordChipData` signature

## Reproducibility
I've only been able to reproduce the bug in production using the very
same opportunity than within the issue, but not all the time

https://crm.twenty-internal.com/objects/opportunities?viewId=b709d3d1-2dd2-455d-ba73-784f3ab00883
```json
// Removed timelineActivities to prevent linking ids
{
  "data": {
    "opportunity": {
      "__typename": "Opportunity",
      "closeDate": null,
      "company": null,
      "companyId": null,
      "createdAt": "2024-06-17T09:45:22.357Z",
      "deletedAt": null,
      "id": "006a22dd-6bd6-4247-a24b-42fb164cd48c",
      "name": "test",
      "pointOfContact": null,
      "pointOfContactId": null,
      "position": 0,
      "probability": "0",
      "stage": "NEW_STAGE",
      "updatedAt": "2025-03-20T16:27:51.927Z",
      "amount": {
        "__typename": "Currency",
        "amountMicros": null,
        "currencyCode": "USD"
      },
      "attachments": {
        "__typename": "AttachmentConnection",
        "edges": []
      },
      "createdBy": {
        "__typename": "Actor",
        "source": "MANUAL",
        "workspaceMemberId": null,
        "name": "",
        "context": {}
      },
      "favorites": {
        "__typename": "FavoriteConnection",
        "edges": []
      },
      "taskTargets": {
        "__typename": "TaskTargetConnection",
        "edges": []
      },
      "noteTargets": {
        "__typename": "NoteTargetConnection",
        "edges": [
          {
            "__typename": "NoteTargetEdge",
            "node": {
              "__typename": "NoteTarget",
              "appEventId": null,
              "companyId": null,
              "createdAt": "2025-01-22T17:11:07.801Z",
              "deletedAt": null,
              "feedbackId": null,
              "id": "2e8eca1c-e2c2-425a-93fc-ef2aeb65f410",
              "issueId": null,
              "listingId": null,
              "noteId": "ab586b51-6931-4a4a-9c24-0d16226211b2",
              "opportunityId": "006a22dd-6bd6-4247-a24b-42fb164cd48c",
              "personId": null,
              "somethingId": null,
              "testId": null,
              "updatedAt": "2025-01-22T17:11:07.801Z"
            }
          }
        ]
      },
    }
  }
}
```
2025-03-20 18:38:19 +01:00
WeikoandGitHub 95014b0ac5 Fix role edit page tab instance id (#11074)
Also fixes workflows
Fixes https://github.com/twentyhq/twenty/issues/11073
2025-03-20 18:30:02 +01:00
Thomas TrompetteandGitHub 3876cb8250 Separate workflow step details and run step details (#11069)
Workflows step details in workflows and versions should be different
from the node tab in run. For most cases, it was using the same
component. But for forms, it will be a different one.

This PR:
- renames form action into formBuilder. formFiller is coming
- put code into a separated folder
- creates a new component for node details
2025-03-20 16:22:55 +00:00
MarieandGitHub 24bae89ebc Fix click outside for RecordDetailRelationSection (#11072)
Fixes https://github.com/twentyhq/twenty/issues/11061
2025-03-20 16:22:28 +00:00
martmullandGitHub 6d8cf442a7 Give worker access to server volume (#11065) 2025-03-20 16:43:38 +01:00
Raphaël BosiandGitHub 7dac60cfee Fix useFindManyRecords withSoftDeleterFilter (#11056)
Fixes #11038

# Fix useFindManyRecords withSoftDeleterFilter

The error came from a faulty implementation of the `withSoftDeleted`
parameter inside `useFindManyRecords` and from the fact that
`withSoftDeleted: true` was added to access deleted records actions.
However, this parameter was always set in
`useFindManyRecordsSelectedInContextStore` instead of considering
whether the filter was active or not.

```
const withSoftDeleterFilter = {
  or: [{ deletedAt: { is: 'NULL' } }, { deletedAt: { is: 'NOT_NULL' } }],
};
```

The final filter was incorrectly doing an `or` operation between the
base filter and `withSoftDeleterFilter` when it should have been an
`and`:

```
filter: {
  ...filter,
  ...(withSoftDeleted ? withSoftDeleterFilter : {}),
}
```

The correct implementation should be:

```
filter:
  filter || withSoftDeleted
    ? {
        and: [
          ...(filter ? [filter] : []),
          ...(withSoftDeleted ? [withSoftDeleterFilter] : []),
        ],
      }
    : undefined,
```

# Fix useFindManyRecordsSelectedInContextStore

- Check if the soft deleted filter is active before using the
`withSoftDeleterFilter` parameter
2025-03-20 16:27:55 +01:00
Antoine MoreauxandGitHub 295f153abe fix(settings): adjust custom domain table cell styling (#11060)
Set table cell display to block to ensure proper rendering and
alignment. This resolves layout issues caused by the previous styling.
2025-03-20 13:35:58 +01:00
Antoine MoreauxandGitHub 5f390d75b0 refactor(button): rename loading to isLoading for clarity (#11058)
Updated all instances of the loading prop to isLoading across Button and
related components. This improves readability and ensures consistency in
the codebase.
2025-03-20 11:57:19 +00:00
Antoine MoreauxandGitHub 548597bfd0 refactor(ui): simplify workspace dropdown component structure (#11040)
Reorganized the workspace dropdown rendering logic for improved
readability and maintainability. Ensured consistent handling of
separators and dropdown items, while preserving the existing
functionality.

Fix #11034
2025-03-20 12:38:10 +01:00
MarieandGitHub 8b7188e85b [fix] [permissions] Fix role assignment at sign-up (#11045)
In [a previous PR](https://github.com/twentyhq/twenty/pull/11023) I
fixed the issue where users where re-assigned the default role when
signin up using SSO.
The "fix" actually introduced another error, calling
`assignRoleToUserWorkspace` only when a user is signing up to twenty,
forgetting about the case where an existing twenty user signs up to a
different workspace. They should still be assigned the role in that
case.

To fix this and improve clarity, I moved assignRoleToUserWorkspace to
addUserToWorkspace and renamed addUserToWorkspace to
addUserToWorkspaceIfUserNotInWorkspace since this is at each sign in but
does nothing if user is already in the workspace.

I think ideally we should refactor this part to improve readability and
understandability, maybe with different flows for each case: signIn and
signUp, to twenty or to a workspace
2025-03-20 10:37:26 +00:00
Lucas BordeauandGitHub 4b34aa60b1 Fix minor bugs on advanced filters (#11044)
This PR fixes some minor bugs on advanced filters.

## Dropdown menu header in filter input

The chevron down icon in the operand dropdown menu header was missing
due to a recent refactor of the DropdownMenuHeader component.

I just removed the unused EndIcon and replaced its usage by
EndComponent.

## Advanced filter dropdown staying open with 0 filters

The behavior we have for non-advanced filters is that the chip should
disappear if the filter gets empty, which is logical, an empty filter is
equivalent to not having filters, so don't want empty chips.

For advanced filters, the principle is the same, except that it's a bit
more complex to handle due to the recursive filter group hierarchy.

Here we create a useRemoveRootRecordFilterGroupIfEmpty hook, that we can
call everywhere a synchronous action should end up removing advanced
filters completely. (instead of using an effect)

This hook is distinct from removeRecordFilterGroup because we want
removeRecordFilterGroup to do only one job and we don't want it to hide
any side effect. It's better to have the side effect in a separate hook
that we call sequentially afterwards, in a self-explanatory manner.

## Miscellaneous

In this PR we add a new component selector to get the root level record
filter group, which is handy in a lot of cases.

The return type of the useChildRecordFiltersAndRecordFilterGroups hook
when it's empty has been fixed, though as discussed with Charles, it
would be better to turn it into selectors, which will certainly be done
in future PRs.
2025-03-20 11:26:14 +01:00
5f8fae9ada i18n - translations (#11054)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-20 11:21:03 +01:00
martmullandGitHub d99f027e8d 400 workflows webhooks trigger (#11041)
https://github.com/user-attachments/assets/dc0ece22-4d87-417f-b9e1-a11c3fd52ce8
2025-03-20 10:12:52 +00:00
bc94891a27 i18n - translations (#11052)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-20 11:12:44 +01:00
Thomas TrompetteandGitHub 369abfe424 Rename onPersist to onChange for form fields (#11047)
We are about to build forms where fields will not be persisted
immediately. It will have to be submitted.
Renaming the prop to reflect it.
2025-03-20 10:58:02 +01:00
e666506ea3 chore: Unify Label Styles Across App #6389 (#10728)
Chores #6389 

## Description
This PR addresses inconsistencies in the codebase where elements that
visually function as labels were implemented with custom-styled
components rather than the standardized Label component from the UI
library.

## Changes
I've replaced several custom-styled text elements with the standardized
Label component from twenty-ui to improve consistency and
maintainability across the application. These modifications maintain the
same visual appearance and functionality while standardizing the
implementation.

## Components Modified:
InputLabel: Converted from a styled label to use the Label component
InputHint: Replaced styled div with a styled Label component
TableSection: Introduced a StyledLabel using the Label component for
section headings
StyledDropdownMenuSubheader: Converted from a styled div to a styled
Label component
NavigationDrawerSectionTitle: Replaced internal text element with the
Label component
SettingsCard: Updated description element to use the Label component
SettingsListItemCardContent: Changed description span to use the Label
component
RecordDetailSectionHeader: Added a StyledLabelLink for link text using
the Label component
TaskList: Modified the task count display to use the Label component
CommandGroup: Updated group headings to use the Label component
WorkerMetricsGraph: Replaced no-data message with a Label-based
component
ViewPickerSelectContainer: Changed from a styled div to a styled Label
component

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-03-20 09:32:34 +00:00
3b3ed1a907 i18n - translations (#11051)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-20 10:20:50 +01:00
d8ea292321 (#11036) task: remove redundant logout button from settings sidebar (#11050)
- Removed logout item from settings navigation drawer
- Removed logout locator and method from E2E tests
- Removed logout item from NavigationDrawer story

The logout functionality is now exclusively available through the menu
switcher, making the UI more consistent and reducing duplication.

Closes #11036

<img width="851" alt="Screenshot 2025-03-19 at 9 46 33 PM"
src="https://github.com/user-attachments/assets/3d73ec84-a2b7-4c4d-9605-dc83a9a760c1"
/>

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-03-20 10:08:59 +01:00
183f497ad7 i18n - translations (#11048)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-19 19:21:35 +01:00
99f68416dc i18n - translations (#11046)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-19 19:01:39 +01:00
Thomas TrompetteandGitHub 7b0bf7c4b0 Form action field base settings (#11035)
- Add settings for text and number fields
- Settings are for now the same but I still separated with two
components because they will evolve


https://github.com/user-attachments/assets/96b7fffd-c3a1-45b9-aeaa-45d63505de3c
2025-03-19 17:44:02 +00:00
GuillimandGitHub 8b513a7d3b contact creation was recreating a primaryemail du to casing (#11042)
a first step to fix some of the issues i notices in grafana for netzero

in grafana, we log this error :  
```
error: error: duplicate key value violates unique constraint "IDX_UNIQUE_87914cd3ce963115f8cb943e2ac"

query failed: INSERT INTO "workspace_20fjk7nksxxxxxxxxxxx"."person"("cdrOpportunityId", "siteOpportunityId", "xLinkPrimaryLinkLabel", "xLinkPrimaryLinkUrl", "xLinkSecondaryLinks", "linkedinLinkPrimaryLinkLabel", "linkedinLinkPrimaryLinkUrl", "linkedinLinkSecondaryLinks", "emailsPrimaryEmail", "emailsAdditionalEmails", "companyId", "deletedAt", "position", "phonesPrimaryPhoneNumber", "phonesPrimaryPhoneCountryCode", "phonesPrimaryPhoneCallingCode", "phonesAdditionalPhones", "createdAt", "id", "searchVector", "avatarUrl", "city", "jobTitle", "nameFirstName", "nameLastName", "updatedAt", "createdBySource", "createdByWorkspaceMemberId", "createdByName", "createdByContext") VALUES (DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $1, $2, $3, DEFAULT, $4, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $5, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $6, $7, DEFAULT, $8, $9, $10, $11), (DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $12, $13, $14, DEFAULT, $15, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $16, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $17, $18, DEFAULT, $19, $20, $21, $22), (DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $23, $24, $25, DEFAULT, $26, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $27, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $28, $29, DEFAULT, $30, $31, $32, $33), (DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $34, $35, $36, DEFAULT, $37, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $38, DEFAULT, DEFAULT, DEFAULT, DEFAULT, $39, $40, DEFAULT, $41, $42, $43, $44) RETURNING "xLinkPrimaryLinkLabel", "xLinkPrimaryLinkUrl", "xLinkSecondaryLinks", "linkedinLinkPrimaryLinkLabel", "linkedinLinkPrimaryLinkUrl", "linkedinLinkSecondaryLinks", "emailsPrimaryEmail", "emailsAdditionalEmails", "companyId", "deletedAt", "position", "phonesPrimaryPhoneNumber", "phonesPrimaryPhoneCountryCode", "phonesPrimaryPhoneCallingCode", "phonesAdditionalPhones", "createdAt", "id", "searchVector", "avatarUrl", "city", "jobTitle", "nameFirstName", "nameLastName", "updatedAt", "createdBySource", "createdByWorkspaceMemberId", "createdByName", "createdByContext" 
```
The index is related to the People table on the netzero workspace
schema. When I looked at the email trying to be inserted, it contains
captial letters. I looked at the DB and there are existing small caps
emails. That's why my guess it that the failure comes from the contact
creation service.

Intersting fact, it comes from the CALENDAR source, not the email one.
That's why i added a little bit of error logging in case it reproduces
itself
2025-03-19 18:24:35 +01:00
Raphaël BosiandGitHub 7fe81f28b7 Update CommandMenuContextChipRecordSetterEffect to use the cache (#11043)
Closes https://github.com/twentyhq/core-team-issues/issues/581

Get records from the cache directly instead of querying them.
2025-03-19 18:21:06 +01:00
Antoine MoreauxandGitHub 28028ca4c0 fix(twenty-front): error on captcha initialisation (#11039) 2025-03-19 16:09:35 +00:00
Raphaël BosiandGitHub cfdb3f5778 584 Refactor Tabs (#11008)
Closes https://github.com/twentyhq/core-team-issues/issues/584

This PR:
- Migrates the component state `activeTabIdComponentState` from the
deprecated V1 version to V2.
- Allows the active tab state to be preserved during navigation inside
the side panel and reset when the side panel is closed.
- Allows the active tab state to be preserved when we open a record in
full page from the side panel


https://github.com/user-attachments/assets/f2329d7a-ea15-4bd8-81dc-e98ce11edbd0


https://github.com/user-attachments/assets/474bffd5-29e0-40ba-97f4-fa5e9be34dc2
2025-03-19 15:53:22 +00:00
0d40126a29 i18n - translations (#11031)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-03-19 15:20:18 +01:00
EtienneandGitHub b8b00e5398 add integration test on global search resolver (#11007)
closes https://github.com/twentyhq/core-team-issues/issues/580
2025-03-19 14:22:02 +01:00
GuillimandGitHub d59c989ecd Align navigation icons (#10983)
Fixes https://github.com/twentyhq/twenty/issues/10550

FYI : I took the same width calculation than the other navigation items.
2025-03-19 13:16:15 +00:00
69b3b34859 [permissions] Fix user is assigned default role after SSO sign-in (#11023)
When logging using a SSO method, we call signInUp service in which we
were wrongfully assigning a role to the user even if the user is signing
in and not signin up.

This went unnoticed during our QA as a different sign-in method is
called when logging with the credentials.

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-03-19 14:14:45 +01:00
8c5335a863 i18n - translations (#11026)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-19 13:22:31 +01:00
Paul RastoinandGitHub 5ba3c09b14 [CHORE] Prepare twenty-serverfor twenty-shared multi barrel refactor (#11022)
# Introduction
While running https://github.com/twentyhq/twenty/pull/10960 scripts
discovers few issues:
- Invalid named folder `pre-hooks.ts`
- Mock consuming outbound imported module resulting in consumed before
initialization
2025-03-19 11:26:42 +00:00
Paul RastoinandGitHub 4ce607869e [CHORE] TypeScript Lingui configuration file (#11021)
# Introduction 
We want theses configurations to be strictly typed but needed as in
https://github.com/twentyhq/twenty/pull/10960 will browse through all
TypeScript files within the codebase
2025-03-19 12:05:55 +01:00
7065f6f15d i18n - translations (#11020)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-19 11:59:34 +01:00
Baptiste DevessierandGitHub 1ecc5e2bf6 Limit nodes opened by default in the JSON Tree component (#11002)
- Add a parameter to choose which nodes to open by default
- On the Admin Panel, open all nodes by default
- On the Workflow Run step output, open only the two first depths
- On the Workflow Run step input, open only the previous step first
depth
- Display `[empty string]` when a node is an empty string
- Now, display `null` instead of `[null]`

## Demo


https://github.com/user-attachments/assets/99b3078a-da3c-4330-b0ff-ddb2e360d933

Closes https://github.com/twentyhq/core-team-issues/issues/538
2025-03-19 11:44:34 +01:00
BOHEUSandGitHub 15a2cb5141 Update playwright (#10927)
Update twenty-e2e-testing to reflect actual state of app
2025-03-19 11:29:36 +01:00
ecc21656cb i18n - translations (#11019)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-19 11:20:44 +01:00
Lucas BordeauandGitHub 62a58816e3 Fix view groups update after field metadata update (#10995)
This PR fixes a difficult to reproduce bug, where a race condition
appears if we go back to a table with view groups before the update
field metadata logic finishes its work.

In order to reproduce this bug on localhost, you'll have to simulate a
slow network in your browser.

The problem was that the view groups are initialized only once by
useLoadRecordIndexStates, in an effect component :
RecordIndexLoadBaseOnContextStoreEffect. And that this component as an
internal state loadedViewId, which prevents subsequent updates of view
groups by useLoadRecordIndexStates, because it considers that loading
already happened, even if it's actually stale data.

So instead of creating other states to burden the effect component with
complex state management, the solution was to add the only needed update
in a synchronous way directly in updateOneFieldMetadataItem logic. This
way we are sure that our boards and tables with view groups get updated
eventually, for each field metadata update, even if the requests take
time.

Fixes https://github.com/twentyhq/twenty/issues/10947
Fixes https://github.com/twentyhq/twenty/issues/10944
2025-03-19 11:13:14 +01:00
martmullandGitHub 7921ee5216 Stop emitting update event if before===after (#11004)
as title
2025-03-19 10:49:21 +01:00
Charles BochetandGitHub ca9c070945 Fix activity (#11015)
Deprecating unused states and making sure that the ActivityRichText
editor loads when activity.bodyV2 is present
2025-03-19 10:45:11 +01:00
Charles Bochet 117a961622 Fix activity content not properly loaded 2025-03-19 00:45:02 +01:00
1044328c66 i18n - translations (#11012)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-19 00:00:58 +01:00
Charles BochetandGitHub a4bd00ae29 Remove opportunity specific code on Kanban (#11000)
In this PR:
- clean board from opportunity specific logic
- remove in place creation in board
- trigger creation in right drawer instead
2025-03-18 23:54:40 +01:00
d47debaff6 i18n - translations (#11010)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 21:32:51 +01:00
7546d9b82c i18n - translations (#11009)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 21:20:45 +01:00
841d48b704 Creating records in side panel not working (#10999)
Fixes https://github.com/twentyhq/core-team-issues/issues/624

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-18 19:34:50 +01:00
MarieandGitHub 9e83d902d8 [permissions V2] Create and update a custom role (without granularity) (#11003)
First steps for https://github.com/twentyhq/core-team-issues/issues/595
and https://github.com/twentyhq/core-team-issues/issues/621

Not handling granular permissions through objectPermissions and
settingsPermissions next; will come next !
2025-03-18 18:42:30 +01:00
489cc13fd9 i18n - translations (#11005)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 18:01:11 +01:00
WeikoandGitHub c3a9c85265 Update 'Settings Permissions' Layout (#10997)
Fixes https://github.com/twentyhq/core-team-issues/issues/566

## Before
<img width="712" alt="Screenshot 2025-03-18 at 17 17 38"
src="https://github.com/user-attachments/assets/5c2dd8c6-e0cc-4610-b858-071d50de692c"
/>
<img width="775" alt="Screenshot 2025-03-18 at 17 17 30"
src="https://github.com/user-attachments/assets/52bdde22-f26d-4698-8138-5f2af28ddd50"
/>


## After
<img width="949" alt="Screenshot 2025-03-18 at 16 58 31"
src="https://github.com/user-attachments/assets/71b77032-0f5d-452b-b088-7af7e306d0a6"
/>
<img width="946" alt="Screenshot 2025-03-18 at 16 58 38"
src="https://github.com/user-attachments/assets/dc2ddf95-1622-419a-a35b-3037da7bdd4d"
/>
2025-03-18 17:48:35 +01:00
6acb70d6a9 i18n - translations (#10998)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 17:36:49 +01:00
Thomas TrompetteandGitHub 0ce91d84c1 Allow to add and delete fields (#10990)
- Allow to add a new field
- On field click, display a delete button
- Use id instead of names for fields



https://github.com/user-attachments/assets/4ebffe22-225a-4bae-aa49-99e66170181a
2025-03-18 17:24:52 +01:00
6d517360d1 i18n - translations (#10994)
Created by Github action

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-03-18 17:21:25 +01:00
Raphaël BosiandGitHub b4412ab3c8 Fix workflow id not being set (#10989)
The workflow id was not set inside `WorkflowRunVisualizerEffect` and
`WorkflowVersionVisualizerEffect` this PR fixes this
2025-03-18 17:00:56 +01:00
Raphaël BosiandGitHub 2680f1d6be 583 refactor useCommandMenu hook (#10984)
Closes https://github.com/twentyhq/core-team-issues/issues/583

- Split hook into smaller hooks
- Create tests
2025-03-18 15:37:28 +01:00
324794707a i18n - translations (#10988)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 15:34:51 +01:00
WeikoandGitHub 0e8d5728b0 Fix permissionAssignment dropdownMenu max height (#10987)
HasMaxHeight prop was missing in the dropdown container so the content
was not scrollable

Before
<img width="692" alt="Screenshot 2025-03-18 at 15 18 08"
src="https://github.com/user-attachments/assets/5ab8fd70-5528-4cf8-a526-38afdae1f502"
/>

After
<img width="703" alt="Screenshot 2025-03-18 at 15 17 59"
src="https://github.com/user-attachments/assets/5bbf4347-c963-4785-948c-8e16272bf067"
/>
2025-03-18 15:29:05 +01:00
38c6222422 i18n - translations (#10986)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 15:20:19 +01:00
WeikoandGitHub eb73838e5d Fix yarn lock (#10985) 2025-03-18 14:57:06 +01:00
martmullandGitHub 1bd3000b5d Investigate workflow user error (#10952)
Investigation related to https://github.com/twentyhq/twenty/issues/10868

- throw an error when computedVersion is undefined
2025-03-18 14:24:21 +01:00
a73b440646 i18n - translations (#10980)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 14:23:52 +01:00
291d6082c9 refactor(captcha): simplify interval handling in hook (#10974)
Close #10708

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-03-18 13:23:31 +00:00
GuillimandGitHub 6255207aa3 Command menu overflow ellipsis (#10977)
Fixes https://github.com/twentyhq/core-team-issues/issues/579
2025-03-18 13:21:47 +00:00
WeikoandGitHub be1b877868 Add empty states to settings tables (#10978)
## Context
Fixes https://github.com/twentyhq/twenty/issues/10964

## Test
<img width="617" alt="Screenshot 2025-03-18 at 12 18 30"
src="https://github.com/user-attachments/assets/dab8738d-d221-4a6b-a72e-061ab5fffb70"
/>
<img width="647" alt="Screenshot 2025-03-18 at 12 18 25"
src="https://github.com/user-attachments/assets/45466a80-7a80-4cde-a0c5-420cd6c05cb2"
/>
<img width="637" alt="Screenshot 2025-03-18 at 12 18 19"
src="https://github.com/user-attachments/assets/46a9f27a-bd3a-4e91-9885-668cf780d562"
/>
<img width="630" alt="Screenshot 2025-03-18 at 12 18 07"
src="https://github.com/user-attachments/assets/e1f805a0-ed7f-4cf2-8f75-78b865bd1ca2"
/>
<img width="649" alt="Screenshot 2025-03-18 at 12 18 01"
src="https://github.com/user-attachments/assets/e9f3086f-fe97-4f3b-99e0-25249e9dd43b"
/>
2025-03-18 14:18:33 +01:00
1ca5a5e9f6 i18n - translations (#10979)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 14:11:37 +01:00
Antoine MoreauxandGitHub ab9498b3de feat(workspace): delete custom domain on hard workspace delete (#10975)
Add logic to remove a workspace's custom domain during hard deletion.
Includes tests to verify behavior for both hard and soft deletion cases.

Fix #10351
2025-03-18 14:06:24 +01:00
Baptiste DevessierandGitHub f5195433f3 Configure Keystatic for release images (#10889)
- Add validation for the `release` field of the releases collection
  - The `release` must follow semver format
- The `slug` matches the `release` by default and must follow semver
format, too
- Order the releases properly
- `0.10.0` appears before `0.3.0`; I made the comparison against
`0000.0010.0000` and `0000.0003.0000`
- Set up images for release's contents
- Refactor the release notes of the version `0.43.0` to be editable in
Keystatic; it will serve as an example

## Demo



https://github.com/user-attachments/assets/d82851e9-11e7-4e27-b645-cf86a93d77bf
2025-03-18 12:45:51 +01:00
3d34f477f9 i18n - translations (#10976)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 12:19:40 +01:00
Baptiste DevessierandGitHub eb5fb51c1b Animate the opening and exiting states of the JSON visualizer (#10965)
I used `overflow-y: clip` instead of `overflow-y: hidden` because of
this behavior:

> Setting overflow to visible in one direction (i.e. overflow-x or
overflow-y) when it isn't set to visible or clip in the other direction
results in the visible value behaving as auto.


## Demo


https://github.com/user-attachments/assets/b7975c99-58cc-4b63-b420-a54b27752188

Closes https://github.com/twentyhq/core-team-issues/issues/562
2025-03-18 12:05:10 +01:00
981308861d i18n - translations (#10973)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 11:01:24 +01:00
0f85d5b94b fix: attachment scroll issue in preview modal (#10925)
Fixes #10919

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-03-18 10:47:11 +01:00
MarieandGitHub aa6fd90424 Create objectPermissions and settingsPermissions tables (#10962)
Closes https://github.com/twentyhq/core-team-issues/issues/594
2025-03-18 10:45:31 +01:00
ecf24eb518 i18n - translations (#10970)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-18 08:32:01 +01:00
Antoine MoreauxandGitHub 606098fef6 refacto(twenty-front): improve DropdownMenuHeader api (#10961) 2025-03-18 08:19:22 +01:00
03f4f73da4 i18n - translations (#10966)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 19:21:36 +01:00
WeikoandGitHub 38dabc9f84 [fix] Users with readOnly permissions should not be able to edit richtext fields (#10959)
Before
<img width="1024" alt="Screenshot 2025-03-17 at 17 46 34"
src="https://github.com/user-attachments/assets/c754adfb-4197-4be8-95dc-2f2024ed8a5c"
/>


After
<img width="954" alt="Screenshot 2025-03-17 at 17 46 20"
src="https://github.com/user-attachments/assets/e6063990-5d30-416f-9d16-2974d8d1d831"
/>
2025-03-17 19:03:43 +01:00
c9a48c0ba9 0.44 changelog (#10963)
Co-authored-by: Guillim <guillim@users.noreply.github.com>
2025-03-17 17:42:07 +00:00
79af21ef59 i18n - translations (#10957)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 17:21:20 +01:00
EtienneandGitHub 2be26ecc98 add temporary log to investigate on deletion logic (#10955)
related to
[611](https://github.com/twentyhq/core-team-issues/issues/611)
2025-03-17 17:13:01 +01:00
b4ec00088b i18n - translations (#10953)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 16:46:03 +01:00
Antoine MoreauxandGitHub bda835b9f8 feat(twenty-front/workspace-menu): improve workspace menu (#10642)
New workspace menu
2025-03-17 15:31:31 +00:00
78b3b7edab i18n - translations (#10951)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 16:20:44 +01:00
Antoine MoreauxandGitHub 8db8d9ad00 feat(twenty-front): improve dropdown menu header (#10672) 2025-03-17 16:10:52 +01:00
c4efb45f04 i18n - translations (#10950)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 16:01:03 +01:00
Baptiste DevessierandGitHub 093d6c0a1a Extract the JSON visualizer component in twenty-ui (#10937)
- Move the JsonTree component and the other components to twenty-ui
- Rely on a React Context to provide translations

## Future work

It would be good to migrate the `createRequiredContext` function to
`twenty-ui`. I didn't want to migrate it in this PR but would have liked
to use it.
2025-03-17 15:00:06 +00:00
Raphaël BosiandGitHub 428499e222 598 remove favorites actions from pinned actions on workflows and add see runs (#10946)
Closes https://github.com/twentyhq/core-team-issues/issues/598
- Add export single run action
- Add export single version action
2025-03-17 15:45:20 +01:00
a2ea831b9b i18n - translations (#10949)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 15:34:42 +01:00
Paul RastoinandGitHub 8b5d5b35ad Workspace seeders with version (#10895)
# Introduction
close https://github.com/twentyhq/core-team-issues/issues/487
Updated the seeders to infer the workspace's version from the
`APP_VERSION` env var

To test in local run: `npx nx database:reset twenty-server` with either
a defined or not defined `APP_VERSION` in your `.env`
( note that invalid semver values will throw an error and stop the
process ) ( valid version ex: `APP_VERSION=1.0.0`)
2025-03-17 15:32:49 +01:00
3e3e8de400 i18n - translations (#10948)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 15:20:27 +01:00
20080256dc i18n - translations (#10940)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 14:12:43 +01:00
nitinandGitHub d01023dfe7 update connected account health status descriptions (#10935)
<img width="694" alt="Screenshot 2025-03-17 at 15 36 03"
src="https://github.com/user-attachments/assets/de43d463-d4c1-421a-be1b-947f247ceb94"
/>
2025-03-17 13:01:55 +00:00
7ff2fccd5b i18n - translations (#10939)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 13:22:36 +01:00
b99e71c37a i18n - translations (#10938)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 13:11:21 +01:00
35119bceaa i18n - translations (#10936)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 11:35:34 +01:00
d51df80c13 fix: add icon for code block (#10924)
Fixes #10923

<img width="422" alt="Screenshot 2025-03-16 at 1 44 51 AM"
src="https://github.com/user-attachments/assets/e8b638ce-0082-486a-92c0-f362dcf25f98"
/>

Co-authored-by: Weiko <corentin@twenty.com>
2025-03-17 11:32:42 +01:00
martmullandGitHub 37599af882 Fix unknown labe (#10934)
## Before

![image](https://github.com/user-attachments/assets/20b5d5c7-907e-4293-a8db-034125e0f4b4)

## After

![image](https://github.com/user-attachments/assets/1df6d597-f06e-49e4-a9a4-ad980f42b07b)
2025-03-17 11:25:13 +01:00
e49ba69f19 i18n - translations (#10933)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-17 11:20:51 +01:00
nitinandGitHub bd7e7713e8 fix workflow view not visible (#10918)
fixes: #10913

1. Original issue:
```typescript
<StyledTabListContainer shouldDisplay={visibleTabs.length > 1}>
  <StyledTabList />
</StyledTabListContainer>
```

TabList wasn't getting full width.

2. First fix attempt ie #10904:
```typescript
{visibleTabs.length > 1 && (
  <StyledTabList />
)}
```
This broke workflow views because:
Workflows use single-tab layouts
The conditional rendering prevented the tab from showing at all when
visibleTabs.length <= 1


3. Current working solution:
```typescript
const StyledOuterContainer = styled.div`
  width: 100%;
`;

<StyledTabListContainer shouldDisplay={visibleTabs.length > 1}>
  <StyledOuterContainer>
    <StyledTabList />
  </StyledOuterContainer>
</StyledTabListContainer>
```
This works because:
Keeps the original display logic that supports single-tab workflows
Fixes the width issue with the new container
Maintains tab state management needed for workflow visualization
2025-03-17 10:27:23 +01:00
Félix MalfaitandGitHub d0c31d3f71 Fix missing translations for advanced mode toggle (#10931)
Advanced mode toggle was in `twenty-ui` which doesn't support Lingui.

I removed lingui from the global package json and moved it to the local
package.json instead to prevent that kind of error from happening again
2025-03-17 10:09:07 +01:00
Félix MalfaitandGitHub fb1e674781 Add ids to translations to make it easier to debug (#10930)
As per title
2025-03-17 09:15:54 +01:00
Paul RastoinandGitHub 23b4605987 [REFACTOR] Workspace version only x.y.z (#10910)
# Introduction
We want the APP_VERSION to be able to contains pre-release options, in a
nutshell to be semVer compatible.
But we want to have workspace, at least for the moment, that only store
`x.y.z` and not `vx.y.z` or `x.y.z-alpha` version in database

Explaining this refactor

Related https://github.com/twentyhq/twenty/pull/10907
2025-03-14 19:21:44 +01:00
1aeef2b68e i18n - translations (#10911)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-14 19:21:23 +01:00
Charles BochetandGitHub 3988eb7787 Fix missing fields in filter on index board (#10909)
Fixes https://github.com/twentyhq/twenty/issues/10046
2025-03-14 19:13:44 +01:00
Paul RastoinandGitHub d0e80a5ba2 [Fix] Class validator native isSemver does not handle v-prefix (#10907)
# Introduction
Under the hood class-validator isSemver uses
https://github.com/validatorjs/validator.js/blob/master/src/lib/isSemVer.js
which does not cover all semVer use cases

## Even tho
Had a discussion with @charles was about to store in db ws version as
`vx.y.z`. We felt like we wanted it to be stored as `x.y.z`, in my
opinion `APP_VERSION` should reflect the tag used to be build the
instance and not be updated
But we could extract only `x.y.z` from it at runtime

Also handling the `v` extraction in CD is IMO not the most reliable

## Env var logging refactor
Now not stopping on first error log
```ts
Successfully compiled: 2128 files with swc (185.34ms)
Watching for file changes.
[Nest] 52686  - 03/14/2025, 6:28:33 PM   ERROR PG_DATABASE_URL should not be null or undefined
PG_DATABASE_URL must be a URL address
[Nest] 52686  - 03/14/2025, 6:28:33 PM   ERROR APP_VERSION must be a valid semantic version (e.g., 1.0.0)

/Users/paulrastoin/ws/twenty/packages/twenty-server/src/engine/core-modules/environment/environment-variables.ts:1019
    throw new Error("Environment variables validation failed")
          ^
Error: Environment variables validation failed
    at Object.validate (/Users/paulrastoin/ws/twenty/packages/twenty-server/src/engine/core-modules/environment/environment-variables.ts:1019:11)
    at Function.forRoot (/Users/paulrastoin/ws/twenty/node_modules/@nestjs/config/dist/config.module.js:67:45)
    at Object.<anonymous> (/Users/paulrastoin/ws/twenty/packages/twenty-server/src/engine/core-modules/environment/environment.module.ts:11:18)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Function.Module._load (node:internal/modules/cjs/loader:960:12)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:121:18)
    at Object.<anonymous> (/Users/paulrastoin/ws/twenty/packages/twenty-server/dist/src/database/typeorm/typeorm.module.js:14:28)
```
2025-03-14 18:00:03 +00:00
WeikoandGitHub ef251f8129 Set attachment authorId nullable (#10908)
## Context
This should fix workspaceMember deletion when attachments exist.
Attachment should still be available even if its author leaves the
workspace. Currently the author is never displayed in the product.

<img width="936" alt="Screenshot 2025-03-14 at 18 46 49"
src="https://github.com/user-attachments/assets/30f85505-11d9-4190-9b9e-2f9a433e5da1"
/>
<img width="953" alt="Screenshot 2025-03-14 at 18 46 25"
src="https://github.com/user-attachments/assets/6a8da47d-70ed-420d-9e18-76f5d901a909"
/>
2025-03-14 18:49:31 +01:00
Rajvir SinghandGitHub 7595d42fef fix: added server preconnect url improving the page load time (#10554)
fixes #10236
2025-03-14 18:35:06 +01:00
Baptiste DevessierandGitHub 5b7b58c85f Remove dead code about workflow leaf nodes (#10901)
Leaf nodes is no longer a concept in the workflow diagrams. This PR
removes dead code.

Closes https://github.com/twentyhq/core-team-issues/issues/386
2025-03-14 18:33:19 +01:00
nitinandGitHub 1bc30e9b21 Side panel tablist fix (#10904)
followup #10832
whats wrong? -- in "before" screen grabs, the light bottom border
doesn't go all the way!

fix -- removed the redundant div :)

(╯°□°)╯︵ ┻━┻

before:
<img width="608" alt="Screenshot 2025-03-14 at 22 26 26"
src="https://github.com/user-attachments/assets/4fff92f7-5adc-4816-95dc-7b78ad08cd1c"
/>
<img width="605" alt="Screenshot 2025-03-14 at 22 26 20"
src="https://github.com/user-attachments/assets/e7a796a3-d5ff-4366-bd45-afbe3a219ee5"
/>
after:
<img width="610" alt="Screenshot 2025-03-14 at 22 24 33"
src="https://github.com/user-attachments/assets/c6f744b8-ec8b-4549-a1bb-db1a9fd1fafe"
/>
<img width="603" alt="Screenshot 2025-03-14 at 22 24 24"
src="https://github.com/user-attachments/assets/4758a591-3375-4387-a115-c74d534decb6"
/>
2025-03-14 18:32:46 +01:00
f44f42e9a0 Advanced toggle alignment (#10844)
This PR address advanced toggle alignment, especially the left yellow
dot placement.
In other advanced settings navigation drawer, the dot appears -20px to
left, while this was not the case for advanced toggle's dot.
Matched the height and paddings to that of NavigationDrawerItem.

@Bonapara FYI

before:
<img width="399" alt="Screenshot 2025-03-13 at 15 49 21"
src="https://github.com/user-attachments/assets/6dd60b3a-1b2e-43a0-ad28-dc44437460ab"
/>

after:
<img width="401" alt="Screenshot 2025-03-13 at 15 47 43"
src="https://github.com/user-attachments/assets/86e51b07-e84a-413a-8a49-1820c165dc68"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-14 18:28:14 +01:00
Charles BochetandGitHub c833b1c449 Fix webhook pages in Settings (#10902)
## Context

Some users were able to set an empty URL as webhook targetUrl, which was
breaking the Webhook List and Detail pages

## Fix
- Making sure to protect getHostNameOrThrow by isValidUrl
- rework webhook form to prevent creation of invalid webhooks

Fixes https://github.com/twentyhq/twenty/issues/10822
2025-03-14 18:26:28 +01:00
Thomas des FrancsandGitHub b47dcba313 added lab custom domain illustration (#10905) 2025-03-14 18:26:13 +01:00
Lucas BordeauandGitHub b0478a5683 Fix record filters, sorts and groups (#10899)
A recent change made
contextStoreCurrentObjectMetadataItemIdComponentState not initialized,
while it was being used for intializing currentRecordFilters,
currentRecordSorts and currentRecordFilterGroups states.

In this PR we use objectMetadataItem in RecordIndexContext to initialize
record filters, sorts and filter groups instead.
2025-03-14 17:27:36 +01:00
d34ec4da2d Fix kanban view picker total count (#10898)
Fixes https://github.com/twentyhq/twenty/issues/9790

Before


https://github.com/user-attachments/assets/332ec338-ce87-4d4d-ac47-a4e76dceb5b0



After


https://github.com/user-attachments/assets/93a03842-386a-4e75-a709-85a91bbc7679

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-14 17:27:25 +01:00
Paul RastoinandGitHub 3168958f8a Allow APP_VERSION to be empty string + dockerFile fix (#10900)
# Introduction
No choice but to allow APP_VERSION to be an empty string as it's though
to dynamically define dockerfile env vars
2025-03-14 16:25:36 +00:00
WeikoandGitHub 326acfe9a5 Fix activity target picker click outside not closing the menu (#10897)
## Context
onClickOutside was not implemented after the refactoring
2025-03-14 16:31:38 +01:00
Paul RastoinandGitHub 61f7625238 Compute any new Workspace version from APP_VERSION (#10893)
# Introduction
We want any new activated workspace to be filled with a version equal to
the current `APP_VERSION`
Please note that in a workspace lifecycle this operation will be run
only once, discussed with @charlesBochet in front of `3 fois plus de
piments`

Going straightforward in this PR in order to release asap
Started et will continue to implem new integrations regarding `SignUp`
and `ActivateWorkspace` happy and expections path in
https://github.com/twentyhq/twenty/tree/prastoin-new-workspace-has-version-integrations-tests
2025-03-14 15:18:48 +01:00
Félix MalfaitandGitHub c371dd5d27 Add custom domain to Lab and move countBoolean command to 0.44 from 0.50 (#10884)
- Add customs domain to Lab
- Moving back countBoolean command to 0.44 from 0.50 (I inadvertently
moved it yesterday night...)

<img width="592" alt="Screenshot 2025-03-14 at 12 07 44"
src="https://github.com/user-attachments/assets/1d8d7b36-f392-4df0-974d-426a55760af2"
/>
2025-03-14 15:13:44 +01:00
WeikoandGitHub 9883472d55 fix public feature flag update (#10887)
## Context
upsert from typeorm does not seem to return keys that are not updated,
I'm reverting back to find/save since upsert is not consistent
2025-03-14 15:01:06 +01:00
Charles BochetandGitHub fe4b47b781 Fix selected record id required after closing settings (#10894)
On Show page, let's only load the actionMenu if the objectMetadataItem
and the selectedRecord are present in the context store
2025-03-14 15:00:52 +01:00
Lucas BordeauandGitHub b12b2485c5 Fixed kanban for advanced filters and other bugs (#10888)
This PR mainly fixes advanced filters on kanban view.

It also fixes various bugs and cleans some old states.

## Advanced filters on kanban views

Kanban views use a different hook to retrieve data from the backend :
useLoadRecordIndexBoardColumn, this hook wasn't using the new state
currentRecordFilterGroupsComponentState.

## Removal of confusing duplicate states

A few different states were used for filters and states, where we only
need one for filters and one for sorts for all indexes. So we remove
here the different states that can lead to confusion about what state
should be used in what case.

States removed : 
- recordIndexFilterState
- recordIndexSortState
- recordIndexViewFilterGroupsState
- tableFiltersComponentState
- tableSortsComponentState

We also remove the logic that was used to manage those states.

## Abstracted non composite field type check into a util

We abstract the check made in mapFieldMetadataToGraphQLQuery into a util
isNonCompositeField, because those kinds of checks should be stored into
a separate unique file that acts as a source of truth.

## Bug with advanced filter rule position not saved

The position of an advanced filter rule wasn't correctly saved in the
backend, here we remove the WorkspaceIsSystem decorator on the
positionInViewFilterGroup fields.

The function that saved view filters was also ignoring the field
positionInViewFilterGroup, we add it back.

## Bug with view picker option dropdown closing weirdly

The view picker option dropdown was closing as soon as we hovered
outside of the option dropdown, which was annoying for the user, here we
apply the same behavior as every dropdown in the app : closing on click
outside.
2025-03-14 14:41:30 +01:00
Charles BochetandGitHub 2b89273241 Fix API playground not loading (#10891)
The @scalar package we use to offer a REST api playground is quite heavy
(3k files compared to the 15k existing) and is not pre-build in the npm
package, which is not unusual.

This is increasing the memory need during vite build. 
I'm increasing the RAM available for vite build.

Long term I recommend using a CDN here as this is not really a React
component so we won't benefit from any reactivity anyway. Exaclty like
we have done for FrontApp support chat integration
<img width="1058" alt="image"
src="https://github.com/user-attachments/assets/5412c6c1-7434-4b19-b9ac-e89f1cb614f3"
/>
2025-03-14 14:38:46 +01:00
d899e65f76 i18n - translations (#10890)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-14 13:56:08 +01:00
WeikoandGitHub 685808c69d Fix activity target creation (#10885)
## Context
Delete was using the wrong id
Create was not setting the morph id
2025-03-14 12:45:34 +00:00
martmullandGitHub d951a5a099 Fix Each child in a list should have a unique key prop. (#10881)
As title
2025-03-14 12:00:03 +01:00
44a11353b4 i18n - translations (#10882)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-14 11:20:37 +01:00
WeikoandGitHub 46c773e5ff Fix update of aggregate operation not reflected in kanban header without refresh (#10879)
Before


https://github.com/user-attachments/assets/1761c49e-3d08-413a-bebd-11f4592a7de8

After


https://github.com/user-attachments/assets/064ef28f-b131-48af-ad66-11f782298670
2025-03-14 11:13:13 +01:00
Paul RastoinandGitHub 362bc333d1 [ENH] APP_VERSIONdocumentation (#10880)
# Introduction
In https://github.com/twentyhq/twenty/pull/10751 we decided not to put
`APP_VERSION` references in `.env.example` as it's programmatically
defined by our CD and should not be override by any manual interaction.

Still, as a dev testing the upgrade command in local, if you do not set
the `APP_VERSION` in local you will encounter the following error:
```ts
'Cannot run upgrade command when APP_VERSION is not defined'
```

@guillim currently doing the release legitimately raised that it was not
very intuitive

## Levers
- Improve error message such as adding reference to checking env
variables
- App local upgrade command dev dedicated documentation ?

## Conclusion
Any suggestions are more than welcomed !
2025-03-14 10:00:32 +00:00
6cf1775fac i18n - translations (#10878)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-14 09:35:03 +01:00
2edf510de2 i18n - translations (#10877)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-14 09:21:17 +01:00
842a68a0aa i18n - translations (#10876)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-14 08:01:27 +01:00
bc4c79bc1c i18n - translations (#10875)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-14 07:47:47 +01:00
1bffe57f6b feat: added countTrue and countFalse (#10741)
fix: #10603 


https://www.loom.com/share/cebc8a19bd8e4ae684a5a215d0fd1f94?sid=cadaa395-285c-45c9-b3ce-2ae6d1330a3c

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-03-14 07:34:21 +01:00
7f8ab6dda5 i18n - translations (#10871)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-13 21:32:55 +01:00
445f1dd352 i18n - translations (#10870)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-13 21:20:47 +01:00
2362fd7f92 i18n - translations (#10867)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-13 19:36:57 +01:00
963c2f8d4a i18n - translations (#10866)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-13 19:21:36 +01:00
Charles BochetandGitHub 3901ff3207 Fix Side Panel v2 bugs (#10865)
Fixing:
- Export as PDF on empty note
- Command O (sub commands) not using the right contextStore
- BelongsToOne Field input triggering an error on open if no existing
relation record is pre-selected
2025-03-13 19:18:34 +01:00
Thomas TrompetteandGitHub cb96f019d6 Set record groups when view groups are updated (#10863)
Currently we need to refresh to see view group updates.
2025-03-13 19:17:48 +01:00
Paul RastoinandGitHub dfb00f2b61 [FIX] Omition on previous integ of upgrade command compare version based on integer result (#10864) 2025-03-13 18:12:05 +00:00
Baptiste DevessierandGitHub ce42928143 Fix keystatic github redirect_uri by relying on x-forwarded-* headers (#10862)
Fix suggested by
https://github.com/Thinkmill/keystatic/issues/1022#issuecomment-2009029315.
2025-03-13 18:18:48 +01:00
GuillimandGitHub db48aa532c bugfix for kunai: email missing in thread (#10861) 2025-03-13 18:14:34 +01:00
fc30ba57f8 Fix server integration tests 2 (#10818)
## Context
- Removing search* integration tests instead of fixing them because they
will be replaced by global search very soon
- Fixed billing + add missing seeds to make them work
- Fixed integration tests not using consistently the correct "test" db
- Fixed ci not running the with-db-reset configuration due to nx
configuration being used twice for different level of the command
- Enriched .env.test
- Fixed parts where exceptions were not thrown properly and not caught
by exception handler to convert to 400 when needed
- Refactored feature flag service that had 2 different implementations
in lab and admin panel + added tests
- Fixed race condition when migrations are created at the same timestamp
and doing the same type of operation, in this case object deletion could
break because table could be deleted earlier than its relations
- Fixed many integration tests that were not up to date since the CI has
been broken for a while

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-03-13 17:48:29 +01:00
Thomas TrompetteandGitHub d48b2b3264 Only store current object metadata id in state (#10856)
Fix group by refresh when adding a select field
2025-03-13 17:26:07 +01:00
Baptiste DevessierandGitHub 29ead8ab69 Create a running variant for workflow diagram nodes (#10857)
- Add all the missing adaptive colors
- Create a running variant for the workflow diagram nodes
- Make the `<Loader />` be precisely `24px` large

## Demo



https://github.com/user-attachments/assets/cc9ef259-30dd-445d-b167-af35b4f9c4cc



Closes https://github.com/twentyhq/core-team-issues/issues/430
2025-03-13 16:50:55 +01:00
martmullandGitHub b1322beac3 Fix console errors (#10859)
Fixes https://github.com/twentyhq/core-team-issues/issues/276

## Before

![image](https://github.com/user-attachments/assets/d1b49746-eb9b-4f96-81af-81332ebb2e43)

![image](https://github.com/user-attachments/assets/41ceccfc-6ee3-4ff5-9d02-c621244bf36b)


## After

![image](https://github.com/user-attachments/assets/67eea9c9-d838-4211-9e75-47d895d2662e)
2025-03-13 16:50:35 +01:00
Charles Bochet 4f0fd0c9f3 Fix stories again 2025-03-13 16:50:24 +01:00
Paul RastoinandGitHub 37afb38479 refactor(server): upgrade command to more human friendly (#10858)
# Introduction
Refactored the upgrade command to be more intuitive to anyone wanting to
add a command to the next relase upgrade instance

Also updated the upgrade command for the next 0.44 release
2025-03-13 16:48:58 +01:00
Baptiste DevessierandGitHub 93f70f8457 Fix e2e tests (#10855) 2025-03-13 16:42:38 +01:00
Paul RastoinandGitHub bd5d211590 [FEAT] New APP_VERSION env var inferred from tag & refactor upgrade-command to integrate versioning (#10751)
# Introduction
This PR contains a big test file and few snapshots
Related to https://github.com/twentyhq/core-team-issues/issues/487

## New env var `APP_VERSION`
Now will be injected directly in a built docker image the twenty's built
version. Inferred from the build git tag name.
Which mean on main or other `not a tag version` built APP_VERSION will
be `null`

## New upgrade-commander-runner
Refactored the upgrade command to be more strict regarding:
 - Version management
 - Sync metadata command always run
 - Added failing workspaces aggregator + logs on cleanup
 
From now on the `upgrade` command will compare the `WORKSPACE_VERSION`
to the `APP_VERSION` in order to bypass any workspace version != than
the upgrade version `fromVersion`
## Existing commands
Note that the version validation will be done only when passing by the
`upgrade` command.
Which means that running the following command
`upgrade:x.y-some-specific-command` won't result in workspace version
mutation

This is to enforce that all an upgrade commands + sync-metadata has been
run on a workspace



## Will do in other PR but related
### New workspace
New workspace will now be inserted with version equal to the APP_VERSION
they've been created by

### Old workspace
Will create a command that should be ran outside of any `upgrade-runner`
extending command, the command will have to be ran on every workspace
before making the next release upgrade
This command iterates over any active and suspended workspace that has
`version` to `NULL` in order to update it `APP_VERSION` -1 minor

### SENTRY_RELEASE
- Either deprecate SENTRY_RELEASE in favor of `APP_VERSION` => What
about main with null version ? or create a new env var that would be
`APP_COMMIT_SHA` instead of SENTRY third party ref

### Update CD to inject APP_VERSION from branch name

### Update docs and release logs
Adding documentation for `APP_VERSION`

## Related PRs:
https://github.com/twentyhq/twenty-infra/pull/181
2025-03-13 15:46:27 +01:00
Charles Bochet 15019d2c66 Fix stories 2025-03-13 15:35:46 +01:00
EtienneandGitHub 3ab73dd777 format duplicate field name error (#10736)
fix temporarily https://github.com/twentyhq/core-team-issues/issues/180
2025-03-13 15:20:57 +01:00
Lucas BordeauandGitHub 8b49c803ec Fixed minor bugs on advanced filters (#10847)
This PR fixes minor bugs on advanced filters : 
- We couldn't close the advanced filter dropdown after removing a rule,
because the rule options dropdown wasn't closed, so focus dropdown id
was in a corrupted state.
- The text filter input in filter dropdown and the search input were the
same component, which was causing conflicts with state management but
this conflict didn't happen with the simple filter dropdown
implementation, the advanced filter dropdown brought this bug to light.
- The chevron down icon disappeared from the filter update button group,
this PR fixes it.

Fixes https://github.com/twentyhq/core-team-issues/issues/557
Fixes https://github.com/twentyhq/core-team-issues/issues/558
2025-03-13 15:20:23 +01:00
Charles BochetandGitHub a2004e6220 Fix storybook stories (#10853)
Small PR to fix flaky stories
2025-03-13 15:19:20 +01:00
794110f9dd Fix wrong font in chips and tabs (#10825)
Fix wrong font in chips and tabs

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-03-13 14:44:04 +01:00
Charles BochetandGitHub 885b2d62d9 Fix stories (#10851)
Fix storybook stories
<img width="1475" alt="image"
src="https://github.com/user-attachments/assets/50327d9b-f3a0-46ea-87f2-93da356ec7c9"
/>
2025-03-13 14:31:20 +01:00
Félix MalfaitandGitHub 2ca0dc243a Fix incorrect error message (#10850)
Fix #10833
2025-03-13 14:12:33 +01:00
Félix MalfaitandGitHub da4eb1e7d2 Fix UI bug in REST API playground (#10848)
When you clicked on the left-side menu to navigate, the top bar would
disappear. This PR fixes that and the top bar always remain visible.
2025-03-13 13:15:03 +01:00
martmullandGitHub 3f7315c2dc Fix test data disapear (#10846)
As title. Init input from source code only once.
2025-03-13 12:08:29 +01:00
WeikoandGitHub f66ae3eff6 Add permissions v1 to lab (#10845)
## Context
Not sure why the image should be self hosted on twenty-website, I've
simply followed what we did with other items of the lab
2025-03-13 12:03:01 +01:00
WeikoandGitHub 5b34f86b6d Add Icon to roles (#10842)
## Context
Adding icon column to role table to distinguish roles.

<img width="621" alt="Screenshot 2025-03-13 at 11 02 37"
src="https://github.com/user-attachments/assets/dc7b121c-2901-4599-9638-d5dcdf443999"
/>
2025-03-13 11:34:30 +01:00
46a57c2167 i18n - translations (#10843)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-13 11:20:38 +01:00
Baptiste DevessierandGitHub ecf282ad99 Highlight consumed variables in workflow runs (#10788)
- Create a function to resolve the variables used in the configuration
of a step
- Let the JSON tree components take a prop (`getNodeHighlighting`) to
determine whether an element must be highlighted
- Compute each element's keyPath recursively; the keyPath is passed as
an argument to the `getNodeHighlighting` function

## Demo


https://github.com/user-attachments/assets/8586f43d-53d1-41ba-ab48-08bb8c74e145

Closes https://github.com/twentyhq/core-team-issues/issues/435
2025-03-13 11:19:12 +01:00
martmullandGitHub 7e291f3cff Fix close right drawer error (#10841)
fixes
https://discord.com/channels/1130383047699738754/1349485390871924796
2025-03-13 10:02:59 +00:00
martmullandGitHub 638fbe2014 Fix flash when creating draft (#10814)
Always set `serverlessWorkflowVersion = 'draft'` in code steps
2025-03-13 10:16:47 +01:00
ebf56b1b19 i18n - translations (#10840)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-13 09:48:10 +01:00
nitinandGitHub 2be2b36e01 Tablist regression fix (#10832)
## Issue
https://discord.com/channels/1130383047699738754/1349428521075871846
@Devessier found a regression where the TabList was getting too tall in
some places. This happened because:
1. The ScrollWrapper inside TabList has `height: 100%` by default
2. The parent container in ShowPageSubContainer uses `display: flex`
when tabs should be shown
3. This combination makes the ScrollWrapper expand to fill the available
space

## Fix
Added a wrapper `<div>` around the ScrollWrapper in the TabList
component. This works because:
1. It creates a new flex container that contains the ScrollWrapper's
expansion
2. It preserves the flex context needed by ShowPageSubContainer for
proper layout
3. It maintains all visual styles including the tab borders

## Technical Details
While using `heightMode="fit-content"` on ScrollWrapper might seem like
a fix, it breaks the interaction between TabList and its parent
containers that use flex layout for positioning.

before: 

<img width="537" alt="Screenshot 2025-03-13 at 02 16 03"
src="https://github.com/user-attachments/assets/9d4ddc81-68e8-44fe-8d32-da1d8e52492c"
/>

after:

<img width="518" alt="Screenshot 2025-03-13 at 02 11 50"
src="https://github.com/user-attachments/assets/dc8866c9-7dc3-4b59-8c18-d08233fc2143"
/>
2025-03-13 08:44:09 +00:00
6ba4ffe4c4 i18n - translations (#10839)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-13 08:31:02 +01:00
nitinandGitHub c0ca09492c Replace connected account table with table card (#10838)
before: 
<img width="624" alt="Screenshot 2025-03-13 at 12 45 03"
src="https://github.com/user-attachments/assets/be09194a-66bb-4e39-afc1-9dd11c89dcef"
/>
after:
<img width="619" alt="Screenshot 2025-03-13 at 12 44 39"
src="https://github.com/user-attachments/assets/759f87c3-995c-4be4-8523-42f5e805ca83"
/>
2025-03-13 13:00:44 +05:30
8cb5d4aa68 i18n - translations (#10837)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-13 08:20:16 +01:00
Raphaël BosiandGitHub 9f9302136f Fix command O delete action on record page (#10820)
There were two issues, the hotkey scope wasn't set properly when opening
the dropdown with the shortcut and we didn't close the command menu upon
completion of the delete action.

Before:


https://github.com/user-attachments/assets/817442ae-6db4-4fc5-a637-4e2e3d9b9b70


After:


https://github.com/user-attachments/assets/b6fd07f6-6c2f-4b29-9162-f29b661ad358
2025-03-13 08:09:49 +01:00
737e17193a i18n - translations (#10835)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 23:33:37 +01:00
8e9a73462b i18n - translations (#10834)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 23:20:10 +01:00
7468f25b80 i18n - translations (#10831)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 21:33:13 +01:00
8f38501aad i18n - translations (#10830)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 21:20:55 +01:00
10bc939634 i18n - translations (#10829)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 21:01:21 +01:00
nitinandGitHub c61748cd6e Admin panel fixes (#10792)
<img width="573" alt="Screenshot 2025-03-12 at 17 36 44"
src="https://github.com/user-attachments/assets/be6c20b0-626d-4a2c-810c-78a49e9f65ee"
/>
<img width="579" alt="Screenshot 2025-03-12 at 17 37 03"
src="https://github.com/user-attachments/assets/23692ff8-ac88-4104-823e-1a06b3074551"
/>
<img width="590" alt="Screenshot 2025-03-12 at 17 37 14"
src="https://github.com/user-attachments/assets/b46de1d3-a312-44cc-a54d-72208224453d"
/>
<img width="556" alt="Screenshot 2025-03-12 at 17 37 37"
src="https://github.com/user-attachments/assets/12176d49-d76d-4fb1-abe6-1f7dc5349d94"
/>
<img width="607" alt="Screenshot 2025-03-12 at 17 37 50"
src="https://github.com/user-attachments/assets/00e2edff-09db-45c5-a4df-6fd9ead830b6"
/>
2025-03-13 01:25:38 +05:30
75da64876a i18n - translations (#10828)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 19:37:22 +01:00
795930f4f8 i18n - translations (#10827)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 19:21:36 +01:00
3f7d9ccdef i18n - translations (#10823)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 18:20:13 +01:00
Thomas TrompetteandGitHub f4a362b53a Add base form action without logic (#10811)
<img width="1298" alt="Capture d’écran 2025-03-12 à 15 32 27"
src="https://github.com/user-attachments/assets/8a3140e5-e165-445e-a718-748aa76b525c"
/>
2025-03-12 17:05:31 +00:00
a4ef820f13 i18n - translations (#10821)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 18:01:13 +01:00
GuillimandGitHub 7a4f082fc5 renaming layout and changing icons (#10781)
Updating icons and renaming View Settings to Layout

Fixes : https://github.com/twentyhq/core-team-issues/issues/486
Fixes : https://github.com/twentyhq/core-team-issues/issues/484
Fixes : https://github.com/twentyhq/core-team-issues/issues/488
2025-03-12 17:49:28 +01:00
Raphaël BosiandGitHub 3eb1aa1b5a Fix alignment and background icon color on record page header (#10817)
Before:
<img width="501" alt="Capture d’écran 2025-03-12 à 17 23 58"
src="https://github.com/user-attachments/assets/b9f58bc1-61e5-4a6b-905d-76eeb63f88be"
/>

After:
<img width="499" alt="Capture d’écran 2025-03-12 à 17 22 12"
src="https://github.com/user-attachments/assets/30c95603-77e9-4647-b233-8c0ea2a27df8"
/>
2025-03-12 17:46:07 +01:00
89faccad4f i18n - translations (#10816)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 17:36:55 +01:00
69f6796021 i18n - translations (#10813)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 17:21:20 +01:00
a818e76d61 i18n - translations (#10812)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 16:34:04 +01:00
Raphaël BosiandGitHub daa501549e 271 remove is command menu v2 enabled (#10809)
Closes https://github.com/twentyhq/core-team-issues/issues/271

This PR
- Removes the feature flag IS_COMMAND_MENU_V2_ENABLED
- Removes all old Right drawer components
- Removes the Action menu bar
- Removes unused Copilot page
2025-03-12 16:26:29 +01:00
martmullandGitHub 1b0413bf8b Add days schedule trigger (#10800)
<img width="1470" alt="image"
src="https://github.com/user-attachments/assets/660d79ba-60c7-4874-aa82-80a7575366ba"
/>
2025-03-12 15:25:07 +00:00
Raphaël BosiandGitHub bfc542290b 545 replace objects icons and names with records avatars and labelidentifiers in command menu context chips (#10787)
Closes https://github.com/twentyhq/core-team-issues/issues/545

This PR:
- Introduces `commandMenuNavigationMorphItemsState` which stores the
information about the `recordId` and the `objectMetadataItemId` for each
page
- Creates `CommandMenuContextChipEffect`, which queries the records from
the previous pages in case a record has been updated during the
navigation, to keep up to date information and stores it inside
`commandMenuNavigationRecordsState`
- `useCommandMenuContextChips` returns the context chips information
- Style updates (icons background and color)
- Updates `useCommandMenu` to set and reset these new states


https://github.com/user-attachments/assets/8886848a-721d-4709-9330-8e84ebc0d51e
2025-03-12 15:26:14 +01:00
e030fc8917 i18n - translations (#10808)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 15:20:40 +01:00
Thomas TrompetteandGitHub 0d7484389e Stop using labelIdentifier when adding record card (#10805)
When creating an object from kanban, we are using
`labelIdentifier.toLowerCase()` for the labelIdentifier field.
Issue is that labelIdentifier is translated.

Using `labelIdentifierField.name` instead.
2025-03-12 15:07:35 +01:00
nitinandGitHub 5ddc34b182 Tablist bottom margin fix (#10801)
### Bug
The active tab bottom border appeared slightly above the TabList's light
bottom border.

### Investigation
- Initial fix: Adjusted margin-bottom to -1px in Tab component to align
borders
- This fix caused active bottom borders to disappear in tabs wrapped
with ShowPageSubContainerTabListContainer
- Found that ShowPageSubContainerTabListContainer was adding a redundant
bottom border that overlapped with TabList's border

### Solution
- Removed ShowPageSubContainerTabListContainer to eliminate the
redundant border
- Kept the -1px margin-bottom fix in Tab component
- This ensures consistent border behavior across all TabList
implementations
2025-03-12 14:45:50 +01:00
nitinandGitHub 6102277de6 Settings counter alignment fix (#10802)
https://discord.com/channels/1130383047699738754/1349342363490844692
2025-03-12 13:09:54 +00:00
b12aa90d89 i18n - translations (#10804)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 14:02:23 +01:00
Baptiste DevessierandGitHub d3b6e2e621 Add Keystatic for twenty-website build (#10798)
The Keystatic's environment variables must be defined during the build.
@prastoin and I identified that the other environment variables aren't
defined during the build. We decided to add fake environment variables
directly in the Dockerfile to make the build pass. Later, the docker
image should be executed with the real environment variables that'll
make Keystatic work properly.
2025-03-12 13:50:59 +01:00
96931fa74c i18n - translations (#10797)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 11:35:02 +01:00
Lucas BordeauandGitHub 911647a279 Fix many bugs on advanced filters for CRUD to work (#10772)
This PR fixes many bugs on advanced filters, the goal here was to have
CRUD working with other simple filters and sorts.

In order to test this PR you'll have to run a sync metadata.

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

## Changed positionInViewFilterGroup field metadata type 

This PR changes the type of positionInViewFilterGroup to NUMERIC instead
of POSITION, there certainly was a confusion during the initial
development, where POSITION type seemed relevant but it is not for this
particular feature because the position in a view filter group is not
the position of a record, which is used for displaying and re-ordering
purpose in table and kanban views.

Here the positionInViewFilterGroup is a specific position concept tied
to a custom feature, and it is handled by the specific logic of this
advanced filter dropdown layout.

## Create new ids when duplicating a view

When we use create view from an existing view, the logic in
useCreateViewFromCurrentView will copy over filters, filter groups and
sorts. The problem is that it copies it with the same ids, and that if
the backend manages somehow to create new ids, the ids that are put in
parentViewFilterGroupId are corresponding to the old filter groups not
the duplicated new ones.

So we had to create a map of old id => new id so that everything that
has to be sent to the backend for creation already has the same mapping
of parent id but with new ids generated by the frontend.

## Bug with creating a simple filter

We couldn't create a simple filter when advanced filters were set, this
was because of findDuplicateRecordFilterInNonAdvancedRecordFilters which
wasn't doing what it's naming tells, it wasn't filtering on simple
filters only before looking for duplicates.

## Clean code

- Use lastChildPosition directly from
useChildRecordFiltersAndRecordFilterGroups instead of drilling it down
- Refactored AdvancedFilterDropdownButton to extract the code lower
where it is really needed in AdvancedFilterChip
- Renamed a few View to Record naming where relevant
2025-03-12 10:23:41 +00:00
martmullandGitHub 8d1a4672de Add console logs to code step (#10796)
code review return -> move console interceptor to dedicated utils
2025-03-12 10:59:41 +01:00
1940fd5850 i18n - translations (#10795)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-12 10:45:46 +01:00
martmullandGitHub 4036933c84 Add console logs to code step (#10786)
Works for local and lambda drivers

## After

![image](https://github.com/user-attachments/assets/ec082cf6-4159-4a15-99b6-243c73a13773)

![image](https://github.com/user-attachments/assets/f42e3f43-5ea4-4167-b4b5-9a17826fd224)
2025-03-12 10:40:59 +01:00
WeikoandGitHub 4d0450069c Fix fieldMetadata sync validation exceptions caught in exception handler (#10789)
## Context
Field metadata service was reusing validators from
validate-**OBJECT**-metadata-input which were throwing ObjectMetadata
exceptions not handled in fieldMetadataGraphqlApiExceptionHandler and
were going to Sentry.
To solve the issue since this validator is associated with both fields
and objects I'm moving the util to the root utils folder of metadata
module and throwing a common metadata user input exception
2025-03-11 18:41:29 +01:00
Baptiste DevessierandGitHub 9880114853 Fix twenty-website CI (#10790) 2025-03-11 18:39:20 +01:00
Baptiste DevessierandGitHub d4c2fa9f66 Fix Keystatic configuration (#10783)
- Always use the `github` mode
- Set a `pathPrefix` as the repository is a monorepo
2025-03-11 18:17:20 +01:00
Charles BochetandGitHub d9817d6b9c Fix tabler icons load (#10782)
As per
https://github.com/tabler/tabler-icons/issues/1233#issuecomment-2428245119
2025-03-11 18:01:28 +01:00
Thomas TrompetteandGitHub ddeba39a2c Reset step output schema when step is removed (#10762)
When a step is deleted in a draft version, its variable are still
available in the following steps. This is because step output schema was
not reset. We needed either to refresh or to change version so output
schema gets updated.

This PR:
- migrates to a family state global + context not linked to a component
- add a reset step output schema function
- reset when a step is removed
2025-03-11 16:38:47 +00:00
680935e605 i18n - translations (#10785)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-11 17:21:25 +01:00
5bbfbf68eb i18n - translations (#10784)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-11 17:06:05 +01:00
WeikoandGitHub 293e3f58c4 Fix TEST env not using the correct DB for datasources (#10780)
## Context
Config was programmatically loaded in our datasources however the
default behavior of dotenv is to ignore vars if they are already
defined. This means we need to be careful about the order of env
injection and sometimes it's done at a higher level (for example
db:reset will depend on build). To make things easier I'm using the
override flag to properly override the PG_DATABASE_URL if different (and
to properly work with the 'test' DB instead of 'default' during
testing).
2025-03-11 16:20:01 +01:00
0516e95330 i18n - translations (#10779)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-11 15:34:53 +01:00
8b523aec92 i18n - translations (#10778)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-11 15:20:37 +01:00
GuillimandGitHub 4e44ae59f7 Delete view & copy link (#10760)
adding the delete view and copy link additional menu option

Fixes https://github.com/twentyhq/core-team-issues/issues/480
Fixes https://github.com/twentyhq/core-team-issues/issues/481
2025-03-11 15:15:00 +01:00
3b40b2d50c i18n - translations (#10775)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-11 13:57:39 +01:00
martmullandGitHub 0eb829dcb5 Remove system email address from cleaning emails (#10774)
as title, to avoid polluting the technical email address
2025-03-11 13:44:33 +01:00
Charles BochetandGitHub 48bd48753b Improve twenty-front build performance (vite rollup option) (#10771)
In this PR, I'm specifying to vite build that
'@scalar/api-reference-react' is an external dependency and should not
be considered as a module we maintain (it won't get its own chunk at
build time and we won't generate sourcemaps on our end).

I'm not sure why vite is considering it internal in the first place (I
can see that it's generating .vue.js files, might be the first time we
are relying on a vue library)
2025-03-11 12:39:54 +01:00
c39843dfd4 i18n - translations (#10770)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-11 12:19:41 +01:00
Paul RastoinandGitHub 41f3a63962 [BUGFIX] ObjectMetadata item server validation (#10699)
# Introduction
This PR contains several SNAPSHOT files explaining big +

While refactoring the Object Model settings page in
https://github.com/twentyhq/twenty/pull/10653, encountered a critical
issue when submitting either one or both names with `""` empty string
hard corrupting a workspace.

This motivate this PR reviewing server side validation

I feel like we could share zod schema between front and back

## Refactored server validation
What to expect from Names:
- Plural and singular have to be different ( case insensitive and
trimmed check )
- Contains only a-z A-Z and 0-9
- Follows camelCase
- Is not empty => Is not too short ( 1 )
- Is not too long ( 63 )
- Is case insensitive( fooBar and fOoBar now rejected )

What to expect from Labels:
- Plural and singular have to be different ( case insensitive and
trimmed check )
- Is not empty => Is not too short ( 1 )
- Is not too long ( 63 )
- Is case insensitive ( fooBar and fOoBar now rejected )

close https://github.com/twentyhq/twenty/issues/10694

## Creation integrations tests
Created new integrations tests, following
[EachTesting](https://jestjs.io/docs/api#testeachtablename-fn-timeout)
pattern and uses snapshot to assert errors message. These tests cover
several failing use cases and started to implement ones for the happy
path but object metadata item deletion is currently broken unless I'm
mistaken @Weiko is on it

## Notes
- [ ] As we've added new validation rules towards names and labels we
should scan db in order to standardize existing values using either a
migration command or manual check
- [ ] Will review in an other PR the update path, adding integrations
tests and so on
2025-03-11 12:14:37 +01:00
de22872c6e i18n - translations (#10766)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-10 21:20:47 +01:00
Félix MalfaitandGitHub e5a7aab733 Fix incorrect Scalar CSS import (#10763)
CSS was loaded in a global context (full screen which might be re-used
for other use cases in the future) instead of a local context.

\+ small update on .env.example
2025-03-10 21:10:40 +01:00
dc66d2498e i18n - translations (#10765)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-10 19:36:18 +01:00
d3e6879ee3 i18n - translations (#10764)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-10 19:21:42 +01:00
0861384351 i18n - translations (#10761)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-10 19:01:21 +01:00
WeikoandGitHub 5fb613a8f7 Fix permissions front followup (#10758) 2025-03-10 18:56:23 +01:00
Thomas TrompetteandGitHub c8b44aa242 Update design for not found variables (#10756)
<img width="494" alt="Capture d’écran 2025-03-10 à 14 09 37"
src="https://github.com/user-attachments/assets/ea4a55a1-c7f0-4138-a494-592b197ec8a2"
/>
2025-03-10 17:42:38 +00:00
252d95c741 i18n - translations (#10759)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-10 17:48:15 +01:00
d8197920dc Fixed hotkeys on advanced filters (#10733)
This PR fixes hotkey escape on advanced filter dropdown, which wasn't
working.

It adds a parameters to openDropdown, because in this particular case,
the dropdown is not opened from its clickable component but from an
openDropdown, in that case it wasn't possible for openDropdown to know
which hotkey scope to take, because the hotkey scope is generally passed
in the Dropdown component props.

We might want to find a more robust solution, where a dropdown knows its
hotkey scope without having to be mounted.

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-03-10 16:41:53 +00:00
martmullandGitHub f79165ff28 450 merge first second tab on side panel (#10757)
Closes https://github.com/twentyhq/core-team-issues/issues/450

## Before


https://github.com/user-attachments/assets/9b3b8fe7-0cf6-49b7-9f1b-d263b8f65dde



## After


https://github.com/user-attachments/assets/b8e48cae-0661-4fc2-912b-bf091d94bde6
2025-03-10 17:40:27 +01:00
Baptiste DevessierandGitHub dd26001372 Handle JSON viewer empty states (#10750)
- Display the number of descendants for object and array elements
- Display an empty state for arrays and objects
- Make the input and output visualizer scrollable horizontally 
  - Prevent JSON visualizer's text to wrap

## Demo: input


https://github.com/user-attachments/assets/d6bd6acf-a779-4fc7-a8b1-12b857cee7f9

Closes https://github.com/twentyhq/core-team-issues/issues/497
2025-03-10 17:39:49 +01:00
Thomas TrompetteandGitHub dc55fac1d5 Wrap all vizualizers into component context (#10755)
Steps are broken when a variable is set.
This is because component instance is not set for version and run
visualizers.
Each step viewer should be wrapped by the instance context.
Each diagram visualizer should be responsible for populating the output
schema.

Also fixing a billing error when running workflow.
2025-03-10 15:56:14 +01:00
GuillimandGitHub 3b79018609 fix 10604 them color (#10749)
fixes https://github.com/twentyhq/twenty/issues/10604
2025-03-10 14:36:47 +00:00
21ecfcaa72 i18n - translations (#10754)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-10 15:20:23 +01:00
Charles BochetandGitHub f0de6d31b7 Refactor MultipleObjectsPicker component (#10552)
Refactor to only have MultipleRecordPicker and SingleRecordPicker

What's done:
- SingleRecordPicker, MultipleRecordPicker
- RelationToOneInput
- RelationFromManyInput
- usage in TableCell, InlineCell, RelationDetailSection, Workflow

What's left:
- Make a pass on the app, to make sure the hotkeyScopes, clickOutside
are properly set
- Fix flashing on ActivityTarget
- add more tests on the code
2025-03-10 15:04:09 +01:00
7eabcc8774 i18n - translations (#10753)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-10 14:36:03 +01:00
77574594f2 admin panel fast follows (#10723)
fast follows:
- https://discord.com/channels/1130383047699738754/1346433965451382845
- https://discord.com/channels/1130383047699738754/1346434512757981264
- https://discord.com/channels/1130383047699738754/1346453484911853610

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-03-10 19:02:40 +05:30
a1e0d7b7d7 Fix file preview text color in dark mode (#10748)
This PR fixes an issue where the file preview text was unreadable due to
white text on a white background in dark mode.

Dark mode ->

![image](https://github.com/user-attachments/assets/1f8f6fd0-b95b-4b78-ae8c-db51acfefac2)

Light mode ->

![image](https://github.com/user-attachments/assets/82996a31-e000-4f04-b8db-bd35838732ec)

Fixes #10743

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-03-10 13:54:01 +01:00
Thomas TrompetteandGitHub c981ae329e Add variable path (#10720)
<img width="537" alt="Capture d’écran 2025-03-07 à 09 44 21"
src="https://github.com/user-attachments/assets/52c4d292-01af-4389-aa66-551be2358dd7"
/>

- search through step output schema the variable
- build the variable path
- returns the variable label 
- display both
2025-03-10 13:44:58 +01:00
c067044e01 i18n - translations (#10752)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-10 13:42:46 +01:00
f8772d205d Allow for unsecure SMTP settings for local unencrypted smtp relays (#10605)
This update provides the flexibility for users to configure SMTP for
local instances where encryption is not required. For environments using
an unencrypted SMTP relay or similar local instances that are not open
to the public, the end user can now choose to disable encryption. This
ensures flexibility in the configuration while still maintaining the
option for secure SMTP connections in other environments.

### From [NodeMailer](https://nodemailer.com/smtp/#tls-options)
**secure** – if true the connection will use TLS when connecting to
server. <mark>If false (the default) then TLS is used if server supports
the STARTTLS extension. In most cases set this value to true if you are
connecting to port 465. For port 587 or 25 keep it false.</mark>

**ignoreTLS** – <mark>if this is true and secure is false then TLS is
not used even if the server supports STARTTLS extension.</mark>

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-03-10 13:30:38 +01:00
a443703a38 i18n - translations (#10740)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 19:36:08 +01:00
7e22d76cf4 i18n - translations (#10739)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 19:21:34 +01:00
9c26ce5dc7 i18n - translations (#10737)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 18:32:17 +01:00
GuillimandGitHub 5056d3e53f send email (#10729)
workflow update to allow microsoft send email
- also handle the case were permissions are not enough
- update the redirection in case the user clicks on new account because
it's not anylonger as easy as simply google

fixes https://github.com/twentyhq/core-team-issues/issues/540
2025-03-07 18:29:35 +01:00
18de7efaaa i18n - translations (#10735)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 18:19:42 +01:00
Raphaël BosiandGitHub f45a682249 491 save the page component instance id for side panel navigation (Part 2) (#10732)
This PR follows #10700, it is the same refactor but for the workflows
pages.

- Duplicates the right drawer workflow pages for the command menu and
replace the states used in these pages by component states
- We store the component instance id upon navigation to restore the
states when we navigate back to a page

There are still states which are not component states inside the
workflow diagram and workflow command menu pages, we should convert them
in a futur refactor.

`closeCommandMenu` was called programmatically in multiple places for
the workflow, I refactored that to only rely on the click outside
listener. This introduced a wiggling bug on the workflow canvas when we
change node selection. This should be fixed in another PR by updating
the canvas animation to take the animation values of the command menu
instead. I'm thinking we could use [motion
values](https://motion.dev/docs/react-motion-value) for this as I told
you @Devessier
2025-03-07 18:18:24 +01:00
fc287dac78 Feat: API Playground (#10376)
/claim #10283

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-03-07 18:03:57 +01:00
d1518764a8 i18n - translations (#10734)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 17:48:02 +01:00
Baptiste DevessierandGitHub b49ec864b1 Visualize workflow run step output (#10730)
- Displays the output of the selected step in the `Output` tab
- Access to the `Output` tab is prevented when the selected node is
currently executed or was skipped
- Display the status of the workflow run instead of the status of the
workflow version at the top left corner of the workflow run visualizer
- Fixed the icon's color for disabled tabs
- Use text/primary color for the step's name even when the input is
disabled

## Demo: Successful execution


https://github.com/user-attachments/assets/02e492f3-1589-48e9-926e-7edb031d9210

## Demo: Failed execution


https://github.com/user-attachments/assets/73e5ec86-5f38-4306-aa9a-46b2e73950da

Closes https://github.com/twentyhq/core-team-issues/issues/434
2025-03-07 17:35:39 +01:00
0e1d742f3d i18n - translations (#10731)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 16:01:10 +01:00
Lucas BordeauandGitHub 3d7f4b7971 Fix view picker total count on board (#10697)
This PR is a follow-up of https://github.com/twentyhq/twenty/pull/10612
where the method of computation of total count was only taking records
fetched on the front end.

In this PR we use `totalCount` returned by `useFindManyRecords` instead,
which returns the total count in DB for the given filters.

We also set `shouldMatchRootQueryFilter` on board card create mutation
to avoid optimistic rendering issues.

Fixes https://github.com/twentyhq/twenty/issues/10598
2025-03-07 15:47:34 +01:00
EtienneandGitHub 96035f0ccf fix redis concurrency issue in health metrics + remove ongoing status count (#10717)
### Context
For calendar and message sync job health monitoring, we used to
increment a counter in redis cache which could lead to concurrency
issue.

### Solution
- Update to a set structure in place of counter + use sAdd redis method
which is atomic
- Each minute another counter was incremented on a new cache key ->
Update to a 15s window
- Remove ONGOING status not needed. We only need status at job end (or
fail).


###  Potential improvements
- Check for cache key existence before fetching data to avoid useless
call to redis ?

closes https://github.com/twentyhq/twenty/issues/10070
2025-03-07 14:41:46 +01:00
02a085df4f i18n - translations (#10727)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 14:21:45 +01:00
GuillimandGitHub 4bdcf77028 Bettertyping (#10725)
To get better at catching errors on providers
(It will ease also my coming PR to send microsoft messages using
workflow)
2025-03-07 14:11:56 +01:00
4be75fb7da eliminate IS_BILLING_PLANS_ENABLED feature flag (#10678)
Solves: https://github.com/twentyhq/core-team-issues/issues/527

**TLDR:**
Basically the title. Fetches the product and prices from the database
instead of the environment variables.

**What this means:**

- new subscriptions in twenty will be hybrid (per seat subscription plus
an usage base product)
- right now the price for the usage base product  is 0$ per unit
- The existing subscription will work normally, however we will need to
update their subscription items in order to contain the usage base
product (remember that the pricing intervals like monthly or yearly
should match in all the subscription items)
-  The previous point can be done using Stripe Postman


**In order to test:**

- Have the environment variable IS_BILLING_ENABLED set to true and add
the other required environment variables for Billing to work
- Do a database reset (to ensure that the new feature flag is deleted
and that the billing tables are created)
- Run the command: npx nx run twenty-server:command
billing:sync-plans-data (if you don't do that the products and prices
will not be present in the database)
- Run the server , the frontend, the worker, and the stripe listen
command (stripe listen --forward-to
http://localhost:3000/billing/webhooks)
- Buy a subscription for acme workspace
- Update the quantity of members in a workspace (add or delete)
- Change the subscription interval

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2025-03-07 11:46:22 +01:00
90d01a6c58 i18n - translations (#10722)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 11:34:56 +01:00
709f5d7829 i18n - translations (#10721)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 11:20:38 +01:00
0210e07497 Only use CAPTCHA in logged out operations and pages (#10607)
Issue #10235

---------

Co-authored-by: ad-elias <elias@autodiligence.com>
2025-03-07 11:03:30 +01:00
f3feaa6a0e i18n - translations (#10719)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 10:32:53 +01:00
f01da6b438 i18n - translations (#10718)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 10:20:27 +01:00
Paul RastoinandGitHub 776632fe79 [REFACTOR] Split in two distinct forms Settings Object Model page (#10653)
# Introduction

This PR contains around ~+300 tests + snapshot additions
Please check both object model creation and edition

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

Refactored into two agnostic forms the Object Model settings page for
instance `/settings/objects/notes#settings`.

## `SettingsDataModelObjectAboutForm`
Added a new abstraction `SettingsUpdateDataModelObjectAboutForm` to wrap
`SettingsDataModelObjectAboutForm` in an `update` context


![image](https://github.com/user-attachments/assets/137b4f85-d5d8-442f-ad81-27653af99c03)
Schema:
```ts
const requiredFormFields = objectMetadataItemSchema.pick({
  description: true,
  icon: true,
  labelPlural: true,
  labelSingular: true,
});
const optionalFormFields = objectMetadataItemSchema
  .pick({
    nameSingular: true,
    namePlural: true,
    isLabelSyncedWithName: true,
  })
  .partial();
export const settingsDataModelObjectAboutFormSchema =
  requiredFormFields.merge(optionalFormFields);
```
##  `SettingsDataModelObjectSettingsFormCard`
Update on change

![image](https://github.com/user-attachments/assets/179da504-7680-498d-818d-d7f80d77736b)
Schema:
```ts
export const settingsDataModelObjectIdentifiersFormSchema =
  objectMetadataItemSchema.pick({
    labelIdentifierFieldMetadataId: true,
    imageIdentifierFieldMetadataId: true,
  });
```

## Error management and validation schema
Improved the frontend validation form in order to attest that:
- Names are in camelCase
- Names are differents
- Names are not empty string ***SHOULD BE DONE SERVER SIDE TOO*** ( will
in a next PR, atm it literally breaks any workspace )
- Labels are differents
- Labels aren't empty strings

Hide the error messages as we need to decide what kind of styling we
want for our errors with forms
( Example with error labels )

![image](https://github.com/user-attachments/assets/d54534f8-8163-42d9-acdc-976a5e723498)
2025-03-07 10:14:25 +01:00
GuillimGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
21c7d2081d send email for outlook (#10703)
driver implementation for sending emails with microsoft

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-03-07 10:12:49 +01:00
53c561e3eb i18n - translations (#10715)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-07 08:20:12 +01:00
2c465bd42e Integrate Keystatic to edit twenty.com content (#10709)
This PR introduces Keystatic to let us edit twenty.com's content with a
CMS. For now, we'll focus on creating release notes through Keystatic as
it uses quite simple Markdown. Other types of content will need some
refactoring to work with Keystatic.


https://github.com/user-attachments/assets/e9f85bbf-daff-4b41-bc97-d1baf63758b2

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-03-07 07:59:06 +01:00
6b4d3ed025 i18n - translations (#10714)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 23:33:41 +01:00
15f5a377cc i18n - translations (#10713)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 23:20:05 +01:00
d2a0376a6f i18n - translations (#10712)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 21:46:03 +01:00
4b19f7f33c i18n - translations (#10711)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 21:32:50 +01:00
nitinandGitHub 3061576302 Admin panel: App health check (#10546)
closes https://github.com/twentyhq/core-team-issues/issues/441
whats new - 
- app health with the proposed format -- update, scratched this format
in favor of a more concise and more intentional health check. Now we
will check app health only based on pendingMigrations
<del>
```
status: 
  system: {
    nodeVersion
  },
  overview: {
    totalWorkspaces,
    criticalWorkspaces,
    workspacesWithPendingMigrations,
    healthDistribution: {
      healthy,
      warning,
      critical,
    }
  },
 problematicWorkspaces: [
    {
      workspaceId,
      severity,
      pendingMigrations,
      issuesSummary: {
        structural,
        data,
        relationship
      }
    }
  ]
  ```
</del>

- errorMessage and details seperation -- before we used to send error in details which made it difficult if we want both error and details on the front -- usecase >>
suppose app health indicator is not healthy but still want to send details
- stateHistory with timestamp -- this is something I introduced, not sure about this. Basically the thought process was to store the LastState of the details, incase of no connection or timeout errors. This is not yet used on the front, just the endpoint. But it could be used on the front too
- name unifying ⁠https://discord.com/channels/1130383047699738754/1346454192776155156
- json tree https://discord.com/channels/1130383047699738754/1346458558048501760
- match figma design https://discord.com/channels/1130383047699738754/1346451659647094815
- fix the collapse/open styles in tables https://discord.com/channels/1130383047699738754/1346452051974160406
- shift eye icon to expanded container https://discord.com/channels/1130383047699738754/1346452282669010987
- use H2Title for title and description of env variables groups https://discord.com/channels/1130383047699738754/1346434955936530452
2025-03-06 21:19:41 +01:00
MarieandGitHub f6314e52fe Delete related userWorkspaceRole and role when deleting workspace (#10707)
Closes https://github.com/twentyhq/core-team-issues/issues/537
2025-03-06 18:24:37 +01:00
Lucas BordeauandGitHub 777c12dd06 Fix advanced filter creation of group rule (#10690)
This PR improves advanced filter code and fixes the bug that prevented
the creation of a filter group.

On the debugging side : 
- Adding an advanced filter rule to create a group now works

On the refactoring side : 
- We now use AdvancedFilterRecordFilterGroupChildOptionsDropdown to
clarify the code that show the option dropdown of a group.
- Refacatored useCurrentViewViewFilterGroup to
useChildRecordFiltersAndRecordFilterGroups. It is now using only
RecordFilter and RecordFilterGroup type instead of view types. It also
exports recordFilters and recordFilterGroups alone, when they are
children of a group, so we don't have to extract them from the merged
array that is typed RecordFilter | RecordFilterGroup, which is necessary
for displaying a group.
- Two typeguards have been introduced to help discern RecordFilter from
RecordFilterGroup : isRecordFilterGroupChildARecordFilterGroup and
isRecordFilterGroupChildARecordFilter, this allows to remove any typing
on child processing.
- Renaming from view to record (but there are still some left)
2025-03-06 17:57:23 +01:00
Baptiste DevessierandGitHub cb5f4820d7 Visualize workflow run step input (#10677)
- Compute the context the selected step had access to during its
execution and display it with the `<JsonNestedNode />` component
- Ensure several steps with the same name can be displayed in order
- Prevent access to the input tab in a few cases
- Hide the input tab when the trigger node is selected as this node
takes no input
- Hide the input tab when the selected node has not been executed yet or
is currently executed
- Fallback to the Node tab when the Input tab can't be accessed

## Successful workflow execution


https://github.com/user-attachments/assets/4a2bb5f5-450c-46ed-b2d7-a14d3b1e5c1f

## Failed workflow execution


https://github.com/user-attachments/assets/3be2784e-e76c-48ab-aef5-17f63410898e

Closes https://github.com/twentyhq/core-team-issues/issues/433
2025-03-06 17:49:10 +01:00
9d78dc322d i18n - translations (#10706)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 17:36:04 +01:00
6bd566ecbb i18n - translations (#10705)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 17:21:10 +01:00
e86116aa57 491 save the page component instance id for side panel navigation (#10700)
Closes https://github.com/twentyhq/core-team-issues/issues/491

This PR:
- Duplicates the right drawer pages for the command menu and replace all
the states used in these pages by component states (The right drawer
pages will be deleted when we deprecate the command menu v1)
- Wraps those pages into a component instance provider
- We store the component instance id upon navigation to restore the
states when we navigate back to a page

The only pages which are not updated for now are the pages related to
the workflow objects, this will be done in another PR.
In another PR, to improve the navigation experience I will replace the
icons and titles of the chips by the label identifier and the avatar if
the page is a record page.


https://github.com/user-attachments/assets/a76d3345-01f3-4db9-8a55-331cca8b87e0

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-03-06 17:09:40 +01:00
MarieandGitHub 37d7c0c994 Bump version to 0.44.0-canary (#10702) 2025-03-06 16:50:22 +01:00
Thomas TrompetteandGitHub 5ddf7c6475 Set steps output schema in a recoil family state (#10688)
- Create a workflow version component family state for each workflow
version : `stepId` => `StepOutputSchema`
- Populate this state when reaching the workflow visualizer of the
workflow version
- Wrap the right drawer when in edit mode with the context. It is the
only one who needs this schema

Next step:
- read this state from the variables
2025-03-06 13:31:35 +00:00
Antoine MoreauxandGitHub 17b488dd3b refactor(custom-domain): simplify record mapping logic (#10685)
Refactored the mapping logic in custom-domain.service to improve
readability and ensure proper handling of undefined records. This change
introduces an early return for nullish records and maintains existing
validation behavior.
2025-03-06 14:19:23 +01:00
GuillimandGitHub 341439092a send email refacto (#10691)
working refacto with min module deps of messaging-import-manager-module
2025-03-06 12:56:40 +00:00
fea8edb16d i18n - translations (#10692)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 11:35:42 +01:00
88c09587db i18n - translations (#10689)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 11:20:45 +01:00
82bc361ff3 i18n - translations (#10687)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 11:01:11 +01:00
MarieandGitHub 23a371fcdb Update wording to indicate how to restore records (#10686) 2025-03-06 09:55:21 +00:00
a7b281dfb0 i18n - translations (#10684)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 09:21:13 +01:00
EtienneandGitHub 54865d91a3 update globalSearch resolver (#10680)
### Context
In order to deprecate search[Object] resolvers, we need to update
globalSearch resolver to bring it to the same level of functionality

### Solution
- Add includedObject args to search in pre-selected tables
- Add record filtering

### Tested on gql api  
- Simple search with search term
- Search with excluded objects, with included objects, with both and
both with search term
- Search with id filtering and all args combined
- Search with deletedAt filtering and all args combined

- from front, search in command menu

back end part of https://github.com/twentyhq/core-team-issues/issues/495
2025-03-06 09:11:25 +01:00
201b1decb9 i18n - translations (#10683)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-06 07:48:09 +01:00
Antoine MoreauxandGitHub e92e094a81 feat(approved-access-domain): QA (#10681) 2025-03-06 07:35:10 +01:00
Baptiste DevessierandGitHub 1ad08cdbe9 Save the trigger's default name (#10657)
Closes https://github.com/twentyhq/core-team-issues/issues/511
2025-03-05 18:19:52 +01:00
8ee26b8185 i18n - translations (#10679)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-05 17:22:13 +01:00
3cd52b052e feat: files visiblity with file configuration (#10438)
Ref: #10404 

- Added `FileFolderConfig` with `isPublic` key.
- Updated `file-path-guard.ts` to `ignoreExpiration` to validate the
token if `isPublic` is `true`.
- Token verification ignores expiration, assuming it's used to fetch
file metadata with a required workspaceId as we cannot remove the token
as we will loose the `workspaceId`.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-03-05 16:17:24 +00:00
MarieandGitHub f4fcf39eb5 [permissions] Prepare for roll-out (#10676)
Closes https://github.com/twentyhq/core-team-issues/issues/469 and
https://github.com/twentyhq/core-team-issues/issues/500

In this PR
1. stop conditioning permission initialization for a workspace to env
variable value. Instead we want to create and assign permissions and
roles in all new workspaces. For now that will be totally silent.
2. temporarily, the default role is set to the admin role for new
workspaces. it will also be the case for existing workspaces through the
backfill command. Member role is still being created though. (when we
will do the final roll-out we will update this so that future workspaces
have the member role as default role. our goal here is not to break any
current behaviour for users, that today have all have the equivalent of
admin rights).
2025-03-05 16:47:41 +01:00
WeikoandGitHub 91e714969f Fix REST API when metadata cache not found (#10669)
## Context
When REST API calls fail due to metadata cache version not found, we
throw an exception without trying to recover.
In Graphql implementation, the exception is thrown after recomputing the
cache. This PR implements the same logic for REST for users only user
the REST API.
2025-03-05 16:47:02 +01:00
GuillimandGitHub 55a45c50cc microsoft sync failed (#10381)
This PR is supposed to solve an issue with the syncrhonisation of
messages, specifically with microsoft driver. Microsoft calls don't need
access_Token so refreshing toekns was not implemented.

However, microsoft rely on its client which calls its refresfh_token,
and I might have missed some underlying dependency from microsoft
impelemtation so I setup the access token process to refresh it

Needs a talk before to be merged

Fix : https://github.com/twentyhq/twenty/issues/10367

EDIT:
it was a problem with microsoft making refreshtoken expire (contrarily
to google) which needs to be handled.
2025-03-05 15:22:51 +00:00
WeikoandGitHub d61f48d7ee Add icons next to permission settings labels (#10673)
## Context
as title

Before
<img width="842" alt="Screenshot 2025-03-05 at 15 11 19"
src="https://github.com/user-attachments/assets/1c228f29-368b-460d-8067-90bb2afc6e41"
/>

After
<img width="862" alt="Screenshot 2025-03-05 at 15 09 51"
src="https://github.com/user-attachments/assets/e7f9d02a-0c4a-49f3-977f-a0d6bef20862"
/>
2025-03-05 16:11:15 +01:00
Lucas BordeauandGitHub f34b59b6b6 Fix view open in settings not saving (#10674)
This PR removes the legacy useGetCurrentView hook that still returned
view with combined filters and sorts, which we don't use anymore.

This allows to remove a bug where we couldn't select the "open in"
settings of a view.
2025-03-05 15:52:37 +01:00
07a72226da i18n - translations (#10675)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-05 15:34:09 +01:00
CloudMinds | Nicklas KarlssonandGitHub 2ed055ecb4 update path for copying pg backup file to docker host folder (#10608)
### Update of path for copying postgres dumpfile to docker host folder.

The original path stated in the upgrade guide for self hosted docker.
(Option 2) Database migration, contains a wrong path to be able to copy
the backup file. The command results in a "there is no such file"
I replaced the  line 
**docker cp twenty-db-1:/databases_backup.sql .**   
with 
**docker cp twenty-db-1:/home/postgres/databases_backup.sql .**  
and it worked as it should.

So this is the edit of the correct path on the user guide on the webpage
2025-03-05 15:28:41 +01:00
Ana Sofia Marin AlexandreandGitHub 4d7e52ef25 deprocate getProductPrices query in front end (#10397)
**TLDR:**
Deprecate getProductPrices in the frontEnd and replace it with
BillingBaseProductPrices.

**In order to test:**

- Have the environment variable IS_BILLING_ENABLED set to true and add
the other required environment variables for Billing to work
- Do a database reset (to ensure that the new feature flag is properly
added and that the billing tables are created)
- Run the command: npx nx run twenty-server:command
billing:sync-plans-data (if you don't do that the products and prices
will not be present in the database)
- Run the server , the frontend, the worker, and the stripe listen
command (stripe listen --forward-to
http://localhost:3000/billing/webhooks)
- Buy a subscription for acme workspace the choose your plan should be
using the new front end endpoint
2025-03-05 15:27:34 +01:00
Lucas BordeauandGitHub e838dfc68b Fix advanced filters (#10665)
This PR partially fixes advanced filters that were not working even with
feature flag activated.

Bugs fixed here : 

- Advanced filters are not applied
- Root advanced filters cannot be created
- Cannot close advanced filters dropdown
- Can create multiple times the same non-advanced filter (reserved for
advanced filters)

upsertRecordFilter and removeRecordFilter have been refactored to take
record filter id instead of field metadata id, because the user should
be allowed to apply multiple filters for the same field.

We now base view filter CRUD directly on id, otherwise it could lead to
inconsistencies between advanced filters and simple filters.

This PR also refactors an important hook :
computeRecordGqlOperationFilter, so that it takes an object instead of
multiple params.

There are still bugs left, they will be taken in other PRs.
2025-03-05 14:01:07 +00:00
WeikoandGitHub 3fa915ac99 Restore nvmrc (#10671) 2025-03-05 14:27:17 +01:00
2296b75e89 i18n - translations (#10670)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-05 14:09:19 +01:00
WeikoandGitHub fd8b130df6 [Fix] Read only users should not be able to open a Relation picker (#10666)
## Context
ActivityTargetsInlineCell was not using the useIsFieldValueReadOnly hook
but a dedicated prop instead. To align with the rest of the
implementation I've updated that part of the code however we still want
the table/kanban views to always be in read-only mode regardless of the
hook logic so I've updated the hook to take the ContextStoreViewType
into account.
2025-03-05 13:56:58 +01:00
da0b0a9e3e i18n - translations (#10668)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-05 12:19:33 +01:00
Raphaël BosiandGitHub f3e667a651 496 add open in full page button on command menu record page (#10659)
Closes https://github.com/twentyhq/core-team-issues/issues/496

I upgraded react tabler icons to the latest version to be able to use
the newest icons.

The option menu was no longer accessible on right drawer record pages,
this pr fixes this and creates a new button which opens the record show
page.
This button is accessible via the shortcut `Command` + `Enter`


https://github.com/user-attachments/assets/570071b2-4406-40bd-be48-a0e5e430ed70
2025-03-05 12:02:31 +01:00
03c945ef97 i18n - translations (#10661)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-04 19:37:02 +01:00
a60f7586f3 i18n - translations (#10660)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-04 19:21:32 +01:00
6a0fcb8c8c i18n - translations (#10658)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-04 18:19:54 +01:00
WeikoandGitHub 5d2be60758 Various frontend fixes for roles pages (#10654) 2025-03-04 18:09:23 +01:00
4bf8af472a i18n - translations (#10656)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-04 17:48:45 +01:00
Paul RastoinandGitHub b83d8a4b27 [BUG] Object Settings Model tabs list heigh value 0 (#10646)
# Introduction
While working on https://github.com/twentyhq/core-team-issues/issues/355
encountered a recent regression:

![image](https://github.com/user-attachments/assets/654349a0-fd3d-4e17-a503-b942165f1771)

I honestly cannot explain this regression, should take time to do some
commits dichotomy in order to identify the problematic one but it feels
overkill

## Remarks
- Modified a common components please while reviewing have a look to
other of its invokation too ( others settings page )
2025-03-04 17:40:17 +01:00
2bddac596e i18n - translations (#10655)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-04 17:36:35 +01:00
Raphaël BosiandGitHub 9da973592d 460 create restore one and restore many records action (#10647)
Closes https://github.com/twentyhq/core-team-issues/issues/460


https://github.com/user-attachments/assets/5271e56d-bf67-49cc-a8da-e25c12171e2e
2025-03-04 17:27:14 +01:00
Paul RastoinandGitHub d6171c66df [BUGFIX] Dynamic default body background depending on device preferences (#10626)
# Introduction
close #9965 

When landing on twenty you should be able to see a white screen
flickering if you had setup dark mode.
This is because before the SPA has been loaded we're not displaying
anything, which in a white screen from the browser.
During this period we should display a background color following the
user's device theme.

## Reproduction
In order to reproduce this behavior define a fast 4G connection from
your network console.

## Cons
Device mode might not the one chosen afterwards when the user has been
authenticated
=> We should store appearance settings in the local storage in order to
optimistically render the default "loading" background ( wouldn't be
100% bullet proof for instance if the user is now unauth for some reason
)

Body background will be override by theme after app bootstrap
2025-03-04 15:54:16 +01:00
f6bc567aaf i18n - translations (#10652)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-04 15:34:31 +01:00
136feb57a7 i18n - translations (#10651)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-03-04 15:20:11 +01:00
WeikoandGitHub 19fce0c77d Fix gap between releases and logout (#10649)
## Context
A gap was introduced when we refactored the menu rendering as Logout
menu item was handled differently in its own NavigationDrawer section
which added the gap.
To fix that we are moving the Logout to the menu rendering logic in
useSettingsNavigationItems hook, allowing items to have onClick prop
instead of a path.

Before
<img width="213" alt="Screenshot 2025-03-04 at 14 36 55"
src="https://github.com/user-attachments/assets/23b63673-a9c4-47de-af71-7dda74469e9f"
/>

After
<img width="225" alt="Screenshot 2025-03-04 at 14 36 38"
src="https://github.com/user-attachments/assets/053c0c0d-8876-40b6-ae2c-b68124393f7f"
/>
2025-03-04 14:58:36 +01:00
GuillimandGitHub 696c510933 Removing empty handles from MessageWithParticipants (#10625)
fixes https://github.com/twentyhq/twenty/issues/10623
2025-03-04 14:53:24 +01:00
150e6bb17a Prepare docker-compose.yml for mail and calendar variables (#10464)
Adding the placeholders for the environment variables related to setting
up the mail and calendar sync. This will make the Twenty setup easier
for new users.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-03-04 14:30:04 +01:00
Thomas TrompetteandGitHub d151b1329c Generate fake form from metadata (#10641)
- add name to form field metadata
- extract field generation from object record schema
- use field generation to generate field from metadata
- add tests
2025-03-04 13:25:29 +01:00
Lucas BordeauandGitHub aba20dae11 Implemented CRUD for view filter group and removed old states (#10590)
This PR implements CRUD for view filter groups with the new logic as
already done for view filters and view sorts.

It also completely removes the old combined view filter group states and
usage.

This PR is quite big but the impact is limited since it only changes
advanced filters module, which is under feature flag at the moment, and
it is already in a broken state so unusable, even if someone activates
the feature flag.
2025-03-04 13:16:02 +01:00
9d80d2a8ef i18n - translations (#10644)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-03-04 11:35:27 +01:00
WeikoandGitHub be1073a2ef Fix settings page container (#10645)
This was changed in https://github.com/twentyhq/twenty/pull/10556 and
was not needed. Reverting to fix the roles page.

## Before

<img width="1155" alt="Screenshot 2025-03-04 at 11 30 30"
src="https://github.com/user-attachments/assets/21ae9c02-7c37-46e1-be40-e69ae809ea80"
/>

## After
<img width="1128" alt="Screenshot 2025-03-04 at 11 30 09"
src="https://github.com/user-attachments/assets/956a6222-7925-4aa2-9adb-efd158189368"
/>

Also checked if security page is still working
<img width="1136" alt="Screenshot 2025-03-04 at 11 30 19"
src="https://github.com/user-attachments/assets/0c30101b-51ae-4755-b5a7-d564fb093160"
/>
2025-03-04 11:35:00 +01:00
Thomas des FrancsandGitHub 85f6597d4c 0.43 changelog (#10643) 2025-03-04 11:22:56 +01:00
WeikoandGitHub ec4b6c9aa2 Fix: security and developers path should not be accessible to non-admin users (#10628)
https://github.com/twentyhq/core-team-issues/issues/468
2025-03-04 10:51:06 +01:00
Paul RastoinandGitHub ad628c1266 [ENH] Do not fail on missed cache within server commands (#10634)
Avoid critical failure if cache is missed when interacting with the
twenty-orm in the upgrade commands
2025-03-04 10:28:21 +01:00
156530ff5e i18n - translations (#10639)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-04 09:12:57 +01:00
749caf5336 i18n - translations (#10638)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-04 08:20:27 +01:00
327f0cd370 Health status worker metrics improvements (#10442)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-03-04 08:17:12 +01:00
WeikoandGitHub 41db10daff Revert "Remove reference to data-testid from styling" (#10635)
Reverts twentyhq/twenty#10407
2025-03-03 19:15:12 +01:00
Antoine MoreauxGitHubLucas BordeauEtienneRaphaël Bosigithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Crowdin Botgithub-actions
e8b6b1b941 fix(): several ui improvements (#10556)
Close #10531

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-03 17:06:16 +01:00
Raphaël BosiandGitHub a5d60919a7 Create import csv action (#10624)
Closes https://github.com/twentyhq/core-team-issues/issues/63

This PR:
- Creates an **Import csv** action
- Allows the import of notes and tasks
- Removes the import action from the index option menu
- Adds export action when only one record is selected
- Adds see deleted record action to workflow objects
2025-03-03 17:03:53 +01:00
Baptiste DevessierandGitHub 3d56e5394f Create a JSON tree visualizer (#10579)
Inspired by
https://github.com/reduxjs/redux-devtools/tree/main/packages/react-json-tree

- Created a reusable JSON tree visualizer
- For now, the visualizer is only meant to render raw JSON. It can't
determine if a string is a UUID and display a specific icon.

**The visualizer is not rendered in the app. You must use Storybook to
review it.**

## Demo



https://github.com/user-attachments/assets/ffd4fc94-b33d-4481-9ac1-fa3a348b7c81
2025-03-03 16:55:16 +01:00
Antoine MoreauxandGitHub 2325e0ae0f fix(): include workspace in reset password flow (#10617)
Fix #10586
2025-03-03 16:47:33 +01:00
EtienneandGitHub b8d944bd6e fix try catch logic in upgrade command (#10616) 2025-03-03 16:37:39 +01:00
9300f0a29b Fix: Prevent Multiple Search Icons in Command Menu (#10424)
Description:
This PR fixes an issue where clicking the search button multiple times
caused multiple search icons to appear in the search bar. The issue was
caused by continuously appending new items to the navigation stack
instead of replacing the existing search page entry.

Before:


https://github.com/user-attachments/assets/1abc4223-6295-4eea-b276-00e4539a2992



After:



https://github.com/user-attachments/assets/04d3a306-f3ca-4d3d-9028-9e4b4574e6a6

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-03-03 15:08:34 +00:00
cb3b0633b5 [FIX]: Overflow issue in delete record popup (#10417)
#10411
**Issue**: After right-clicking on deleted record, popup is cut
**Solution**: Added text-overflow ellipsis

previous behaviour: 


![image](https://github.com/user-attachments/assets/415e3603-5181-4656-a719-a5898e02128d)

fix:


![image](https://github.com/user-attachments/assets/a5178990-df14-45b4-a5cd-0b0261990407)

![image](https://github.com/user-attachments/assets/bdbc385f-4a92-4049-b0bc-70f6a38afeac)

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-03-03 15:08:06 +00:00
5c71969c75 i18n - translations (#10621)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-03 15:20:32 +01:00
Raphaël BosiandGitHub 44018911f2 Fix buttons size (#10620)
The button size attribute was removed accidentally in this PR
https://github.com/twentyhq/twenty/pull/10536, I'm putting it back.
All the buttons were 32px instead of 24px for the small ones.
2025-03-03 14:02:30 +00:00
Antoine MoreauxandGitHub 83899ff26b feat(button): add accent prop and disable pointer events (#10618)
Added an accent prop to the StyledButtonWrapper for additional styling
capabilities. Also disabled pointer events on ButtonIcon to prevent
interference during loading states.
2025-03-03 13:59:55 +00:00
EtienneandGitHub d2ad23d1cf fix workspace member search (#10613) 2025-03-03 11:57:07 +01:00
Lucas BordeauandGitHub c5795b7325 Fixed board total count on view picker button (#10612)
This PR adds a missing call to `setRecordIndexEntityCount` during board
data loading.
2025-03-03 11:25:48 +01:00
fddac1e250 i18n - translations (#10611)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-03-03 11:20:57 +01:00
Antoine MoreauxandGitHub 51c34b77d9 feat(twenty-front/Button): add loading state on Button (#10536) 2025-03-03 11:04:32 +01:00
Paul RastoinandGitHub 2e4c596644 [TEST] Covering useDeleteOne relations optimistic cache behavior (#10238)
## Introduction
Added coverage on the `useDeleteOneRecord` hooks, especially its
optimistic behavior feature.
Introduced a new testing tool `InMemoryTestingCacheInstance` that has
builtin very basic expectors in order to avoid future duplication when
covering others record hooks `update, create, destroy` etc etc

## Notes
Added few comments in this PR regarding some builtin functions I've
created around companies and people mocked object model and that I think
could be cool to spread and centralize within a dedicated "class
template"

Also put in light that unless I'm mistaken some tests are running on
`RecordNode` and not `RecordObject`

Took few directions on my own that as I always I would suggestion nor
remarks on them !

Let me know

## Misc
- Should we refactor `useDeleteOneRecord` tests to follow `eachTesting`
pattern ? => I feel like this is inappropriate as this hooks is already
high level, the only plus value would be less tests code despite
readability IMO
2025-03-03 10:22:26 +01:00
Charles BochetandGitHub c6e5238d71 Fix Docker compose CI to stop building postgres-spilo image (#10595)
As a follow up of #10594
2025-02-28 20:55:34 +01:00
Charles BochetandGitHub cd069fb941 Update docker-compose to use postgres container (#10594)
There is no reason to use a custom image for postgres anymore as we have
migrated out pg_graphql postgres extension
2025-02-28 20:09:30 +01:00
f6a5c81a55 i18n - translations (#10593)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-28 20:01:03 +01:00
WeikoandGitHub d19144208b Improve migration runner performances (#10572)
## Context
Workspace creation and more specifically sync-metadata performances are
bad at the moment. We are trying to identify bottlenecks and one of the
root causes is the migration runner that can take up to 10s when setting
up a new workspaces with all its tables.
First observation is we do a lot of things sequentially, mostly to make
the code easier to read and debug but it impacts performances. For
example, a table creation is done in two steps, we first ask typeorm to
create the table then ask typeorm to create columns (and sometimes
columns one by one), each instruction can take time because typeorm
seems to do some checks internally.

The proposition here is to try to merge migrations when possible, for
example when we create a table we want the migration to also contain the
columns it will contain so we can ask typeorm to add the columns at the
same time. We are also using batch operations when possible (addColumns
instead of addColumn, dropColumns instead of dropColumn)
Still, we could go further with foreign keys creations or/and try with
raw query directly.

## Test
New workspace creation:
See screenshot, 9865.40233296156ms is on main, the rest is after the
changes:

<img width="610" alt="Screenshot 2025-02-28 at 09 27 21"
src="https://github.com/user-attachments/assets/42e880ff-279e-4170-b705-009e4b72045c"
/>

ResetDB and Sync-metadata on an existing workspace commands still work
2025-02-28 19:51:45 +01:00
Charles BochetandGitHub baa3043954 Refactor upgrade commands (#10592)
Simplifying a lot the upgrade system.

New way to upgrade:
`yarn command:prod upgrade`

New way to write upgrade commands (all wrapping is done for you)
```
  override async runOnWorkspace({
    index,
    total,
    workspaceId,
    options,
  }: RunOnWorkspaceArgs): Promise<void> {}
```

Also cleaning CommandModule imports to make it lighter
2025-02-28 19:51:32 +01:00
194b5889fe i18n - translations (#10591)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-28 18:45:52 +01:00
Thomas TrompetteandGitHub cbd4a15148 Add test on workflow executor (#10589)
As title
2025-02-28 18:38:49 +01:00
2773dde714 Remove reference to data-testid from styling (#10407)
Fixes https://github.com/twentyhq/core-team-issues/issues/204

---------

Co-authored-by: ad-elias <elias@autodiligence.com>
2025-02-28 16:37:14 +01:00
EtienneandGitHub 47b7c696d5 update website (#10588) 2025-02-28 16:08:52 +01:00
129037da6c i18n - translations (#10587)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-28 16:01:27 +01:00
Charles BochetandGitHub 00b650a121 Fix export view missing column and viewGroups not persisted bug (#10584)
Fixes https://github.com/twentyhq/twenty/issues/10535
Also fixes missing columns in export view
2025-02-28 15:59:13 +01:00
122a6a7801 [permissions] Backfill command to prepare workspaces (#10581)
Closes https://github.com/twentyhq/core-team-issues/issues/317

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-02-28 15:46:51 +01:00
EtienneandGitHub fba63d9cb7 migrate rich text v1 workspace + move relation migration to 0.44 (#10582)
Adapt from MigrateRichTextFieldCommand
2025-02-28 14:46:34 +01:00
EtienneGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
33370f5d1f add sentry monitoring + update cron pattern to each hour (#10583)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-02-28 14:34:18 +01:00
EtienneandGitHub 2aa72de210 remove isRichTextV2Enabled feature flag (#10562) 2025-02-28 14:34:06 +01:00
Lucas BordeauandGitHub ea1ac3708c Implemented view filter group CRUD hooks and utils (#10551)
This PR implements hooks and utils logic for handling CRUD and view
filter group comparison.

The main hook is useAreViewFilterGroupsDifferentFromRecordFilterGroups,
like view filters and view sorts.

Inside this hook we implement getViewFilterGroupsToCreate,
getViewFilterGroupsToDelete and getViewFilterGroupsToUpdate.

All of those come with their unit tests.

In this PR we also introduce a new util to prevent nasty bugs happening
when we compare undefined === null,

This util is called compareStrictlyExceptForNullAndUndefined and it
should replace every strict equality comparison between values that can
be null or undefined (which we have a lot)

This could be enforced by a custom ESLint rule, the autofix may also be
implemented (maybe the util should be put in twenty-shared ?)
2025-02-28 13:32:54 +01:00
b7abaa242c i18n - translations (#10580)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-28 13:22:26 +01:00
nitinandGitHub 85bfd87bb4 input alignment fix (#10577)
this fix was already the case before this
[change](https://github.com/twentyhq/twenty/pull/10124/files#diff-a48e37b645699a3309d359e3084f0218c38441585d8e3884083c411dacb096f4L273)

Unsure why this change was necessary. 

<img width="914" alt="Screenshot 2025-02-28 at 16 02 38"
src="https://github.com/user-attachments/assets/c8bd791b-81b3-429b-9d0a-88a47058a979"
/>
2025-02-28 17:39:11 +05:30
a234e00657 i18n - translations (#10578)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-28 11:45:51 +01:00
Raphaël BosiandGitHub 4d7ba29d9f Add PageHeaderOpenCommandMenuButton on Record index page header for command menu v1 (#10576)
The only way to open the command menu in v1 on the index page was
through the shortcut, but since important actions (export and see
deleted records) have been moved to the command menu, we want an easy
way to open it on v1.


https://github.com/user-attachments/assets/b446f385-da69-4dcc-af9d-74d36b52e94f
2025-02-28 11:42:02 +01:00
Lucas BordeauandGitHub 0c4a984110 Fixed view bar chips margin and gaps (#10575)
This PR fixed ViewBar chips that were using margin instead of padding
and gaps.

This SortOrFilter chip was using margin left to space itself where it
was the role of the view bar to handle gap between chips and
padding-left at the beginning.
2025-02-28 11:39:59 +01:00
EtienneandGitHub 8762c06ff2 add tests on workspace deletion logic (#10530)
closes [#424](https://github.com/twentyhq/core-team-issues/issues/424)
2025-02-28 10:38:51 +01:00
EtienneandGitHub 124e69447d add missed search decorator (#10573) 2025-02-28 10:22:22 +01:00
adf8c68f57 i18n - translations (#10574)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-28 10:20:37 +01:00
Thomas TrompetteandGitHub a29c26c8d7 Add submit form step endpoint (#10538)
- add endpoint to submit form step
- update context and output of workflow run
- resume workflow execution
2025-02-28 10:03:45 +01:00
15d3751b73 i18n - translations (#10571)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-28 08:01:09 +01:00
MarieandGitHub ef7581f4ef [permissions] Fix redirection at sign-up after configuring billing (#10569)
During sign-up, new users setting new workspaces are required to choose
a billing plan (30-days or 7 days). They are then redirected to
billing.twenty.com to confirm and configure their plan choice.
Then they are quickly redirected to /settings/billing before being
redirected to /create-workspace.

The problem is that even though /create-workspace is not a gated path,
/settings/billing is: it is a path gated by WORKSPACE permission which
has not been granted to the user at this stage. therefore the user is
not redirected to /create-workspace since they do not reach
/settings/billing path but is redirected to the profile page instead.
(To see this feature flag must be removed + billing enabled: you can use
this branch [from this closed
PR](https://github.com/twentyhq/twenty/pull/10570)).

The chosen workaround is to bypass, in the FE, the permission check for
WORKSPACE permission if the workspace's activation status is
PENDING_CREATION. There is no need for any BE change.
2025-02-28 07:52:28 +01:00
MarieandGitHub a3a05c63f6 [permisions] Bypass permission checks with api key (#10516)
Closes https://github.com/twentyhq/core-team-issues/issues/325
2025-02-28 07:50:49 +01:00
Paul RastoinandGitHub 0dc1cd9df1 [REG/FEAT] Sync metadata after upgrade (#10557)
# Introduction
Historically we've been programmatically running sync metadata just
after all upgrade command's migration.
Adding back this behavior as default to the new dynamic modules

Duplicated already existing synchronize metadata logic as a quick fix as
we're about to iterate over commands next sprint
2025-02-27 18:44:41 +01:00
Raphaël BosiandGitHub aa74c36ce9 Fix record opening on board card (#10559)
The record opening when clicking on the body of the board card should
behave the same as when clicking on the record chip.

Before:


https://github.com/user-attachments/assets/8d5956e4-d529-455c-9d28-02d5a8b6e290

After:


https://github.com/user-attachments/assets/70dadd77-a151-47b5-b8b4-ec01d6e2c48e
2025-02-27 18:29:09 +01:00
23889d360d i18n - translations (#10560)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-27 18:19:56 +01:00
Raphaël BosiandGitHub dddf67ed01 Prevent command menu backspace shortcut on V1 (#10555)
Before:


https://github.com/user-attachments/assets/87be65fa-4b24-4e15-b0a4-ca1aa06f5ca6


After:


https://github.com/user-attachments/assets/ef9076a0-214f-4680-a455-157a206e8197
2025-02-27 18:14:45 +01:00
Paul RastoinandGitHub 65e569986d [ENHC] Create Yarn constraints to validate node version (#10542)
## Introduction
This is PR is a suggestion ! And should be discussed

With yarn `^4`, during installation won't raise an error if current dev
env does not satisfies the `engines` policy.
We have usually 10+ contributors support request regarding higher node
version issue per week

I would have preferred a very declarative integration using npm
[engines](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#engines)
but this does not seems to be natively supported by `yarn`

We should keep in mind that this might block any machines from our CICD
if they have diff node version installed ( such as running the project
on a different node version could result in bugs too )

## Implem

Created a yarn [constraints](https://yarnpkg.com/features/constraints)
run after each installation that checking if current node version
satisfies defined engines range ( might also be done for others engines
entries )

I assume we will always have the same engines policy for every packages,
at least that's not a consideration from now

## Further
We could refactor our package.json engines into only one using
`Yarn.set` etc

## Resource
- https://yarnpkg.com/configuration/yarnrc
- https://yarnpkg.com/features/constraints

## Note
- Not running constraints in `preInstall` hook as won't be effective on
fresh install
-
[engine-strict](https://docs.npmjs.com/cli/v8/using-npm/config#engine-strict)
is an npm-config
-
[devEngines](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#devengines)
are npm feature too ( for instance pnpm current PR
https://github.com/pnpm/pnpm/issues/8153 )

## Conclusion
As always any suggestions are more than welcomed !
2025-02-27 15:18:07 +01:00
Charles BochetandGitHub 6be66f27d3 API rest exception filter (#10548)
While troubleshooting with a person self-hosting Twenty (v0.42.2), we
figured out that logs were missing on REST findMany, findOne and
duplicate endpoints

This PR fixes it
2025-02-27 15:03:26 +01:00
890b5c42d1 i18n - translations (#10547)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-27 14:08:48 +01:00
EtienneandGitHub 39543872e6 add new @WorkspaceIsSearchable decorator + updates services + add migration command (#10507)
closes https://github.com/twentyhq/core-team-issues/issues/345
2025-02-27 13:57:07 +01:00
MarieandGitHub 17dbb634ca [permissions] forbid deletion of last admin user (#10504)
A user should not be able to delete their account if they are the last
admin of a workspace.

It means that if a user wants to sign out of twenty, they should delete
their workspace, not their account
2025-02-27 12:44:51 +01:00
Raphaël BosiandGitHub fb38828943 Fix command menu list item overflow (#10544)
Before:
<img width="501" alt="Capture d’écran 2025-02-27 à 12 10 52"
src="https://github.com/user-attachments/assets/dd3637b4-cfe4-44b9-8db2-78e14741a415"
/>

After:
<img width="503" alt="Capture d’écran 2025-02-27 à 12 10 40"
src="https://github.com/user-attachments/assets/71ebb02d-cdc8-44e6-82dd-d00b3a45e7c0"
/>
2025-02-27 11:38:30 +00:00
Raphaël BosiandGitHub d9e6b95c04 Disable drag select when the command menu is opened (#10541)
Before:


https://github.com/user-attachments/assets/3d6a3833-cf5d-4330-a814-896a5c9df930

After:


https://github.com/user-attachments/assets/5f490fc2-59aa-45d5-b485-2abced4b31ef
2025-02-27 12:36:47 +01:00
Raphaël BosiandGitHub 05f15a827f Fix contact creation (#10540)
Fixes the following bug:
When I connect an account, a contact is created for that email if the
domain name differs from the workspace domain name.
2025-02-27 11:51:15 +01:00
f186b728e3 i18n - translations (#10539)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-27 11:20:33 +01:00
WeikoandGitHub 084554eaa8 Fix filter rest api (#10537)
## Context
Rest API is now using cache metadata but the change was not done
everywhere which was breaking the API
<img width="953" alt="Screenshot 2025-02-27 at 10 48 31"
src="https://github.com/user-attachments/assets/84f549a6-59b5-4989-b1ba-2d5c515ee47c"
/>
2025-02-27 11:05:53 +01:00
Thomas TrompetteandGitHub 83930551d8 Move workflow versions and steps building to workflow-builder folder (#10523)
We are starting to put too many services in common folder. Version and
step building should be separated into different services and go to the
builder folder. Today builder folder only manage schema.

We should:
- keep services responsible for only one action
- keep modules based on the actual action these provide rather than
having common module

This PR:
- creates a service for workflow version builder
- moves version and step builders to workflow builder folder rather than
commun
- creates separated folders for schema, version and steps

No logic has been added. Only modules created and functions moved.
2025-02-27 10:39:48 +01:00
Baptiste DevessierandGitHub 8bd9bc9d31 Make the frontend resilient to old workflow run output formats (#10522)
- Create zod schemas for everything related to a workflow run
- Update the types to be inferred from the zod schemas
- Improper workflow run outputs will render a blank screen; we could
show an error in the future



https://github.com/user-attachments/assets/8e666c3e-82b0-4ab5-8804-2f70130ea257
2025-02-27 10:36:19 +01:00
Lucas BordeauandGitHub 5a39903d42 Implemented record filter group initialization from view (#10527)
This PR implements the initialization of current record filter groups
state from view.

It also implements mapRecordFilterGroupToViewFilterGroup,
mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator and
mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator with
their corresponding unit tests.

Some unused states not caught by ESLint are also removed.
2025-02-27 10:25:59 +01:00
Charles BochetandGitHub 2f048201ad Fix field empty value check for Person standard object (#10533)
The previous code was not correct if labelIdentifier is a FULL_NAME.
We already have an util for this

Fixes: https://github.com/twentyhq/twenty/issues/10532
2025-02-27 10:08:47 +01:00
4189ce2a9e i18n - translations (#10534)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-27 10:01:08 +01:00
Charles BochetandGitHub d246010c5c RecordPicker refactoring part 3: remove effects (#10505)
This PR is part 3 of RecordPicker refactoring. 

It aims to remove all effects from:
- (low level layer) SingleRecordPicker, MultipleRecordPicker
- (higher level layer) RelationPicker, RelationToOneInput,
RelationFromManyInput, ActivityTargetInput...

In this PR, I'm re-grouping Effects in ActivityTarget section and
creating a hook that will be called on inlineCellOpen
2025-02-27 09:56:03 +01:00
aa25a80171 i18n - translations (#10529)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-26 19:36:21 +01:00
7f406bc349 i18n - translations (#10528)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-26 19:21:31 +01:00
f94d75c27f i18n - translations (#10526)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-26 19:01:29 +01:00
Raphaël BosiandGitHub b349d3f8c2 62 create see deleted records action (#10525)
Closes https://github.com/twentyhq/core-team-issues/issues/62

- Created action
- Removed action from the option menu
- Fixed the filters and sorts providers for the command menu



https://github.com/user-attachments/assets/b42de3ea-536c-458c-a0e7-abd6f929d234
2025-02-26 18:51:17 +01:00
Paul RastoinandGitHub 5327febcbe [REFACTOR] remove isRemote assertion from hasFieldPosition util (#10519)
Following this discussion
https://github.com/twentyhq/twenty/pull/10510#discussion_r1971845556
with @ijreilly
2025-02-26 18:28:55 +01:00
Raphaël BosiandGitHub 24aca790f7 Remove export action from the view options menu (#10517)
Closes https://github.com/twentyhq/core-team-issues/issues/64
Remove export action from the view options menu
2025-02-26 18:20:07 +01:00
fa2930b0f9 i18n - translations (#10524)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-26 18:19:54 +01:00
WeikoandGitHub 431da37cdf add stories to roles components (#10503)
## Context
Adding stories for roles components. Also moving modules components to
the proper "modules" folder, "pages" folder being only for entry points.

## Test
Run storybook

<img width="1145" alt="Screenshot 2025-02-26 at 13 40 40"
src="https://github.com/user-attachments/assets/bc184ab0-c590-4362-8c5a-1bf5ef176e6c"
/>
<img width="1149" alt="Screenshot 2025-02-26 at 13 40 32"
src="https://github.com/user-attachments/assets/699cd205-31db-45e9-b9c1-caff1832bd47"
/>
<img width="1153" alt="Screenshot 2025-02-26 at 13 40 11"
src="https://github.com/user-attachments/assets/72e45a67-ea89-4999-8b16-6f7d027d07f6"
/>
<img width="471" alt="Screenshot 2025-02-26 at 13 38 16"
src="https://github.com/user-attachments/assets/62676943-9935-42b5-b769-5544f7eed85f"
/>
<img width="472" alt="Screenshot 2025-02-26 at 13 38 12"
src="https://github.com/user-attachments/assets/946baab9-1be4-439e-bf99-0ebeab0995f7"
/>
2025-02-26 18:16:05 +01:00
WeikoandGitHub d40a5ed74f Fix REST API not using metadata cache (#10521) 2025-02-26 17:59:35 +01:00
a6ea8b98b6 i18n - translations (#10518)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-26 17:21:18 +01:00
Paul RastoinandGitHub ea0d3c605f [FIX] Optimistically compute position only for objectMetadataItem that has the field (#10510)
# Introduction
In this PR https://github.com/twentyhq/twenty/pull/10493 introduced a
regression on optimistic cache for record creation, by expecting a
`position` `fieldMetadataItem` on every `ObjectMetadataItem` which is a
wrong assertion
Some `Tasks` and `ApiKeys` do not have one

## Fix
Dynamically compute optimistic record input position depending on
current `ObjectMetadataItem`

## Refactor
Refactored a failing test following [jest
each](https://jestjs.io/docs/api#describeeachtablename-fn-timeout)
pattern to avoid error prone duplicated env tests. Created a "standard'
and applied it to an other test also using `it.each`.
2025-02-26 17:04:52 +01:00
Lucas BordeauandGitHub e6355c7c49 Fixed record sort on kanban (#10515)
This PR fixes a leftover from the removal of combined filters and sorts.

Board request hook was still relying on combinedViewSorts, here we just
use currentRecordSorts instead and it works well.
2025-02-26 16:59:08 +01:00
Raphaël BosiandGitHub d47e5ec47d Fix command menu closing and opening (#10497)
Since I introduced AnimatePresence to animate the exit of the command
menu, the command menu wasn't working properly. By adding this
animation, I had to reset the command menu states at the end of the
animation, otherwise, the component inside the command menu would throw
errors. The problem was that, by closing and instantly reopening the
command menu, the `onExitComplete` wasn't triggered and the states
weren't reset before the opening. By introducing a new state
`isCommandMenuClosingState`, I can reset those states at the beginning
of the opening if the animation didn't have the time to finish.
2025-02-26 16:52:44 +01:00
Baptiste DevessierandGitHub f74e4bedc4 Create a right drawer for viewing steps in workflow runs (#10366)
- Improve the type-safety of the objects mapping the id of a right
drawer or side panel view to a React component
- Improve the types of the `useTabList` hook to type the available tab
identifiers strictly
- Create a specialized `WorkflowRunDiagramCanvas` component to render a
`WorkflowRunDiagramCanvasEffect` component that opens
`RightDrawerPages.WorkflowRunStepView` when a step is selected
- Create a new side panel view specifically for workflow run step
details
- Create tab list in the new side panel; all the tabs are `Node`,
`Input` and `Output`
- Create a hook `useWorkflowSelectedNodeOrThrow` not to duplicate
throwing mechanisms

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

## Demo


https://github.com/user-attachments/assets/8d5df7dc-0b99-49a2-9a54-d3eaee80a8e6
2025-02-26 16:48:24 +01:00
Lucas BordeauandGitHub 694553608b Implements record filter group upsert and remove (#10514)
This PR implements a parallel code path to upsert and remove record
filter groups.

Those record filter groups aren't keeping track of the view id but since
they are in a view context, it's implicit that the advanced filter
feature can keep track of view for record filter groups.

We'll need record filter group for an upcoming feature without views, so
we need to abstract record filter group from view.

We have viewFilterGroup.id === recordFilterGroup.id, so it's easy to map
each other.
2025-02-26 16:24:11 +01:00
Raphaël BosiandGitHub dd12bc31ca Fix record page context store instance id (#10508)
Fixes bug introduced by https://github.com/twentyhq/twenty/pull/10272
- Replace show page context store instance id by 'main-context-store'
2025-02-26 15:05:22 +00:00
fe46ede1ac i18n - translations (#10512)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-26 15:20:11 +01:00
Thomas TrompetteandGitHub b705425358 Create Workflow Form action (#10509)
- create form action
- add `pendingEvent` to executor output
- when receiving pendingEvent, exit workflow execution
- let the workflow in running status for now before taking a decision
2025-02-26 14:15:39 +00:00
1af25bf31d i18n - translations (#10506)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-26 14:08:14 +01:00
Charles BochetandGitHub 64938d5a05 Refactor RecordPicker part 2 (#10502)
Keep clarifying folders:
- record-picker is now clean
- record-picker-morph-legacy contains activityTarget logic that will be
abstracted later
2025-02-26 13:54:16 +01:00
Paul RastoinandGitHub ec87218b9c [Refactor] generateDepthOneRecordGqlFieldsFromRecord (#10499)
## Introduction
This refactor results from this
https://github.com/twentyhq/twenty/pull/10493 review
Introduced a new abstraction to the extinsting
`generateDepthOneRecordGqlFields` that was accepting an optional record
in arg in order to map generated `recordGqlFields` to the keys in the
record

1/ Created a dedicated util method
`generateDepthOneRecordGqlFieldsFromRecord` to do so
2/ Updated each previous `generateDepthOneRecordGqlFields` passing a
record to call new `generateDepthOneRecordGqlFieldsFromRecord`
2025-02-26 11:11:45 +00:00
41a412bd55 i18n - translations (#10498)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-26 11:20:35 +01:00
Paul RastoinandGitHub 611e89e5c9 [BUGFIX] Create optimistic cache generate recordGqlFields from prefilled record (#10493)
# Introduction
The record does not appear in the table because the optimistic record
input cached does not fulfill the mutation response fields, which result
in it being considered as invalid response
close #10199 
close https://github.com/twentyhq/twenty/issues/10153
2025-02-26 11:11:01 +01:00
26ea465862 i18n - translations (#10494)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 19:36:34 +01:00
45853aed8c i18n - translations (#10492)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 19:21:34 +01:00
Lucas BordeauandGitHub 4d02bf1362 Implement record filter group states and context (#10490)
This PR simply implements record filter group states and context, as we
did for record filter and record sort.

We use a separate context for record filter and record filter group,
we'll see later if it can be merged in practice, but better be cautious
for now.
2025-02-25 18:31:34 +01:00
WeikoandGitHub d9bde155ff update twenty team members danger (#10491) 2025-02-25 18:24:42 +01:00
9fbd698ea4 i18n - translations (#10487)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 17:48:13 +01:00
Raphaël BosiandGitHub 42ea02329a Fix thread pagination (#10485)
Fixes https://github.com/twentyhq/twenty/issues/10308.

The issue came from the fact that the pagination inside the
`findAndCount` wasn't working properly. The limit was applied on the
joint table. Adding a `groupBy` fixes this, but since it isn't available
on the `findAndCount` I had to modify the query using the query builder.
2025-02-25 17:44:42 +01:00
WeikoandGitHub 2331176c53 Remove current workspace member from role assignment picker (#10482)
## Context
Removing the ability to assign yourself from the UI. The backend already
checks that. This is because a member can only have one role for the V1
of permissions
Took the opportunity to move some roles related components in dedicated
folders
2025-02-25 17:43:57 +01:00
EtienneandGitHub 90a390ee33 add new globalSearch resolver + update useSearchRecords hook (#10457)
# Context

To enable search records sorting by ts_rank_cd / ts_rank, we have
decided to add a new search resolver serving `GlobalSearchRecordDTO`.

-----

- [x] Test to add - work in progress


closes https://github.com/twentyhq/core-team-issues/issues/357
2025-02-25 17:43:35 +01:00
3f25d13999 i18n - translations (#10486)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 17:36:21 +01:00
85a2ad1659 i18n - translations (#10484)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 17:21:25 +01:00
1d49fcae77 i18n - translations (#10483)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 17:01:24 +01:00
Antoine MoreauxandGitHub 7c9b902cfe feat(approval-domain): add UI for approval domains (#10480) 2025-02-25 15:44:07 +00:00
9997cf5a4e 322 compact command chips dropdown (#10456)
Closes https://github.com/twentyhq/core-team-issues/issues/322



https://github.com/user-attachments/assets/d4806f04-e217-40f5-9707-93334bbd49ea

---------

Co-authored-by: Devessier <baptiste@devessier.fr>
2025-02-25 16:42:38 +01:00
Charles BochetandGitHub a1c7e3279c Refactor RecordSingleSelect and RecordMultiSelect to be synchronous (#10469)
## Context
We are experiencing a lot of re-rendering / flash on MultiRecordSelect /
SingleRecordSelect / RelationPicker.

This PR is a first step to refactor this components

## Scope

Only move files to uniformize and prepare for the upcoming refactoring

## Vision
- SingleRecordPicker
- MultipleRecordPicker
- sharing RecordPicker tooling (RecordPickerComponentInstanceContext,
searchState)

Used in other areas:
- RelationPicker (which is actually only a subcomponent of
RelationToOneFieldInput)
- RelationFromManyFieldInput
- WorkflowRelationFieldInput
- etc.

+ remove all effects
+ migrate to the latest APIs
+ make a pass on re-renders to remove them completely (we likely need to
use a bit more familyStates here)
2025-02-25 15:48:25 +01:00
WeikoandGitHub 589a0c7b2d Fix graphql conflict between role custom object and role dto (#10479)
## Context
Following the strategy where we want to block custom object creation
when the type is reserved by core objects. The issue happened again with
the recently introduced role table.
2025-02-25 15:46:06 +01:00
89e11b4626 [BUGFIX] Account owner should not be clickable & [Refactor] Chip.tsx links (#10359)
# Introduction

closes #10196 
Initially fixing the `Account Owner` record field value should not be
clickable and redirects on current page bug.
This has been fixed computing whereas the current filed is a workspace
member dynamically rendering a stale Chip components instead of an
interactive one

## Refactor
Refactored the `AvatarChip` `to` props logic to be scoped to lower level
scope `Chip`.
Now we have `LinkChip` `Chip`, `LinkAvatarChip` and `AvatarChip` all
exported from twenty-ui.

The caller has to determine which one to call from the design system

## New rule regarding chip links
As discussed with @charlesBochet and @FelixMalfait 
A chip link will now ***always*** have `to` defined. ( and optionally an
`onClick` ).
`ChipLinks` cannot be used as buttons anymore

## Factorization
Deleted the `RecordIndexRecordChip.tsx` file ( aka
`RecordIdentifierChip` component ) that was duplicating some logic,
refactored the `RecordChip` in order to handle what was covered by
`RecordIdentifierChip`

## Conclusion
As always any suggestions are more than welcomed ! Took few opinionated
decision/refactor regarding nested long ternaries rendering `ReactNode`
elements

## Misc


https://github.com/user-attachments/assets/8ef11fb2-7ba6-4e96-bd59-b0be5a425156

---------

Co-authored-by: Mohammed Razak <mohammedrazak2001@gmail.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-02-25 14:36:17 +00:00
fc0e98b53e i18n - translations (#10478)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 15:34:31 +01:00
531babd46f i18n - translations (#10477)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-25 15:20:14 +01:00
MarieandGitHub 9fe5c96d56 [permissions] Update updateRole logic + disallow self role-assignment (#10476)
In this PR

- updateWorkspaceMemberRole api was changed to stop allowing null as a
valid value for roleId. it is not possible anymore to just unassign a
role from a user. instead it is only possible to assign a different role
to a user, which will unassign them from their previous role. For this
reason in the FE the bins icons next to the workspaceMember on a role
page were removed
- updateWorkspaceMemberRole will throw if a user attempts to update
their own role
- tests tests tests!
2025-02-25 15:20:07 +01:00
Lucas BordeauandGitHub 2247d3fa91 Clean record filter and record sort (#10466)
This PR removes what's left from record filter and record sort previous
logic to handle CRUD and state management with view.

So everything that is named combinedFilter and combinedSort is removed
here.

We implement currentRecordFilters and currentRecordSorts everywhere.

We also remove the event in a state onSortSelectComponentState. (a
pattern we want to avoid)
2025-02-25 14:03:30 +00:00
61904050ac i18n - translations (#10474)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 13:22:32 +01:00
9c0c4ebf27 i18n - translations (#10472)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 12:01:01 +01:00
Raphaël BosiandGitHub e77ba2be52 Add non root user for twenty website docker file (#10470)
- Create user 1000 and give it the necessary permissions
2025-02-25 10:51:09 +00:00
3f7bb4f958 i18n - translations (#10471)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 11:46:17 +01:00
7abc67c905 refactor(forms): simplify form handling and button behavior (#10441)
Removed redundant handleSave and handleSubmit props in domain settings.
Integrated form submission logic directly into form components, ensuring
consistent behavior and reducing complexity. Updated button components
to explicitly support the "type" attribute for improved accessibility
and functionality.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-02-25 10:37:36 +00:00
bfc92fc00d i18n - translations (#10468)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-25 11:35:02 +01:00
WeikoandGitHub 0220672fa9 Add default role to workspace (#10444)
## Context
Adding a defaultRole to each workspace, this role will be automatically
added when a member joins a workspace via invite link or public link
(seeds work differently though).
Took the occasion to refactor a bit the frontend components, splitting
them in smaller components for more readability.

## Test
<img width="948" alt="Screenshot 2025-02-24 at 14 54 02"
src="https://github.com/user-attachments/assets/13ef1452-d3c9-4385-940c-2ced0f0b05ef"
/>
2025-02-25 11:26:35 +01:00
Jérémy MandGitHub a1eea40cf7 feat: populate relation join column (#10212)
Fix
https://github.com/twentyhq/core-team-issues/issues/241#issue-2793030259
2025-02-25 11:24:05 +01:00
dde70ee3b0 Add fields for admin panel access and workspace version (#10451)
Prepare for better version upgrade system + split admin panel into two
permissions + fix GraphQL generation detection

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-02-24 21:38:41 +01:00
d3fe322fc7 i18n - translations (#10460)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 19:36:31 +01:00
6a73a58ad9 i18n - translations (#10458)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 19:21:26 +01:00
MarieandGitHub ac0fd364e9 [permissions] Add tests on role resolver (#10452) 2025-02-24 18:13:01 +01:00
Charles BochetandGitHub 9046a9ac16 Migrate url tooling to twenty-shared (#10440)
Migrate and unify URL tooling in twenty-shared.

We now have:
- isValidHostname which follows our own business rules
- a zod schema that can be re-used in different context and leverages is
isValidHostname
- isValidUrl on top of the zod schema
- a getAbsoluteURl and getHostname on top of the zod schema

I have added a LOT of tests to cover all the cases I've found

Also fixes: https://github.com/twentyhq/twenty/issues/10147
2025-02-24 18:01:51 +01:00
d4bdae562f i18n - translations (#10450)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 17:43:32 +01:00
Félix MalfaitGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
cbd4d98c85 Data changes to prepare for workspaceMember page (#10439)
Workspace Member will get their own record page in the future.

This PR lays backend changes to prepare for this:
- Settings most fields on WorkspaceMember as system fields
- Renaming workspaceMember/workspaceMemberId to
forWorkspaceMember/forWorkspaceMemberId as it conflicts with the morph
relationship, if we want to be able to add a workspace member as
favorite

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-02-24 17:37:08 +01:00
ccca441ff5 i18n - translations (#10449)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 17:21:21 +01:00
9c7213a1e1 Fix hover on table cells when the command menu is opened (#10446)
This PR allows the table cell hover to be accessible even when the
command menu is opened.
I extracted the hotkeys logic from `RecordTableCellSoftFocusMode` into
`RecordTableCellSoftFocusModeHotkeysSetterEffect`. This component is
mounted conditionally if the hotkey scope is `TableSoftFocus`. By doing
so, the table cell hotkey scopes are not available when the command menu
is opened.

Before


https://github.com/user-attachments/assets/f0925565-f00a-4962-b18d-3c1617f77dd0


After


https://github.com/user-attachments/assets/49ec9195-3110-46d7-abb6-12854a8bb991

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-02-24 17:09:23 +01:00
MarieandGitHub e4f06a7c97 [permissions] Add permission gates on workspaceMember (#10447)
- Adding permission gates on workspaceMember to only allow user with
admin permissions OR users attempting to update or delete themself to
perform write operations on workspaceMember object
- Reverting some changes to treat workflow objects as regular metadata
objects (any user can interact with them)
- (fix) Block updates on soft deleted records
2025-02-24 16:59:28 +01:00
Lucas BordeauandGitHub 970aa4c5a1 Implements new record sort CRUD (#10448)
This PR implements new record sorts CRUD as already done on record
filters, which is based on record sorts state instead of combined view
sorts.

It implements a new useSaveRecordSortsToViewSorts with its underlying
utils, to compute diff between two view sorts array.

The associated unit tests have also been written.

This PR also fixes the bug where the view bar disappeared when deleting
the already saved record sort of a view.
2025-02-24 16:46:00 +01:00
Baptiste DevessierandGitHub dc7a9fc767 Minor design fixes in date picker (#10443)
- Fix the dimensions of the "Clear" button in the date picker
- Improve the contrast of the hover state of the selected day

## Before



https://github.com/user-attachments/assets/f15ee79b-8389-4e05-a7d7-cca23da64b7b



## After



https://github.com/user-attachments/assets/9b391bea-bdc5-479c-8f71-b45ebcef4f66
2025-02-24 15:03:52 +01:00
Thomas TrompetteandGitHub 446924cf24 Migrate workflow actions to executors (#10432)
Actions will now:
- receive the complete input
- get the step they want to execute by themself
- check that the type is the right one
- resolve variables

These all share a common executor interface.

It will allow for actions with a special execution process (forms, loop,
router) to have all required informations.

Main workflow executor should:
- find the right executor to call for current step
- store the output and context from step execution
- call next step index
2025-02-24 14:36:24 +01:00
1f2c5c5fa5 i18n - translations (#10437)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 13:42:39 +01:00
8315d389ca i18n - translations (#10436)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 13:22:32 +01:00
MarieandGitHub 730792c947 [permissions] Move SettingsPermissions from twenty-shared to twenty-server (#10430) 2025-02-24 11:16:53 +00:00
36602eab17 i18n - translations (#10435)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 11:35:06 +01:00
Antoine MoreauxandGitHub 92462b3ae5 feat(settings): review custom domain (#10393)
Introduce improved validation logic for custom domains, including regex
validation with descriptive error messages. Implement asynchronous
domain update functionality with a loading indicator and polling to
check record statuses. Refactor components to streamline functionality
and align with updated state management.

Fix https://github.com/twentyhq/core-team-issues/issues/453
2025-02-24 11:31:45 +01:00
c5c6192434 i18n - translations (#10434)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 11:20:40 +01:00
edbef102c4 i18n - translations (#10433)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 11:06:48 +01:00
Félix MalfaitandGitHub 16869a333c Better cursor rules (#10431)
Move to the new cursor rule folder style and make it more granular
2025-02-24 10:35:28 +01:00
Ana Sofia Marin AlexandreandGitHub 1b64f87d75 Add error management to the Billing Package (#10343)
Solves https://github.com/twentyhq/core-team-issues/issues/403

**TLDR:**
Enhance error management in Billing and when a customer is updated it
updates automatically the Stripecustomer id in the entitlements.


- Add Billing exceptions to filter. 
- Add onUpdate for billing customer and entitlement.
- Remember to run the migrations with is BILLING_ENABLED set to true.

**In order to test (a simple test case)**

- Ensure that the environment variables for Sentry and Billing are set,
ensuring that SENTRY_ENVIRONMENT=staging
- Run the server, the worker and the stripe cli
- Do a database reset with IS_BILLING_ENABLED set to true
- Go to stripe in test mode and update a random price description, this
causes an exception because you are trying to write a price of. a
product that doesn't exists in the database
- You should see an error in Sentry:


![image](https://github.com/user-attachments/assets/7b3c8c7f-6628-4a20-9889-a691e7838d79)
2025-02-24 10:10:06 +01:00
cc0d892de0 i18n - translations (#10429)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 09:33:57 +01:00
097b118053 i18n - translations (#10428)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 09:21:21 +01:00
7445a22c58 i18n - translations (#10427)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 08:08:46 +01:00
76a033f7ac i18n - translations (#10426)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-24 08:01:21 +01:00
ff001d9def Add missing translations (#10414)
As per title, add ~200 missing translations in different places of app.
Most places are now available for translation with AI but still some
aren't available - some enums (like in MenuItemSelectColor.tsx) or
values in complex types (like in
SettingsNonCompositeFieldTypeConfigs.ts) or values where are injected
some variables (like in SettingsDataModelFieldNumberForm.tsx)

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-02-23 23:35:03 +01:00
2162538b8b i18n - translations (#10416)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-23 21:31:33 +01:00
7846764769 i18n - translations (#10415)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-23 21:20:15 +01:00
Félix MalfaitandGitHub df0d23a365 Email translation and snackbar translation (#10395)
This pull request focuses on improving localization by replacing
hardcoded strings with translatable strings using the `Trans` component
from `@lingui/react/macro`. Additionally, it introduces locale support
to several email components. Here are the most important changes:

### Localization Improvements:

* Replaced hardcoded strings with `Trans` components in various email
templates to support localization.
(`packages/twenty-emails/src/emails/clean-suspended-workspace.email.tsx`,
`packages/twenty-emails/src/emails/password-reset-link.email.tsx`,
`packages/twenty-emails/src/emails/password-update-notify.email.tsx`,
`packages/twenty-emails/src/emails/send-email-verification-link.email.tsx`,
`packages/twenty-emails/src/emails/send-invite-link.email.tsx`,
`packages/twenty-emails/src/emails/warn-suspended-workspace.email.tsx`)
[[1]](diffhunk://#diff-ca227a03c0aa66428daff938c743435e8a4dc3ffa960c0952f2697a23e280fdbR6-R25)
[[2]](diffhunk://#diff-ca227a03c0aa66428daff938c743435e8a4dc3ffa960c0952f2697a23e280fdbL42-R45)
[[3]](diffhunk://#diff-523cd37f5680ce418450946f62b7804b6586158efb190ced73920ef0fdf96bc8L1)
[[4]](diffhunk://#diff-523cd37f5680ce418450946f62b7804b6586158efb190ced73920ef0fdf96bc8L23-R23)
[[5]](diffhunk://#diff-cf16aa55d3eeb6be606bbe93de4c83b6f146c49b60d6f512d4b87e49fe14338cL29-R29)
[[6]](diffhunk://#diff-cf16aa55d3eeb6be606bbe93de4c83b6f146c49b60d6f512d4b87e49fe14338cL46-R46)
[[7]](diffhunk://#diff-16b613160f937563ec108176f595d8f275a1d87a5b8245d84df60d775f3efebeL1)
[[8]](diffhunk://#diff-16b613160f937563ec108176f595d8f275a1d87a5b8245d84df60d775f3efebeL22-R22)
[[9]](diffhunk://#diff-0da62e7cc5cfcb32cc25f067fa1d50123047c239af210398f065455ab6700886L1)
[[10]](diffhunk://#diff-0da62e7cc5cfcb32cc25f067fa1d50123047c239af210398f065455ab6700886L42-R41)
[[11]](diffhunk://#diff-0da62e7cc5cfcb32cc25f067fa1d50123047c239af210398f065455ab6700886L57-R56)
[[12]](diffhunk://#diff-483346065c074946a43c18492334bd680422a1d4cb994dc8c3cd39d0208e6016L1-R21)
[[13]](diffhunk://#diff-483346065c074946a43c18492334bd680422a1d4cb994dc8c3cd39d0208e6016L28-R31)
[[14]](diffhunk://#diff-483346065c074946a43c18492334bd680422a1d4cb994dc8c3cd39d0208e6016L53-R55)

### Locale Support:

* Added `locale` prop to email components to dynamically set the locale.
(`packages/twenty-emails/src/emails/clean-suspended-workspace.email.tsx`,
`packages/twenty-emails/src/emails/warn-suspended-workspace.email.tsx`)
[[1]](diffhunk://#diff-ca227a03c0aa66428daff938c743435e8a4dc3ffa960c0952f2697a23e280fdbR6-R25)
[[2]](diffhunk://#diff-483346065c074946a43c18492334bd680422a1d4cb994dc8c3cd39d0208e6016L1-R21)

### SnackBar Messages:

* Replaced hardcoded SnackBar messages with translatable strings using
the `t` function from `@lingui/react/macro`.
(`packages/twenty-front/src/modules/auth/components/VerifyEmailEffect.tsx`,
`packages/twenty-front/src/modules/auth/hooks/useVerifyLogin.ts`,
`packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResendEmailVerificationToken.ts`,
`packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts`,
`packages/twenty-front/src/modules/object-record/record-field/components/LightCopyIconButton.tsx`,
`packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/PhonesFieldDisplay.tsx`)
[[1]](diffhunk://#diff-551f2f94eacd8856d22bab7e63dd3ad693f87e9fa9b289864802ebc387f72b42R7)
[[2]](diffhunk://#diff-551f2f94eacd8856d22bab7e63dd3ad693f87e9fa9b289864802ebc387f72b42L24-R29)
[[3]](diffhunk://#diff-551f2f94eacd8856d22bab7e63dd3ad693f87e9fa9b289864802ebc387f72b42L43-R51)
[[4]](diffhunk://#diff-428199461992a01325159f5fbf826d845f05f3361279eccd3f1ce416e0114845R7-R15)
[[5]](diffhunk://#diff-428199461992a01325159f5fbf826d845f05f3361279eccd3f1ce416e0114845L24-R26)
[[6]](diffhunk://#diff-cde42d6abfed63e52c2bda09d537a6577148d0baf957fde75ceaa8657ed58403R5)
[[7]](diffhunk://#diff-cde42d6abfed63e52c2bda09d537a6577148d0baf957fde75ceaa8657ed58403L16-R17)
[[8]](diffhunk://#diff-cde42d6abfed63e52c2bda09d537a6577148d0baf957fde75ceaa8657ed58403L28-R33)
[[9]](diffhunk://#diff-9332c1988864863f12516c2fb77e814af60bedb37c36ffa094f49afc335d5457R5-R17)
[[10]](diffhunk://#diff-9332c1988864863f12516c2fb77e814af60bedb37c36ffa094f49afc335d5457L27-R33)
[[11]](diffhunk://#diff-9332c1988864863f12516c2fb77e814af60bedb37c36ffa094f49afc335d5457L42-R44)
[[12]](diffhunk://#diff-8d64afa825b47ab71d18e3e284408e2097f5fd2365eae84d9d25d3568c48e49cR7)
[[13]](diffhunk://#diff-8d64afa825b47ab71d18e3e284408e2097f5fd2365eae84d9d25d3568c48e49cR20-R28)
[[14]](diffhunk://#diff-6e4361ded2b5656afaeb1befa8b1d23a45b490a1118550da290e27cdb8ebcdceR6)
[[15]](diffhunk://#diff-6e4361ded2b5656afaeb1befa8b1d23a45b490a1118550da290e27cdb8ebcdceR19-R20)
[[16]](diffhunk://#diff-6e4361ded2b5656afaeb1befa8b1d23a45b490a1118550da290e27cdb8ebcdceL29-R38)
2025-02-23 21:15:41 +01:00
Charles BochetandGitHub 2039986684 Fix error messages on sign up (#10399)
In this PR:
- adding logs to track workspace creation performance
- refactor useIsWorkspaceSuspended to be more generic
- only fetch favorites and views if workspace is Active to avoid error
messages on sign up (workspace is not created yet)
2025-02-21 18:34:40 +01:00
MarieandGitHub 1ed9de2300 [permission] (fix ) use SettingsPermissions and not SettingsFeatures (#10398)
oops
2025-02-21 17:29:01 +01:00
MarieandGitHub ee2810281e [permissions] Add permission gates on workspace-invitations (#10394)
Adding permission gates on all workspace-invitations endpoints:
sendInvitation, resendInvitation, deleteWorkspaceInvitation,
findWorkspaceInvitations (the latter being from my understanding only
used to list the invitations to then re-send them or detee them).

+ tests on Api & webhooks permission gates
2025-02-21 17:26:01 +01:00
MarieandGitHub 50bd91262f [permissions] Rename enum SettingsFeatures --> SettingsPermissions (#10389) 2025-02-21 16:04:30 +00:00
bf92860d19 feat(twenty-server): add trusted domain - backend crud (#10290)
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
2025-02-21 16:02:48 +00:00
Lucas BordeauandGitHub 22203bfd3c Removed sort definitions (#10368)
This PR focuses on complete removal of sort definitions.
2025-02-21 16:59:38 +01:00
Charles BochetandGitHub d747366bf3 Provide a wrapper to execute command on workspace with easier devXP (#10391)
Proposal:
- Add a method in ActiveWorkspaceCommand to loop over workspace safely
(add counter, add try / catch, provide datasource with fresh cache,
destroy datasource => as we do always do it)

Also in this PR:
- make sure we clear all dataSources (and not only the one on metadata
version in RAM)
2025-02-21 16:40:33 +01:00
Raphaël BosiandGitHub 7a3e92fe0b Fix command menu selectable items ordering (#10392)
The order of the selectableItems was not the same as the command groups
so the navigation with arrow keys inside the command menu was broken.

Before:


https://github.com/user-attachments/assets/a3487b58-9c26-4522-9e7b-584d30396a21


After:


https://github.com/user-attachments/assets/bd60263b-b4e2-4d41-bad1-eef9115caec6
2025-02-21 16:05:31 +01:00
Félix MalfaitandGitHub ba51c091f0 Improve i18n CI (#10390) 2025-02-21 15:42:01 +01:00
Raphaël BosiandGitHub f269f8b905 Fix autogrow input whitespace bug (#10388)
Also fixed chip alignment.

Before:


https://github.com/user-attachments/assets/7bfe7c73-676a-4dee-b5df-fed15b663267

After:


https://github.com/user-attachments/assets/9060b3cc-051b-41f7-8149-418ed1c223cb
2025-02-21 15:37:07 +01:00
MarieandGitHub 6fb81e757b [permissions] Add conditional permission gate on billing's checkoutSession (#10387)
Following a conversation with @etiennejouan and @martmull, we are adding
a permission gate on billing resolver's checkoutSession, which should
only be accessible to entitled users or at workspace creation (when
there are no roles yet), when the subscription is incomplete
2025-02-21 14:01:36 +00:00
Raphaël BosiandGitHub 0571eb2cf6 Only display record actions inside the RecordIndexActionMenuDropdown (#10384)
In the action menu dropdown, we only want to display the actions for the
selected records, so we need to filter available actions according to
their type and scope.
Note: the `Search record` action was appearing twice because one is a
standard action and one is a fallback action and both are registered in
the available actions. We don't want to display this action because it
isn't related to the selected records, it is a global action.

Before:
<img width="226" alt="Capture d’écran 2025-02-21 à 12 12 53"
src="https://github.com/user-attachments/assets/0a4f9b8c-4e30-4697-9861-559e76dc288f"
/>

After:
<img width="241" alt="Capture d’écran 2025-02-21 à 12 10 34"
src="https://github.com/user-attachments/assets/0a98c9d5-432d-4018-a4d3-bf3a6d0c49be"
/>
2025-02-21 12:29:41 +01:00
EtienneandGitHub 5863c45d4b cleaning workspace job - fix on soft delete condition (#10380)
Context
If the command runs multiple times, soft deleted workspaces are soft
deleted again (+ email spamming)

Solution
Check for soft deletion before entering soft delete condition
2025-02-21 12:12:08 +01:00
WeikoandGitHub 29d079babc [FE] Improve Read-only field behavior (#10382)
Fixes https://github.com/twentyhq/core-team-issues/issues/235
2025-02-21 12:09:52 +01:00
Raphaël BosiandGitHub ec9587414b Fix open record in setting for command menu v1 (#10383)
- Hide open record in settings for command menu version 1 users
- Create a selector to check which version of the command menu the user
has before returning if the record should be opened in the record page
or in the side panel
2025-02-21 12:06:27 +01:00
Charles BochetandGitHub 311fc402d5 Enhance ActiveWorkspaceCommand to order, limit and startFrom workspaceId (#10378)
I have tested it locally with all combinaisons of params
2025-02-21 10:37:04 +01:00
nitinandGitHub 4720afe3fb health status refactor followup fix (#10379) 2025-02-21 10:32:00 +01:00
Raphaël BosiandGitHub 9f454c565b 410 open in side panel (#10363)
Closes https://github.com/twentyhq/core-team-issues/issues/410

- Added `openRecordIn` column in the `view` entity, which is set to
`SIDE_PANEL` by default
- Created a new option inside the view option dropdown to be able to set
`openRecordIn`
- Updated all record show page openings to reflect the setting behavior
- For `workflow`, `workflowVersion` and `workflowRun` (what I call
workflow objects), we want the default view `openRecordIn` to be set to
`RECORD_PAGE`. When seeding the views for the new workspaces, we set
`openRecordIn` to `RECORD_PAGE` for workflow objects. Since the workflow
objects views `openRecordIn` will be set to the default value
`SIDE_PANEL` for the existing workspaces when the sync metadata runs, I
created a script to run in the 0.43 update to update this value.
- Updated `closeCommandMenu` because of problems introduced by the
animate presence wrapper around the command menu. We now reset the
states at the end of the animation.

Note: We want to be able to open all workflow objects pages in the side
panel, but this requires some refactoring of the workflow module. For
now @Bonapara wanted to allow the possibility to change the
`openRecordIn` setting to `SIDE_PANEL` even for the workflows even if
it's buggy and not ready for the moment. Since this is an experimental
feature, it shouldn't cause too many problems.
2025-02-21 09:27:33 +00:00
e301c7856b Add all object level read-only behavior (#10356)
Fixes https://github.com/twentyhq/core-team-issues/issues/427

---------

Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
2025-02-21 09:59:47 +01:00
nitinandGitHub c46f7848b7 refactor + new account sync metrics + isolating health status inside folder admin-panel > health-status (#10314)
closes https://github.com/twentyhq/core-team-issues/issues/444
https://github.com/twentyhq/core-team-issues/issues/443
https://github.com/twentyhq/core-team-issues/issues/442
2025-02-21 09:48:47 +01:00
Charles Bochet 41bbb4b47f Fix upgrade command 0.42 2025-02-21 00:20:44 +01:00
Weiko d397981d99 Fix billing page routing 2025-02-20 23:49:16 +01:00
Charles BochetandGitHub 4037fb5860 Fix upgrade command 0.42 (#10373) 2025-02-20 20:22:27 +01:00
WeikoandGitHub c0fda41519 Fix N+1 featureFlags (#10371)
## Context
featureFlag query was done for each record returned by the ORM and
transformed in the QueryResultGettersFactory which was causing an N+1
2025-02-20 19:32:30 +01:00
Baptiste DevessierandGitHub 05d00e6604 Store the current flow definition in a state to not depend on a specific workflow version (#10352)
This PR introduces a new Recoil state to store the flow.

A few parts of the application need to know the definition of the
current flow. Previously, we stored the workflow version's ID and
fetched its definition with the `useWorkflowVersion` hook. However, we
must use another strategy to visualize workflow runs. Indeed, we now
store the definition of the workflow in the workflow run output when it
is executed. This is useful for draft versions, which can change between
the moment they were executed and the moment they are visualized.
2025-02-20 17:12:03 +01:00
EtienneandGitHub d96865abc3 fix deleteCurrentWorkspace resolver output (#10365)
Tests are planned in this sprint - Core priority

closes https://github.com/twentyhq/twenty/issues/10347
2025-02-20 17:09:59 +01:00
Paul RastoinandGitHub 68cb94f365 [BUGFIX] Call and await destroyDataSourceForWorkspace to avoid killing poor pod (#10364)
# Motivations
Upgrade migration is not possible atm in production because running over
all workspaces cause cpu raise leading to pod termination
2025-02-20 16:45:21 +01:00
GuillimGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
f12bc5e126 Deduplicate-emails (#10361)
last request from @felix

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-02-20 16:34:27 +01:00
MarieandGitHub b2bbf88e28 [permissions] Place lab + billing behind settings/workspace permission gates (#10354) 2025-02-20 15:31:11 +00:00
Lucas BordeauandGitHub 3c80e2601f Add initialization of new record sorts state and added remove record sorts util (#10358)
This PR adds the same synchronization utils and hooks from view to
record sorts, as we did with view and record filters.

The goal is to apply what's in the view sorts only when needed.

Also added tests for those utils and hooks.

We also add useRemoveRecordSorts.
2025-02-20 16:24:02 +01:00
GuillimandGitHub aeb8806f0d replyto-microsoft-fix (#10360)
During QA on main, I realised there was a tiny issue with this new
button for microsoft
2025-02-20 14:49:56 +00:00
GuillimGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
04a62e9749 Deduplicate-emails (#10355)
Following User request to remove duplicate emails

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-02-20 15:40:49 +01:00
EtienneandGitHub d4aba8d1ff move deletion limit on hard deletion (#10353) 2025-02-20 11:20:58 +01:00
94c0d0f8d2 [BUG] Refactor actor composite type (#10232)
fixes #10200 

The FieldActor Zod schema was updated to correctly handle null context.

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-02-20 11:05:26 +01:00
martmullandGitHub 927b8c717e Poc lambda deployment duration (#10340)
closes https://github.com/twentyhq/core-team-issues/issues/436

## Acheivements
Improve aws lambda deployment time from ~10/15 secs to less that 1 sec

## Done
- migrate with the new code executor architecture for local and lambda
drivers
- support old and new executor architecture to avoid breaking changes
- first run is long, next runs are quick even if code step is updated

## Demo using `lambda` driver
### Before


https://github.com/user-attachments/assets/7f7664b4-658f-4689-8949-ea2c31131252


### After



https://github.com/user-attachments/assets/d486c8e2-f8f8-4dbd-a801-c9901e440b29
2025-02-20 10:49:57 +01:00
Lucas BordeauandGitHub 3f93aba5fc Added parallel code path to set new record sorts state (#10345)
This PR implements a parallel code path to set record sorts without
impacting the actual sort, like we did on record filter.

We add a ViewBarRecordSortEffect which mirrors
ViewBarRecordFilterEffect.

It also adds availableFieldMetadataItemsForSortFamilySelector to replace
sortDefinitions progressively.
2025-02-20 10:40:25 +01:00
316876fcb5 Add files deletion when destroying attachment, workspace or workspaceMember (#10222)
Solution
- update attachment soft delete logic by destroy (seen with Weiko &
Felix)
- add two jobs for file and workspace folder deletion
- add listener to attachment and workspaceMember destroy event -> add
file deletion job
- update logic in deleteWorkspace method -> add wokspace folder deletion
job

closes https://github.com/twentyhq/core-team-issues/issues/147

To go further
- delete old avatar when workspaceMember replaces its avatar
- same with workspace picture

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-02-20 09:35:14 +00:00
Paul RastoinandGitHub 422e4e33c0 [BUGFIX][PROD] RICH_TEXT_V2 command handle {} body col value (#10324)
# Introduction
Encountered in issue in production where we have a lot of records that
has RICH_TEXT_FIELD set to `{}`

```sh
[Nest] 20106  - 02/19/2025, 12:43:08 PM     LOG [MigrateRichTextFieldCommand] Generating markdown for 1 records
[Nest] 20106  - 02/19/2025, 12:43:09 PM     LOG [MigrateRichTextFieldCommand] Error in workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db: TypeError: o is not iterable
```

## Fix
While reading `fieldValue` definition also strictly check if it's `{}` +
checking after JSON parse if it's an iterable to pass to the
`serverBlockNoteEditor` in order to be 100 bullet proof for prod
migration command

## Refactor Dry run
Implemented dry run

## Refactor to Idempotency
Made the script idempotent in order to avoid issues with re-running
commands

## Error repro
- In local checkout on v0.41.5 run `yarn && npx nx reset && npx nx
start`
- Create record manually in db that has a RICH_TEXT body to `{}`
- Checkout to main, `yarn && npx nx reset && npx nx build twenty-server
&& yarn command:prod upgrade-0.42:migrate-rich-text-field -d`
2025-02-20 09:16:58 +00:00
EtienneandGitHub ef9328e2e9 add not found redirection logic if object in url param not exists (#10339)
closes #10150
2025-02-20 09:17:52 +01:00
WeikoandGitHub 65bd1d7775 Role permissions tab should display object permissions from API result (#10344)
## Context
Role all-objects permissions were mocked. Now that the backend returns
it, we are using its values.

<img width="556" alt="Screenshot 2025-02-19 at 18 39 07"
src="https://github.com/user-attachments/assets/9a1c57fd-dc18-43ef-bc2d-be738d1716f5"
/>
2025-02-19 18:58:19 +01:00
WeikoandGitHub 4a2a312efd remove lingui no single variables to translate #2 (#10342) 2025-02-19 18:34:35 +01:00
WeikoandGitHub 202af87be5 Remove no-single-variables-to-translate eslint rule (#10341)
## Context
This rule crashes the FE for some reason, disabling it for now
2025-02-19 18:22:41 +01:00
GuillimandGitHub 78178010f1 following emails logic with intertnal conversaiotn (#10333) 2025-02-19 16:44:09 +00:00
984eeda807 refactor(sso): standardize SSO identity provider query names (#10335)
Updated method, query, and variable names to align with a consistent
naming convention for fetching SSO identity providers. Added
comprehensive unit tests to validate SSO service logic, ensuring better
reliability and maintainability.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-02-19 17:39:31 +01:00
4fd0c28439 i18n - translations (#10334)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-19 17:17:07 +01:00
Lucas BordeauandGitHub 2fc8eaa25b Implement record sort states and record sort context (#10257)
This PR is simple, it creates states for record sort, mirroring record
filter states.

It also implements RecordSortsComponentInstanceContext everywhere
RecordFiltersComponentInstanceContext is used.

This could be later merged into a common RecordContext concept but we
first need to decide how to handle the existing ContextStore and
RecordIndexContext and ideally end up with a unique context (or a
context provider component that wraps in all those contexts at once).

Some bugs are already present on main when trying to delete a sort, they
will be fixed in the next PRs.
2025-02-19 16:51:49 +01:00
2372114f52 i18n - translations (#10332)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-19 16:45:44 +01:00
ad47ab5bcd Display confirmation dialog on connected account deletion (#10323)
![deleteConfirmation](https://github.com/user-attachments/assets/1f0fea78-d02c-4351-b79f-733c08e0e0ec)

Fairly straightforward change, it's my first contribution in this
project so tried to follow the existing patterns.
I couldn't find any component tests or e2e Playwright tests touching
this area to update - happy to write some from scratch if necessary!

Closes #10285

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-02-19 16:29:10 +01:00
Félix MalfaitandGitHub 7bf851b29b I18n ci 9 (#10331) 2025-02-19 16:08:31 +01:00
Félix MalfaitandGitHub 3b8647e368 Improve i18n CI - 8 (#10330) 2025-02-19 15:44:34 +01:00
Baptiste DevessierandGitHub 77caf36d90 Fix workflow run ouput format (#10302)
- Adapt the frontend to use the new output format
2025-02-19 15:10:59 +01:00
GuillimandGitHub ad9af65898 internal-messages-backend-and-frontend (#10291)
fixes https://github.com/twentyhq/twenty/issues/10263
fixes https://github.com/twentyhq/twenty/issues/10262 also
2025-02-19 15:02:10 +01:00
GuillimandGitHub 7636def54d typo (#10327)
typo when doing the fix
2025-02-19 13:52:43 +00:00
f9763ff7ac fixing test mainly by @charlesBochet (#10325)
to enable CI to work

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-02-19 14:13:30 +01:00
Thomas TrompetteandGitHub d628958905 Remove status check when ending workflow (#10299)
Should be possible to end workflow, not matter what the current status
is.
On failure before the workflow was started, this error prevent the
workflow to be marked as failed with the right error message.
2025-02-19 13:58:32 +01:00
nitinandGitHub d5b04fae28 impersonate regression fix (#10306) 2025-02-19 12:05:40 +01:00
MarieandGitHub 861face2a8 [permissions] Enforce object-records permission checks in resolvers (#10304)
Closes https://github.com/twentyhq/core-team-issues/issues/393

- enforcing object-records permission checks in resolvers for now. we
will move the logic to a lower level asap
- add integration tests that will still be useful when we have moved the
logic
- introduce guest seeded role to test limited permissions on
object-records
2025-02-19 11:21:03 +01:00
Lucas BordeauandGitHub 33178fa8b2 Fix sorts on table and board (#10311)
This PR fixes sorts on table and board.

The sorts were not taken into account due to the recent view refactor
that had the side effect of removing the synchronization between
recordSortsState and changing the state.

The fix was to use combined view sorts instead, which are currently the
source of truth for sorts.

Also added a confirmation modal for manual sorting on board.
2025-02-19 10:57:13 +01:00
MarieandGitHub 645065abba Fix queryRunnerArgsFactory for updateMany resolver (#10322)
This was updated a few weeks ago and went unnoticed since 1) integration
tests were broken + 2) we don't have actionnable updateMany mutations in
the product at the moment

It will fix some tests, at least
all-people-resolvers.integration-spec.ts for instance
2025-02-19 10:09:27 +01:00
Antoine MoreauxGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
c0014cfe96 refactor(domain-manager): improve default workspace resolution (#10282)
Refactor logic for determining the default workspace in single-workspace
mode. Added fallback to Apple workspace when multiple workspaces are
found and updated validations to ensure a workspace is always returned.
Simplified handling of scenarios where multi-workspace mode is enabled.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-02-19 09:06:34 +00:00
GuillimandGitHub dca4fc1423 [BUGFIX] Reply button opens google (#10269)
fixes https://github.com/twentyhq/twenty/issues/10242
2025-02-19 09:58:50 +01:00
Félix MalfaitandGitHub 248ec4cd6f i18n CI 7 (#10321) 2025-02-19 09:24:01 +01:00
Félix MalfaitandGitHub df3d3a3c0c I18n ci 6 (#10320) 2025-02-19 08:35:07 +01:00
45566fbdb6 i18n - translations (#10319)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-19 07:21:43 +01:00
84eb5fa46a i18n - translations (#10318)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-19 05:20:53 +01:00
dce7f375bc i18n - translations (#10317)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-19 03:44:15 +01:00
46914652b2 i18n - translations (#10316)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-19 01:32:47 +01:00
8d819a1489 i18n - translations (#10315)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-18 23:20:04 +01:00
Félix MalfaitandGitHub 7f4b5795bf Stop showing lines on translation files (#10313) 2025-02-18 21:21:32 +01:00
9c5b6c844b i18n - translations (#10312)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-18 21:21:01 +01:00
82acafb843 i18n - translations (#10310)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-18 19:21:28 +01:00
GuillimandGitHub 8d8bd4a597 feedback from Thomas (#10297)
as required by @bonapara
here :
https://discord.com/channels/1130383047699738754/1341421200739536978/1341421200739536978
2025-02-18 19:05:24 +01:00
GuillimandGitHub 9cdfa3384f fix the missing createdBy icon for Companies (#10307)
fixes the missing icons for createdBy chips on Companies

Refference fo the bug detection :
https://discord.com/channels/1130383047699738754/1341407800424927232/1341407800424927232


<img width="378" alt="Screenshot 2025-02-18 at 17 37 34"
src="https://github.com/user-attachments/assets/8c35ebf4-b946-4674-9f56-290be7c20c4f"
/>
2025-02-18 19:04:07 +01:00
MarieandGitHub 222f475cc6 [permissions] Fix db reset leads to broken state if env var permission is not true (#10309) 2025-02-18 17:25:54 +00:00
Baptiste DevessierandGitHub 804aab6e0b Bring back raw workflow run output visualizer (#10294)
[My last
PR](https://github.com/twentyhq/twenty/pull/10146#issuecomment-2665863910),
which introduced the workflow run visualizer, made it impossible to
debug an execution as it's not complete yet.

In this PR, I'm bringing back the raw output visualizer and hiding the
flow visualizer as it's been broken by the recent change to the output
format.
2025-02-18 18:14:46 +01:00
ded6767dae 0.42 changelog (#10298)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-02-18 18:11:52 +01:00
EtienneandGitHub af8a167fb2 Update searchVector on new richTextV2 note and task entities + migration command (#10303)
closes https://github.com/twentyhq/core-team-issues/issues/343
closes https://github.com/twentyhq/core-team-issues/issues/340
2025-02-18 18:11:29 +01:00
Raphaël BosiandGitHub aeed1c9f15 406 animate the command menu button (#10305)
Closes https://github.com/twentyhq/core-team-issues/issues/406

- Added animation on the Icon (The dots rotate and transform into an a
cross)
- Introduced a new component `AnimatedButton`. All the button styling
could be extracted to another file so we don't duplicate the code, but
since `AnimatedLightIconButton` duplicates the style from
`LightIconButton`, I did the same here.
- Added an animate presence component on the command menu to have a
smooth transition from `open` to `close` state
- Merged the open and close command menu button
- For all the pages that are not an index page or a record page, we want
the old behavior because there is no button in the page header to open
the command menu

# Before


https://github.com/user-attachments/assets/5ec7d9eb-9d8b-4838-af1b-c04382694342


# After


https://github.com/user-attachments/assets/f700deec-1c52-4afd-b294-f9ee7b9206e9
2025-02-18 18:07:11 +01:00
fef6a7dcee i18n - translations (#10300)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-18 17:21:14 +01:00
WeikoandGitHub 5cf0a71d12 fix server ci integration (#10296)
Now that the CI is running, I'm trying to fix the tests
2025-02-18 17:01:29 +01:00
d6655a2c3b Health monitor status for admin panel (#10186)
# Health Monitoring for Self-Hosted Instances

This PR implements basic health monitoring for self-hosted instances in
the admin panel.

## Service Status Checks
We're adding real-time health checks for:
- Redis Connection
- Database Connection
- Worker Status
- Message Sync Status

## Existing Functionality
We already have message sync and captcha counters that store aggregated
metrics in cache within a configurable time window (default: 5 minutes).

## New Endpoints
1. `/healthz` - Basic server health check for Kubernetes pod monitoring
2. `/healthz/{serviceName}` - Individual service health checks (returns
200 if healthy)
3. `/metricsz/{metricName}` - Time-windowed metrics (message sync,
captcha)
4. GraphQL resolver in admin panel for UI consumption

All endpoints use the same underlying service, with different
presentation layers for infrastructure and UI needs.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-02-18 15:52:19 +01:00
WeikoandGitHub 2fca60436b Add settingsPermission gate on the frontend (#10179)
## Context
With the new permissions system, we now need to hide some items from the
settings navigation and gate some routes so they can't be accessed
directly.
To avoid having to set permission gates in all the component pages, I'm
introducing wrapper at the route level and in the Navigation. This is
not required and is mostly for pages that are strictly mapped to a
single permission, for the rest we still need to use the different hooks
manually but it should avoid a bit of boilerplate for most of the cases.

- currentUserWorkspaceState to access settingsPermissions
- SettingsProtectedRouteWrapper in the router that can take a
settingFeature or a featureFlag as a gate logic, if the currentUser does
not have access to the settingFeature or the featureFlag is not enabled
they will be redirected to the profile page.
- SettingsNavigationItemWrapper & SettingsNavigationSectionWrapper. The
former will check the same logic as SettingsProtectedRouteWrapper and
not display the item if needed. The later will check if all
SettingsNavigationItemWrapper are not visible and hide itself if that's
the case.
- useHasSettingsPermission to get a specific permission state for the
current user
- useSettingsPermissionMap to get a map of all permissions with their
values for the current user
- useFeatureFlagsMap same but for featureFlags
2025-02-18 15:50:23 +01:00
755d1786fc i18n - translations (#10292)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-18 15:20:07 +01:00
WeikoandGitHub 0234c8d707 Fix featureFlag N+1 queries (#10261)
## Context
Regression was introduced 3 weeks ago when we added relations v2.
Because the relation logic is recursive during the life of a request, we
were querying the featureFlags many times.

We are now always using the featureFlag map and it's now available in
the base resolver so we don't need to query it everywhere, preferably
passing it as a parameter instead.

Note: We should introduce a cache for featureFlags in the future, this
is something easy to control and invalidate when needed.
2025-02-18 14:43:42 +01:00
Baptiste DevessierandGitHub ade13826c2 Fix e2e tests (#10289)
- Remove the demo test as I don't think it provides much value
- Re-run a test that was discarded because it failed due to a bug;
modified the test so the bug doesn't make the test fail
- Fixed all workflow tests
2025-02-18 14:30:40 +01:00
fb42046033 Refacto views (#10272)
In this huge (sorry!) PR:
- introducing objectMetadataItem in contextStore instead of
objectMetadataId which is more convenient
- splitting some big hooks into smaller parts to avoid re-renders
- removing Effects to avoid re-renders (especially onViewChange)
- making the view prefetch separate from favorites to avoid re-renders
- making the view prefetch load a state and add selectors on top of it
to avoir re-renders

As a result, the performance is WAY better (I suspect the favorite
implementation to trigger a lot of re-renders unfortunately).
However, we are still facing a random app freeze on view creation. I
could not investigate the root cause. As this seems to be already there
in the precedent release, we can move forward but this seems a urgent
follow up to me ==> EDIT: I've found the root cause after a few ours of
deep dive... an infinite loop in RecordTableNoRecordGroupBodyEffect...

prastoin edit: close https://github.com/twentyhq/twenty/issues/10253

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: prastoin <paul@twenty.com>
2025-02-18 13:51:07 +01:00
Félix MalfaitandGitHub 103dff4bd0 File previewer (#10260)
Add a file previewer for pdf, image, doc, xls

<img width="991" alt="Screenshot 2025-02-17 at 15 03 10"
src="https://github.com/user-attachments/assets/7516c13d-d6cb-4a10-b10f-b422268d223b"
/>
2025-02-18 10:18:59 +01:00
Raphaël BosiandGitHub 270744eca6 Fix command menu context chip display on show page (#10267)
## New Company
### Before:
<img width="500" alt="Capture d’écran 2025-02-17 à 16 47 54"
src="https://github.com/user-attachments/assets/4573450d-14b1-41f0-9b86-24003f489fde"
/>

### After:
<img width="500" alt="Capture d’écran 2025-02-17 à 16 46 24"
src="https://github.com/user-attachments/assets/6622bd75-900a-451b-ac21-c98bddeee32d"
/>


## Task
### Before:
<img width="500" alt="Capture d’écran 2025-02-17 à 16 47 35"
src="https://github.com/user-attachments/assets/04b77faa-b628-4839-ab94-95c8570c1818"
/>

### After:
<img width="501" alt="Capture d’écran 2025-02-17 à 16 47 03"
src="https://github.com/user-attachments/assets/1577dea6-7541-497e-af6e-3a4559f1a913"
/>
2025-02-18 09:52:25 +01:00
905cfedaf0 i18n - translations (#10279)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-18 09:21:08 +01:00
5b38059c4d i18n - translations (#10278)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-18 07:21:23 +01:00
3bebc187fd i18n - translations (#10277)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-18 05:20:50 +01:00
09f5e230ff i18n - translations (#10276)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-18 03:43:55 +01:00
3dbd2ec39e i18n - translations (#10275)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-18 01:32:25 +01:00
41ff6aaf89 i18n - translations (#10274)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-17 23:19:50 +01:00
0cb6f35baf i18n - translations (#10273)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-17 21:20:21 +01:00
df30850e82 i18n - translations (#10271)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-17 19:21:20 +01:00
Paul RastoinandGitHub cd8e240311 [NITPICK] call closeDropdown before openModal import spreadsheet (#10254)
# Introduction
Just a nitpick resulting from
https://github.com/twentyhq/twenty/pull/10205
Avoid any possible race condition between competing event handlers by
closing dropdown before opening modal
2025-02-17 19:14:46 +01:00
MarieandGitHub cb3bd1353a [permissions] Add object records permissions to role entity (#10255)
Closes https://github.com/twentyhq/core-team-issues/issues/388

- Add object records-related permissions to role entity
- Add it to queriable `currentUserWorkspace` (used in FE)
2025-02-17 18:32:39 +01:00
Charles BochetandGitHub 5b4cb4bd2c Simplify last visited (#10259)
In this PR, I'm simplifying the lastVisitedView / Object logic:
- removing fallback logic as it's not useful
- splitting hooks into smaller hooks (to avoir re-renders)
- removing componentState on those states that are global
2025-02-17 17:27:28 +01:00
a526472ddc i18n - translations (#10268)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-17 17:21:23 +01:00
Raphaël BosiandGitHub e6a484bb58 Fix search fallback action (#10256)
The command menu search bar was reset after clicking on the `Search
records` fallback action, but it shouldn't.
This PR:
- Introduces a new type of action: `Fallback` actions
- Reset the search bar only if the action key differs from
'record-search-fallback'
2025-02-17 14:24:42 +00:00
e8a55fd4dc i18n - translations (#10258)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-17 15:20:16 +01:00
Mohammed Abdul Razak WahabandGitHub 91b7d2855e Fix: Ensure First Click on Spreadsheet Import 'Select File' Button Triggers File picker (#10205)
Fixes #10154 

### What was happening:
1. Click "Import" in dropdown -> Dropdown stays open
2. Click "Select file" button -> Two events occur:
   - Button tries to open file dialog
   - Click event bubbles up, reaches dropdown, dropdown tries to close
3. These competing actions cause the first click to fail

### Fix
By closing the dropdown immediately when clicking "Import":

No competing event handlers are active
The dropdown is fully closed before any file selector interactions
The open() function from useDropzone can work without interference
2025-02-17 14:28:28 +01:00
fca5fc364b i18n - translations (#10251)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-17 13:11:35 +01:00
Raphaël BosiandGitHub 7ed142e987 Fix command menu selection (#10248)
- Created a state `hasUserSelectedCommandState` : This state is set to
`true` when the user selects an element in the command menu list. It is
set to false upon redirection or when the command menu is closed.
- Modified `CommandMenuDefaultSelectionEffect` to have the expected
selection behavior for the command menu
2025-02-17 11:02:17 +00:00
14478afa7e i18n - translations (#10250)
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-02-17 12:00:59 +01:00
Félix MalfaitandGitHub ecc388c4bf Skip ref checkout in 18n (#10249) 2025-02-17 11:54:26 +01:00
WeikoandGitHub 2ba9f2d0e5 Fix integration test ci (#10226)
## Context
Integration test ci was not running properly. This PR should fix that

Todo: This was not running for a while, many tests are not succeeding so
I'll try to fix them in this PR now that the action is running properly.
2025-02-17 11:45:44 +01:00
Félix MalfaitandGitHub 896ff1dc2e I18n ci 5 (#10247) 2025-02-17 11:42:32 +01:00
Félix MalfaitandGitHub 13053fd6fa Fix i18n ci (#10246) 2025-02-17 11:30:25 +01:00
5b961cbb7f Tasks assigned to me view (#9567) (#9568)
Issue: https://github.com/twentyhq/core-team-issues/issues/154

View is now added.

TODO: Fix filtering a relation field by 'Me' in Tasks.

---------

Co-authored-by: ad-elias <elias@autodiligence.com>
2025-02-17 10:13:55 +00:00
Raphaël BosiandGitHub 9ef6486b06 Fix autogrowing input glitch (#10224)
- Removed unnecessary resize observer
- Removed unused component
- Fixed autogrowing input glitch

# Before


https://github.com/user-attachments/assets/a7de71d5-bc6e-495f-851c-18df596749dd

# After


https://github.com/user-attachments/assets/63588d0e-1122-43fe-b685-3f3a4ec4114e
2025-02-17 10:10:39 +00:00
Charles BochetandGitHub 0cd6e29bff Leave old body field on task and note object (#10243) 2025-02-17 10:38:20 +01:00
Raphaël BosiandGitHub 9ddaaa803b Display object name plural instead of object (#10228)
Display object name plural instead of 'Object' inside the command menu
section related to the current object.
2025-02-17 10:34:58 +01:00
JarWarrenandGitHub afdd44ff66 Cloudflare name typo (#10239)
Fix typo in Cloudflare
2025-02-17 08:50:15 +01:00
Félix MalfaitandGitHub 1dca3694f7 Delay loading support chat (#10234)
There are a lot of requests being done in parallel when you load the
page, and the support chat is responsible for some of them. I don't
think it's critical to have it upon loading so delaying it by 2 seconds
2025-02-16 12:58:20 +01:00
Paul RastoinandGitHub f795d90702 [WEBSITE] Upgrade guide 0.41.0 -> 0.42.0 (#10231)
# Introduction
Upgrade guide from 0.41.0 to 0.42.0

## Note
@guillim I've been searching for references to the new `env vars` added
in the Microsoft scope to the version to the `setup.mdx` page, unless
I'm mistaken `IS_MICROSOFT_SYNC_ENABLED` seems to be missing ? I'm not
sure if it's required or not and on where to add it within the page,
could you please give it a look 🙏 ?
2025-02-15 09:11:57 +01:00
Paul RastoinandGitHub db1b11742b [0.42][FIX] Seeder activate rich text v2 feature flag (#10229)
as per title
2025-02-14 17:57:32 +00:00
GuillimandGitHub bab529b138 Fixing unhandled exception for microsoft driver (#10223)
Fixing a difficult bug: an unhandled exception for microsoft driver when
one of the many Microsoft BATCH request failed.
2025-02-14 18:50:53 +01:00
Lucas BordeauandGitHub 70e5cdfe83 Remove filter definition (#10227)
This PR removes completely filter definition usage and states,
everything is now derived from fieldMetadataItem.
2025-02-14 17:37:34 +00:00
MarieandGitHub 68db9a7a8c (fix) throw if Access JWT does not have a userWorkspaceId (#10225)
After introducing userWorkspaceId into JWTs, we were wrongfully
executing
```
const userWorkspace = await this.userWorkspaceRepository.findOne({
      where: {
        id: payload.userWorkspaceId,
      },
    });
```

which would return a random userWorkpace if `payload.userWorkspaceId` is
undefined.

All generated JWTs have had a userWorkspaceId for more than a week now,
but in tests we had not modified the accessToken in use, which did not
have a userWorkspaceId, until [this
pr](https://github.com/twentyhq/twenty/pull/10204)
2025-02-14 17:48:06 +01:00
MarieandGitHub 12cc61e096 [permissions] Add workspace + security settings permission gates (#10204)
In this PR

- closing https://github.com/twentyhq/core-team-issues/issues/313
- adding permission gates on workspace settings and security settings
- adding integration tests for each of the protected setting and
security
2025-02-14 17:32:42 +01:00
EtienneandGitHub db526778e3 Update suspended cleaning command (#10195)
closes https://github.com/twentyhq/core-team-issues/issues/382
2025-02-14 15:49:44 +00:00
Paul RastoinandGitHub 968ad3bd31 [NITPICK] From args list to record args RecordPositionFactory (#10215)
# Introduction
Just some nitpicking while debugging a bug that wasn't one
2025-02-14 15:43:09 +01:00
Charles BochetandGitHub c624657b29 update seeding views to seed the new bodyV2 field on workspace creation (#10221)
As per title
2025-02-14 15:28:25 +01:00
Thomas TrompetteandGitHub 017280384a Add flow to run output (#10220)
We need the version trigger and steps to be stored in the output. We
should not rely on the version itself because some run are made on draft
versions. Which means versions could be edited afterwards.
2025-02-14 15:20:27 +01:00
Thomas TrompetteandGitHub 5fe101545d Add side panel in lab (#10183)
<img width="908" alt="Capture d’écran 2025-02-13 à 11 15 22"
src="https://github.com/user-attachments/assets/642b181c-8a20-4935-bb32-97d9d2b0f4c9"
/>
2025-02-14 13:59:27 +00:00
Charles BochetandGitHub 258025a18f Fix upgrade-0-42 command to migrate RICH_TEXT field metadata to RICH_TEXT_V2 (#10218)
While making sure the upgrade-0.42 command was working as expected to
upgrade from 0.41 to 0.42, we've detected that the standardId of the new
bodyV2 (type RICH_TEXT_V2) was not properly set ; standardId was not
correct.

This was forcing the sync-metadata command to try to re-create the field
again.
2025-02-14 13:50:06 +01:00
Félix MalfaitandGitHub a36ba02efe Imrove I18n ci (#10219) 2025-02-14 13:42:16 +01:00
Raphaël BosiandGitHub 80c55b4462 384 update the input of the record show page inside the command menu (#10213)
Created a new component `RecordTitleCell` with an API close to
`RecordInlineCell`.
This new component is an autogrowing input. 
It consumes the `FieldContext`. It uses some hooks and states from
`RecordInlineCell` because I didn't want to duplicate all the logic, but
this logic could be duplicated.

Two issues that I didn't solve in this PR:
- There is a flashing glitch inside the input when typing
- The input of a workflow isn't focused when creating a new one. This is
because of an issue with the `useHotkeyScopeOnMount` hook which is
deprecated but still used in some components. Upon redirection on the
workflow showpage, the hokey scope of the input is overridden by the
hokey scopes of the components which use `useHotkeyScopeOnMount`. I
decided not to open the input for now.

## Command menu record show page

### Single input


https://github.com/user-attachments/assets/50dc235c-8f34-4445-8b04-586125606bd5

### Double input


https://github.com/user-attachments/assets/bdcfd6eb-d25e-4006-a87f-6e615e8a6e7e

## Workflow breadcrumb


https://github.com/user-attachments/assets/ded38dd6-5794-4779-a4ae-b3948567595a

## Record show page

### Single input


https://github.com/user-attachments/assets/8ad7a606-556a-416b-8788-93415f7989e1

### Double input


https://github.com/user-attachments/assets/55aae40b-36ae-40f1-8171-06f1a5db3532
2025-02-14 12:33:18 +00:00
Antoine MoreauxandGitHub a4a085392d fix(auth): Invite with public url and social sso. (#10216)
Correct the URL parameter name from "inviteHash" to
"workspaceInviteHash" and enhance domain URL handling for
multi-workspace environments.
2025-02-14 11:58:01 +00:00
Antoine MoreauxandGitHub 171091e1ef refactor(domain-manager): simplify frontend URL configuration (#10194)
Replaced multiple environment variables for frontend URL construction
with a single FRONTEND_URL variable. This change reduces complexity and
improves clarity by consolidating frontend URL handling into one source.
Updated relevant validations and removed unused variables like
FRONT_PROTOCOL and FRONT_PORT.

Fix #10016
2025-02-14 12:03:07 +01:00
Charles BochetandGitHub 01665ca8ae Fix bug visibility table (#10214) 2025-02-14 11:48:41 +01:00
WeikoandGitHub 934a97df51 Fix custom exceptions not propagating error code (#10210)
## Context
In some CustomException exceptions, we were instantiating a code without
initializing it which was overriding the parent code and it was then
lost when retrieving it in filters.
Removing them to make sure we don't reproduce this pattern
2025-02-14 10:27:47 +01:00
Antoine MoreauxGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
ea07692abb refactor(ui/settings): update styles and improve structure (#10201)
Adjusted border color in SettingsRadioCard for better visual hierarchy.
Simplified grid template layout in SSO form for consistency. Enhanced
HorizontalSeparator by wrapping text in Label for improved accessibility
and styling.

Fix
https://github.com/twentyhq/core-team-issues/issues/385#event-16262349051

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-02-14 10:19:02 +01:00
Antoine MoreauxandGitHub 8bd2f5c3c4 refactor(server): rename PORT to NODE_PORT (#10193)
Updated the environment variable name from PORT to NODE_PORT for more
clarity and alignment with node server conventions. Adjusted references
in configuration and application bootstrap accordingly.

Fix #10017
2025-02-14 10:03:58 +01:00
Félix MalfaitandGitHub f45f7c28f2 Improve i18n ci (#10209) 2025-02-14 09:56:05 +01:00
Félix MalfaitandGitHub 1090fb8fad Remove localization feature flag and improve CI workflow (#10208) 2025-02-14 09:41:35 +01:00
martmullandGitHub f2da915b20 Poc lambda subhosting (#10192)
Add `SERVERLESS_LAMBDA_SUBHOSTING_ROLE` to allow hosting lambdas in
separate aws account

Tested with old configuration and new configuration
2025-02-14 09:18:49 +01:00
Lucas BordeauandGitHub 9cbcf6293b Fix number null value forced to 0 (#10202)
This PR fixes https://github.com/twentyhq/twenty/issues/9980

In here we implement a check to pass null through instead of converting
it to 0.
2025-02-13 18:15:21 +00:00
Baptiste DevessierandGitHub 81b2d5bc89 Add workflow run visualizer (#10146)
- Remove the tabs from the workflowRun show page; now, we only show the
visualizer with the nodes highlighted based on the run's output
- Create the `generateWorkflowRunDiagram` function to go other each step
and assign a `runStatus` to it based on the workflow run's output

Remaining to do:

- Show the output of each step in the right drawer when selecting one
- The labels (e.g. "1 item") are not set on the edges; we might
implement that later


https://github.com/user-attachments/assets/bcf22f4c-db8c-4b02-9a1a-62d688b4c28e

Closes https://github.com/twentyhq/core-team-issues/issues/338
Closes https://github.com/twentyhq/core-team-issues/issues/336
2025-02-13 18:57:54 +01:00
Lucas BordeauandGitHub 1863ef7d10 Fix bug with table aggregate footer when switching object (#10198)
This PR fixes a bug that happens when switching from an object to
another.

It is a temporary fix because it fixes a problem downstream, that
shouldn't happen, but it is tied to the new implementation of the main
context store.

We should find a way to have context store states defined earlier
because it might impact logic that was developed during the previous
months that didn't anticipated the state of current view id taking more
re-renders to be correctly set between page change / table change.
2025-02-13 18:36:36 +01:00
Paul RastoinandGitHub 5963c0f384 [REFACTOR][BUG] Dynamically compute field to write in cache CREATE (#10130)
# Introduction
While importing records encountering missing expected fields when
writting a fragment from apollo cache

## Updates

### 1/ `createdBy` Default value
When inserting in cache in create single or many we will now make
optimistic behavior on the createdBy value

### 2/ `createRecordInCache` dynamically create `recordGrqlFields`
When creating an entry in cache, we will now dynamically generate fields
to be written in the fragment instead of expecting all of them. As by
nature record could be partial

### 3/ Strictly typed `RecordGqlFields`

# Conclusion
closes #9927
2025-02-13 17:43:54 +01:00
GuillimandGitHub 58a62ec6f0 [settings/security] Prevent toggle if only 1 authentication option (#10169)
fix https://github.com/twentyhq/core-team-issues/issues/387
2025-02-13 15:54:37 +00:00
Antoine MoreauxGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
8a425456f2 feat(workspace): add support for custom domain status toggle (#10114)
Introduce isCustomDomainEnabled field in Workspace entity to manage
custom domain activation. Update related services, types, and logic to
validate and toggle the custom domain's status dynamically based on its
current state. This ensures accurate domain configurations are reflected
across the system.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-02-13 15:01:33 +00:00
Charles BochetandGitHub b67e850011 Fix table content missing when navigating to previously browsed page (#10188)
We are using useInView to detect if a row should be rendered or not.

# Behavior issue

When browsing an Index page (let's say People), then navigating to
another one (Company), then back to People, the rows were not displayed
anymore. For some reason the inView value was set to false in this case

# Fix
- I have updated the useInView (react-intersection-observer) package but
it did not fix it
- useInView provides a ref. However, I believe this was conflicting with
the draggableRef; cecause we are in a <table> we cannot add additional
containers and are forced to apply both refs to the <tr> (draggableRef +
inViewRef). I believe this was causing the issue. I have added the
inView ref to an empty <td> within the row which is achieving the same
goal without forcing to combine refs
2025-02-13 13:40:33 +01:00
Charles BochetandGitHub 41dfeb34d1 Add sync metadata to migrate command (#10182)
Add sync-metdata to 0-42 upgrade command
2025-02-13 13:36:29 +01:00
Antoine MoreauxandGitHub 75268c3040 chore: update eslint configuration and clean up index file (#10185)
Removed eslint disable comment from the index file and updated the
eslint ignore list to exclude the serverless driver index file. This
ensures the file is skipped during linting without unnecessary inline
comments.
2025-02-13 11:35:55 +01:00
Lucas BordeauandGitHub 467aa775a8 Fixed context menu bug with new record filters refactor (#10181)
This PR enforces objectMetadataItem to be passed to hook
useColumnDefinitionsFromFieldMetadata, which was never used without an
objectMetadataItem passed in parameters (and probably shouldn't anyway)

Removed the associated test that tested for an undefined
objectMetadataItem parameter in useColumnDefinitionsFromFieldMetadata.

This allows to remove the need to rely on recordIndexContext to retrieve
the filterableFieldMetadataItems.
2025-02-13 11:15:41 +01:00
Antoine MoreauxandGitHub 77d72e9b1c refactor(auth/sso): rename GetAuthorizationUrl for clarity (#10173)
- Rename `GetAuthorizationUrl` to `GetAuthorizationUrlForSSO`
- Move `GetAuthorizationUrlForSSO` from `sso.resolver.ts` to
`auth.resolver.ts` to avoid the permission guard and let users use an
SSO provider.
- Fix an issue in OIDC guard that breaks the connection if you have
multiple SSO providers + add tests for OIDC guard.
2025-02-13 11:15:22 +01:00
WeikoandGitHub d7b84de1b5 Fix CI after SettingsFeature enum update (#10178) 2025-02-13 09:19:36 +00:00
GuillimandGitHub 372ebd14fe withDelete option to TypeOrm (#10161)
fixes https://github.com/twentyhq/core-team-issues/issues/112
2025-02-13 08:50:24 +01:00
Charles Bochet d2a5027549 Fix contextProvider not set preventing login 2025-02-13 01:03:10 +01:00
Charles Bochet eb6757f99c Fix linter on main 2025-02-13 00:58:14 +01:00
ba8797d220 Remove filterDefinition.type usage (#10164)
This PR essentially removes the usage of filterDefinition.type, by
replacing it with fieldMetadataItem.type derivation. Thus allowing to
completely remove filterDefinition later on.

In computeFilterRecordGqlOperationFilter, emptyOperationFilter is now
returned before going into the big switch case. This avoids repeating
the same exact call to getEmptyRecordGqlOperationFilter for each type.

Fixed some tests that need
getJestMetadataAndApolloMocksAndActionMenuWrapper to have record filters
properly working with the new implementation. We'll probably want to
refactor the record context store, record index context, etc.

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-02-13 00:57:28 +01:00
GuillimandGitHub 6e57f02ae3 Feature flag IS_MICROSOFT_SYNC_ENABLED removal (#10170)
Since we have already removed the feature flag from twenty-infra, and
the most part of the application. we can now remove it from these
declaration

fixes https://github.com/twentyhq/core-team-issues/issues/331
2025-02-13 00:52:31 +01:00
Charles BochetandGitHub 466f8c733f Fix latest visited view (#10158)
Fixes https://github.com/twentyhq/twenty/issues/9772

In this PR:
- the root cause of the issue that the ContextStoreViewIdEffect was not
filtering the views on objectMetadata properly
- I'm also deleting some over complex in the latestVisited view logic
- Duplicated logic between ContextStoreViewIdEffect and
ViewBarViewIdEffect, see my comment
2025-02-13 00:52:04 +01:00
8f69352d17 i18n - translations (#10174)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-12 21:20:38 +01:00
0fa03aeb2c i18n - translations (#10172)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-12 19:21:30 +01:00
WeikoandGitHub 193ef432a0 add object settings permission tab (#10159)
## Context
Introducing the "Permissions" tab in the role page

Next: Need to address some css improvements, some components might be
reusable and it still does not fully match the figma (icon missing for
permission types for example). We decided to merge like this for now so
we have something functional and I will update the code in an upcoming
PR

<img width="633" alt="Screenshot 2025-02-12 at 13 54 16"
src="https://github.com/user-attachments/assets/762db5d7-e0a6-4ee1-b299-24de6645bad1"
/>
2025-02-12 18:49:50 +01:00
WeikoandGitHub 61881d6d0f Fix relation creation (#10171)
## Context
We recently introduced a createMany on the field metadata service to
improve seeding performances. This broke relation metadata creation
because it was using a method with the same name that was inherited from
TypeOrmQueryService.
2025-02-12 18:49:26 +01:00
EtienneandGitHub 0609b31c64 add WorkspaceDuplicateCriteria decorator + update duplicate resolver logic (#10128)
## Context

All objects have '...duplicates' resolver but only companies and people
have duplicate criteria (hard coded constant).
Gql schema and resolver should be created only if duplicate criteria
exist.

## Solution

- Add a new @WorkspaceDuplicateCriteria decorator at object level,
defining duplicate criteria for given object.
- Add a new duplicate criteria field in ObjectMetadata table
- Update schema and resolver building logic
- Update front requests for duplicate check (only for object with
criteria defined)



closes https://github.com/twentyhq/twenty/issues/9828
2025-02-12 17:32:59 +01:00
martmullandGitHub b66289c44c replace log by throw (#10167)
as title
2025-02-12 16:31:41 +00:00
fb936cccfb i18n - translations (#10168)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-12 17:11:13 +01:00
martmullandGitHub 39e7a0b61c Remove log to fix serverless function (#10166)
as title
2025-02-12 15:39:00 +00:00
martmullandGitHub c30f416912 Add log (#10162)
add log to fix issue in staging
2025-02-12 15:01:34 +00:00
f98668febf i18n - translations (#10160)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-12 15:20:02 +01:00
GuillimandGitHub f3586d4989 HandleAlias (#10156)
If a user has microsoft aliases, they will be taken into account, in a
similar way as we did for google
2025-02-12 14:22:13 +01:00
2b24bf43a4 i18n - translations (#10157)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-12 13:22:35 +01:00
d2d3b21c90 consistent background color in notes (#10097)
fixes #10086 

![image](https://github.com/user-attachments/assets/c8233d63-9020-457f-9ce1-4c88d6dc2019)

![image](https://github.com/user-attachments/assets/3deeb644-eeb1-4073-9ee8-dd08745282f6)

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-02-12 17:15:26 +05:30
23d2e54439 RICH_TEXT_V2 upgrade command (#10094)
Adds two migration commands:
- copy note and task `body` data to `bodyV2`
- hide `body` view field and swap position with `bodyV2` view field

Related to issue https://github.com/twentyhq/twenty/issues/7613

---------

Co-authored-by: ad-elias <elias@autodiligence.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-02-12 12:26:29 +01:00
Thomas TrompetteandGitHub 33af71ccd3 Create base search record action (#10135)
Create Search Record action without filters neither sorting

<img width="234" alt="Capture d’écran 2025-02-11 à 18 19 25"
src="https://github.com/user-attachments/assets/f18caaa3-476a-436f-9f93-1ad506b24da2"
/>
<img width="262" alt="Capture d’écran 2025-02-11 à 18 19 38"
src="https://github.com/user-attachments/assets/25fcbfcf-57fb-476f-aba9-119be7c3e067"
/>
<img width="236" alt="Capture d’écran 2025-02-11 à 18 19 53"
src="https://github.com/user-attachments/assets/1eb2be25-0727-4797-868c-afdc05040e6a"
/>
2025-02-12 10:29:32 +00:00
9cc6ea501a i18n - translations (#10149)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-12 11:20:24 +01:00
MarieandGitHub e4ae76ac20 [permissions] Add permission gates on API & Webhooks + Security settings (#10133)
Closes https://github.com/twentyhq/core-team-issues/issues/312
Closes https://github.com/twentyhq/core-team-issues/issues/315
2025-02-12 09:40:26 +00:00
08fd227049 i18n - translations (#10145)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-12 09:21:13 +01:00
Félix MalfaitandGitHub 2c0f66dab6 Progress on translations (#10142) 2025-02-12 08:13:29 +01:00
b55a366e2f i18n - translations (#10144)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-12 03:43:55 +01:00
1d4bf2c576 i18n - translations (#10143)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-12 01:32:33 +01:00
Thomas TrompetteandGitHub 959046ee12 Prevent data visualizer from fetching workflows when not enabled (#10116)
- Use existing active objects filter
- Add memoization on active objects. Otherwise the reference will keep
changing into
[SettingsDataModelOverviewEffect.tsx](https://github.com/twentyhq/twenty/compare/tt-fix-data-visualizer?expand=1#diff-737ffd4d69acac03975f83069add9503ef3d0a744b56c9760a2d386f1f50e85c),
which will cause infinite re-renders

With workflows
<img width="694" alt="Capture d’écran 2025-02-10 à 18 28 04"
src="https://github.com/user-attachments/assets/72b1d707-4bf7-4920-a442-92f3e685978f"
/>


No workflows
<img width="694" alt="Capture d’écran 2025-02-10 à 18 28 19"
src="https://github.com/user-attachments/assets/0fe54ed4-6776-4e70-ae6a-8e7a5c59e0a0"
/>
2025-02-11 23:36:11 +01:00
6faf356be2 i18n - translations (#10141)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-11 23:19:57 +01:00
d5b247fa6b i18n - translations (#10140)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-11 21:20:29 +01:00
nitinandGitHub 5f8fc8cad8 minor env tab description font color fix (#10139)
Before: 

<img width="630" alt="Screenshot 2025-02-12 at 00 48 14"
src="https://github.com/user-attachments/assets/0df50cc6-be0c-4286-9883-2a9d23f4f9d9"
/>

After:

<img width="628" alt="Screenshot 2025-02-12 at 00 47 54"
src="https://github.com/user-attachments/assets/cb02c127-fb01-493f-8183-e558449c0193"
/>
2025-02-12 01:03:19 +05:30
88ab7cb553 i18n - translations (#10137)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-11 19:21:13 +01:00
Lucas BordeauandGitHub b757a37d07 Fix bug where aggregate resets record filters (#10136)
This PR fixes a bug where setting an aggregate in the footer of a record
table makes the currentRecordFilters state being overwritten by the
view, which we don't want.
2025-02-11 19:14:18 +01:00
252922b522 Admin panel refactor (#10119)
addressing > 
There are two patterns to avoid:
Creating functions that return JSX like renderThing() -> this was taken
already addressed in https://github.com/twentyhq/twenty/pull/10011
Making a hook that "stores" all the logic of a component - > this PR is
addressing this particular pattern
In essence, handlers should remain in the component and be connected to
their events.
And everything in a handler can be abstracted into its dedicated hook.
For example:
const { myReactiveState } =
useRecoilValue(myReactiveStateComponentState);
const { removeThingFromOtherThing } = useRemoveThingFromOtherThing();

const handleClick = () => {
  if (isDefined(myReactiveState)) {
    removeThingFromOtherThing();
  }
}

Broadly speaking, this is how you can split large components into
several sub-hooks.

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-02-11 17:10:28 +00:00
martmullandGitHub 83bf2d1739 Webhook follow up (#10124)
- fix webhook creation
- fix pointer
2025-02-11 16:30:11 +00:00
5252b22b64 i18n - translations (#10131)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-11 17:21:21 +01:00
GuillimandGitHub a4806b72c7 folders (#10081)
# Folders

Adding the possibility to synchronize messages form more than one
microsoft folder (think "inbox" or "sent items")

It will keep the current way for gmail.

- step 1 : implement a first version of full message & partial message 
- step 2 : implement retro-compatibility which includes the command to
run the migration to backfill microsoft synccursor from messageChannelt
o messageFolders
2025-02-11 16:19:53 +00:00
Félix MalfaitandGitHub b4fd408109 Update i18n-compile.yaml (#10132) 2025-02-11 17:19:42 +01:00
ed4a5b0c15 fix: many fields in an object (#10061)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-02-11 17:15:30 +01:00
Paul RastoinandGitHub 47f262c970 [REFACTOR][BUG] Dynamically compute field to write in cache UPDATE & DELETE (#10079)
# Introduction
At the moment when updating any record cache occurence, we will build a
fragment that will expect all of the object metadata item fields to be
provided.
Which result in the following traces: ( in the video companies aren't
fetch with companyId and other missing fields )


https://github.com/user-attachments/assets/56eab7c1-8f01-45ff-8f5d-78737b788b92

By definition as we're using graphql we might not request every record's
fields each time we wanna consume them.
In this way we will now dynamically compute or expect depending on the
CRUD operation specific fields to be written in the cache, and not all
of them

Tested all optimistic and failure management use cases

## Covering cache
Added coverage only for the `deleteOne` and `deleteMany` hooks, it cover
only the record record cache and not its relations hydratation ( for the
moment )

## Why not closing #9927 
Unless I'm mistaken everything done here have fixed the same logs/traces
issue for updates and deletion but not creation.
Which means we still need to investigate the mass upload from import and
prefillRecord behavior

In a nutshell: went over each `updateRecordFromCache` calls, still need
to do all `createRecordInCache` calls

related to #9927 

## Conlusion
Sorry for the big PR should have ejected into a specific one for the
`MinimalRecord` refactor
Will also continue covering others hooks later in my week as for the
`deleteOne`
As always any suggestions are welcomed !
2025-02-11 16:21:44 +01:00
Félix MalfaitandGitHub 05403ae247 I18n CI (#10129) 2025-02-11 15:58:17 +01:00
0307815e84 i18n - translations (#10126)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-02-11 15:50:25 +01:00
Félix MalfaitandGitHub dabb140b3e Update i18n-push.yaml (#10127) 2025-02-11 15:38:55 +01:00
Félix MalfaitandGitHub cc68deaab1 Translations cleaning / workflows (#10125) 2025-02-11 15:26:21 +01:00
Thomas TrompetteandGitHub 6da9976193 Fix readonly in some steps (#10121)
- readonly in titles
- readonly in code step
- update a few icons
- update event label
2025-02-11 14:22:18 +00:00
WeikoandGitHub 02ced028e5 add role assignment page (#10115)
## Context
This PR introduces the "assignment" tab in the Role edit page, currently
allowing admin users to assign workspace members to specific roles.

Note: For now, a user can only have one role and a modal will warn you
if you try to re-assign a user to a new role.

## Test
<img width="648" alt="Screenshot 2025-02-10 at 17 59 21"
src="https://github.com/user-attachments/assets/dabd7a17-6aca-4d2b-95d8-46182f53e1e8"
/>
<img width="668" alt="Screenshot 2025-02-10 at 17 59 33"
src="https://github.com/user-attachments/assets/802aab7a-db67-4f83-9a44-35773df100f7"
/>
<img width="629" alt="Screenshot 2025-02-10 at 17 59 42"
src="https://github.com/user-attachments/assets/277db061-3f05-4ccd-8a83-7a96d6c1673e"
/>
2025-02-11 14:51:31 +01:00
Baptiste DevessierandGitHub 179d3ae2a4 Add workflow success edge (#10120)
- Refactor the handles: the source handles are now part of the edges as
markerStart
- **As the source handles are now part of the edges, we can delete the
`markLeafNodes` logic; this can be done in another PR**. See
https://github.com/twentyhq/core-team-issues/issues/386
- Create a custom edge component for the default edge
- Create a custom edge component for the success edge; this includes a
label

**The edges can be tested in Storybook. I wrote two stories for the
edges.**

| Default | Success |
|--------|--------|
| ![CleanShot 2025-02-11 at 11 46
09@2x](https://github.com/user-attachments/assets/c7c42328-6502-4c77-bdc9-dea825d4651a)
| ![CleanShot 2025-02-11 at 11 46
16@2x](https://github.com/user-attachments/assets/572204de-299c-4cbc-9900-46744b59c351)
|
2025-02-11 13:01:11 +00:00
4f06b83d7f RICH_TEXT_V2 frontend (#10083)
Adds task and note support for the new `bodyV2` field. (Field metadata
type of `bodyV2` is `RICH_TEXT_V2`.)

Related to issue https://github.com/twentyhq/twenty/issues/7613

Upgrade commands will be in separate PRs.

Fixes https://github.com/twentyhq/twenty/issues/10084

---------

Co-authored-by: ad-elias <elias@autodiligence.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-02-11 10:21:03 +00:00
Antoine MoreauxandGitHub de91a5e39e chore(twenty-server): remove eslint warn + add maxWarning 0 (#10103) 2025-02-11 10:38:43 +01:00
Antoine GCandGitHub 59af303b4c Update docker-compose.mdx (#10118)
Add details on how to configure Twenty when using docker compose
2025-02-11 00:35:16 +01:00
EtienneandGitHub 3eaafbde55 fix log + add 3 indexes on fielMetadata and indexFieldMetadata (#10113) 2025-02-11 00:34:33 +01:00
Thomas TrompetteandGitHub b5736a28fd Fix workflow activation optimistic rendering in Cmd+K (#10109)
Close
https://discord.com/channels/1130383047699738754/1334441759484149793

Using refetch queries was not working for certain use cases.
To find manual active workflows in cmd+k, we use a query with specific
filters that was complicated to refetch.

Finally I will update the cache manually. It was not properly updated
before because the json value of the version trigger was stringified
without spaces. So the entity was not found in apollo cache.
2025-02-10 16:46:36 +00:00
GuillimandGitHub d52c7ffd73 we don't create companies for personal domain emails anylonger (#10110)
and we reomve an usued function
2025-02-10 16:34:35 +00:00
0083f0b939 chore: add translations (#10112)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-02-10 17:16:03 +01:00
5948bc2685 Fix: Get rid of subgroups in admin/env-variables (#10105)
closes https://github.com/twentyhq/core-team-issues/issues/379

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-02-10 16:54:37 +01:00
martmullandGitHub c07f43fcb1 Simplify webhook creation flow (#10107)
## Before


https://github.com/user-attachments/assets/6bc61970-f0e2-4826-bf95-2b0c9fff5113


## After
- no new webhook form anymore
- autosave on update


https://github.com/user-attachments/assets/c7a304ec-76f5-4c2b-ac5e-7a846bd7f23b

@Bonapara ok for you?
2025-02-10 16:48:51 +01:00
Antoine MoreauxandGitHub f733307517 refacto(*): rename hostname to custom domain (#10100) 2025-02-10 15:12:36 +00:00
2a0f937899 Hide inactive objects and fields (#10104)
This PR modifies the data model visualizer to only show objects and
fields which are active.

- Added `isActive` check in the filter within the useEffect of the
`packages/twenty-front/src/modules/settings/data-model/graph-overview/components/SettingsDataModelOverviewEffect.tsx`
to filter out objects that are inactive
- Also added `isActive` check to the `StyledInnerCard` in the file
`packages/twenty-front/src/modules/settings/data-model/graph-overview/components/SettingsDataModelOverviewObject.tsx`
within the filter to filter out fields that have been marked inactive

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-02-10 15:45:09 +01:00
Félix MalfaitandGitHub 62e44de831 Fix issue with pr-PT and pt-BR casing (#10106)
Fix a casing issue affecting MacOS users
2025-02-10 15:25:36 +01:00
Mohammed Abdul Razak WahabandGitHub 6ae80c5f93 hide inactive objects (#10099)
fixes #10090
2025-02-10 15:19:02 +01:00
EtienneandGitHub d4ffd52988 add invalid captcha and messageChannel sync status health monitoring (#10029)
Context : 
We want to implement some counters to monitor server health. First
counters will track : messageChannel sync status during job execution
and invalid captcha.

How : 
Counters are stored in cache and grouped by one-minute windows.
Controllers are created for each metric, aggregating counter over a
five-minutes window.
Endpoints are public and will be queried by Prometheus.

closes https://github.com/twentyhq/core-team-issues/issues/55
2025-02-10 11:24:42 +00:00
Thomas TrompetteandGitHub e70e69cf94 Store output step by step (#10101)
- add context field
- store it with the output after each step execution
2025-02-10 11:27:15 +01:00
martmullandGitHub c908a687fb Fix doc (#10102)
## Why
Lots of sefl-hosted Help thread require to check if the worker is
running

This PR adds a new section to document **How to check the worker is
running?**

![image](https://github.com/user-attachments/assets/b2cbea68-0788-4ca0-9491-1dbc8264c688)
2025-02-10 11:22:47 +01:00
d4b23e020a chore: add translations (#10098)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-02-10 10:29:13 +01:00
Antoine MoreauxandGitHub 1b98f40f17 feat(custom-domain): enable UI for custom domain (#10062) 2025-02-10 08:43:13 +00:00
Félix MalfaitandGitHub f8c653f153 Iterations on i18n CI (#10093) 2025-02-10 08:27:09 +01:00
Félix MalfaitandGitHub f9d7f62ec2 I18n CI and small type improvement (#10092) 2025-02-09 22:17:54 +01:00
Félix MalfaitandGitHub bb24c97f80 Translations - Crowdin, Set workspace member locale on signup, and optimizations (#10091)
More progress on translations:
- Migrate from translations.io to crowdin
- Optimize performance and robustness 
- Set workspaceMember/user locale upon signup
2025-02-09 22:10:41 +01:00
Raphaël BosiandGitHub fd3f01ab80 Focus on the input on command menu page change (#10082)
Add effect component to focus on the input on command menu page change

Before:


https://github.com/user-attachments/assets/a066b5b4-d495-42ca-8c13-8cc456eaaeda

After:


https://github.com/user-attachments/assets/1abd06dc-5714-44b5-80e4-22b55dc341c5
2025-02-07 18:56:30 +01:00
Raphaël BosiandGitHub acae5f910d Reset search bar when clicking on search action (#10076)
Before:


https://github.com/user-attachments/assets/c10f990a-6446-4436-b687-5a0384a461bf


After:


https://github.com/user-attachments/assets/1a6bcb26-9079-4f39-b16a-01cad1ece435
2025-02-07 18:27:54 +01:00
Raphaël BosiandGitHub c16cbc6fd5 Updates in the workflow actions config (#10080)
- Update discard draft icon
- Pin `Remove from favorites` action
- Update workflow action labels to add clarity

Note: this is a small PR, the number of modified lines is due to the
translations
2025-02-07 16:26:25 +00:00
Lucas BordeauandGitHub f74028d9bb Fix soft delete filter hook bug with actions (#10077)
This PR fixes a bug that happened when we open the command menu with
multiple records selected.

The problem was that the new useCheckIsSoftDeleteFilter hook depended on
RecordIndexContext which can be undefined in the command menu context.

Because our direction right now is not completely clear with
RecordIndexContext and ContextStore, in this PR I just removed the
dependency and used objectMetadataItems state directly so that the hook
has no dependency anymore.

Also renamed useFilterableFieldMetadataItems to
useFilterableFieldMetadataItemsInRecordIndexContext.
2025-02-07 17:24:17 +01:00
martmullandGitHub ead626c2ec 360 workflow implement workflow cron triggers frontend 2 (#10051)
as title, closes https://github.com/twentyhq/core-team-issues/issues/360

## Cron Setting behavior

https://github.com/user-attachments/assets/0de3a8b9-d899-4455-a945-20c7541c3053

## Cron running behavior


https://github.com/user-attachments/assets/4c33f167-857c-4fcb-9dbe-0f9b661c9e61
2025-02-07 17:15:03 +01:00
Raphaël BosiandGitHub 988ab9697c Command menu list design updates (#10075)
- Add 2px gap between items
- Update `MenuItemCommand` style to distinguish `hovered` and `selected`
states



https://github.com/user-attachments/assets/d1e29f07-32e7-4ace-9aa1-0ea83712f052
2025-02-07 16:55:24 +01:00
MarieandGitHub a24e411384 [permissions] Add SettingsPermissionGuard on data model and roles features (#10063)
Adding SettingsPermissionsGuard to execute permission check. 

The guard is added directly in resolver, either at resolver level (ex:
roles) or resolver-endpoint level (ex: metadata). this can be challenged
!
2025-02-07 16:48:04 +01:00
MarieandGitHub 859e7c94f9 [permissions] Add settingsPermissions to getCurrentUser (#10054)
For a member with admin role:
<img width="392" alt="Capture d’écran 2025-02-06 à 15 04 07"
src="https://github.com/user-attachments/assets/f47e8611-9577-4d0b-889c-0846acfb0d75"
/>

For a member without admin role:
<img width="394" alt="Capture d’écran 2025-02-06 à 15 04 51"
src="https://github.com/user-attachments/assets/5daacd7a-aa4f-4e06-a886-661bf0830418"
/>

For a member of a workspace that does not have the feature flag enabled:
<img width="390" alt="Capture d’écran 2025-02-06 à 15 05 22"
src="https://github.com/user-attachments/assets/05071bd6-fd2d-4823-b121-8fd11313b833"
/>
2025-02-07 15:33:17 +01:00
Raphaël BosiandGitHub 08b8a0cc60 Do not display back button at the root level of the command menu (#10073)
Do not display back button at the root level of the command menu
2025-02-07 15:33:02 +01:00
Paul RastoinandGitHub aee43b10ad [BUG] Avoid backfilling record position on update one (#10069)
# Introduction
Disabled backfilling position process on single record update

It might be a too global solution ? feels a bit too easy tbh
Please let me know, could not think of other side-effects

close [#9925](https://github.com/twentyhq/twenty/issues/9925)
2025-02-07 14:19:58 +00:00
Félix MalfaitandGitHub 22c9acf993 Remove session store secret (#10074)
Fixes #10033
2025-02-07 14:58:50 +01:00
Raphaël BosiandGitHub 1403c55625 321 command menu context chips compact version (#10072)
Closes https://github.com/twentyhq/core-team-issues/issues/321

- Create component
- Create stories
- Fix bug due to `WorkflowDiagramCanvasEditableEffect`
2025-02-07 13:48:41 +00:00
Antoine MoreauxandGitHub 68183b7c85 feat(): enable custom domain usage (#9911)
# Content
- Introduce the `workspaceUrls` property. It contains two
sub-properties: `customUrl, subdomainUrl`. These endpoints are used to
access the workspace. Even if the `workspaceUrls` is invalid for
multiple reasons, the `subdomainUrl` remains valid.
- Introduce `ResolveField` workspaceEndpoints to avoid unnecessary URL
computation on the frontend part.
- Add a `forceSubdomainUrl` to avoid custom URL using a query parameter
2025-02-07 14:34:26 +01:00
Baptiste DevessierandGitHub 3cc66fe712 Remove the source handle for leaf nodes (#10057)
- Do not render a source handle for the leaf nodes
- Upgrade the `@xyflow/react` library

| Before | After |
|--------|--------|
| ![CleanShot 2025-02-06 at 16 21
08@2x](https://github.com/user-attachments/assets/42b7d11b-76bf-43b9-ba91-8d0c5c2f1792)
| ![CleanShot 2025-02-06 at 16 21
24@2x](https://github.com/user-attachments/assets/ac94aa32-45ad-4462-8db9-0078d6252ea4)
|

## Other options considered

React Flow exposes a hook to get the connections of the current node. I
tried to use this hook – which makes things way simpler – but I couldn't
find a way to make it work in Storybook. I had two options: 1. Set up
React Flow to render the nodes properly, 2. Mock the hook in Storybook.

The first option was hard to achieve as the `<Reactflow />` component
renders a whole flow, and it doesn't play well with the idea of
rendering a single node in a story.

The second option seemed overkill as mocking modules with Storybook is
not straightforward. See
https://storybook.js.org/docs/writing-stories/mocking-data-and-modules/mocking-modules.

I chose to keep the initial version of my code, written before I spot a
function simplifying the code. We can give it a look another time.
2025-02-07 13:17:43 +01:00
Lucas BordeauandGitHub 30e4fdbd06 Refactor duplication of hard coded soft delete filter logic (#10058)
This PR adds a useCheckIsSoftDeleteFilter hook instead of the
undocumented in-place logic to retrieve the soft delete filter.

Also took the opportunity to refactor a recent change of @prastoin with
it.

Split VariantFilterChip into SoftDeleteFilterChip and RecordFilterChip
to separate concerns about this soft delete filtering.
2025-02-07 10:03:13 +00:00
Antoine MoreauxandGitHub e081d8ab5e refactor(auth): simplify continueWithEmail and remove useCallback (#10068)
Refactored continueWithEmail to remove unnecessary dependencies and
simplified the useIsMatchingLocation hook by eliminating useCallback.
This reduces complexity and addresses potential infinite loop issues.
2025-02-07 09:50:23 +00:00
Antoine MoreauxandGitHub aaea49d5f5 fix(auth): prevent infinite redirect (#10065)
Refactored the isMatchingLocation function to use useCallback for
memoization, improving performance by avoiding unnecessary re-creations.
Moved addTrailingSlash and getConstructedPath inside useCallback for
better encapsulation.
2025-02-07 09:27:11 +00:00
Félix MalfaitandGitHub 8df59c085d Lingui working with NODE ENV=production again (#10067)
Lingui now offers an option to disable stripping even in prod mode so we
can bring it back
2025-02-07 10:05:07 +01:00
Félix MalfaitandGitHub 12cec01d80 Update billing to EE (#10060)
Doesn't make sense to have billing under GPL since it's only used for
our cloud and not by self-hosters
2025-02-06 21:10:30 +01:00
Antoine MoreauxandGitHub 005762c240 fix(auth): reset signInUp state when email change (#9990)
When you use a prefilled email the web app checks the db to know if the
user exists. If not the web app enter in signUp mode.
If you changed your email after, the signup mode was not reset.

This PR fixes that.

Fix the error with the message "Invalid sign in up params".
2025-02-06 19:53:31 +01:00
Baptiste DevessierandGitHub c27e930293 Make the e2e ci pass (#10059)
An E2E test always fails due to an identified bug. Since it's best to
keep the E2E CI pass rather than get used to it being broken, I mark the
test as needing to be fixed.

The identified bug:
https://discord.com/channels/1130383047699738754/1337002448602005567
2025-02-06 17:11:39 +01:00
1b150e1da6 Environment variables in admin panel (read only) - front (#10011)
Frontend for https://github.com/twentyhq/core-team-issues/issues/293

POC - https://github.com/twentyhq/twenty/pull/9903

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-02-06 17:08:44 +01:00
Antoine MoreauxandGitHub a85c4f263a fix(settings routing): handle trailing slashes in base paths (#10055)
Adjusted URL construction to properly handle trailing slashes in base
paths, ensuring consistent matching logic. Added logic for setting the
hotkey scope when navigating to the domain settings path.
2025-02-06 16:07:19 +00:00
Antoine MoreauxandGitHub 5b79ac771c fix(auth): update error message in sign-in-up service test (#10056)
Revised exception message for better clarity when a user is not part of
the workspace. Adjusts test expectations to match the updated error
output.
2025-02-06 16:33:41 +01:00
Félix MalfaitandGitHub f40d7e2ba8 Deprecate message queue type (#10040)
Not removing all the code for now, maybe we should 🤔
2025-02-06 16:06:54 +01:00
GuillimandGitHub adc6dd5c07 signup sync with microsoft (#10008)
We want users to be able to sync their emails with microsoft duting
signup

We also want to respect the env ariables that decide if we allow
messaging and calendar providers.
```
MESSAGING_PROVIDER_GMAIL_ENABLED=false
MESSAGING_PROVIDER_MICROSOFT_ENABLED=false
CALENDAR_PROVIDER_GOOGLE_ENABLED=false
CALENDAR_PROVIDER_MICROSOFT_ENABLED=false
```

# design

https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=53729-251492&t=1cwVzB0xFAom9PlM-0
2025-02-06 14:29:21 +01:00
Antoine MoreauxandGitHub d85b8bef4e fix(signin): allow to signin in pending creation workspace (#10052) 2025-02-06 14:05:19 +01:00
WeikoandGitHub e849378726 Add role edit page container (#10037)
## Context

This PR adds a new SettingsRoleEdit page, the existing roles page now
redirects to the role edition page when clicking on it.
For now, we can't edit anything. Next step is to allow role assignment
in the corresponding tab.

<img width="941" alt="Screenshot 2025-02-05 at 17 16 14"
src="https://github.com/user-attachments/assets/ca46de15-6237-4de6-88e1-2384a09d4a27"
/>
2025-02-06 11:27:56 +01:00
MarieandGitHub 8a660d5d3f [permissions] Avoid N+1 on roles (#10041) 2025-02-06 11:27:11 +01:00
Lucas BordeauandGitHub 049a0118aa Record filters - Introduced fieldMetadataItemUsedInDropdown instead of filterDefinitionUsedInDropdown (#10044)
This PR progressively introduces fieldMetadataItemUsedInDropdown instead
of filterDefinitionUsedInDropdown where most easy to replace.

This allows to use `fieldMetadataItemUsedInDropdown.id` instead of
`filterDefinition.fieldMetadataId`, which is one easy dependency to
remove on filter definition.

We still derive filterDefinition instead of fully replacing it, because
it will be easier to remove RecordFilterDefinition usage in a bottom-up
approach instead.

In multiple components of the filter dropdown, we try to replace
filterDefinition by fieldMetadataItem derivation : Icon, label, id,
type, etc.

We also introduce the usage of subFieldNameUsedInDropdown instead of
storing it dynamically on filterDefinition, for handling filtering on
composite sub fields.

The method `formatFieldMetadataItemAsFilterDefinition()` that is used to
derive filterDefinition from fieldMetadataItem is what was being used
originally to create the availableFilterDefinition state. (That is
already removed)

Fixed associated unit tests accordingly.
2025-02-06 11:03:55 +01:00
Baptiste DevessierandGitHub e21cbb2fe2 Simplify the component layers for workflow nodes (#10042)
- Remove the `WorkflowDiagramBaseStepNode` component
- Create the `WorkflowDiagramStepNodeIcon` component to centralize the
icon put in workflow step nodes; that was the main task of the
`WorkflowDiagramBaseStepNode` component and the new
`WorkflowDiagramStepNodeIcon` component made it obsolete
- Update the `WorkflowDiagramStepNodeBase` component to be THE low level
component
2025-02-06 10:42:32 +01:00
Raphaël BosiandGitHub 9838bec004 259 add navigation hotkeys for command menu level 2 (#10043)
Closes https://github.com/twentyhq/core-team-issues/issues/259



https://github.com/user-attachments/assets/abdcb44d-fc13-4597-befc-da99c94c1ef0
2025-02-06 10:07:20 +01:00
Antoine MoreauxandGitHub f6ce27b61e refactor(security): extend SAML prefix handling (#10047)
Revised parsing logic to handle multiple XML prefixes for SAML metadata,
improving flexibility in handling diverse metadata structures. Added
corresponding test case to ensure robustness of the implementation.
2025-02-05 21:46:38 +01:00
Baptiste DevessierandGitHub 700eb2d473 Add the new workflow not executed node type (#10030)
- Added the new workflow `not executed` node type
- Fixed minor style issues
- Created one big catalog for all node variants


![image](https://github.com/user-attachments/assets/5e510d49-c6a2-42a9-9641-057cff481dd9)
2025-02-05 18:43:46 +01:00
Raphaël BosiandGitHub 5528577707 10004 tasks will not delete in people view (#10039)
Fixes #10004 
- Fixed `useListenClickOutside` which wasn't working with
`excludeClassNames` for `comparePixels` mode
- Added `emitCloseEvent` parameter to the `closeRightDrawer` function
because closing the right drawer after deleting a note or a task was
triggering an update after the deletion.

This bug was only for the old version of the command menu.
2025-02-05 18:25:39 +01:00
MarieandGitHub e3182a145d Implement updateRole (#10009)
In this PR, we are implementing the updateRole endpoint with the
following rules

1. A user can only update a member's role if they have the permission (=
the admin role)
2. Admin role can't be unassigned if there are no other admin in the
workspace
3. (For now) as members can only have one role for now, when they are
assigned a new role, they are first unassigned the other role (if any)
4. (For now) removing a member's admin role = leaving the member with no
role = calling updateRole with a null roleId
2025-02-05 18:02:14 +01:00
ef1b492e2f Lab image cover (#10027)
Added Object-Cover to eliminate image distortion. Set all cards to the
large variant to enhance the design.

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-02-05 22:24:23 +05:30
Paul RastoinandGitHub f31ee88fe8 [NITPICK] Avoid duplicated action position index in DefaultActionsConfigV2 (#10031)
# Introduction Nitpick
Action's record has two entries with `position: 0`
Unless I'm mistaken I could not find any place where the `position`
property is consumed
So this is just for sake of the +1 suite
2025-02-05 16:20:57 +01:00
Paul RastoinandGitHub dadee81175 [FEAT] Destroy many Workflow actions (#10028)
# Introduction
Added destroy many records to the `WorkflowActionConfig`

## Repro:
- Filter by deleted workflow
- Select mulitple rows
- Click on destroy

# Pinned action standardization
After discussion with @Bonapara and @bosiraphael we landed on a
standardization of the pinned actions between `DefaultActionsConfigV2`
and `WorkflowActionConfig` which means that now are pinned the `DELETE`
and `DESTROY` for both `single/multiple` modes for both features

Related to https://github.com/twentyhq/twenty/pull/9991
2025-02-05 16:16:13 +01:00
Paul RastoinandGitHub 710366514c BaseObjectRecord and__typename naming updates (#10024)
Folllowing:
https://github.com/twentyhq/twenty/pull/10014/commits/9049c47fd24c55dc7b03227a99587aadf651854d
From PR https://github.com/twentyhq/twenty/pull/10014
2025-02-05 14:51:30 +01:00
Paul RastoinandGitHub c3c800b097 Post #10014 merged nitpicks followup (#10021)
## Only nitpicks
Method signature mutation from several to one record arg
Renamed a variable in map to fit related business logic

#10014 Followup
2025-02-05 14:28:17 +01:00
Raphaël BosiandGitHub 5c24cf4084 320 new command menu navigation bar buttons (#10018)
Closes https://github.com/twentyhq/core-team-issues/issues/320


https://github.com/user-attachments/assets/8082e986-07fd-46fb-9652-ad006aa9dac8
2025-02-05 13:25:29 +00:00
36d148d5e5 Fetch roles in roles settings page (#10001)
## Context
Following the addition of the new Roles page, we are now fetching roles
from the DB thanks to this PR #9955

## Test
<img width="1136" alt="Screenshot 2025-02-04 at 14 46 21"
src="https://github.com/user-attachments/assets/2c55c4d0-ee51-47bb-8113-efce172a9365"
/>

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-02-05 14:22:00 +01:00
Paul RastoinandGitHub 3e05c3743e [BUG][PROD] Fix ViewGroup creation optimistic cache (#10014)
# Introduction
When we create a new `view` from record table that has relation such as
opportunities.
Encountered invariant conditions:

## Unknown fiel `__typename`
`Should never occur, encountered unknown fields __typename in
objectMetadaItem viewGroup`,

### Fixed by ignoring unknown internal fields


## Provided both relation `view` and `viewId`
`Should never provide relation mutation through anything else than the
fieldId e.g companyId and not company, encountered: view`

### Fixed by sending only `viewId` to `createManyRecords` in
`usePersistViewGroupRecords.ts`
2025-02-05 12:22:45 +01:00
martmullandGitHub 736b845c98 335 workflow implement workflow cron triggers backend (#9988)
[Backend side] Add cron triggers to workflow
Closes https://github.com/twentyhq/core-team-issues/issues/335
2025-02-05 11:02:49 +00:00
Lucas BordeauandGitHub 074cc113ac Implement query variables in useCombinedFindManyRecords (#10015)
Implements filtering, ordering and cursor filtering for the hook
useCombinedFindManyRecords, because it was not implemented, which was
misleading because variables could be passed to it.

The difficult part was to make sure that the cursor filtering was
working, both before and after a cursor, because it was only hard coded
for last cursor (equivalent to after).

The duplicate limit parameter in the type RecordGqlOperationVariables
was merged into one limit parameter, because it was making the developer
guess how both could be handled.

This single limit parameter can be used for either : general limit
without cursor, first records from after cursor, last records until
before cursor. Since those cases are exclusive it's better to have only
one limit parameter and have an internal logic handling those cases.

Tests were added on the relevant parts, especially
useCombinedFindManyRecordsQueryVariables which requires its own unit
test to handle this cursor + limit logic.

Record show page pagination was tested to make sure removing the
duplicate limit parameter had no impact.
2025-02-05 11:59:38 +01:00
Paul RastoinandGitHub 28a3f75946 [FEAT] RecordAction destroy many record (#9991)
# Introduction
Added the `RecordAction` destroy multiple record

## Repro
Select multiples `deletedRecords`, you should be able to see the
`Destroy` pinned CTA ( iso short label with the destroy one ), open
control panel and fin new CTA `Permanently delete records`


https://github.com/user-attachments/assets/31ee8738-9d61-4dec-9a1f-41bb6785e018

## TODO
- [ ] Gain granularity within tests to assert the action should be
registered only when filtering by deleted

## Conclusion
Closes https://github.com/twentyhq/core-team-issues/issues/110
2025-02-05 11:33:01 +01:00
Paul RastoinandGitHub aa003f25d9 [CHORE] Twenty emails deps to twenty-shared lockfile update (#10013)
Related to https://github.com/twentyhq/twenty/pull/10010
Forgot to add lockfile
2025-02-05 10:28:11 +01:00
Paul RastoinandGitHub 0a8d75bc07 [FIX] Nx project's scope build dependency management (#10010)
# Introduction
Defined `dependsOn` for each nx project's configuration that has a
dependency to another local package ( ui, shared ).
As follows:
```json
"dependsOn": ["^build"]
``` 
Where the `^` symbol means "all dependencies of this project"

Now on a fresh repo, no built or install deps after install dependencies
you can directly hit `npx nx build PROJECT_NAME`
closes https://github.com/twentyhq/core-team-issues/issues/371

Related what was failing
[run](https://github.com/twentyhq/twenty-infra/actions/runs/13141544809/job/36669643182)
Cancelled before deploy, attested build was correct within the publish
and digest
2025-02-04 18:46:16 +01:00
Baptiste DevessierandGitHub 125a0c3419 Create variants for workflow visualizer nodes (#10006)
Closes https://github.com/twentyhq/core-team-issues/issues/332

- Create the success and failed variants
- Introduce the first responsive color
- Creating stories for the new variants

These components are not yet in use in the source code. If you want to
see them, launch Storybook.

| Success | Failure |
|--------|--------|
| ![CleanShot 2025-02-04 at 16 24
43@2x](https://github.com/user-attachments/assets/0dd68a8f-3914-4b6e-b2d8-43108c2f5e8c)
| ![CleanShot 2025-02-04 at 16 24
59@2x](https://github.com/user-attachments/assets/e4e408d3-29fb-4fbc-a277-044aec9b0f4b)
|
| ![CleanShot 2025-02-04 at 16 24
54@2x](https://github.com/user-attachments/assets/d565ee47-1476-475d-adf6-dadfff9c6719)
| ![CleanShot 2025-02-04 at 16 25
05@2x](https://github.com/user-attachments/assets/9a0aabcc-84d1-41e2-a5a1-7c8cb05f963f)
|
2025-02-04 18:38:38 +01:00
P A C · 先生andGitHub 5be22413c9 [3/n]: Migrate the PUT rest/* and PATCH rest/* to use TwentyORM (#10002)
# This PR

- Is addressing #3644 
- Migrates the PUT and PATCH rest/* endpoints to use twentyORM directly
- Adds integration tests
2025-02-04 17:25:02 +01:00
Thomas TrompetteandGitHub 7dfb9dd77f Fix send email error when empty connected account (#10005)
- Fix send email error when empty connected account
- Add a global util to valid uuid
- Add an util to check if object is workflow related
2025-02-04 17:13:29 +01:00
GuillimandGitHub 0113e40399 Dockerfile update (#10007)
partially fixes https://github.com/twentyhq/core-team-issues/issues/371
2025-02-04 17:11:50 +01:00
0675017b5e Fix:Empty link in record details isn't deleted by default (#9840)
Gives a fix for #9780 . I have added handleDelete inside the submit
function and created a state to manage the empty placeholder
[Screencast from 2025-01-24
01-45-22.webm](https://github.com/user-attachments/assets/87b209a0-7f60-4d72-ad06-c8b955cf6cd2)

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2025-02-04 16:04:34 +01:00
Thomas des FrancsandGitHub c9f45a30d6 0.41 release note -> Introducing Lab Tab (#9989) 2025-02-04 15:50:06 +01:00
cc14c7e0d0 Update cleaning suspended workspace job (#9999)
- split workspace metadata deletion into multiple queries
- delete all subscriptions when workspace is deleted

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-02-04 15:49:22 +01:00
Raphaël BosiandGitHub dfc1bb7c29 361 create a navigation stack for the command menu (#9995)
Closes https://github.com/twentyhq/core-team-issues/issues/361

- Created navigation stack state
- Created navigation functions inside the `useCommandMenu` hook
- Added tests
2025-02-04 15:47:43 +01:00
Lucas BordeauandGitHub b2e4d0d04d Fixed cannot close record table cell header filter (#9998)
With the introduction of dropdown focus id, the table header cell filter
dropdown wasn't taken into account by this new system that prevents
multiple dropdowns from conflicting.

The fix was to just add a dropdown focus id when opening the dropdown.

There was also a bug with the hotkey scope which was staying on table
hotkey scope, thus triggering table hotkeys, this PR also fixes that.
2025-02-04 15:41:26 +01:00
Thomas TrompetteandGitHub 2368dad9ad Enable workflow in lab (#9997)
Refresh of `objectmetadataitems` was not happening fast enough. Page was
breaking when enabling the feature flag. Instead of not storing worklow
objects in state, we will use the feature flag to block on read. This
way we avoid race conditions

<img width="1511" alt="Capture d’écran 2025-02-04 à 14 11 56"
src="https://github.com/user-attachments/assets/912cc59a-f422-48ab-84b7-7fdd7bbc35c1"
/>
2025-02-04 15:25:04 +01:00
GuillimandGitHub 53b51c8bba Fix-issue-370 (#9996)
Fixes the issue from introduced when alowing gmail and outlook.

fixes https://github.com/twentyhq/core-team-issues/issues/370
2025-02-04 14:20:35 +00:00
Félix MalfaitandGitHub b9b7700155 Improve translations with gpt (#10000)
Running GPT4 on all files to improve the quality of translations
2025-02-04 14:56:55 +01:00
P A C · 先生andGitHub a5e27aa751 [2/n]: Rest API -> TwentyORM migration POST rest/* (#9986)
# This PR

- Addressing #3644 
- Migrates the `POST rest/*` endpoint to use TwentyORM directly
- Adds integration tests
- Refactors common login in the v2 service file
- Refactors test utility files
2025-02-04 12:36:52 +01:00
WeikoandGitHub 40f43a4076 add createMany fields to fieldMetadataService to batch field creation (#9957)
## Context
Not exposed in the API yet, this new method allows us to reduce the time
to create multiple fields at once, mostly during seeding. This allows us
to batch transactions and avoid recomputing the cache everytime.

With this change, we recompute the cache 7 times instead of 35 during
seeding. We could do the same for objects.
2025-02-04 11:18:57 +01:00
nitinandGitHub 0e5c2cff42 optimize feature flag query in Lab (#9987)
addressing
https://github.com/twentyhq/twenty/pull/9981/files/ee4a321c71704216f2dee990db2f94d849e9d686#r1939711930
2025-02-04 09:45:14 +01:00
nitinandGitHub edeaecad05 hotfix for lab (#9981)
Issue:
When attempting to toggle a public feature flag that didn't exist in the
workspace's feature flags array, the LabService threw a
FeatureFlagException with code FEATURE_FLAG_NOT_FOUND. This prevented
users from enabling public feature flags for the first time in their
workspace.
Fix:
Modified the LabService to handle non-existent public feature flags by
creating them instead of throwing an error. When the flag doesn't exist,
the service now saves a new feature flag record with the provided key
and value, associates it with the workspace, and returns the newly
created flag.
2025-02-03 22:25:46 +01:00
Félix MalfaitandGitHub 7a0f2f8c0a Add logged out translations (#9983)
Add translation for logged in / sub pages
2025-02-03 22:00:54 +01:00
MarieandGitHub 351e768038 [Permissions] Implement getRoles (#9955)
In this PR

- introducing roles module to separate roles logic (assign a Role, get a
workspace's roles etc.) from permission logic (check if a user has a
permission)
- Introduces getRoles endpoint to fetch a workspace's roles
- introduces the first permission check: getRoles in only accessible to
users with permission on ROLE setting. Implemented
validatesUserHasWorkspaceSettingPermissionOrThrow
2025-02-03 19:14:18 +01:00
GuillimandGitHub caee5b1f89 allow people to connect their mailbox (#9982)
allow people to connect their mailbox independantly from the auth
possibilities
2025-02-03 17:53:19 +00:00
Antoine MoreauxandGitHub 47487f5d1c feat(sso): fix saml + allow to use public invite with sso + fix invite page with multiple sso provider (#9963)
- Fix SAML issue
- Fix the wrong state on the Invite page when multiple SSO provider
exists
- Allow to signup with SSO and public invite link
- For OIDC, use the property upn to guess email for Microsoft and enable
oidc with a specific context in azure
- Improve error in OIDC flow when email not found
2025-02-03 17:48:25 +00:00
Chandragupt GosaviandGitHub 253a3eb83f fix: prevent updating isCustom on object and field metadata (#9968)
This PR prevents updating isCustom on object and field metadata.

Example graphql mutation now cannot be used to modify existing field's
isCustom property as expected.

```
mutation UpdateOneFieldMetadataItem(
    $idToUpdate: UUID!
    $updatePayload: UpdateFieldInput!
  ) {
    updateOneField(input: { id: $idToUpdate, update: $updatePayload }) {
      id
     isCustom
    }
  }
```

Example payload is not allowed now and it will return error in response.

```
{
  "idToUpdate": "80c6c8df-f719-42d2-985a-353468a3ed00",
  "updatePayload": {
    "isCustom": true
  }
}
```

fixes- #6581
2025-02-03 17:30:08 +01:00
Lucas BordeauandGitHub b29ff9b4e6 Removed availableFilterDefinitions as a state but kept its usage as a derived state of objectMetadataItems (#9972)
The global record filter refactor will derive everything at runtime from
objectMetadataItemsState, thus removing the need for a filter definition
concept.

Here we don't yet remove available filter definition usage but we
replace the available filter definitions states, we now derive the same
value from objectMetadataItemsState.

This will allow us to progressively remove the usage of the concept of
filter definition, at the end it will then be easy to just remove from
the codebase because nothing will use it anymore.
2025-02-03 17:29:57 +01:00
c8af90dc01 Environment variables in admin panel (read only) - backend (#9943)
Backend for https://github.com/twentyhq/core-team-issues/issues/293

POC - https://github.com/twentyhq/twenty/pull/9903

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-02-03 21:05:43 +05:30
Raphaël BosiandGitHub 49e4484937 324 add search records as a fallback action in case of no results (#9976)
Closes https://github.com/twentyhq/core-team-issues/issues/324

Fixed typos: 'No results' is used when multiple results are expected and
'No result' is used when only one result is expected.


https://github.com/user-attachments/assets/e3655ced-465a-44b1-92af-63878b9d8a94
2025-02-03 15:54:24 +01:00
Antoine MoreauxandGitHub eb0762dc58 refactor(auth): update SSO provider selection logic (#9975)
Refined the logic to check for SSO providers before setting the sign-in
step. Consolidated conditions to ensure clarity and avoid redundant
checks.
2025-02-03 14:12:56 +00:00
GuillimandGitHub 5a13d5ae29 Sort active workspaces (#9973)
Adding an order when fetching active workspaces so that when we run
command we can better understand the workspaces from the logs. Also, if
the command fails, we know we could start from a specific createdAt
later on
2025-02-03 13:33:00 +01:00
GuillimandGitHub 9d24bfb747 preparing version 0.42-caanry (#9938) 2025-02-03 10:53:05 +01:00
39e7f6cec3 setup localization for twenty-emails (#9806)
One of the steps to address #8128 

How to test:
Please change the locale in the settings and click on change password
button. A password reset email in the preferred locale will be sent.


![image](https://github.com/user-attachments/assets/2b0c2f81-5c4d-4e49-b021-8ee76e7872f2)

![image](https://github.com/user-attachments/assets/0453e321-e5aa-42ea-beca-86e2e97dbee2)

Todo:
- Remove the hardcoded locales for invitation, warn suspended workspace
email, clean suspended workspace emails
- Need to test invitation, email verification, warn suspended workspace
email, clean suspended workspace emails
- The duration variable `5 minutes` is always in english. Do we need to
do something about that? It does seems odd in case of chinese
translations.

Notes:
- Only tested the password reset , password update notify templates.
- Cant test email verification due to error during sign up `Internal
server error: New workspace setup is disabled`

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-02-02 21:01:34 +01:00
4b9414a002 Add Japanese language (#9956)
I added Japanese translation.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-02-01 12:49:18 +01:00
GuillimandGitHub c9ca87f49f Add instructions to upgrade to 0.41 in docs (#9964)
As per title

Also:
- making sure to destroy datasource in upgrade commands to lower memory
usage
2025-02-01 12:11:27 +01:00
Paul RastoinandGitHub 7fd89678b7 [CHORE] Avoid isDefined duplicated reference, move it to twenty-shared (#9967)
# Introduction
Avoid having multiple `isDefined` definition across our pacakges
Also avoid importing `isDefined` from `twenty-ui` which exposes a huge
barrel for a such little util function

## In a nutshell
Removed own `isDefined.ts` definition from `twenty-ui` `twenty-front`
and `twenty-server` to move it to `twenty-shared`.
Updated imports for each packages, and added explicit dependencies to
`twenty-shared` if not already in place

Related PR https://github.com/twentyhq/twenty/pull/9941
2025-02-01 12:10:10 +01:00
Raphaël BosiandGitHub d9b86475d3 323 add object name inside the search (#9962)
Closes https://github.com/twentyhq/core-team-issues/issues/323

Before:
<img width="495" alt="Capture d’écran 2025-01-31 à 18 11 56"
src="https://github.com/user-attachments/assets/dd1d3ac1-6c97-4398-b233-d323eeacdbb9"
/>

After:
<img width="500" alt="Capture d’écran 2025-01-31 à 18 09 58"
src="https://github.com/user-attachments/assets/68d23990-2d0b-437d-ad2e-a686cdb320e1"
/>
2025-02-01 08:18:48 +01:00
MarieandGitHub 58aa86cc0c [Permissions] Add userWorkspaceId to JWT token (#9954)
This information will be used to fetch a user's role and check their
permissions
2025-01-31 18:15:29 +01:00
f00e7cc670 Make variable nodes undeletable in a readonly tiptap editor (#9950)
In this PR:

- Refactor how we initialize the content of the tiptap editor; providing
a default value for the editor makes node appear instantly
- Hide the button to remove a variable tag when the editor is readonly

| Editable | Readonly |
|--------|--------|
| ![CleanShot 2025-01-31 at 15 04
25@2x](https://github.com/user-attachments/assets/54b90c80-aab1-4ff0-93f9-a0550f031d82)
| ![CleanShot 2025-01-31 at 15 05
51@2x](https://github.com/user-attachments/assets/0480a7dc-9d7a-4e3f-b1a5-0550548622c6)
|

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-01-31 18:00:40 +01:00
Charles BochetandGitHub fa3ea4bb68 Fix composite type update migration builder (#9959) 2025-01-31 16:34:42 +00:00
martmullandGitHub ae62789159 Serverless function follow up (#9924)
- remove asynchronous serverless function build
- build serverless function synchronously instead on activate workflow
or execute
- add a loader on workflow code step test tab test button
- add a new `ServerlessFunctionSyncStatus` `BUILDING`
- add a new route to build a serverless function draft version 
- delay artificially execution to avoid UI flashing



https://github.com/user-attachments/assets/8d958d9a-ef41-4261-999e-6ea374191e33
2025-01-31 17:12:42 +01:00
Antoine MoreauxandGitHub f47c0d45e3 fix(icon): update Microsoft Outlook icon import (#9953)
Replaced the incorrect Microsoft icon with the correct Microsoft Outlook
icon. This ensures the displayed icon matches the intended usage and
improves consistency.
2025-01-31 16:24:01 +01:00
66296a4787 [1/n]: Migrate deleteOne Rest API to use TwentyORM directly (#9784)
# This PR

- Addressing #3644 
- Migrates the `DELETE /rest/*` endpoint to use TwentyORM
- Factorizes common middleware logic into a common module

---------

Co-authored-by: martmull <martmull@hotmail.fr>
2025-01-31 16:12:20 +01:00
Félix MalfaitandGitHub d6788348ba More progress on translations (#9951) 2025-01-31 15:49:37 +01:00
Antoine MoreauxandGitHub b801307d92 refacto(auth): improve type + remove complexity (#9949)
- Improve type
- Remove unnecessary code
- Fix the issue that prevents the usage of invitations when a user signs
in with social media.
- Add Microsoft icon for sso list page
2025-01-31 15:39:45 +01:00
Charles BochetandGitHub 591301f7ce Remove demo from readme as users can create free trial on production (#9952)
We have recently introduced the possibility to sign up on Twenty cloud
without having to input a credit card which makes the demo.twenty.com
useless. Deprecating it!
2025-01-31 15:36:30 +01:00
2ab88a6cfe fix slow search resolver without searchTerm input (#9947)
### Issue
Empty searchTerm search resolver 
```
      .orderBy(
        `ts_rank_cd("${SEARCH_VECTOR_FIELD.name}", to_tsquery(:searchTerms))`,
        'DESC',
      )
      .addOrderBy(
        `ts_rank("${SEARCH_VECTOR_FIELD.name}", to_tsquery(:searchTermsOr))`,
        'DESC',
      )
```
builds the following SQL query:
```
ORDER BY
	ts_rank_cd("searchVector", to_tsquery('')) DESC, ts_rank("searchVector", to_tsquery('')) DESC
```

I haven't been able to find doc on this issue, but after testing,
`ts_rank_cd("searchVector", to_tsquery(''))` slows down/freezes my local
db.
As well, ordering by ts_rank is useless without a searchTerm.

### Result
In local, with the imported 300k rows appEvent custom object,
'combinedSearchRecords' gql request with empty searchTerm reduces exec
time from 3s to 300ms.

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-31 14:26:19 +01:00
Baptiste DevessierandGitHub d946cdcba4 Disable the fields of all CRUD workflow actions on readonly mode (#9939)
Fixes
https://discord.com/channels/1130383047699738754/1333822806504247467

In this PR:

- Make the workflow step title input readonly when the visualizer is in
readonly mode
- Make all the fields of the Update Record and Delete Record readonly
when the visualizer is in readonly mode
- Create stories for the Create Record, Updated Record and Delete Record
actions; I'm checking for the default mode and several variants of the
disabled mode
- Set up mocks for the workflows and use them in msw handlers

Follow up:

- We use `readonly` and `disabled` alternatively; these are two
different states when talking about a HTML `<input />` element. I think
we should settle on a single word.
- Refactor the `<WorkflowSingleRecordPicker />` component to behave as
other selects

| Current component | Should look like |
|--------|--------|
| ![CleanShot 2025-01-30 at 17 30
29@2x](https://github.com/user-attachments/assets/104f2e7f-d758-4121-987a-f62f2e138df2)
| ![CleanShot 2025-01-30 at 17 30
49@2x](https://github.com/user-attachments/assets/e74b318e-a41a-40b9-9db8-bcc8015a1d67)
|
2025-01-31 12:31:57 +01:00
Thomas TrompetteandGitHub 4e32fd1c98 Fix refetch on workflow status update (#9946)
Refetch was not set-up properly on activation/deactivation
2025-01-31 11:19:53 +01:00
WeikoandGitHub 502891a430 Add settings roles page (#9940)
## Context
This PR introduces a new Roles settings page, accessible through the
settings menu when the isPermissionsEnabled feature flag is enabled. The
page provides a foundation for managing user roles within the workspace.

This is not fetching the roles from the BE for now and will be done in a
followup PR.
2025-01-30 17:24:02 +00:00
e7ed9530ca Implement parallel code path for fieldMetadataItem instead of filterDefinition (#9931)
This PR doesn't remove or change the current behavior of the filter
definition used in filter dropdown, but adds a parallel code path where
we set the field metadata item used in filter dropdown, which is enough
to replace the filter definition.

The goal at the end is to compute dynamically the equivalent of filter
definition where needed, by deriving from objectMetadataItems global
state + fieldMetadataItemId used in dropdown, that way we don't create
any other source of truth for the concept of filter definition and
everything is easier to work with, especially with advanced filters.

The general spirit is that it's always better to derive everywhere from
a unique state as much as possible, and only create the equivalent of
selectors where needed that will only take the relevant chunk of state
for the small zone of the code operating some reading/writing.

- Added utils and hooks to get a FieldMetadataItem more easily
- Removed some properties from RecordFilterDefinition (the easiest to
remove) and replaced them with a dynamic logic, deriving what's needed
where it is needed
- Added a new fieldMetadataItemIdUsedInDropdownComponentState that is
set in parallel of filterDefinitionUsedInDropdown (to prepare the
removal of filter definition used in dropdown)
- Fixed some stories

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-01-30 16:48:38 +00:00
Ana Sofia Marin AlexandreandGitHub d777f62651 clean code and normalize billing eventNames (#9928)
Solves :
https://github.com/twentyhq/private-issues/issues/251

**TLDR:**

Clean Billing Code using feedback of the previous PR (#9865). Normalized
the metadata and names of the products, prices, and meters in Stripe so
that they can be accessed in stripe's test mode and live mode.

**In order to test:**

1. Have the environment variable IS_BILLING_ENABLED set to true and add
the other required environment variables for Billing to work
2. Do a database reset (to ensure that the new feature flag is properly
added and that the billing tables are created)
3. Run the command: npx nx run twenty-server:command
billing:sync-plans-data (if you don't do that the products and prices
will not be present in the database)
4. Run the server , the frontend, the worker, and the stripe listen
command (stripe listen --forward-to
http://localhost:3000/billing/webhooks)
5. Buy a subscription for the Acme workspace
6. Create a workflow and run it
7. After the run has been finished check in sprite the quantity of
events in the CreditMeter, you should see that there is a new occurence
with value one.
2025-01-30 17:39:02 +01:00
625466f38d Fix optimistic effect for implicit and filters (#9935)
The optimistic effect for record creations and updates wasn't working
properly for `and filters` without explicit `and`.
The problem was located inside `isRecordMatchingFilter` which didn't
consider implicit `and filters` as `and filters`. This caused queries to
be updated by the optimistic effect even if they didn't match the root
query filter.

I also removed `fetchPolicy: 'cache-and-network'` from a query. This was
a temporary fix for this issue.

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-01-30 17:31:02 +01:00
Thomas TrompetteandGitHub 460253ab98 Use refetch instead of cache modify when activating/deactivating a workflow (#9937)
Workflow version statuses are too complex to handle in cache. You always
need to:
- modify entity in cache
- modify queries in cache
- do the same for all other version statuses that should also be updated

This complex behavior leads to bugs because of a cache wrongly updated.

Let's simply do a refetch versions on status update.
2025-01-30 17:30:50 +01:00
Thomas TrompetteandGitHub afed36ef5b Remove before-after + fix header label (#9932)
- Fix header label on step

Before
<img width="224" alt="Capture d’écran 2025-01-30 à 12 11 27"
src="https://github.com/user-attachments/assets/e04e2d83-2414-4a92-a307-159e1ca16c64"
/> <img width="224" alt="Capture d’écran 2025-01-30 à 13 27 40"
src="https://github.com/user-attachments/assets/72e2c567-7ee0-43ff-9ae2-898e46d677c1"
/>

After
<img width="224" alt="Capture d’écran 2025-01-30 à 13 29 00"
src="https://github.com/user-attachments/assets/e7e458ab-458d-4e84-98a2-63596f44e0e7"
/> <img width="224" alt="Capture d’écran 2025-01-30 à 13 29 25"
src="https://github.com/user-attachments/assets/df1b0cbd-c8f2-44f6-b2f6-944e5ec8e14f"
/>



- Remove before - after when there is only one of them
2025-01-30 16:19:47 +00:00
GuillimandGitHub a5273732b3 Icon microsoft (#9907)
Implementing the Outlook icon for CreatedBy, only for emails.

Not in this PR original scope : The similar feature for calendar created
records. Since it was straightforward, I added it to the scope of this
PR.

Fix https://github.com/twentyhq/core-team-issues/issues/252
2025-01-30 16:09:42 +00:00
Félix MalfaitGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
9ec524213c Localization of actions (#9934)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-01-30 17:00:35 +01:00
Paul RastoinandGitHub 385bf591cf [FIX] Storybook race condition (#9936)
Flaky test can be found
[here](https://github.com/twentyhq/twenty/actions/runs/13052735697/job/36416799488)
Action should be outside the waitFor callback

## Context
It seems to occurs since the Charles tooltip perf refactor
https://github.com/twentyhq/twenty/commit/ae4bf8d9298ca77cc45f6f4b0c25b66b51ad834f
Maybe the tests render being faster it changed order of execution ? idk
still interesting
2025-01-30 16:57:53 +01:00
GuillimandGitHub 4084f2114e creating the messagefolder entity (#9933)
first step for the
https://github.com/twentyhq/core-team-issues/issues/149 issue
2025-01-30 16:47:22 +01:00
MarieandGitHub 3a78e6f889 Introduce userWorkspaceRoles and Roles + seed standard admin role at workspace creation (#9929)
Closes https://github.com/twentyhq/core-team-issues/issues/303
2025-01-30 15:05:33 +00:00
Antoine MoreauxandGitHub e895aa27e6 feat(custom-domains): allow to register a custom domain (without UI) (#9879)
# In this PR
- Allow to register a custom domain
- Refacto subdomain generation

# In other PRs
- Add UI to deal with a custom domain
- Add logic to work with custom domain
2025-01-30 13:51:16 +01:00
Charles BochetandGitHub ae4bf8d929 Fix tooltip performances (#9930)
Rendering the Tooltip is creating performance issues on the whole app.

In this PR we only render the tooltip on hover
2025-01-30 12:37:56 +01:00
GuillimandGitHub a039987549 quick fix for microsoft : removing feature flag for microsoft (#9926)
after customer complain, we found a little bug. removing feature flag
for microsoft sync fixes the issue.
2025-01-30 11:46:16 +01:00
9635fe9222 [BUG] Handle optimistic cache deletion operation (#9914)
# Introduction
This PR is highly related to previous optimistic cache refactor:
https://github.com/twentyhq/twenty/pull/9881
Here we've added some logic within the
`triggerUpdateRelationsOptimisticEffect` which will now run if given
recordInput `deletedAt` field is defined.

If deletion, we will iterate over all the fields searching for
`RELATION` for which deletion might implies necessity to detach the
relation

## Known troubleshooting ( also on main )

![image](https://github.com/user-attachments/assets/10ad59cd-e87b-4f26-89df-0a028fcfa518)
We might have to refactor the `prefillRecord` to spread and
overrides`inputValue` over defaultOne as inputValue could be a partial
one for more info please a look to

# Conclusion
Any suggestions are welcomed !
fixes https://github.com/twentyhq/twenty/issues/9580

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-30 11:12:37 +01:00
Jérémy MandGitHub e7da9b6b87 feat: MenuItem disabled color (#9923)
Fix #9874
2025-01-30 10:23:06 +01:00
Félix MalfaitandGitHub 16c2d383ee Fix E2E tests (#9919)
Fortunately we're not using NODE_ENV=production for our deployment, but
we need to think of a better long-term fix. Not easy because Lingui
strips out messages in production environment
2025-01-29 22:01:10 +01:00
4edbb13706 Fix - Input box shadow, left icon focus and new size variant (#9902)
Favorite folder input needs to be 28px --- added a new sizeVariant 
Removed box shadow completely -- checked with @Bonapara 
The left icon used to be of color light on focus -- added a state to
check if input is focused

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-01-29 19:44:25 +01:00
Ana Sofia Marin AlexandreandGitHub 0d6f4a32a7 Add billing meter event service (#9865)
Solves :
https://github.com/twentyhq/private-issues/issues/241
https://github.com/twentyhq/private-issues/issues/254

**TLDR:**

- Add BillingMeterEventService and StripeBillingMeterEventService in
order to send billing meter events to stripe.
- Plugged the service into workflow node execution for testing purposes
(more improvements on this area will be done in the next PR's)

**In order to test:**

- Have the environment variable IS_BILLING_ENABLED set to true and add
the other required environment variables for Billing to work
- Do a database reset (to ensure that the new feature flag is properly
added and that the billing tables are created)
- Run the command: npx nx run twenty-server:command
billing:sync-plans-data (if you don't do that the products and prices
will not be present in the database)
- Run the server , the frontend, the worker, and the stripe listen
command (stripe listen --forward-to
http://localhost:3000/billing/webhooks)
- Buy a subscription for the Acme workspace 
- Create a workflow and run it
- After the run has been finished check in sprite the quantity of events
in the CreditMeter, you should see that there is a new occurence with
value one.

**Take into consideration:**

- I used an eventName that I have made a long time ago, so it hasn't a
significant naming. I'm updating the meters and associated prices in
stripe to use the correct meter with a more clearer eventName.
- I put some error handling in the execution of the workflow nodes, this
is still incomplete and needs some refinement, I would like the feedback
of the workflows track for a more cleaner approach
2025-01-29 19:36:01 +01:00
1b3181b14e add command to run cleaning suspended workspaces job (#9895)
Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-29 19:30:46 +01:00
4edeb7f991 feat(auth): enhance SSO handling and workspace auth logic (#9858)
- Return only SSO providers with an `activate` status
- If only 1 SSO provider is enabled for auth, redirect the user to the
provider login page.
- if only SSO auth is available set the step to SSO selection.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-29 19:28:21 +01:00
Baptiste DevessierandGitHub 85df6ada52 Prevent all workflow node and edge deletions made through the UI (#9918)
## Old

In the demo, I press the `Delete` key multiple times, and it deletes the
nodes.


https://github.com/user-attachments/assets/75bf84d3-b182-488c-a781-bbe236985142

## New


https://github.com/user-attachments/assets/4ae4f387-e143-4ce8-8140-6cb2c549f5d2
2025-01-29 18:29:01 +01:00
Raphaël BosiandGitHub ce296fae4f Add search records actions to the command menu (#9892)
Closes https://github.com/twentyhq/core-team-issues/issues/253 and
https://github.com/twentyhq/core-team-issues/issues/256.

- Created `CommandMenuList`, a component used at the root level of the
command menu and inside the search page of the command menu
- Refactored record agnostic actions
- Added shortcuts to the action menu entries (`/` key for the search)
and updated the design of the shortcuts
- Reordered actions at the root level of the command menu


https://github.com/user-attachments/assets/e1339cc4-ef5d-45c5-a159-6817a54b92e9
2025-01-29 17:23:40 +00:00
Baptiste DevessierandGitHub 03f3ccd060 Fix workflow edges color (#9917)
Fixes
https://discord.com/channels/1130383047699738754/1333831150535442462
2025-01-29 18:04:32 +01:00
Antoine MoreauxandGitHub ce8c6c4bac fix: correct typo in property name from "Entreprise" to "Enterprise" (#9916)
The property name "hasValidEntrepriseKey" was corrected to
"hasValidEnterpriseKey" across multiple files for consistency and
accuracy. This ensures proper alignment with naming conventions and
avoids potential issues in usage or understanding.
2025-01-29 17:39:04 +01:00
Raphaël BosiandGitHub 04bc42aa47 Improve command menu chip design (#9915)
Before:

<img width="236" alt="Capture d’écran 2025-01-29 à 17 07 13"
src="https://github.com/user-attachments/assets/edc277f3-3e50-405a-9981-3ac63e270f3f"
/>
<img width="259" alt="Capture d’écran 2025-01-29 à 17 07 23"
src="https://github.com/user-attachments/assets/81863c50-5b96-4cbf-bc15-ab437d839fa1"
/>
<img width="224" alt="Capture d’écran 2025-01-29 à 17 07 41"
src="https://github.com/user-attachments/assets/c0783544-6928-4b05-bf86-66d37ddca5e5"
/>

After:

<img width="230" alt="Capture d’écran 2025-01-29 à 17 03 49"
src="https://github.com/user-attachments/assets/c47be446-32fa-40d1-af25-207ed91c0ea2"
/>
<img width="254" alt="Capture d’écran 2025-01-29 à 17 04 15"
src="https://github.com/user-attachments/assets/99b9ab30-c77d-4392-8ef6-2a1a5fb00047"
/>
<img width="218" alt="Capture d’écran 2025-01-29 à 17 04 37"
src="https://github.com/user-attachments/assets/6e214a42-438d-495f-9855-fd5397fcc6d3"
/>
2025-01-29 16:37:59 +00:00
Félix MalfaitandGitHub 9d32e63111 Continue Frontend localization (#9909)
Translation more content on the frontend
2025-01-29 17:36:28 +01:00
Thomas TrompetteandGitHub ce0a6c1b17 Fix empty trigger on readonly + fix cache apollo on deactivation (#9912)
- On deactivation, we should not need to refresh so the workflow
disappear from cmd+k


https://github.com/user-attachments/assets/826fa4c6-3faa-49d1-b180-ed5d3ed187e5

- When readonly, step empty, we should not see the right drawer


https://github.com/user-attachments/assets/b557ef61-da81-446d-b160-f26c4c7a5191
2025-01-29 17:25:20 +01:00
Paul RastoinandGitHub 85ae7084ab [FiX] Optimistic cache useUpdateOneRecord (#9913)
# Introduction
~~this could be cool for the updateRecordFromCache to return the updated
record, so we could consume its return value more explicitly such as
`updatedRecordValue`~~

In fact this is nitpick as it would really be the same than returning
the received params

## Fixes duplicated optimistic cache upsert
<img
src="https://github.com/user-attachments/assets/289f4801-5b67-4e4e-a87b-a512deb5180c"
width="300px" height="300px">

We were before comparing the previously `cachedRecord` which is now, not
the latest as the optimistic is (should) be working successfully since
https://github.com/twentyhq/twenty/pull/9881

## Reproduction
1-  Open any Company
2- Attach an Opportunity it should appears only once
3bis- If you revert the last branch commit it will appear duplicated

Related to #9580
2025-01-29 17:11:36 +01:00
Jérémy MandGitHub 07197d1e6d feat: new relation in graphql-query-runner (#9883)
Fix https://github.com/twentyhq/core-team-issues/issues/300

Within GraphQLQueryRunner the new relation format will be used when the
feature flag `IsNewRelationEnabled` is set to true.
2025-01-29 17:04:39 +01:00
29745c6756 [BUG] Fix record relation optimistic mutation (#9881)
# Introduction
It seems like optimistic caching isn't working as expected for any
record relation mutation, CREATE UPDATE DELETE.
It should not have an impact on the destroy

We included a new `computeOptimisticRecordInput` that will calculate if
a relation is added or detach.

Updated the `triggerCreateRecordsOptimisticEffect` signature we should
have a look to each of its call to determine if it should be checking
cache or not

Related to #9580

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-29 16:00:59 +01:00
Thomas TrompetteandGitHub 7291a1ddcd Add event when creating draft from previous version (#9910)
We create draft without emitting creation event. So workflow statuses
are not properly updated

This service needs a refacto. Will do it once we get out from fast
follows rush
2025-01-29 15:48:22 +01:00
Baptiste DevessierandGitHub 5a34f6bfa7 Disable variables for the country code in the form phone field (#9897)
Fixes
https://discord.com/channels/1130383047699738754/1333820080651501691

We disable the variable picker for the country code for now. We'll
implement a proper solution later.
2025-01-29 15:40:59 +01:00
Thomas TrompetteandGitHub 7536a5a9a0 Add missing fields in update action (#9908)
Fix https://discord.com/channels/1130383047699738754/1333806855264145500
2025-01-29 14:23:21 +00:00
Jérémy MandGitHub c17dbe7115 fix: broken schema generation (#9905) 2025-01-29 13:46:36 +01:00
Jérémy MandGitHub fbb67d74c8 feat: new relation schema generation (#9882)
Fix https://github.com/twentyhq/core-team-issues/issues/295

Based on the feature-flag `IsNewRelationEnabled` the schema will be
marked as outdated and regenerated, this will cause an error on the
front-end on the first request on the following ones schema will be well
generated ans request will work.
2025-01-29 10:33:17 +01:00
Félix MalfaitandGitHub f74bb5a60b Add field description+label translations (#9899)
Add translations for field descriptions
2025-01-28 23:20:28 +01:00
Félix MalfaitandGitHub b1219ff107 Add POC for Field translation (#9898)
Similar to ObjectMetadata translation

Also fixed an issue linked to the migration from `t` to `message`
helper: we're forced to rebuild the ID ourselves
2025-01-28 21:25:09 +01:00
8754b7107d Fix Icon Padding and Size in Select Item (#9888)
This pull request addresses issue
[#9458](https://github.com/twentyhq/twenty/issues/9458) by making the
following changes:

Increase the icon size from 14x14px to 16x16px
Add 8px padding to the right side of the icon
Ensure the icon is not cropped and displays with rounded angles

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-28 19:50:59 +01:00
martmullandGitHub 5329dd0c63 Disable variable picker when no available variables (#9894)
- Disable variable picker when no available variables
(https://discord.com/channels/1130383047699738754/1331236819227906049)
<img width="496" alt="image"
src="https://github.com/user-attachments/assets/e4cb97c8-648c-4bdf-b230-49687113c9e6"
/>
2025-01-28 18:53:26 +01:00
Baptiste DevessierandGitHub 7195614926 Add history (undo/redo) to text variable editors (#9889)
https://github.com/user-attachments/assets/83689fd9-1b00-49ff-938a-748822baf15f
2025-01-28 18:35:36 +01:00
MarieandGitHub 180f6c28a4 Aggregates - Update Date label (#9862)
https://discord.com/channels/1130383047699738754/1333388007293849640/1333388007293849640
2025-01-28 17:18:29 +00:00
WeikoandGitHub 381c180ab9 Update bullmq queue option for job failure strategy (#9887)
## Context
This config tells bullmq what to do with jobs once they have been
processed.
We used to retain 100 completed jobs and 500 failed jobs. We never
really needed that much retention and keeping succeeded job is not
useful either in our case. I'm updating the strategy so all completed
jobs are removed from the queue and we now keep 100 failed jobs in case
we need to debug. (Although we should have good monitoring with
ExceptionHandler driver)
2025-01-28 17:39:10 +01:00
GuillimandGitHub 72d4619cd4 adding the predicate in the UPSERT function (#9891)
Bug fix : we are adding the predicate in the UPSERT function in order to
fix a postgres constraint
2025-01-28 16:51:37 +01:00
aa6d5c4c51 fix link validation and matching during csv import (#9890)
### Context
[Issue 9019](https://github.com/twentyhq/twenty/issues/9019) opens by
user having domain name not imported while importing through CSV.
@samyakpiya (thank you for your investigation !) has tested various
domain imports and has reported issue with its import test. Issues that
no longer exist : when I test your import, I get all records imported.

### Solution
- Remove "Link label" (cf screenshot - before fix) composite field in
matching options, not used in front that could mislead the user.
<img width="300" alt="Screenshot 2025-01-28 at 15 39 18"
src="https://github.com/user-attachments/assets/0ea24d9e-b339-42f3-b8d9-e271b33dbcfd"
/>

- Check links type fields validity in "Validate data" step


closes #9019

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-28 16:51:19 +01:00
Antoine MoreauxandGitHub eb88f6f584 feat(custom-domain): remove domainName + add migration for custom dom… (#9872)
…ain + feature flag

Blocked by #9849
2025-01-28 15:28:18 +01:00
Thomas TrompetteandGitHub 0e981bae0a Fix workflows empty states (#9878)
Versions and runs cannot be added manually. Updating message.

<img width="545" alt="Capture d’écran 2025-01-28 à 11 33 47"
src="https://github.com/user-attachments/assets/36b7ade8-3061-4b72-bfa5-c262e4d7d25e"
/>
<img width="614" alt="Capture d’écran 2025-01-28 à 11 34 02"
src="https://github.com/user-attachments/assets/9b524eb4-f40c-4330-a37f-fb33e08d22f4"
/>
2025-01-28 15:16:36 +01:00
Charles BochetandGitHub ac92aed87f Add command to remove duplicate messageChannelMessageAssociations (#9886)
In this PR:
- create a command to remove duplicate (groupBy messageId,
messageChannelId) within messageChannelmessageAssociaitions.

THis is needed to apply a constraint already present on
messageChannelmessageAssociaitions (to be executed before syncing
metadata)
2025-01-28 15:04:52 +01:00
Baptiste DevessierandGitHub 1e9dce3fd5 Fix the design of the Variable chip (#9871)
- Use a React component for variable tags in tiptap
- Fix the design of the variable chip
- Always display a button to delete the chip

![CleanShot 2025-01-28 at 12 35
55@2x](https://github.com/user-attachments/assets/d78ffa52-fcc3-4bbc-b427-68edde255408)
2025-01-28 14:59:45 +01:00
Andrii BodnarandGitHub ac8c0c72cc docs: add Lingui to the Readme (#9884)
This PR adds Lingui to the translation tools in the Stack section of the
Readme, based on the suggestion in the comment
https://github.com/lingui/js-lingui/issues/2159#issuecomment-2618922147
2025-01-28 14:48:46 +01:00
b63ae14318 RICH_TEXT_V2 backend (#9848)
- Add RICH_TEXT_V2 composite type to backend.
- Add `bodyV2` field to tasks and notes.
- Minimum required frontend changes to avoid errors when creating a note

[Testing
instructions](https://github.com/twentyhq/twenty/pull/9690#issuecomment-2602378218)

---------

Co-authored-by: ad-elias <elias@autodiligence.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-01-28 14:05:06 +01:00
Charles BochetandGitHub 6f72f1af33 Fix Messaging sync upsert in messageChannel association (#9880)
We have recently changed an .insert into a .upsert but we forgot to add
the unique index on the postgres schema.
2025-01-28 11:48:09 +01:00
Thomas TrompetteandGitHub 069c34cd7b Add link on snack bar (#9873)
Add link to workflow execution 

<img width="639" alt="Capture d’écran 2025-01-27 à 18 15 34"
src="https://github.com/user-attachments/assets/f2a1b3b5-7bf6-4b33-bba7-bf8907f6bcc6"
/>
2025-01-28 11:26:20 +01:00
af8d22ee99 Fix ObjectType casing and conflict between Relation and RelationMetadata (#9849)
Fixes #9827 

Also uncovered a conflict with `@objectType('Relation')` and
`@objectType('relation)`

I don't want to address it in this PR so I will create a followup issue
when we close this but I think there's a confusion between
Relation/RelationMetadata, it's unclear what is what

---------

Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
2025-01-28 10:06:18 +01:00
Félix MalfaitandGitHub 08a0e67477 Translate label and descriptions for objects (#9876)
Begin server-side translations
2025-01-28 09:54:59 +01:00
Charles BochetandGitHub 4542199e5c Fix object metadata view creation issue (#9875)
Fixes https://github.com/twentyhq/core-team-issues/issues/26
Fixes https://github.com/twentyhq/twenty/issues/9350
2025-01-27 21:25:02 +01:00
Félix MalfaitandGitHub 549c3faf71 Add server translation (#9847)
First proof of concept for server-side translation.

The goal was to translate one metadata item:

<img width="939" alt="Screenshot 2025-01-26 at 08 18 41"
src="https://github.com/user-attachments/assets/e42a3f7f-f5e3-4ee7-9be5-272a2adccb23"
/>
2025-01-27 21:07:49 +01:00
Antoine MoreauxandGitHub 2a911b4305 feat(auth): centralize SSO error handling logic (#9832)
Introduce `SsoErrorRedirectService` to handle SSO error redirection and
exception capturing across the authentication controllers. Refactor
Microsoft, Google, and SSO authentication controllers to utilize this
service, replacing the previous direct calls to `DomainManagerService`.
Added unit tests for the new service to ensure robust error handling.
2025-01-27 17:55:20 +00:00
10476fcb01 remove freeAccess user logic (#9866)
closes #9763

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-27 17:49:16 +01:00
martmullandGitHub 7362558e30 Reset selectedStep with proper step (#9867)
as title
fixes
https://discord.com/channels/1130383047699738754/1331215762840485908
2025-01-27 15:35:29 +01:00
martmullandGitHub 687b61849a Fix rightDrawer padding (#9869)
Fixes
https://discord.com/channels/1130383047699738754/1331236153713627157
## Before

![image](https://github.com/user-attachments/assets/3b265461-774b-480b-83dd-d3a410cfb31b)

## After

![image](https://github.com/user-attachments/assets/259122fa-3759-4cd6-8698-b94ccd5470bc)
2025-01-27 14:31:47 +00:00
martmullandGitHub 68c4f9cb0d Fix design to match figma (#9864)
As title
Fixes
https://discord.com/channels/1130383047699738754/1331212573902770228

## Before

![image](https://github.com/user-attachments/assets/4b556022-92c3-4197-ab18-91c089117936)

## After

![image](https://github.com/user-attachments/assets/67f97c60-d08b-4ae1-87b4-79c24ae79b93)
2025-01-27 15:23:28 +01:00
GuillimandGitHub 4bb8e3a50e updating SettingsAccountsListEmptyStateCard (#9868)
changing from "Connect a Google account" to  "Choose your provider"

updating all languages using 
`npx nx run twenty-front:lingui:extract`
2025-01-27 15:20:48 +01:00
GuillimandGitHub fded1cb5a0 Bug fix microsoft require approval (#9863)
Rolling back since apparently requiring "select_account" fails for
google
2025-01-27 13:58:42 +00:00
GuillimandGitHub 77c586db24 fix the bug "require approval" (#9859)
## The bug : 
"Approval required" even though admin consent has been granted for the
whole tenant"

Fix https://github.com/twentyhq/core-team-issues/issues/277 

### More details
described here in
[stackoverflow](https://stackoverflow.com/questions/79385342/approval-required-even-though-admin-consent-has-been-granted-for-the-whole-ten?noredirect=1#comment140006092_79385342)
2025-01-27 14:36:01 +01:00
martmullandGitHub c1e84a746c Fix design for select action (#9857)
as title 
fixes
https://discord.com/channels/1130383047699738754/1330945172489371771
2025-01-27 13:29:04 +01:00
martmullandGitHub fb0b342374 Fix background color in code step right drawer (#9856)
Fixes
https://discord.com/channels/1130383047699738754/1331211019430924380
as title
2025-01-27 12:16:21 +01:00
GuillimandGitHub 8df3214e84 decoupling isMicrosoftAuthEnabled and IsMicrosoftSyncEnabled (which has no reason to be used here) (#9854)
### what
decoupling auth and email synchro

### why
IsMicrosoftSyncEnabled (which has no reason to be used here) since we
now allow microsoft as a auth provider
2025-01-27 11:04:19 +01:00
GuillimandGitHub 98671b6cd2 bug fix urgent (#9851)
upsert messaging
2025-01-27 10:38:18 +01:00
Baptiste DevessierandGitHub 84c299f8d4 Create a reusable Label component (#9833)
As seen with @Bonapara, I'm creating a Label component and use it in the
workflows.
2025-01-24 19:25:04 +01:00
55be726105 Rename Unintuitive Function Names in Authentication Flow (#9706)
Resolves #9623

## Description

This PR renames the following functions to better reflect their purpose.

- Backend:
  - Verify → GetAuthTokensFromLoginToken
  - Challenge → GetLoginTokenFromCredentials

- Frontend:
  - challenge → getLoginTokenFromCredentials
  - verify → getAuthTokensFromLoginToken

## Testing
_Sign in works as expected:_


https://github.com/user-attachments/assets/7e8f73c7-2c7d-4cd2-9965-5ad9f5334cd3

_Sign up works as expected:_
  

https://github.com/user-attachments/assets/d1794ee4-8b59-4934-84df-d819eabd5224

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-24 19:19:14 +01:00
Lucas BordeauandGitHub 570b2e3530 Refactored record filter saving to view filters (#9844)
This PR refactors the record filter saving to view filters.

Before we used states to track the change of view filters, now we just
check if there's a difference between the current record filters and the
current view filters before saving.

We also use this check to show the reset and save buttons.

CRUD operations to perform on view filters are computed by utils , and .

Also added unit tests on those utils.
2025-01-24 18:48:59 +01:00
Baptiste DevessierandGitHub a4011676f0 Add e2e tests for the Use as Draft feature (#9845)
Test with and without a draft version as the last version of the
workflow
2025-01-24 18:38:35 +01:00
aacbf11435 add new emails in suspended workspace cleaning job (#9834)
From: Felix from Twenty <noreply@yourdomain.com>
Subject: Action needed to prevent workspace deletion
<img width="400" alt="Screenshot 2025-01-24 at 16 31 35"
src="https://github.com/user-attachments/assets/8350a499-6815-4b00-a4fb-615b2a3b60e0"
/>


From: Felix from Twenty <noreply@yourdomain.com>
Subject: Your workspace has been deleted
<img width="456" alt="Screenshot 2025-01-24 at 16 33 15"
src="https://github.com/user-attachments/assets/7e392e7c-519c-4b38-ae8c-ab3c9dd72c24"
/>



closes [284](https://github.com/twentyhq/core-team-issues/issues/284) &
[285](https://github.com/twentyhq/core-team-issues/issues/285) - [parent
issue](https://github.com/twentyhq/core-team-issues/issues/179)

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-24 18:37:06 +01:00
Thomas TrompetteandGitHub 07dec36976 Tt fast follows 24/01 (#9843)
- Add icons on steps
- Add search input on object selection
- Improve event label
<img width="503" alt="Capture d’écran 2025-01-24 à 17 59 34"
src="https://github.com/user-attachments/assets/4e5d31d6-6fe5-4f78-9112-3fbd6ee66743"
/>
<img width="503" alt="Capture d’écran 2025-01-24 à 17 59 54"
src="https://github.com/user-attachments/assets/7f37402f-3d1a-4bea-9082-05f50a711f35"
/>
<img width="503" alt="Capture d’écran 2025-01-24 à 18 00 08"
src="https://github.com/user-attachments/assets/fffabaff-9d5d-4584-9297-e21434333de0"
/>
2025-01-24 17:25:01 +00:00
17def223b6 Feat/2fa (#9634)
# Description
Closes #7003 
Implements 2FA with TOTP. 

>[!WARNING]
> This is a draft PR, with only partial changes, made as a mean of
discussion about #7003 (it's easier to reason about real code)

## Behaviour
- a `totpSecret` is stored for each user
- use [`otplib`](https://github.com/yeojz/otplib/tree/master) to create
a QR code and to validate an `otp` against an `totpSecret` (great [demo
website](https://otplib.yeojz.dev/) by `otplib`)
- OTP is asked upon each login attempt

## Source
Inspired by:
- [RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238)
- Cal.com's implementation of 2FA, namely
- [raising a
401](https://github.com/calcom/cal.com/blob/c21ba636d2bec4ed55775f0b058f70fdc371c410/packages/features/auth/lib/next-auth-options.ts#L188-L190)
when missing OTP and 2FA is enabled, with a [specific error
code](https://github.com/calcom/cal.com/blob/c21ba636d2bec4ed55775f0b058f70fdc371c410/packages/features/auth/lib/ErrorCode.ts#L9)
- [catching the
401](https://github.com/calcom/cal.com/blob/c21ba636d2bec4ed55775f0b058f70fdc371c410/apps/web/modules/auth/login-view.tsx#L160)
in the frontend and
[displaying](https://github.com/calcom/cal.com/blob/c21ba636d2bec4ed55775f0b058f70fdc371c410/apps/web/modules/auth/login-view.tsx#L276)
the OTP input

## Remaining
- [ ] encrypt `totpSecret` at rest using a symetric algorithm

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-01-24 18:23:57 +01:00
Ana Sofia Marin AlexandreandGitHub f58f84114c update subscription interval and quantity for hybrid susbscription (#9822)
Solves https://github.com/twentyhq/private-issues/issues/253

**TLDR:**

Can update the billing subscription interval for a subscription with a
base product and metered product. It also updates correctly as the
quantity of base products depending on how many people are in the
workspace.

**In order to test:**

1. Have the environment variable IS_BILLING_ENABLED set to true and add
the other required environment variables for Billing to work
2. Do a database reset (to ensure that the new feature flag is properly
added and that the billing tables are created)
3. Run the command: npx nx run twenty-server:command
billing:sync-plans-data (if you don't do that the products and prices
will not be present in the database)
4. Run the server , the frontend, the worker, and the stripe listen
command (stripe listen --forward-to
http://localhost:3000/billing/webhooks)
5. Buy a subscription for the Acme workspace , change the interval in
the Billing Settings
6. Add another person to the workspace, you should see all the previous
changes reflected in the database

**Doing**
Moving the BillingSubscriptionsService.getUpdatedSubscriptionItems to an
util (for a less cluttered service)
2025-01-24 18:19:09 +01:00
Paul RastoinandGitHub c89cc38729 [MISC] Twenty-shared build declaration and declarationMap tsconfig (#9838)
# Motivations
By adding the declaration and declaration mapping this allows a better
`go to source` in our IDE
Should also be done for
https://github.com/twentyhq/core-team-issues/issues/281

## FROM


https://github.com/user-attachments/assets/5cc307d0-b2dc-46bf-b61f-0731015c4a30


## TO


https://github.com/user-attachments/assets/5ed1d7af-2716-435d-a1b8-6738b5a77956

## Notes
Might be interesting to add global commands for:
- watch mode for `twenty-ui` and `twenty-shared`
- clean, output folders such as `dist` and `node_modules` and so on
2025-01-24 17:56:42 +01:00
martmullandGitHub 03197226f4 Fix Cmd enter to test code step (#9841) 2025-01-24 16:46:56 +00:00
Paul RastoinandGitHub 95c772664e Refactor triggerUpdateRelationsOptimisticEffect to compute relationship from Metadatas (#9815)
# Introduction
At the moment the relationships are inferred from the record data
structure instead of its metadatas
We should refactor the code that computes or not the necessity to detach
a relation on a mutation

We've refactored the `isObjectRecordConnection` method to be consuming a
`relationDefintion` instead of "typeChecking" at the runtime the data
structure using zod validation schema

Related to #9580
2025-01-24 17:24:23 +01:00
Kevin KimandGitHub a8552a6a67 Fix Typo in Filename (#9835)
- Rename `mircosoft-apis-oauth-request-code.guard.ts` to
`microsoft-apis-oauth-request-code.guard.ts `
- Update import statement in
`packages/twenty-server/src/engine/core-modules/auth/controllers/microsoft-apis-auth.controller.ts`
to reflect the updated filename.
2025-01-24 16:24:41 +01:00
25cb909e17 Improve Docker-Compose Install Experience (#9781)
This PR updates the docker-compose installation documentation and env
sample to improve the setup experience.

- Updates the URLs for raw files to reference main branch, which is
likely where new users will be pulling from initially. This seems to be
the most straightforward option; assume that advanced users who want to
retrieve it from a particular tag will know to change the URL for their
scenario.
- Fixes an improperly stated curl command.
- Adds a note that the PGPASSWORD_SUPERUSER should be URL-safe. This is
required since the value is later concat into a PG_DATABASE_URL as a
URL, and expected to be in proper URL format. Touches on #8597.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-01-24 16:13:28 +01:00
Raphaël BosiandGitHub ff41768e8f 250 implement restore context button on command menu (#9836)
Closes https://github.com/twentyhq/core-team-issues/issues/250



https://github.com/user-attachments/assets/9c120188-497d-4273-9137-f8d0de3bd884
2025-01-24 16:10:02 +01:00
Thomas TrompetteandGitHub 29df6e64a0 Fix icon matching + small other fixes on workflows (#9814)
- Record Fields label
- body height fix
- Icons on object picker
- Fix icon matching between nodes and right drawer

<img width="1296" alt="Capture d’écran 2025-01-23 à 18 51 12"
src="https://github.com/user-attachments/assets/ecd5fb00-49cd-416e-96af-9200418294e0"
/>
2025-01-24 15:47:09 +01:00
martmullandGitHub 1a42483aa9 Fix wrong label formatting (#9830)
Fixes
https://discord.com/channels/1130383047699738754/1324785862830985266
## Before
<img width="451" alt="image"
src="https://github.com/user-attachments/assets/53ae96f9-4bbd-40e3-beaa-a5702f2adee4"
/>

## After
<img width="388" alt="image"
src="https://github.com/user-attachments/assets/e36da162-bc60-4596-823b-ffb6ddfed98d"
/>
2025-01-24 15:11:30 +01:00
Antoine MoreauxandGitHub f23de2fa22 chore(auth): update SAML strategy configuration (#9829)
Added `disableRequestedAuthnContext` flag to SAML auth strategy to align
with compatibility requirements. Adjustments ensure seamless integration
with certain Identity Providers. No functional impact on existing flows.
2025-01-24 14:52:42 +01:00
edd7212f0b feat: add clean suspended workspaces command (#9808)
closes [283
sub-issue](https://github.com/twentyhq/core-team-issues/issues/283) -
[parent issue
](https://github.com/orgs/twentyhq/projects/1/views/3?filterQuery=sprint%3A%40current+assignee%3Aetiennejouan&pane=issue&itemId=93520456&issue=twentyhq%7Ccore-team-issues%7C179)

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-24 11:10:52 +01:00
Félix MalfaitandGitHub 15814d465a Fix missing events during account connection (#9825)
Fix #8765
2025-01-24 10:10:42 +00:00
Jérémy MandGitHub 8d794374f1 feat: new relation resolver (#9794)
Fix [#240](https://github.com/twentyhq/core-team-issues/issues/240)
2025-01-24 10:38:50 +01:00
Antoine MoreauxandGitHub 5783c41df2 fix(auth): Improve error management with sso + fix microsoft saml (#9799)
Fix #9760 #9758
2025-01-24 10:36:18 +01:00
3c85516f77 fixed ellipsis for calendar events (#9823)
Fixed Missing ellipsis for long calendar event names #5267 introducing
width for the title

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-24 10:33:46 +01:00
6af42b9b9b Fix: Remove default value for name field in CustomWorkspaceEntity (#9805) (#9824)
### Summary
This pull request addresses issue #9805 by removing the default value
`'Untitled'` for the `name` field in the `CustomWorkspaceEntity` class.

### Details
- Removed the default value `'Untitled'` for the `name` field.
- This change ensures that new records do not have an empty or default
name.
- Ensures consistency across different standard object records.

### Issue
This pull request resolves issue #9805.

### Testing
Tested the creation of new records to ensure that the `name` field is
now correctly handled without a default value.

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-01-23 19:01:03 +01:00
Baptiste DevessierandGitHub 23400e9679 Normalize the spacing between nodes (#9820)
## Old

![CleanShot 2025-01-23 at 16 38
25@2x](https://github.com/user-attachments/assets/0c8e3b26-5ef4-455a-978e-b430e54b63ba)

![CleanShot 2025-01-23 at 16 38
51@2x](https://github.com/user-attachments/assets/929b73d3-2d7f-45b9-a0fb-62516969bd63)

## New

![CleanShot 2025-01-23 at 17 12
25@2x](https://github.com/user-attachments/assets/670ba386-c643-408d-a682-d279bc81f5c1)
2025-01-23 18:26:51 +01:00
martmullandGitHub daa8ff1299 148 cant access note without title from kanban board (#9817)
closes https://github.com/twentyhq/core-team-issues/issues/148

- fixes not openable kanban card when identifier empty
- update card behavior (onClick open recordPage)
- fixes right click actionDropdown position

## Before


https://github.com/user-attachments/assets/696194b8-d7fa-4fc1-a6f9-b46241a262e5

![image](https://github.com/user-attachments/assets/63a5f634-2688-41ba-9ac4-51292ef09b7a)

## After


https://github.com/user-attachments/assets/41e296e5-ae16-47f8-b174-7dd21d74188d

![image](https://github.com/user-attachments/assets/7f859764-946e-40d3-9b66-5460edb215f2)
2025-01-23 17:05:35 +00:00
Félix MalfaitandGitHub afa2282ea3 Fix left menu highlight (#9821)
Fix #9777

getAppPath doesn't return object/pet/ but actually object/pet so it
needed a small adjustment (pet - 1 = PE is included in PEople)
2025-01-23 17:59:30 +01:00
Jérémy MandGitHub bf564788c3 fix: board hide button not working (#9818)
Fix #9816
2025-01-23 16:17:46 +00:00
1d7cbcabee fix: scrolling inside the table with scrollbar (#9753)
Fixed- when scrolling inside the table with scrollbar, cursor also
selects rows. Now on scrolling with scrollbar content is scrolled in
respective direction as expected and table rows don't get selected.

fixes issue #6773

---------

Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-01-23 15:41:57 +00:00
bbd3af108b bugfix: escape destroyed objects on workers (#9719)
# This PR

- Fixes #9358 

@FelixMalfait please check this workaround

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-01-23 16:29:54 +01:00
Baptiste DevessierandGitHub bbb0c9a761 Improve the design of workflow nodes (#9810)
- Go over every node in the workflows and fix the styles to conform to
Figma
- Create stories for every node type
2025-01-23 15:12:37 +00:00
Raphaël BosiandGitHub 337b6a86ab 251 create top bar chips inside the command menu (#9809)
Closes #https://github.com/twentyhq/core-team-issues/issues/251



https://github.com/user-attachments/assets/065c97fe-1daf-4b48-9d57-6bbb96d24ede
2025-01-23 14:44:21 +01:00
Ana Sofia Marin AlexandreandGitHub cc53cb3b7b Add metered product to checkout session (#9788)
Solves https://github.com/twentyhq/private-issues/issues/238

**TLDR:**
Add metered product in the checkout session when purchasing a
subscription

**In order to test:**

1. Have the environment variable IS_BILLING_ENABLED set to true and add
the other required environment variables for Billing to work
2. Do a database reset (to ensure that the new feature flag is properly
added and that the billing tables are created)
3. Run the command: npx nx run twenty-server:command
billing:sync-plans-data (if you don't do that the products and prices
will not be present in the database)
4. Run the server , the frontend, the worker, and the stripe listen
command (stripe listen --forward-to
http://localhost:3000/billing/webhooks)
5. Buy a subscription for the Acme workspace , in the checkout session
you should see that there is two products
2025-01-23 14:28:13 +01:00
GuillimandGitHub e7ba1c82b4 isMicrosoftAuthEnabled = true (#9812) 2025-01-23 12:22:03 +01:00
GuillimandGitHub 2f0fa7ae3e Microsoft-multi-tenant (#9801)
Microsoft fixes
2025-01-23 12:08:08 +01:00
Lucas BordeauandGitHub bddca09451 Refactored table filters to consume new currentRecordFilters component state (#9652)
This PR implements a first real use case, now currentRecordFilters
component state acts as the global record filter reference.

It is set by the view initially and can be reset to view filters state
at any point.

This new state is also modified by two new upsertRecordFilter /
removeRecordFilter hooks that will be drop-in replacement of the actual
upsertCombinedViewFilter and removeCombinediewFilter hooks.

This PR implements the logic to manipulate record filters but only reads
it to make the table find many request, all other features are still
relying on the old view filter implementation.

Advanced filters are ignored because they are hidden and because this
effort is made precisely to allow the completion of the advanced filters
feature.
2025-01-23 11:09:44 +01:00
martmullandGitHub 3ab193f298 Remove isServerlessFunctionSettingsEnabled feature flag (#9797)
Removes `isFunctionSettingsEnabled` feature flag
We consider this featureFlag as false for everyone. We decided to keep
the code in the code base for now
2025-01-22 22:39:52 +01:00
Charles BochetandGitHub e881616822 Fix captcha token not being loaded early enough (#9800)
I've re-investigated the captchaToken being invalid on workspace domain
url in case where email is passed in the URL.
We need to be a bit more granular
2025-01-22 18:11:21 +01:00
WeikoandGitHub 5902dbd0b4 Fix signup submit disabled when waiting for captcha without provider (#9796) 2025-01-22 17:49:11 +01:00
Charles BochetandGitHub d340605578 Fix View Picker broken (#9798)
In this PR:
- fixing a regression introduced in a recent PR (#9735)
- fixing a typing issue in ViewPicker @ehconitin FYI
2025-01-22 17:48:27 +01:00
Jérémy MandGitHub b662609948 feat: add targetFieldMetadataId and migration script for relations (#9793)
Fix https://github.com/twentyhq/core-team-issues/issues/238 and
https://github.com/twentyhq/core-team-issues/issues/239
2025-01-22 17:01:54 +01:00
Paul RastoinandGitHub 984dc4dec0 [MISC] Twenty-emails as package (#9770)
Charles has done everything within
https://github.com/twentyhq/twenty/pull/9754
Last thing to be done is removing the custom module `path` configured in
the `tsconfig.json`

close https://github.com/twentyhq/core-team-issues/issues/282
2025-01-22 16:33:48 +01:00
8ab01ebef4 [BUG] Record settings not saved (#9762)
# Introduction
By initially fixing this Fixes #9381, discovered other behavior that
have been fix.
Overall we encountered a bug that corrupts a workspace and make the
browser + api crash
This issue https://github.com/twentyhq/core-team-issues/issues/25
suggests a refactor that has final save button instead of auto-save

## `labelIdentifierFieldMetadataId` form default value
The default value resulted in being undefined, resulting in react hook
form `labelIdentifierFieldMetadataId` is required field error.

### Fix
Setting default value fallback to `null`  as field is `nullable`

## `SettingsDataModelObjectSettingsFormCard` never triggers form
Unless I'm mistaken in production touching any fields within
`SettingsDataModelObjectSettingsFormCard` would never trigger form
submission until you also modify `SettingsDataModelObjectAboutForm`
fields

### Fix
Provide and apply `onblur` that triggers the form on both
`SettingsDataModelObjectSettingsFormCard` inputs

## Wrong default `labelIdentifierFieldMetadataItem` on first page render
When landing on the page for the first time, if a custom
`labelIdentifierFieldMetadataItem` has been set it won't be computed
within the `PreviewCard`.
Occurs when `labelIdentifierFieldMetadataId` form default value is
undefined, due to `any` injection.

### Fix
In the `getLabelIdentifierFieldMetadataItem` check the
`labelIdentifierFieldMetadataIdFormValue` definition, if undefined
fallback to current `objectMetadata` identifier

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-22 16:32:57 +01:00
martmullandGitHub 80c9ebfd4e Remove isGmailSendEmailScopeEnabled featureFlag (#9787)
as title
2025-01-22 15:53:40 +01:00
MarieandGitHub d759559506 Fix COUNT operation on view group aggregate header (#9789)
Fixes
[sentry](https://twenty-v7.sentry.io/issues/6235128210/?referrer=discord&notification_uuid=898a081c-f8c7-42b8-b598-7660470a1975&alert_rule_id=15135099&alert_type=issue)

In a [previous work](https://github.com/twentyhq/twenty/pull/9749) I set
the default field to run totalCount aggregate operation on to the "name"
field, which I was wrong think was present on all objects.
2025-01-22 15:05:38 +01:00
Raphaël BosiandGitHub 8213995887 Open showpage on workflow creation (#9714)
- Created an new component state
`isRecordEditableNameRenamingComponentState`
- Updated `useCreateNewTableRecord` to open the ShowPage on workflow
creation
- Refactored `RecordEditableName` and its components to remove the
useEffect (This was causing the recordName state to be updated after the
focus on `NavigationDrawerInput`, but we want the text so be selected
after the update).
- Introduced a new component `EditableBreadcrumbItem`
- Created an autosizing text input: This is done by a hack using a span
inside a div and the input position is set to absolute and takes the
size of the div. There are two problems that I didn't manage to fix:
If the text is too long, the title overflows, and the letter spacing is
different between the span and the input creating a small offset.


https://github.com/user-attachments/assets/4aa1e177-7458-4691-b0c8-96567b482206


New text input component:


https://github.com/user-attachments/assets/94565546-fe2b-457d-a1d8-907007e0e2ce
2025-01-22 14:44:10 +01:00
Thomas TrompetteandGitHub 441b88b7e1 Seed workflow views and favorites in upgrade to 0.41 (#9785)
- Sync metadata to create workflow entities, since those are not behind
a flag anymore
- Seed workflow views
- Seed workspace favorite for workflow
- Put all steps in upgrade command
2025-01-22 14:40:44 +01:00
Baptiste DevessierandGitHub 26aca9508b Align the workflow visualizer's nodes on the left (#9776)
**This PR implements a new layout for the visualizer, but the dimensions
of the nodes will change soon. I used hard-coded dimensions, like
`40px`, but I'll update them when I work on fixing the nodes' design. I
think we can merge this PR first and then fix the nodes' design.**



https://github.com/user-attachments/assets/580fa812-ee8e-4452-b6ac-ca55ecb31759
2025-01-22 11:03:36 +01:00
Ana Sofia Marin AlexandreandGitHub 7d30b7577d add fetch billing products from tables instead of env variables (#9601)
Solves https://github.com/twentyhq/private-issues/issues/237

**TLDR:**

- Fetches billing products and prices from the tables BilllingProducts
and BillingPrices instead of fetching the product from the environment
variables and the prices from the stripe API.
- Adds new feature flag for this feature
- Fixes calls used to fetch stripe products and prices for the command
Billing Sync Plans Data.


**In order to test:**

1. Have the environment variable IS_BILLING_ENABLED set to true and add
the other required environment variables for Billing to work
2. Do a database reset (to ensure that the new feature flag is properly
added and that the billing tables are created)
3. Run the command: `npx nx run twenty-server:command
billing:sync-plans-data` (if you don't do that the products and prices
will not be present in the database)
4. Run the server , the frontend, the worker, and the stripe listen
command (`stripe listen --forward-to
http://localhost:3000/billing/webhooks`)
5. Buy a subscription for the Acme workspace and play with the project

**Doing**

I think there is some room of progress for the function
formatProductPrices, I used a similar version that was done before, I'll
look into that.
2025-01-21 20:19:29 +01:00
GuillimandGitHub 3d2bb03c6d microsoft domain publisher (#9771)
for MS auth and outlook recognition
2025-01-21 18:17:16 +01:00
Antoine MoreauxandGitHub aef01816d7 fix(recaptcha|sso): recaptcha not generated issue (#9764)
Fix https://github.com/twentyhq/twenty/issues/9759
https://github.com/twentyhq/twenty/issues/9694
https://github.com/twentyhq/twenty/issues/9323
2025-01-21 17:07:20 +00:00
Antoine MoreauxandGitHub f4779a02ca fix(workspace): ensure proper handling of updates and errors (#9752)
Added `await` to `updateWorkspaceById` in resolver for proper async
handling. Enhanced workspace settings UI with specific error handling
for subdomain conflicts and improved feedback for invalid form values.


Fix
https://github.com/twentyhq/twenty/issues/9709#issuecomment-2597919251
2025-01-21 17:17:58 +01:00
75ba270ba8 fix: handle billingSubscriptions gql field if billing is disabled (#9767)
Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-21 16:47:19 +01:00
Antoine MoreauxandGitHub 34afd73923 refacto(invite|signin): remove unused code + fix signin on invite page. (#9745)
- Replace `window.location.replace` by `useRedirect` hook.
- Remove unused code: `switchWorkspace, addUserByInviteHash...`
- Refacto `Invite` component.
- Fix signin on invite modal.
2025-01-21 16:33:31 +01:00
Thomas TrompetteandGitHub 2e9a77f702 Hide workflows + remove feature flag from entities (#9768)
From now on workflow entities and views will be seed for every new
workspace. What will prevent user to see those is the feature flag used
in frontend. It will prevent workflow objects to be stored in the recoil
state.

Without feature flag, workflows will:
- remain invisible in metadata
- not be accessible through views or show page
- remain invisible on side menu
2025-01-21 15:11:57 +00:00
Winston HoyandGitHub e82d4d9f8e Document Google OAuth scopes required (#9657)
Attempts to resolve #9656
2025-01-21 16:09:30 +01:00
martmullandGitHub ed7c48e12a Fix use as draft (#9718)
- remove delete serverless function when archiving workflow version
- update copy serverless function to reset serverless function to old
version
- remove createNewWorkflowVersion and use createDraftFromWorkflowVersion
- fix step update issue and optimistic rendering when generate draft
from active version
2025-01-21 15:44:52 +01:00
d8815d7ebf fix: prevent billingPortal creation if no active subscription (#9701)
Billing portal is created in settings/billing page even if subscription
is canceled, causing server internal error. -> Skip back end request

Bonus : display settings/billing page with disabled button even if
subscription is canceled

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-21 15:01:18 +01:00
47c2c774e3 Add GraphQL Generation Check to CI Workflow (#9742)
This pull request addresses the issue of ensuring that npx nx run
twenty-front:graphql:generate and npx nx run
twenty-front:graphql:generate --configuration=metadata commands are run
to generate the necessary GraphQL files. This prevents changes from
being missed and ending up in subsequent unrelated PRs.

Changes:
Added a step in the ci-server.yml workflow to check for pending GraphQL
generation.
If any GraphQL changes are detected, the CI will fail, and an error
message will be displayed instructing the developer to run the necessary
commands and commit the changes.
This approach is similar to the existing TypeORM migration check and
helps maintain consistency and correctness in the codebase.

Issue Resolved: #9726

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-21 14:43:19 +01:00
dadb7db6cf doc (#9737)
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-01-21 14:39:05 +01:00
nitinandGitHub 50f36e345e Lab (#9667)
https://github.com/twentyhq/core-team-issues/issues/76
2025-01-21 14:30:59 +01:00
Félix MalfaitandGitHub 86b0a7952b Fix API key not displayed (#9766)
Fixes #9761

Instead of cleaning RecoilState we should keep the api key visible as
long as the user didn't refresh/leave the app, it's better from a UX
perspective and the code is also more elegant, removing a useEffect


Note: the root cause of the bug was a missing "/settings" path in
isMatchingLocation in useCleaningRecoilState (due to the recent
refactoring) ; but I think this fix is better
2025-01-21 14:18:22 +01:00
Baptiste DevessierandGitHub 8e0467e2e4 Workflow E2E tests – batch 2 (#9747)
- Fix the e2e according to the last changes in the workflows
- Create a few more tests regarding the workflow visualizer
2025-01-21 11:46:27 +01:00
e1731bb31e chore: update codegen config for enum naming convention (#9751)
Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-21 11:34:33 +01:00
d4b038f24a fix: skeleton not using theme variables (#9712)
Fix linked to this discord issue:
https://discord.com/channels/1130383047699738754/1329509340494692444

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-01-21 09:19:06 +01:00
Charles BochetandGitHub e3f7cec82f Fix import twenty-shared (#9754)
In this PR:
- removing rootDir / baseUrl from any tsconfig.json
- we need to keep it in tsconfig.spec.json and also specify rootDir in
jest.config.ts moduleMapper because of the way nx jest executor works
(automatically moving back to root)
- we need to explictly specify the depencies to twenty-shared /
twenty-emails (built packages) in packages package.json to help nx
understand dependencies
2025-01-20 23:10:39 +01:00
MarieandGitHub 3838fef812 Add aggregate on view groups headers (#9749)
Adding aggregate operations on view groups headers, with a design
similar to what is done on kanban headers: all view groups share the
same operation on the same field.


https://github.com/user-attachments/assets/26f6dd6f-1cf7-4ea6-9600-78d5ad5d690a
2025-01-20 18:26:30 +01:00
Thomas TrompetteandGitHub 8762af050a Fix action selection design (#9748)
<img width="1512" alt="Capture d’écran 2025-01-20 à 16 24 22"
src="https://github.com/user-attachments/assets/fc1ce873-1b7b-49bc-9ab3-105e16adde2e"
/>
2025-01-20 16:56:19 +00:00
Antoine MoreauxandGitHub 4254ce9b2b fix(auth): improve query to find invitation (#9743) 2025-01-20 17:39:12 +01:00
Paul RastoinandGitHub e0ea5b35d9 [SERVER] Typecheck the twenty-server (#9736)
# Introduction
It seems like that within the `twenty-server` `nx-project` there's no
entry for the `typecheck` command. It also seems to silently fail along
the `start` command even if it depends on it.
Looking at this
[run](https://github.com/twentyhq/twenty/actions/runs/12865329787/job/35865644811?pr=9736)
we can see that even when containing following diff it still does not
fail
```ts
// twenty-server/main.ts
// @ts-expected-error: Manually triggering TSC error should be deleted afterwards
const bootstrap = async () => {
```

By adding the `typecheck` entry in the project the same run will now
[fails](https://github.com/twentyhq/twenty/actions/runs/12865516249/job/35866224325)

![image](https://github.com/user-attachments/assets/e7d29307-05d0-4614-8e0f-b395129c3602)


# Notes
- There're no existing TSC errors even if wasn't guarded by the CI rn 😎 
- The ci will take dozen of more seconds to run, should keep an eye on
// with nx implem checking if it works as expected
2025-01-20 16:46:50 +01:00
b25330b607 fix: soft delete user when removing last userWorkspace (#9741)
### Context 

User (who has create a workspace and deleted it) can't create new
workspace because after deleting his previous workspace, user has not
been soft deleted.

There is several cases where user should be soft deleted :
1/ if user delete his account
2/ if a user's workspace is deleted + user has no other workspace
3/ If a workspaceMember is removed + user has no other workspace


### Solution
In `handleRemoveWorkspaceMember` method (logic used in the 3 cases),
soft delete user when removing the last userWorkspace


closes #9728

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-20 16:19:20 +01:00
Weiko a9f186e85c start 0.41.0-canary 2025-01-20 15:38:40 +01:00
GuillimandGitHub 0612d905cf adding the microsoft publisher domain (#9739) 2025-01-20 15:37:19 +01:00
Félix MalfaitandGitHub feac6861f1 Fix save button not well positioned (#9740)
Regression I introduced with the translations
2025-01-20 15:02:23 +01:00
Antoine MoreauxandGitHub 59cb420d82 refactor(invitation): streamline invitation validation logic (#9699)
Replaced `validateInvitation` with `validatePersonalInvitation` across
services for consistent and specific validation handling. Removed
outdated public invitation validation and improved error handling for
workspace invitations. Updated tests to align with the refactored logic
and added checks for edge cases.
2025-01-20 12:25:08 +01:00
Antoine MoreauxandGitHub 2c8954a44d fix(session-storage): add typing and trust proxy setting (#9725)
Added explicit typing for session storage options to improve type
safety. Enabled 'trust proxy' to ensure proper client IP and protocol
detection behind proxies. These changes improve security and reliability
in session handling.
2025-01-20 10:05:34 +00:00
7ed2c12e7a Workflow e2e tests – 1st batch (#9713)
- Clean Playwright's configuration:
  - Remove artificial 500ms delay between each step
- Group all tests under a `chrome` project relying on a `setup` project
to get an authentication state which all tests can reuse
- Changes on the `Sign up with invite link via email` test:
- Generate a new email for each test trial, as previously it was failing
when run many times
- Make deleting the account part of the test; if we write other tests
for account sign-up, we'll prefer to delete the accounts with an HTTP
call to speed up things
- Added some assertions to ensure we reached steps when expected, as we
removed the 500ms delay between each step, and it made some assertions
fail
- Wrote new tests for workflows:
- Created `Create workflow`, a test asserting we can create a workflow
from the record table
- Created `Create simple workflow`, a test asserting we can create a
simple flow; I will add more assertions to this test and write other
tests once this first PR is approved
- I make HTTP calls to delete and destroy workflows after they run to
keep the database clean
- Added a data-testid to ensure we focus elements from the Cmd+K; our
selectors are not strong – see `getByRole('textbox')` – and I preferred
to scope them to a root element
  - Added an `aria-label` to a button

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-01-20 10:59:01 +01:00
Thomas TrompetteandGitHub d50294d39a Update trigger selection design (#9717)
https://github.com/user-attachments/assets/62bc705a-2f69-4ce7-986f-0208154c9965
2025-01-20 10:54:27 +01:00
Félix MalfaitandGitHub 056cb7c66d Translation followup (#9735)
Address PR comments and more progress on translation
2025-01-19 13:29:19 +01:00
Félix MalfaitandGitHub 052331685f Add more translations (#9733) 2025-01-18 17:38:05 +01:00
Félix MalfaitandGitHub 152902d1be New useNavigateApp (#9729)
Todo : 
- replace all instances of useNavigate(
- remove getSettingsPagePath
- add eslint rule to enfore usage of useNavigateApp instead of
useNavigate
2025-01-18 13:58:12 +01:00
Charles BochetandGitHub 8572471973 Introduce IsScrollable on ScrollWrapper (#9724)
It's beautiful!

Using same techniques as for the Header! Was not that easy but looks
very nice now!
2025-01-17 19:26:34 +01:00
Baptiste DevessierandGitHub 18dea07344 Create many steps in a row (#9727)
Fixes
https://discord.com/channels/1130383047699738754/1329099124515274823
2025-01-17 18:12:11 +01:00
WeikoandGitHub 06033040d8 remove swc folder (#9723) 2025-01-17 16:35:50 +01:00
MarieandGitHub 3f372c0edf Revert "Fix last record row cells are cropped when selected (#9678)" (#9722)
This reverts commit 446bbdbd96.
2025-01-17 16:32:36 +01:00
Lucas BordeauandGitHub 6bd0244045 Fix date type update (#9700)
This PR fixes a problem with how TypeORM handles date without time. 

A date without time that is stored in PostgreSQL database as `date` type
gets returned as an ISO string date with a timezone that can shift its
date part in an unwanted way.

In short DB stores `2025-01-01`, TypeORM query builder returns
`2024-12-31T23:00:00Z` which gets parsed as `2024-12-31` on the front
end field.

We don't want to handle timezone here because we are manipulating a date
without its time part, so this PR adds a step that counteracts what
TypeORM does and returns `2025-01-01T00:00:00.000Z` so that the front
can parse it correctly.

@Weiko We might want to check other places of the backend where date
types are returned by TypeORM, we might have the same problem, this PR
only fixes it for updateOne resolver return.

- Fixed date persist on frontend which was shifting the date to a
different day due to timezone issue
- Fixed date returned by the backend update logic, which was shifting
the date by the timezone offset (so this PR adds back the offset so that
it stays at 00:00:00Z time)
2025-01-17 16:19:49 +01:00
Antoine MoreauxandGitHub b6b5fd1759 refactor(auth): remove redundant workspace lookup logic (#9716)
Removed unnecessary workspace lookup in `findWorkspaceForSignInUp` when
using password-based auth. Updated tests to validate the refactored
behavior and ensure no regressions in workspace resolution for different
auth scenarios.
2025-01-17 14:59:54 +01:00
Félix MalfaitandGitHub 2efc71b5cb Add first real translations + translation.io (#9715) 2025-01-17 14:59:19 +01:00
martmullandGitHub f8f9bb2b78 Serverless function timeout concerns (#9689)
closes https://github.com/twentyhq/core-team-issues/issues/242
- unify timeout behavior between local and lambda
- add timeout in serverless entity
- set timeout default to 300s (5min)
2025-01-17 13:49:02 +00:00
Antoine MoreauxandGitHub 679429447d fix(auth): update onboarding activation for specific users (#9702)
Adjust onboarding activation to trigger only for new users with
pictures. This prevents unnecessary activation steps for other user
types, streamlining the flow.
2025-01-17 14:31:24 +01:00
Félix MalfaitandGitHub f38a25412e Add more translations (#9707)
As per title
2025-01-17 12:50:28 +01:00
Paul RastoinandGitHub 55feeaeef1 [CI][FIX] Storybook coverage configuration injection per scope (#9711)
# Introduction
Running `storybook` with `configuration=pages` outputs a coverage that
is not replicated afterwards by the `storybook:coverage` command.
```sh
npx nx storybook:serve-and-test:static twenty-front --configuration=pages --shard=1/1 --checkCoverage=true
# ...
[TEST] Test Suites: 40 passed, 40 total
[TEST] Tests:       52 passed, 52 total
[TEST] Snapshots:   0 total
[TEST] Time:        84.786 s
[TEST] Ran all test suites.
[TEST] Coverage file (13067196 bytes) written to .nyc_output/coverage.json
[TEST] > nx storybook:coverage twenty-front --coverageDir=coverage/storybook --checkCoverage=true
[TEST] 
[TEST] 
[TEST] > nx run twenty-front:"storybook:coverage" --coverageDir=coverage/storybook --checkCoverage=true
[TEST] 
[TEST] > npx nyc report --reporter=lcov --reporter=text-summary -t coverage/storybook --report-dir coverage/storybook --check-coverage=true --cwd=packages/twenty-front
[TEST] 
[TEST] 
[TEST] =============================== Coverage summary ===============================
[TEST] Statements   : 70.45% ( 775/1100 )
[TEST] Branches     : 45.39% ( 197/434 )
[TEST] Functions    : 63.52% ( 209/329 )
[TEST] Lines        : 71.28% ( 767/1076 )
[TEST] ================================================================================
[TEST] 
```

```sh
> npx nyc report --reporter=lcov --reporter=text-summary -t coverage/storybook --report-dir coverage/storybook --check-coverage=true --cwd=packages/twenty-front


=============================== Coverage summary ===============================
Statements   : 37.4% ( 9326/24931 )
Branches     : 22.99% ( 2314/10063 )
Functions    : 28.27% ( 2189/7741 )
Lines        : 37.81% ( 9261/24488 )
================================================================================
ERROR: Coverage for lines (37.81%) does not meet global threshold (39%)
ERROR: Coverage for branches (22.99%) does not meet global threshold (23%)
ERROR: Coverage for statements (37.4%) does not meet global threshold (39%)
Warning: command "npx nyc report --reporter=lcov --reporter=text-summary -t coverage/storybook --report-dir coverage/storybook --check-coverage=true --cwd=packages/twenty-front" exited with non-zero status code
```

## Fix
Persist configuration scope arg to the `check-coverage` command

## Question
Should we add a step in the `ci-front` what would merge all
`performance,modules,pages` coverage and calculate the `global` coverage
? => I think that this has no plus value as we still compute each of
them individualy
2025-01-17 12:42:32 +01:00
Paul RastoinandGitHub 0357797612 [CI] Add performance to merge coverage matrix strategy job (#9708)
# Introduction
It seems like I've just oversight adding it back while debugging

# Centralization
Please note that we only have access to the following context within a
job matrix properties:
```
Available expression contexts: github, inputs, vars, needs
```
We could centralize the `storybook_scope` as a job `outputs` in order to
avoid this to re-occurs.
2025-01-17 11:17:39 +01:00
GuillimandGitHub b2a0eb6620 [Microsoft Outlook] fix + error handling (#9696)
- bettter error handling
- small fix in the amount of items Microsoft graph api accepts
2025-01-17 11:04:49 +01:00
Paul RastoinandGitHub 22ee77145a [CI] ci-server reorder twenty-shared build after cache restoration (#9672)
# Introduction
Unless I'm mistaken we can win few seconds `~12s` by reordering the
`twenty-shared` build step after the cache restoration in order for `nx`
to hit it if possible.

[Related
run](https://github.com/twentyhq/twenty/actions/runs/12809421832/job/35714544486)
2025-01-17 08:06:30 +01:00
Félix MalfaitandGitHub 7acb68929f Progress on translations (#9703)
Start adding a few translations on setting pages, introduce
pseudo-locale, switch to dynamic import, add eslint rule
2025-01-16 23:34:54 +01:00
f44b31573a Set up localization with feature flag control (#9649)
Refers #8128 

Changes Introduced:
- Added i18n configuration.
- Added a feature flag for localization.
- Enabled language switching based on the flag.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-01-16 21:00:56 +01:00
Raphaël BosiandGitHub b81ffcc77c Add viewId to recordIndexId (#9647)
Before the `recordIndexId` was the name plural. This caused problems
because the component states were the same for every view of an object.
When we switched from one view to another, some states weren't reset.
This PR fixes this by:
- Creating an effect at the same level of page change effect to set the
`currentViewId` inside the object `contextStore`
- Adding the `currentViewId` to the `recordIndexId`

Follow ups:
- We need to get rid of
`packages/twenty-front/src/modules/views/states/currentViewIdComponentState.ts`
and use the context store instead
2025-01-16 18:41:19 +01:00
WeikoandGitHub a248e891ae Upgrade to 0.40 guide (#9695) 2025-01-16 17:48:45 +01:00
Antoine MoreauxandGitHub 6540057c98 fix(auth): return early in workspace access check (#9697)
Ensure early return in `hasUserAccessToWorkspaceOrThrow` for existing
users during sign-in. This prevents further unnecessary execution when
access validation is complete.
2025-01-16 17:36:53 +01:00
f621af1732 fix: date input click outside (#9676)
cc @lucasbordeau

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-01-16 17:35:59 +01:00
Thomas TrompetteandGitHub 1df0603aaa Fix filter displayed value from query params (#9693)
Filter displayed value that use query params was broken. Recently we
added a new type of filters using the schema `{ selectedRecordIds:
string[] }` while before we were using `string[]` directly.
In that case, when fetching relation record name, we need to fix the
findManyRecord query.

Before
<img width="1512" alt="Capture d’écran 2025-01-16 à 16 10 33"
src="https://github.com/user-attachments/assets/36dc8c4f-91a4-438f-8480-bc237745a59e"
/>

After
<img width="1512" alt="Capture d’écran 2025-01-16 à 16 04 43"
src="https://github.com/user-attachments/assets/544512a3-0ef9-4d3e-993b-a4416737ab53"
/>
2025-01-16 17:16:42 +01:00
Raphaël BosiandGitHub 0ff8637469 Add create new record action to workflows (#9692)
- Added create new record action to `WorkflowActionsConfig`

As @FelixMalfait suggested
[here](https://github.com/twentyhq/core-team-issues/issues/72), we
should introduce an inheritance system for actions.
2025-01-16 17:10:16 +01:00
Thomas des FrancsandGitHub 2eb98bf966 0.40 changelog (#9688)
![0
40-group-by](https://github.com/user-attachments/assets/0e013739-af86-4650-9508-98b233064c4c)
![0
40-aggregates](https://github.com/user-attachments/assets/d9af1a60-c67c-40e9-9ecc-f84d52512c8a)
2025-01-16 16:50:50 +01:00
Antoine MoreauxandGitHub ad0dc7d664 fix(auth): streamline SSO auth callback logic (#9668)
Removed unused UserService dependency and simplified authCallback
function by using destructured parameters. Added checks for user email
and integrated invitation lookup and access validation for enhanced SSO
sign-in/up flow.
2025-01-16 16:07:06 +01:00
91eac86520 fix empty actor field (#9677)
<img width="300" alt="Screenshot 2025-01-16 at 14 19 18"
src="https://github.com/user-attachments/assets/1d8558b1-cab2-4256-9ab8-cc085dced7cd"
/>
<img width="300" alt="Screenshot 2025-01-16 at 14 19 24"
src="https://github.com/user-attachments/assets/e7100be8-be76-4bed-b149-658cd996adb1"
/>

closes #9180

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-16 15:28:06 +01:00
Thomas TrompetteandGitHub 7ec48b93eb Use main apollo client for workflows (#9675)
We were using metadata client by legacy. Architecture is not great for
Core engine: workflows are available both in data and metadata client.
It makes more sense to use the data client since workflows are part of
standard objects
2025-01-16 15:21:29 +01:00
df93b5b311 fix: increase font height and decrease gap in TrialCard (#9686)
### Context

Fix design to match 'Choose Your Trial' [figma
design](https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=52632-204440&t=mRMsJYiGtmCmWrs6-4)

<img width="331" alt="Screenshot 2025-01-16 at 15 04 30"
src="https://github.com/user-attachments/assets/b582ee71-2b1a-4003-ac0a-e39028fe432a"
/>

[Bug bash link

](https://discord.com/channels/1130383047699738754/1329445193300312084/1329445193300312084)

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-16 15:20:21 +01:00
446bbdbd96 Fix last record row cells are cropped when selected (#9678)
Before
<img width="432" alt="Capture d’écran 2025-01-16 à 14 52 34"
src="https://github.com/user-attachments/assets/0d23c48a-ad27-49ee-9194-7ae12397f928"
/>

After
<img width="503" alt="Capture d’écran 2025-01-16 à 14 51 55"
src="https://github.com/user-attachments/assets/c8b1c8d1-8655-48f0-81fc-d451878e0d10"
/>

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-01-16 15:14:06 +01:00
Charles BochetandGitHub f545bd1c40 Treat suspended workspace as workspaces that need to be synced (#9669)
In this PR:
- migrate WorkspaceActivationStatus to twenty-shared (and update case to
make FE and BE consistent)
- introduce isWorkspaceActiveOrSuspended in twenty-shared
- refactor the code to use it (when we fetch data on the FE, we want to
keep SUSPENDED workspace working + when we sync workspaces we want it
too)
2025-01-16 15:01:04 +01:00
4a0b89d094 Update GetClientConfigQuery type (#9673)
Co-authored-by: Weiko <corentin@twenty.com>
2025-01-16 14:49:20 +01:00
MarieandGitHub 5982a5a8ba Aggregate queries and field metadata deletion (#9660) 2025-01-16 14:46:56 +01:00
Paul RastoinandGitHub 560f715c37 [CI][NITPICK]: Rename prerequisites jobs to changed-files-check (#9670)
Related to https://github.com/twentyhq/twenty/pull/9643

Renaming `prerequisites` jobs to a more accurate `changed-files-check`
2025-01-16 14:09:59 +01:00
Paul RastoinandGitHub f8ddc02b8e [CI] Refactor changed files integration (#9643)
# BEFORE
[run](https://github.com/twentyhq/twenty/actions/runs/12806801953)

![image](https://github.com/user-attachments/assets/f0a8ffe3-3fc0-42ca-b2ee-8a980606b5dd)
# AFTER
[run](https://github.com/twentyhq/twenty/actions/runs/12807034402)

![image](https://github.com/user-attachments/assets/5117c680-6804-416b-a8c8-bf00614ca453)

## Motivations:
- less workflow to whitelist as blocking for PRs
- less if condition per step

cons:
- quite verbose
- need to manually sync the `ci-NAME-status-check` needs list to any
other existing and should be dep jobs

## Version migration
Migrated to the latest `changed-files@45` version, getting rid of the
`set-output` usage warnings

## Tests runs:

With mutation:
- [Success
flow](https://github.com/twentyhq/twenty/actions/runs/12791958651/job/35661546343)
- [server-setup failure
flow](https://github.com/twentyhq/twenty/actions/runs/12792225779)
- [Other job failure
flow](https://github.com/twentyhq/twenty/actions/runs/12792313463), one
of the `inner` job failed
- [Manual cancel
flow](https://github.com/twentyhq/twenty/actions/runs/12792313463)
`ci-server-status-check` also has the `cancelled` status
- [Matrix
failure](https://github.com/twentyhq/twenty/actions/runs/12806883553)

Without mutation:
- [Nothing to do
flow](https://github.com/twentyhq/twenty/actions/runs/12792098384),
skipped `inner` job but `ci-server-status-check` still succeeded

## Notes
### Linter
We should setup a `yml` prettier and linter for the `.github/worfklows`
folder
### Centralized `ci-NAME-status-check` logic
Unfortunately I couldn't achieve to either make a `composite` action or
a `reusable-workflow`, as I could not access the correct layer to run
the `always` but also acessing the `needs` context
2025-01-16 13:37:28 +01:00
4503ee3fbd bugfix: fix navigation between onboarding screens (#9637)
# This PR

- Fixes #9565

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-16 11:24:03 +01:00
Paul RastoinandGitHub 6a738181b4 [CI][NITPICK] .yml to yaml github workflows (#9664)
# Introduction
Applying the most present `yaml` file extension to all
`.github/workflows/` files

## Notes
Regarding the `restore-cache` and `save-cache` composite actions github
agnostically searches for any `DockerFile` `action.yml` and
`action.yaml` within the target folder when invoking composite actions
as follows:
```yml
      - name: Restore storybook build cache
        if: steps.changed-files.outputs.any_changed == 'true'
        uses: ./.github/workflows/actions/restore-cache
        with: 
          key: ${{ env.STORYBOOK_BUILD_CACHE_KEY }}
```
2025-01-16 11:21:00 +01:00
Jérémy MandGitHub 9a82fb980b fix: record group chevron alignment (#9661)
<img width="142" alt="Screenshot 2025-01-16 at 10 23 07 AM"
src="https://github.com/user-attachments/assets/07ea1d2f-0172-4f8e-94e4-bfeb87f4092a"
/>
<img width="153" alt="Screenshot 2025-01-16 at 10 22 37 AM"
src="https://github.com/user-attachments/assets/685bd859-cc51-4d52-8c3f-aba83056e92c"
/>

Fix Chevron alignment and CheckBox alignment
2025-01-16 11:20:39 +01:00
Jérémy MandGitHub f74b12adb8 fix: group by disabled in dark mode wrong color (#9662)
<img width="255" alt="Screenshot 2025-01-16 at 10 51 50 AM"
src="https://github.com/user-attachments/assets/c171401e-6c19-42f1-975b-fdb33b0a0789"
/>
2025-01-16 11:15:03 +01:00
26058f3e25 Update ChooseYourPlan page with new trial period options (#9628)
### Context
- Update /plan-required page to let users get free trial without credit
card plan
- Update usePageChangeEffectNavigateLocation to redirect paused and
canceled subscription (suspended workspace) to /settings/billing page

### To do

- [x] Update usePageChangeEffectNavigateLocation test
- [x] Update ChooseYourPlan sb test



closes #9520

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-16 11:10:36 +01:00
Thomas TrompetteandGitHub c79cb14132 Refetch query on draft creation (#9650)
After hitting use as draft, we redirect the user to the workflow page.
If the user already accessed that page, the workflow and its current
version will be stored in cache. So we also need to update that cache.

I tried to update it manually but it was more complex than expected.
Steps and trigger are not fully defined objects.

I ended with a simple refetch query that I wanted to avoid but that is
at least fully working with minimum logic.
2025-01-16 10:46:23 +01:00
BOHEUSandGitHub 34ddeade83 Documentation + docker-compose.yml update (#9653)
Related to #9469 #9455 #9419 #8943
2025-01-16 10:43:27 +01:00
Jérémy MandGitHub 5bae5a9f7c fix: filter dark mode (#9659)
Fix dark mode color of dropdown menu in Filter
2025-01-16 10:29:35 +01:00
Jérémy MandGitHub f5b0926b63 feat: record group chevron button (#9645)
This ticket is related to this Discord post
https://discord.com/channels/1130383047699738754/1328756649657110559
2025-01-16 10:03:05 +01:00
GuillimandGitHub f077efd171 Outlook integration (#9631)
Get Partial messages
2025-01-16 09:50:01 +01:00
Antoine MoreauxandGitHub 789ff30dc7 fix(sso|auth): fix sso signinup (#9651)
Renamed `user` to `payload` for better context clarity and updated
related references. Adjusted the login token generation to use
`workspace.id`, improving readability and maintainability of the code.
2025-01-15 19:27:05 +01:00
f722a2d619 Add Email Verification for non-Microsoft/Google Emails (#9288)
Closes twentyhq/twenty#8240 

This PR introduces email verification for non-Microsoft/Google Emails:

## Email Verification SignInUp Flow:

https://github.com/user-attachments/assets/740e9714-5413-4fd8-b02e-ace728ea47ef

The email verification link is sent as part of the
`SignInUpStep.EmailVerification`. The email verification token
validation is handled on a separate page (`AppPath.VerifyEmail`). A
verification email resend can be triggered from both pages.

## Email Verification Flow Screenshots (In Order):

![image](https://github.com/user-attachments/assets/d52237dc-fcc6-4754-a40f-b7d6294eebad)

![image](https://github.com/user-attachments/assets/263a4b6b-db49-406b-9e43-6c0f90488bb8)

![image](https://github.com/user-attachments/assets/0343ae51-32ef-48b8-8167-a96deb7db99e)

## Sent Email Details (Subject & Template):
![Screenshot 2025-01-05 at 11 56
56 PM](https://github.com/user-attachments/assets/475840d1-7d47-4792-b8c6-5c9ef5e02229)

![image](https://github.com/user-attachments/assets/a41b3b36-a36f-4a8e-b1f9-beeec7fe23e4)

### Successful Email Verification Redirect:

![image](https://github.com/user-attachments/assets/e2fad9e2-f4b1-485e-8f4a-32163c2718e7)

### Unsuccessful Email Verification (invalid token, invalid email, token
expired, user does not exist, etc.):

![image](https://github.com/user-attachments/assets/92f4b65e-2971-4f26-a9fa-7aafadd2b305)

### Force Sign In When Email Not Verified:

![image](https://github.com/user-attachments/assets/86d0f188-cded-49a6-bde9-9630fd18d71e)

# TODOs:

## Sign Up Process

- [x] Introduce server-level environment variable
IS_EMAIL_VERIFICATION_REQUIRED (defaults to false)
- [x] Ensure users joining an existing workspace through an invite are
not required to validate their email
- [x] Generate an email verification token
- [x] Store the token in appToken
- [x] Send email containing the verification link
  - [x] Create new email template for email verification
- [x] Create a frontend page to handle verification requests

## Sign In Process

- [x] After verifying user credentials, check if user's email is
verified and prompt to to verify
- [x] Show an option to resend the verification email

## Database

- [x] Rename the `emailVerified` colum on `user` to to `isEmailVerified`
for consistency

## During Deployment
- [x] Run a script/sql query to set `isEmailVerified` to `true` for all
users with a Google/Microsoft email and all users that show an
indication of a valid subscription (e.g. linked credit card)
- I have created a draft migration file below that shows one possible
approach to implementing this change:

```typescript
import { MigrationInterface, QueryRunner } from 'typeorm';

export class UpdateEmailVerifiedForActiveUsers1733318043628
  implements MigrationInterface
{
  name = 'UpdateEmailVerifiedForActiveUsers1733318043628';

  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      CREATE TABLE core."user_email_verified_backup" AS
      SELECT id, email, "isEmailVerified"
      FROM core."user"
      WHERE "deletedAt" IS NULL;
    `);

    await queryRunner.query(`
      -- Update isEmailVerified for users who have been part of workspaces with active subscriptions
      UPDATE core."user" u
      SET "isEmailVerified" = true
      WHERE EXISTS (
        -- Check if user has been part of a workspace through userWorkspace table
        SELECT 1 
        FROM core."userWorkspace" uw
        JOIN core."workspace" w ON uw."workspaceId" = w.id
        WHERE uw."userId" = u.id
        -- Check for valid subscription indicators
        AND (
          w."activationStatus" = 'ACTIVE'
          -- Add any other subscription-related conditions here
        )
      )
      AND u."deletedAt" IS NULL;
  `);
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      UPDATE core."user" u
      SET "isEmailVerified" = b."isEmailVerified"
      FROM core."user_email_verified_backup" b
      WHERE u.id = b.id;
    `);

    await queryRunner.query(`DROP TABLE core."user_email_verified_backup";`);
  }
}

```

---------

Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-01-15 18:43:40 +01:00
Antoine MoreauxandGitHub 266b771a5b [test(auth)]: Add unit tests for useSignInUpForm hook (#9648)
Introduce unit tests to validate the behavior of the useSignInUpForm
hook. Tests cover default initialization, handling of developer
defaults, and prefilled values based on state.
2025-01-15 18:07:06 +01:00
MarieandGitHub 585212b441 Aggregate queries - Fix empty / not empty operations on composite fields and array fields (#9644)
as per title

closes https://github.com/twentyhq/twenty/issues/9353
2025-01-15 16:59:46 +00:00
martmullandGitHub b5c5bee6cf Fix error message (#9646)
- fix typo
2025-01-15 16:29:42 +00:00
martmullandGitHub c01e3af8ee Fix race condition on stripe subscription (#9629)
Fixes https://github.com/twentyhq/core-team-issues/issues/191
- remove automatic redirection on payment success page when subscription
status is undefined
- add an effect component to refresh the subscription status on payment
success page

Observation: Locally, I had to delay the stripe webhook subscription
created endpoint by 7s to see race condition issue


https://github.com/user-attachments/assets/463e1816-34fd-4c4f-b590-3994a3a3e91a
2025-01-15 16:08:34 +01:00
Paul RastoinandGitHub d63aec44bb [CI] Yarn install composite action remove --immutable-cache (#9641) 2025-01-15 16:02:29 +01:00
MarieandGitHub 8e0c9fbf16 Aggregate queries - add seeds (#9640)
as per title
adding seeds on table views, kanban views, view groups
2025-01-15 15:52:09 +01:00
Paul RastoinandGitHub 7cb259d692 [CI] Refactor yarn-install composite action (#9613)
# Introduction
Unless I'm mistaken in the existing `yarn-install` composite action
`dependencies` are cached twice.

## Cached through `setup-node`
As we're providing `yarn` value to cache inputs.
Setup node will cache the global `.yarn`
```yml
    - name: Setup Node.js and get yarn cache
      uses: actions/setup-node@v3
      with:
        node-version: 18
        cache: yarn
```

## Programmatic `node_modules` caching
We even manually still cache `node_modules` folder using:
```yml
    - name: Cache node modules
      id: node-modules-cache
      uses: actions/cache@v3
      with:
        path: |
          node_modules
          packages/*/node_modules
        key: root-node_modules-${{ hashFiles('yarn.lock') }}
        restore-keys: root-node_modules-
```
By the way it seems like that the `yarn.lock` file is useless as the
restore-key pattern omits it
This could, unless I'm mistaken, leads to invalid cache restore

## Runtime
The current infra results in the following install deps logs:
```sh
Prepare all required actions
Getting action download info
Download action repository 'actions/setup-node@v3' (SHA:1a444[2](https://github.com/twentyhq/twenty/actions/runs/12770942233/job/35596946506#step:6:2)cacd436585916779262731d5b162bc6ec7)
Download action repository 'actions/cache@v[3](https://github.com/twentyhq/twenty/actions/runs/12770942233/job/35596946506#step:6:3)' (SHA:f4b3439a656ba812b8cb417d2d49f9c810103092)
Run ./.github/workflows/actions/yarn-install
Run actions/setup-node@v3
Found in cache @ /opt/hostedtoolcache/node/18.20.5/x6[4](https://github.com/twentyhq/twenty/actions/runs/12770942233/job/35596946506#step:6:4)
Environment details
/usr/local/bin/yarn --version
4.4.0
/usr/local/bin/yarn config get cacheFolder
/home/runner/.yarn/berry/cache
/usr/local/bin/yarn config get enableGlobalCache
true
Cache Size: ~421 MB (441369819 B)
/usr/bin/tar -xf /home/runner/work/_temp/883eae34-9b21-4684-96[5](https://github.com/twentyhq/twenty/actions/runs/12770942233/job/35596946506#step:6:5)8-cdb937f62965/cache.tzst -P -C /home/runner/work/twenty/twenty --use-compress-program unzstd
Cache restored successfully
Cache restored from key: node-cache-Linux-yarn-a8c18b6600f1bc685e60192f39a0a0c5c51b918829090129d3787302789547fc
Run actions/cache@v3
Cache Size: ~506 MB (530305961 B)
/usr/bin/tar -xf /home/runner/work/_temp/becd3767-ac80-4ca9-8d[21](https://github.com/twentyhq/twenty/actions/runs/12770942233/job/35596946506#step:6:23)-93fa61e3070c/cache.tzst -P -C /home/runner/work/twenty/twenty --use-compress-program unzstd
Cache restored successfully
Cache restored from key: root-node_modules-a8c18b6600f1bc685e60192f39a0a0c5c51b918829090129d378730[27](https://github.com/twentyhq/twenty/actions/runs/12770942233/job/35596946506#step:6:30)89547fc
```
Where we can see in details that a cache is hit twice.
```
Cache Size: ~421 MB (441369819 B)
Cache Size: ~506 MB (530305961 B)
```

## Suggestion
We should stick to only one deps caching mechanism.
Also caching the node_modules folder is not
[recommended](https://github.com/actions/cache/blob/611465405cc89ab98caca2c42504d9289fb5f22e/examples.md#node---npm).
That's why I would factorize our caching to the `setup-node` scope only.

## The cache-primary-key crafting
Within the cache-primary-key we will inject the following metrics:
- Node version, as we're caching `node_modules` directly in this way to
avoid cache desync in case we upgrade node.
- Hash of the lockfile, in this way if the lockfile comes to mutate we
will re-install the deps from scratch, in this way no need to
programmatically listen for `changed-files` on the `package.json` and
the `lockfile`
- Strict installation with `check-cache` and `enableHardenedMode` to
true and obviously the `--immutable` flag ( note adding the
`--immutable-cache` by principle even if on paper is overkill as a cache
restoration and install should never occurs )
2025-01-15 15:46:53 +01:00
Raphaël BosiandGitHub 77a11d30d3 Make calendar event details readonly (#9638)
Before:


https://github.com/user-attachments/assets/870aee34-58b4-48bc-b90f-ce17d61da26e


After:


https://github.com/user-attachments/assets/498d46f9-bd4e-400f-a645-076a86999479
2025-01-15 15:30:45 +01:00
Antoine MoreauxandGitHub 4fdea61f1d fix(auth): handle missing invitation during sign-up (#9572)
Add validation to throw an exception when a sign-up is attempted without
a valid invitation. Updated the test suite to cover this case and ensure
proper error handling with appropriate exceptions.

Fix https://github.com/twentyhq/twenty/issues/9566
https://github.com/twentyhq/twenty/issues/9564
2025-01-15 15:26:51 +01:00
MarieandGitHub f828e75b72 Aggregate queries follow up (#9636)
In this PR 

- [X] Fix missing IconCheck for count all on kanban headers:
https://discord.com/channels/1130383047699738754/1319330910361096242/1319330910361096242
- [X] Fix aggregate cell height:
https://discord.com/channels/1130383047699738754/1328749516488441997/1328749516488441997
- [X] Fix aggregate bar should extend fully to the right:
https://discord.com/channels/1130383047699738754/1328750532193681569/1328750532193681569
- [X] Fix first aggregate cell should fully spread to the left:
https://discord.com/channels/1130383047699738754/1326614678788374638/1326614678788374638
2025-01-15 15:25:10 +01:00
Raphaël BosiandGitHub ff93fd3c74 190 display ctrl instead of for windows users (#9617)
Closes https://github.com/twentyhq/core-team-issues/issues/190

<img width="226" alt="Capture d’écran 2025-01-15 à 12 07 12"
src="https://github.com/user-attachments/assets/b9a13746-2629-477a-9795-cda03c63f8f6"
/>

To test, update the user agent in your browser dev tools:
<img width="459" alt="Capture d’écran 2025-01-15 à 12 14 29"
src="https://github.com/user-attachments/assets/4371d5fc-fd3c-403d-beaa-7ba58019d3c9"
/>
2025-01-15 12:53:18 +00:00
Paul RastoinandGitHub 9ba510eb3f [CI] Always save cache agnostically of the actions/restore cache-hit output (#9635)
## Motivations
This is not because we've hit the `actions/cache/restore` cache that NX
won't be re-building sub commands.
Which means the grain to save or not the cache should be extracted from
nx sub commands and not from the `actions/cache` outputs.

We should investigate on the way to retrieve this granularity level

From the moment we will be saving everything, which could result
sometimes in duplicating cache instances.
We should keep in mind that our cache occurrences have a 1 day retention
date, is low cost and pretty fast to perform
2025-01-15 11:59:17 +01:00
Jérémy MandGitHub eae300a95d fix: add hover effect on record table action row (#9633)
Related to this discord follow up
https://discord.com/channels/1130383047699738754/1328751649174585427
2025-01-15 11:42:21 +01:00
Raphaël BosiandGitHub 5fb6b18b18 77 create new record action and remove old behavior (#9598)
Closes https://github.com/twentyhq/core-team-issues/issues/77
2025-01-15 11:39:37 +01:00
Baptiste DevessierandGitHub 765dedab0a Ensure users can set the empty value for the FormPhoneFieldInput (#9632)
Fixes
https://discord.com/channels/1130383047699738754/1328729510547296288
2025-01-15 11:33:36 +01:00
WeikoandGitHub 5d0ec9116f Fix delete workspace-member avatar (#9630)
## Context
avatarUrl is a TEXT field type so non nullable, which means if we try to
run a mutation with null it will either fail or be ignored. Here this is
the second option, done in sanitizeRecordInput where when a
fieldMetadata has isNullable=false and the value is null, we return
undefined. This caused the mutation to send an empty input and not
remove the avatar
2025-01-15 11:26:39 +01:00
GuillimandGitHub fc484bde2d [Outlook integration] part 2 : GetMessages (#9612)
### Introducing

- mock files in order to setup unit test on parsing outlook messages
- special spec files for development purposes : dev.spec files. They are
CI skipped with xdescribe but very useful for iterating on new messages
format
- main functionality : getMessages. We use microsoft default client to
do so, using the $batch endpoint to group calls by 20

### documentation
final touch to add troubleshooting tips
2025-01-15 09:48:57 +01:00
Jérémy MandGitHub eaa68424f5 Fix/record group index and seed (#9605)
- [x] [Disable group by on default view Options
menu](https://discord.com/channels/1130383047699738754/1328421803399446568)
- [x] Add default seed for view group
2025-01-15 09:37:15 +01:00
Winston HoyandGitHub 1a5b3ef2f8 for docker installs, override SIGN_IN_PREFILLED=false (#9627)
fixes #9231
2025-01-15 08:11:39 +01:00
Baptiste DevessierandGitHub c543a930cd Improve workflow arrows' design (#9619)
Old design:

![CleanShot_2024-11-12_at_17 37
33](https://github.com/user-attachments/assets/1fcaba6d-f23c-4679-b038-d051abeb0bbd)


New design:

![CleanShot 2025-01-14 at 18 22
10@2x](https://github.com/user-attachments/assets/a683163d-2e3c-42ed-8abd-1f1fd31bf7db)
2025-01-14 22:38:44 +01:00
Thomas TrompetteandGitHub f2bee55e6c Remove missing log (#9621)
Forgot one log to remove
2025-01-14 17:42:33 +00:00
Thomas TrompetteandGitHub 9360a6b1de Clean logs from console.time (#9620)
As title. We do not need those anymore.
2025-01-14 18:32:54 +01:00
Charles BochetandGitHub 42ddc09f74 Add command to tag workspace as suspended or as deleted (#9610)
In this PR:
- remove old versions upgrade commands
- add a 0.40 upgrade command to loop over all INACTIVE workspaces and
either: update to SUSPENDED (if workspaceSchema exists), update them to
SUSPENDED + deletedAt (if workspaceSchema does not exist anymore)

Note: why updating the deleted one to SUSPENDED? Because I plan to
remove INACTIVE case in the enum in 0.41

Tests made on production like database:
- dry-mode
- singleWorkspaceId
- 3 cases : suspended, deleted+suspended, deleted+suspended+delete all
data
2025-01-14 18:23:42 +01:00
Thomas TrompetteandGitHub 87be542185 Fix workflow run output empty (#9616)
- catch error on action execution. We will log the error and return it
in the step
- catch error on workflow run
- remove the catch in the action. All actions should simply throw and
let the executor do the job

<img width="1512" alt="Capture d’écran 2025-01-14 à 17 35 53"
src="https://github.com/user-attachments/assets/dcf79567-a309-45f1-a640-c50b7ac4769b"
/>
2025-01-14 17:18:40 +00:00
MarieandGitHub 3e8fee7ff7 Fix overflowing aggregate value on kanban header (#9614)
before


![image](https://github.com/user-attachments/assets/d7a98f27-ec66-4341-8c49-1b0626e923db)

after

<img width="232" alt="image"
src="https://github.com/user-attachments/assets/5bdd286e-b60c-42f1-aaca-d1d6ee6e82aa"
/>
2025-01-14 17:46:47 +01:00
Raphaël BosiandGitHub 8fb9cb4f5f Fix command menu avatar url (#9611)
Closes #9488
2025-01-14 15:37:14 +00:00
Paul RastoinandGitHub d133d7f10e [CI] Migrate to ubuntu 24.04 runners (#9607)
## Introduction
Our GitHub Runners provider just
[released](https://depot.dev/changelog/2024-07-12-ubuntu-24-04-github-actions-runner-beta)
ubuntu-24.04 runners lately

## Cache primary key factorization
Refactored the calculation of the cache-primary-key prefix to avoid
duplication

## Runs
- twenty-front lint
https://github.com/twentyhq/twenty/actions/runs/12770312293/job/35595272862
- twenty-server
https://github.com/twentyhq/twenty/actions/runs/12770218595
2025-01-14 16:18:45 +01:00
Thomas TrompetteandGitHub b83793f9dc Fix placeholders in select (#9608)
Before
<img width="537" alt="Capture d’écran 2025-01-14 à 14 36 59"
src="https://github.com/user-attachments/assets/b29cc4da-ac67-4ea7-83dd-03e1e68e7938"
/>
<img width="537" alt="Capture d’écran 2025-01-14 à 14 37 05"
src="https://github.com/user-attachments/assets/7645e905-0421-48e8-8f91-f1bb6064bb18"
/>


After
<img width="537" alt="Capture d’écran 2025-01-14 à 14 35 36"
src="https://github.com/user-attachments/assets/8b059fb5-9137-46e5-8c81-105e254831c2"
/>
<img width="537" alt="Capture d’écran 2025-01-14 à 14 35 44"
src="https://github.com/user-attachments/assets/aa0a754b-2fb7-4985-8154-e69ddef10596"
/>
<img width="537" alt="Capture d’écran 2025-01-14 à 14 35 56"
src="https://github.com/user-attachments/assets/d90d1f89-1480-4de9-b02b-519370a27bfe"
/>
<img width="537" alt="Capture d’écran 2025-01-14 à 14 36 11"
src="https://github.com/user-attachments/assets/67c25d62-d509-4e23-b2b6-c44d3b7cd37a"
/>
2025-01-14 15:30:47 +01:00
Lucas BordeauandGitHub 6ab9b79bf3 Moving record filter related types, hooks and utils into record-filter module (#9604)
This PR is only moving and renaming types, hooks and utils to
record-filter module folder.

- Moved and renamed types from object filter modules to record filter…-
Moved and renamed types from object filter modules to record filter
module
- Moved useApplyRecordFilter to record filter module
- Renamed util getOperandsForFilterDefinition to
getRecordFilterOperandsForRecordFilterDefinition
2025-01-14 14:21:05 +00:00
Charles BochetandGitHub 508feb4e7e Introduce SUSPENDED Activation Status (#9609)
We are introducing a new workspace activationStatus "SUSPENDED". This
status represents a workspace which is SUSPENDED (either manually by the
admin or in case if IS_BILLING_ENABLED if the subscription is unpaid |
canceled | paused).

We will keep making sure these workspaces are healthy but prevent the
user from using it (they will be redirected to the billing page)
2025-01-14 14:52:45 +01:00
Baptiste DevessierandGitHub c9b91dcfaa Fix error when deleting the trigger of an activated workflow version (#9606)
Fixes
https://discord.com/channels/1130383047699738754/1328375628512100412
2025-01-14 14:34:51 +01:00
Paul RastoinandGitHub b815de3e26 [FIX][CI] cache-hit incorrectly computed (#9603)
## Introduction
The `cache-hit` value should be a string boolean, but it seems like not
to always be the case ?

## Related runs
- twenty-server first attempt saves cache second retrieves it
https://github.com/twentyhq/twenty/actions/runs/12768260350
- twenty-front
https://github.com/twentyhq/twenty/actions/runs/12767064201
2025-01-14 14:18:33 +01:00
Baptiste DevessierandGitHub 4719fe6ed9 Fix form date time field right border when variable picker is provided and field is readonly (#9600) 2025-01-14 13:58:52 +01:00
f151963e66 fixs #9456 : Workspace switcher font weight (#9591)
Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
2025-01-14 11:52:19 +00:00
Paul RastoinandGitHub 5d09bd4b93 [CI][NITPICK] Remove input types invalid syntax (#9596)
## Introduction
Unless I'm mistaken neither the `inputs.type` or `inputs.type` syntax
exists for `composite actions`.
By default it seems like any `Composite action` inputs are considered as
`string`.
```yml
name: Nx Affected CI
inputs:
  parallel:
    required: false
    types: [number]
    default: 3
  tag:
    required: false
    types: [string]
  tasks:
    required: true
    types: [string]
```

## Suggestion
To avoid misunderstanding of our composite actions inputs signature I
would recommend removing any `type` props but also default any inputs as
`strings`

## Misc
- Please find related GitHub community discussion
https://github.com/orgs/community/discussions/65588
2025-01-14 12:23:37 +01:00
Félix MalfaitandGitHub 459d0b18cf Simplify docker compose (#9602)
Seems like Spilo doesn't take into account the password?!
2025-01-14 12:19:57 +01:00
MarieandGitHub 35d165dbe9 Fix header dropdown button style (#9599) 2025-01-14 12:13:26 +01:00
Paul RastoinandGitHub 6fc691beb0 [CI] Refactor composite action task-cache (#9583)
## Introduction
In this previous PR https://github.com/twentyhq/twenty/pull/9448 we've
refactored the storybook build caching flow to be using the new
[actions/cache](https://github.com/actions/cache) `restore` and `save`
functions, which significantly improve caching operations duration.

In this way, in this PR, we've standardize both of the `restore` and
`save` by refactoring the `task-cache` composite action. By creating two
new composite actions `save-cache` and `restore-cache` that centralize
the paths to cache and the way to compute the primary key.

## Misc
- **If no cache** is hit, then a job duration will long for its task
duration and nothing else, previously the cache upload would sometimes
take up to 3 mins.
- **if cache** is hit, then mainly the only time consuming step is the
dependencies installation ( which is theory is also cached, in fact
twice. We will be having a look on this issue in an upcoming PR )
2025-01-14 12:06:23 +01:00
Félix MalfaitandGitHub 90d984d27d Remove signin prefill from docker compose (#9597)
I think this was affecting the 1-click install
2025-01-14 11:46:17 +01:00
martmullandGitHub f0287d273d Add containsAny filter comparators in rest api (#9595)
- add missing `containsAny` filter comparator to filter multiSelect
fields
- fix app break if object with same name created
- fix flash when clicking on choose plan
### Before


https://github.com/user-attachments/assets/71709912-63e8-40f8-bc52-3ec0a62746bb


### After



https://github.com/user-attachments/assets/93ee02c2-e3d9-4bab-8b6a-62813fd40b2b
2025-01-14 11:40:02 +01:00
Baptiste DevessierandGitHub 5eeee6a7ed Add readonly mode to form fields - 2nd part (#9582)
In this PR, I implemented or confirmed that the read-only mode works for
the following fields:

- [x] FormUuidFieldInput
- [x] FormRawJsonFieldInput
- [x] FormPhoneFieldInput
- [x] FormEmailsFieldInput
- [x] FormLinksFieldInput
- [x] FormAddressFieldInput
- [x] FormFullNameFieldInput
2025-01-14 11:34:26 +01:00
Félix MalfaitandGitHub 21a6dff2c9 1-click install take latest version from docker (#9592)
There was a small issue where if you used the 1-click install script
right after it was tagged on Github but before it was built and
published to Docker hub, then it would fail
2025-01-14 10:20:47 +01:00
21e2295ade Support old relation filter value format (#9590)
Fix production bug caused by old relation filter value.

**Draft, not tested yet at all, working on it right now.**

---------

Co-authored-by: ad-elias <elias@autodiligence.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-13 21:45:39 +01:00
Thomas TrompetteandGitHub e893c4dcce Workflow fast follows batch (#9587)
- Add icon chevron on select
- Fix event step label
- Fix generate function output
2025-01-13 18:31:15 +01:00
WeikoandGitHub f9a90a6561 Fix featureFlag not matching gql type (#9585)
## Context

<img width="1349" alt="Screenshot 2025-01-13 at 17 18 24"
src="https://github.com/user-attachments/assets/4f5da0e9-0245-41c6-bde2-4d52e0ba34ed"
/>

Feature flags are stored in DB and then cast as FeatureFlag gql type
from its corresponding enum.
This means if a value from the DB does not match that enum type, the gql
server will reject the call when returning the object in the resolver.
(see screenshot above)

To solve that, we want to do 2 things:
- The ORM should still return the feature flag even if it's not valid,
this is actually in the DB so we don't want to "hide" that, however we
now have a warning message.
- The service is not changed for the same reason, the limitation comes
from gql behaviour so this is not the goal of the service nor the ORM to
act on it (except the warning message)
- The resolver should be updated, here we want to filter-out non-valid
feature flags so it does not break the API.

Because featureFlags used to be auto-generated by nestjsquery and we
want to change its behavior, I had to manually create a resolveField for
featureFlags and remove the auto-generated one. That means we lose some
features such as filter/sort coming from nestjs-query pagination (which
is something we will want to implement once we will remove nestjs-query
but that's a whole other subject)
2025-01-13 18:30:16 +01:00
martmullandGitHub 55bae60f69 Fix wrong domainName for redirect url (#9586)
Closes https://github.com/twentyhq/twenty/issues/9097

Fixes the redirect url of stripe `checkout` and `billingPortal` sessions

## Before


https://github.com/user-attachments/assets/4ccab325-41e1-494e-854a-9d9a72e534f1

## After


https://github.com/user-attachments/assets/740b07f4-84b0-4670-a5b6-2684fde640c8
2025-01-13 17:03:01 +00:00
MarieandGitHub 17850b76ab Aggregate queries follow up (#9581)
In this PR

- fixing Collapse on view groups views: aggregate bar should be included
in the collapse (@magrinj )
- respect the html table pattern: the aggregate bar is now a <tr>
element included in a <table> (before that, it was a <tr> not included
in anything)
- add a top-border on the aggregate bar
- introduce short labels for the on-cell value display (display "Empty"
instead of "Count empty" to lighten the interface)
- remove the feature flag !
2025-01-13 17:20:35 +01:00
Raphaël BosiandGitHub 739611afa8 Migrate copilot to command menu (#9522)
Open copilot chat inside command menu


https://github.com/user-attachments/assets/60d83a77-6e96-4daa-98b0-33b7c1157d9a
2025-01-13 17:12:31 +01:00
Lucas BordeauandGitHub 86c4decdbd Refactored sort dropdown hooks (#9584)
- Removed useObjectSortDropdown hook
- Removed useSortDropdown hook
2025-01-13 17:07:05 +01:00
Raphaël BosiandGitHub 530a18558b 9426 migrate workflow pages to command menu (#9515)
Closes twentyhq/core-team-issues#53 

- Removes command menu top bar text input when the user is not on root
page
- Fixes bug when resetting command menu context
- Added animations on command menu open and close
- Refactored workflow visualizer code to remove unnecessary rerenders
and props drilling


https://github.com/user-attachments/assets/1da3adb8-220b-407b-9279-30354d3100d3
2025-01-13 16:53:57 +01:00
martmullandGitHub 330addbc0b Refech code after code update (#9577)
- fixes code step update, then close code step, then open code step,
code not up to date
2025-01-13 15:53:56 +01:00
Baptiste DevessierandGitHub 9ebe519e66 Finalize the readonly for a few form fields #1 (#9524)
There are many fields so I will cut my work in several small PRs.

Here, I updated the following fields:

- [x] `FormBooleanFieldInput`
- [x] `FormCurrencyFieldInput`
- [x] `FormNumberFieldInput`
- [x] `FormDateFieldInput`
- [x] `FormDateTimeFieldInput`
- [x] `FormMultiSelectFieldInput`
- [x] `FormSelectFieldInput`

The updates in the components are relatively small. I wrote Storybook
tests, and this is why the PR is quite big.

The changes in the components should mostly the same.

I added a disabled state to some inputs.

I created a specialized `VariableChip` as its styles started diverging
from the original `SortOrFilterChip`.
2025-01-13 15:07:41 +01:00
Jérémy MandGitHub b81879dead fix: drop record group feature flag (#9575) 2025-01-13 14:50:27 +01:00
Jérémy MandGitHub 6314cdb36c fix: remove sticky shadow from RecordTableActionRow (#9576) 2025-01-13 14:48:33 +01:00
Jérémy MandGitHub cc2d6154e7 fix: table acton row wrong stroke (#9574)
As requested by @Bonapara the stroke of `RecordTableActionRow` should be
in `sm` instead of `md`.
2025-01-13 14:42:37 +01:00
Lucas BordeauandGitHub 719344f980 Refactor record sort dropdown (#9578)
- Refactored all sort dropdown states to V2
- Added ObjectSortDropdownComponentInstanceContext
- Cleaned some constants
2025-01-13 14:42:02 +01:00
martmullandGitHub 5783d68d62 Remove serverless functions on version archivation (#9535)
Fixes https://github.com/twentyhq/core-team-issues/issues/52
- contrary to title, we do not remove serverless functions on workflow
version archivation because serverless fucntion might be used in another
workflow version
- we fix the serverless funciton version displayed in the code step
- we allow test function version in step display right drawer
- we delete serverless function only when serverless function has no
published version
2025-01-13 13:09:57 +00:00
nitinandGitHub 8643eaa28f Aggregate footer should have pseudo element only if there is horizontal scroll (#9559)
fixes
https://discord.com/channels/1130383047699738754/1326614903414587534/1326903218214666261
2025-01-13 13:40:33 +01:00
Jérémy MandGitHub 61c5acb982 fix: StyledMenuItemBase remove spacing when no icon (#9573) 2025-01-13 11:42:39 +01:00
002cbd3b78 Fixing phone search functionality (#9466)
This PR targets twentyhq/core-team-issues#85. 

@FelixMalfait As we discussed I have made those changes . Could you
please test it at your end?

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-13 10:54:00 +01:00
Jérémy MandGitHub 128abb2b85 fix: error thrown when switching between table with/without record group (#9571)
Fix an error when switching between a table with and without record
group.
2025-01-13 10:48:13 +01:00
GuillimandGitHub 34ee64a36c [Microsoft integration] getFullMessageList (#9544)
Creation of the GmailGetMessageListService
Implementation of the driver to MS Graph API getFullMessageList
2025-01-13 10:13:37 +01:00
c1847054f8 Playwright E2E test - sign up with invite link via email (#9332)
Related to
https://github.com/twentyhq/twenty/issues/8469#issuecomment-2471573054

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-01-12 21:52:30 +01:00
ba77091b06 fix: reset table selection when navigating away from index page (#9140)
Fixes #9132 

## Purpose
Currently, when navigating away from an index page and returning,
previously checked selections remain checked. This fix ensures the
selection context is properly reset on navigation.

## Changes
- Add `RecordIndexResetSelectionEffect` component to handle selection
cleanup
- Integrate effect into `RecordIndexPage`
- Uses existing `useResetTableRowSelection` hook to clear selections

## Testing
1. Go to any index page (e.g., Companies)
2. Select some records using checkboxes
3. Navigate to a detail page
4. Return to the index page
5. Verify that no records are selected

## Demo
I've recorded a short video demonstrating how this PR fixes the issue:

[Loom Video
Link](https://www.loom.com/share/72ca46a5dc194b5092e1944a985fa0d2?sid=55c95d8b-2376-4ac5-b406-6483aa7e341f)

Before fix: Selections persist after navigation
After fix: Selections are properly reset

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-11 11:23:07 +01:00
LazalatinandGitHub 9ed9b310f7 Update links in docs to current release (#9553)
As this was missing I just updated to reference the files from the
current release tag
2025-01-10 21:58:30 +01:00
Charles BochetandGitHub 9d735b8562 Try migrating to depot (#9555) 2025-01-10 21:46:26 +01:00
Charles BochetandGitHub 5ec28afac9 Fix Storybook tests (#9554)
Finally fixing the storybook tests!
2025-01-10 20:54:10 +01:00
MarieandGitHub 2e0169b954 Aggregate follow-up (#9547)
In this PR
- fix [some UI
regressions](https://discord.com/channels/1130383047699738754/1327189577575956514/1327189577575956514)
introduced by work on view groups
- address some follow-ups:
1. [Menu should keep selected when the menu is
open](https://discord.com/channels/1130383047699738754/1326607851824877639/1326607851824877639)
2.
[Cropping](https://discord.com/channels/1130383047699738754/1326610578869063800/1326610578869063800)
3. [Put earliest date / latest date in a separate "Date"
submenu](https://discord.com/channels/1130383047699738754/1326856023985618966/1326856023985618966)
- Refactor around date aggregate operations
2025-01-10 20:01:36 +01:00
Paul RastoinandGitHub 873f20bc0e [CI][FRONT] Storybook tests sharding (#9448)
# Introduction
The idea here is to improve perf nor fluidity of both storybook build
and tests execution duration.

## Levers:
- Storybook tests
[shards](https://storybook.js.org/docs/writing-tests/test-runner)
- Refactored storybook's build caching using `actions/cache/restore` and
`actions/cache/save` to avoid useless computation with we wanna just
write or retrieve it
- Running storybook build with --test
[flag](https://storybook.js.org/docs/api/main-config/main-config-build)
( please note that we only disable docs addons in order to keep coverage
up and running )

closes https://github.com/twentyhq/core-team-issues/issues/49
2025-01-10 18:40:03 +01:00
Antoine MoreauxandGitHub b40f58a512 refactor(admin-panel): standardize FeatureFlagKey usage (#9548)
Replaced string-based feature flag keys with the typed FeatureFlagKey
enum across the admin panel module and related front-end hooks. This
ensures stronger type safety, reduces potential errors, and improves
consistency in handling feature flags.
2025-01-10 18:38:50 +01:00
Lucas BordeauandGitHub ed51bff2f4 Clean up object record filter (#9550)
Last clean up of object dropdown filter states v1. 

Removed old state scope context component.
2025-01-10 18:37:29 +01:00
Thomas TrompetteandGitHub 4efa959401 Fix apollo cache for workflow cmd+k (#9549)
When a workflow was activate, the previous activated version was still
available in cmd+k
This is because we were only updating entities in cache after
activation.
We also need to update the queries stored in cache, because this is
where the cmd+k look to know which workflow is active.


https://github.com/user-attachments/assets/750cc24a-7583-4641-856c-0f9892d26331
2025-01-10 18:33:10 +01:00
11a47264a7 fix: fix regression on multiItem input field when no item (#9543)
### Context
Fix on [8904 issue](https://github.com/twentyhq/twenty/issues/8904)
([PR](https://github.com/twentyhq/twenty/pull/9439)) introduces a
regression when field has no item.
Background should be lighter.
<img width="250" alt="Screenshot 2025-01-10 at 16 08 03"
src="https://github.com/user-attachments/assets/1eb39455-f24a-4301-9a72-7a9a8f5c8382"
/>


### Solution
Conditional styling, displayed only when MultiInput has item
<img width="250" alt="Screenshot 2025-01-10 at 16 08 20"
src="https://github.com/user-attachments/assets/6bc02aa0-0430-4207-8163-c31d66751f3e"
/>

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-10 18:32:52 +01:00
Antoine MoreauxandGitHub 4ca03d0066 fix(auth): handle error properly in loadCurrentUser (#9539)
Updated the loadCurrentUser function to throw specific errors when an
API error occurs. This improves clarity and error handling, replacing
the generic "No current user result" exception.

Fix #9536
2025-01-10 17:21:33 +01:00
Nicolas RouanneandGitHub 07fa58b042 docs(server-commands): fix typo in command to generate migrations (#9545)
- the command had `--migration:generate` instead of `migration:generate`
written in the doc
- when copy pasting it we got this error
```
Not enough non-option arguments: got 0, need at least 1
```
- after removing the extra `--` it worked as expected
2025-01-10 17:21:15 +01:00
Charles BochetandGitHub b46bc84dab Fix mail import gmail driver when message has been deleted (#9546)
We forgot to ignore messages that were removed
2025-01-10 16:52:29 +01:00
Antoine MoreauxandGitHub d1170668df refactor: update import paths for FeatureFlagKey (#9542)
Replaced references to '~/generated-metadata/graphql' with
'~/generated/graphql' across multiple files. This change ensures
uniformity in import paths and aligns with the updated directory
structure.
2025-01-10 16:20:10 +01:00
Thomas TrompetteandGitHub 92c119ed43 Add suggested values for variable dropdown (#9437)
<img width="378" alt="Capture d’écran 2025-01-07 à 15 37 20"
src="https://github.com/user-attachments/assets/c15abcac-684a-4c3b-ad12-62cf91afe927"
/>

Here is a first version:
- simple fields have a suggested value
- composite do not, but sub values of composite do
- json, arrays or complex values do not
2025-01-10 16:18:37 +01:00
Antoine MoreauxandGitHub 5648c3b31c [refactor]: Remove isSSOEnabled logic throughout the codebase (#9462)
Eliminated all references to `isSSOEnabled` across the frontend,
backend, and configuration files. This change simplifies the codebase by
removing unnecessary feature flag checks, associated logic, and
environment variables. The SSO feature remains available without
reliance on this flag.
2025-01-10 14:45:35 +01:00
Lucas BordeauandGitHub e58edc3bc1 Removed useFilterDropdown hook (#9537)
Removed useFilterDropdown hook and its many calls which were only
exporting states.

The test has been removed because it was used to do the equivalent of
testing Recoil states, so it wasn't useful anymore.
2025-01-10 14:45:17 +01:00
martmullandGitHub 7b2debf6fb Add error marker when invalid main function (#9489)
## Before

![image](https://github.com/user-attachments/assets/f6af6721-0896-48b5-8556-9d2a9c19de06)

## After

![image](https://github.com/user-attachments/assets/c59407c8-8244-4906-9d05-713909a19c33)
2025-01-10 14:29:58 +01:00
ddcb3dfd28 Feature flags env variable gating (#9481)
closes #9032

---------

Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
2025-01-10 14:04:00 +01:00
Antoine MoreauxandGitHub 75bf9e3c69 fix(admin-panel): resolve feature flag key mismatch (#9530)
Update feature flag handling by mapping input keys to enum values. This
ensures compatibility and prevents potential runtime errors when
updating workspace feature flags.
2025-01-10 12:30:42 +01:00
Lucas BordeauandGitHub c716a30d92 Refactored empty filter (#9532)
Refactored empty filter function and removed it from useFilterDropdown
hook
2025-01-10 12:30:01 +01:00
Charles Bochet 654a0bb79e Fix CI Server 2025-01-10 12:29:22 +01:00
Jérémy MandGitHub 0a798a6671 Feat/view groups fast follow (#9513)
Fix #9512 

- 🟠 [Icon should be
lighter](https://discord.com/channels/1130383047699738754/1326487470895923222)
The current weight is the same as in Figma, waiting for confirmation
- 🟠 [None has an unwanted margin
left](https://discord.com/channels/1130383047699738754/1326493647796961323)
This component is used in lot of places, removing the padding left can
brake other places
- 🟢 [All cells should have a the same right
design](https://discord.com/channels/1130383047699738754/1326489001926066176)
- 🔴 [Group Sorting should not "freeze" when mouse is
release](https://discord.com/channels/1130383047699738754/1326494381795966996)
Can't find a good way to fix it, seems more related to the fact it's
running in debug mode.
- 🟢 [Alignment
issue](https://discord.com/channels/1130383047699738754/1326486523822084140)
- 🟢 [View record count
error](https://discord.com/channels/1130383047699738754/1326491489466978365)
- 🟢 [Vertically align tags and
numbers/count](https://discord.com/channels/1130383047699738754/1326490661800902728)
- 🟢 [Display "Calculate" only on hover in view
groups](https://discord.com/channels/1130383047699738754/1326490411929436191)
- 🟢 [Aggregates height in view groups is 28px instead of
32px](https://discord.com/channels/1130383047699738754/1326489587127943188)
- 🟠 [Picker under the
aggregate](https://discord.com/channels/1130383047699738754/1326487940557439039)
Can't reproduce the issue
- 🟢 [Icon should not be
hoverable](https://discord.com/channels/1130383047699738754/1326477402360123425)
- 🟢 [Crop long view
titles](https://discord.com/channels/1130383047699738754/1326477009576136755)
- 🟢 [Removing the group by on opportunities (group by none) give an
white
screen](https://discord.com/channels/1130383047699738754/1324651927962910750)
2025-01-09 19:12:57 +01:00
1f1cac3b00 chore: update returned attachement fullPath (#9516)
### Solution

fullPath prop on attachement (when returned by backend) is updated to
'domain + path' (formerly 'path').

Consequently, getFileAbsoluteURI util in front is removed.

closes #8763

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-09 19:12:36 +01:00
Charles Bochet 4c8c338316 Update ci runner for sb build 2025-01-09 18:58:36 +01:00
21774c60c7 Refactored reset filter dropdown (#9523)
This PR extracts reset filter logic from useFilterDropdown hook.

The goal is to remove useFilterDropdown hook by incrementally removing
each sub hook one by one.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-09 18:56:21 +01:00
Lucas BordeauandGitHub 17e2e38812 Refactored select filter and select filter definition logic (#9519)
This PR extracts the logic to manage filter and filter definition
setting.

Previously it was ambiguous, we had the same "selectFilter" naming used
for setting filter definition in filter dropdown and for setting the
actual filter value and saving to view filter states.

This is another incremental refactor, which will allow to remove
useFilterDropdown hook.
2025-01-09 18:54:34 +01:00
71a4593ba4 Move FieldMetadataType to twenty-shared (#9482)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-09 18:43:30 +01:00
c39af5f063 Add Integration and unit tests on Billing (#9317)
Solves [ https://github.com/twentyhq/private-issues/issues/214 ]

**TLDR**
Add unit and integration tests to Billing. First approach to run jest
integration tests directly from VSCode.

**In order to run the unit tests:**
Run unit test using the CLI or with the jest extension directly from
VSCode.

**In order to run the integration tests:**
Ensure that your database has the billingTables. If that's not the case,
migrate the database with IS_BILLING_ENABLED set to true:
` npx nx run twenty-server:test:integration
test/integration/billing/suites/billing-controller.integration-spec.ts`

**Doing:**
- Unit test on transformSubscriptionEventToSubscriptionItem
- More tests cases in billingController integration tests.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-01-09 18:30:41 +01:00
Weiko 4ed1db3845 fix AuthException parameters 2025-01-09 18:29:09 +01:00
Lucas BordeauandGitHub f44d99d2ff Refactored object filter dropdown states (#9507)
Refactored object filter dropdown states while keeping the existing
structure to avoid creating a big PR.

The goal is to extract each sub hook returned by the useFilterDropdown
hook and create a PR for each function and the associated refactor for
the dependent zones in the code, so that we proceed by small increments.
2025-01-09 18:18:27 +01:00
5756 changed files with 474674 additions and 98423 deletions
+65
View File
@@ -0,0 +1,65 @@
# Twenty Development Rules
This directory contains Twenty's development guidelines and best practices. The rules are organized into several key categories:
## Guidelines Structure
### 1. Architecture and Structure
- `architecture.md`: Project overview, technology stack, and infrastructure setup
- `file-structure-guidelines.md`: File and directory organization patterns
### 2. Code Style and Development
- `typescript-guidelines.md`: TypeScript best practices and conventions
- `code-style-guidelines.md`: General coding standards and style guide
### 3. React Development
- `react-general-guidelines.md`: Core React development principles and patterns
- `react-state-management-guidelines.md`: State management approaches and best practices
### 4. Testing
- `testing-guidelines.md`: Testing strategies, patterns, and best practices
### 5. Internationalization
- `translations.md`: Translation workflow, i18n setup, and string management
## Common Development Commands
### Frontend Commands
```bash
# Testing
npx nx test twenty-front # Run unit tests
npx nx storybook:build twenty-front # Build Storybook
npx nx storybook:serve-and-test:static # Run Storybook tests
# Development
npx nx lint twenty-front # Run linter
npx nx typecheck twenty-front # Type checking
npx nx run twenty-front:graphql:generate # Generate GraphQL types
```
### Backend Commands
```bash
# Database
npx nx database:reset twenty-server # Reset database
npx nx run twenty-server:database:init:prod # Initialize database
npx nx run twenty-server:database:migrate:prod # Run migrations
# Development
npx nx run twenty-server:start # Start the server
npx nx run twenty-server:lint # Run linter (add --fix to auto-fix)
npx nx run twenty-server:typecheck # Type checking
npx nx run twenty-server:test # Run unit tests
npx nx run twenty-server:test:integration:with-db-reset # Run integration tests
# Migrations
npx nx run twenty-server:typeorm migration:generate src/database/typeorm/metadata/migrations/[name] -d src/database/typeorm/metadata/metadata.datasource.ts
# Workspace
npx nx run twenty-server:command workspace:sync-metadata -f # Sync metadata
```
## Usage
These rules are automatically attached to relevant files in your workspace through Cursor's context system. They help maintain consistency and quality across the Twenty codebase.
For the most up-to-date version of these guidelines, always refer to the files in this directory.
+97
View File
@@ -0,0 +1,97 @@
# Twenty Project Architecture
## Overview
Twenty is an open-source CRM built with modern technologies, using TypeScript for both frontend and backend development. This document outlines the core architectural decisions and structure of the project.
## Monorepo Structure
The project is organized as a monorepo using nx, with the following main packages:
### Main Packages
- `packages/twenty-front`: Main Frontend application
- Technology: React
- Purpose: Provides the main user interface for the CRM
- Key responsibilities: User interactions, state management, data display
- `packages/twenty-server`: Main Backend application
- Technology: NestJS
- Purpose: Handles business logic, data persistence, and API
- Key responsibilities: Data processing, authentication, API endpoints
- `packages/twenty-website`: Marketing Website and Documentation
- Technology: NextJS
- Purpose: Public-facing website and documentation
- Key responsibilities: Marketing content, documentation, SEO
- `packages/twenty-ui`: UI Component Library
- Technology: React
- Purpose: Shared UI components and design system
- Key responsibilities: Reusable components, design consistency
- `packages/twenty-shared`: Shared Utilities
- Purpose: Cross-package shared code between frontend and backend
- Contents: Utils, constants, types, interfaces
## Core Technology Stack
### Package Management
- Package Manager: yarn
- Monorepo Tool: nx
- Benefits: Consistent dependency management, shared configurations
### Database Layer
- Primary Database: PostgreSQL
- Schema Structure:
- Core schema: Main application data
- Metadata schema: Configuration and customization data
- Workspace schemas: One schema per tenant, containing tenant-specific data
- ORM Layer:
- TypeORM: For core and metadata schemas
- Purpose: Type-safe database operations for system data
- Benefits: Strong typing, migration support
- TwentyORM: For workspace schemas
- Purpose: Manages tenant-specific entities and customizations
- Benefits: Dynamic entity management, per-tenant customization
- Example: Entities like CompanyWorkspaceEntity are managed per workspace
### State Management
- Frontend State: Recoil
- Purpose: Global state management
- Use cases: User preferences, UI state, cached data
### Data Layer
- API Technology: GraphQL
- Client: Apollo Client
- Purpose: Data fetching and caching
- Benefits: Type safety, efficient data loading
### Infrastructure
- Cache: Redis
- Purpose: High-performance caching layer
- Use cases: Session data, frequent queries
- Authentication: JWT
- Purpose: Secure user authentication
- Implementation: Token-based auth flow
- Queue System: BullMQ
- Purpose: Background job processing
- Use cases: Emails, exports, imports
- Storage: S3/Local Filesystem
- Purpose: File storage and management
- Flexibility: Configurable for cloud or local storage
### Testing Infrastructure
- Backend Testing:
- Framework: Jest
- API Testing: Supertest
- Coverage: Unit tests, integration tests
- Frontend Testing:
- Framework: Jest
- Component Testing: Storybook
- API Mocking: MSW (Mock Service Worker)
- End-to-End Testing:
- Framework: Playwright
- Coverage: Critical user journeys
+259
View File
@@ -0,0 +1,259 @@
# Code Style Guidelines
## Core Code Style Principles
Twenty emphasizes clean, readable, and maintainable code. This document outlines our code style conventions and best practices.
## Control Flow
### Early Returns
- Use early returns to reduce nesting
- Handle edge cases first
```typescript
// ✅ Correct
const processUser = (user: User | null) => {
if (!user) return null;
if (!user.isActive) return null;
return {
id: user.id,
name: user.name,
};
};
// ❌ Incorrect
const processUser = (user: User | null) => {
if (user) {
if (user.isActive) {
return {
id: user.id,
name: user.name,
};
}
}
return null;
};
```
### No Nested Ternaries
- Avoid nested ternary operators
- Use if statements or early returns
```typescript
// ✅ Correct
const getUserDisplay = (user: User) => {
if (!user.name) return 'Anonymous';
if (!user.isActive) return 'Inactive User';
return user.name;
};
// ❌ Incorrect
const getUserDisplay = (user: User) =>
user.name
? user.isActive
? user.name
: 'Inactive User'
: 'Anonymous';
```
### No Else-If Chains
- Use switch statements or lookup objects
- Keep conditions flat
```typescript
// ✅ Correct
const getStatusColor = (status: Status): string => {
switch (status) {
case 'success':
return 'green';
case 'warning':
return 'yellow';
case 'error':
return 'red';
default:
return 'gray';
}
};
// Or using a lookup object
const statusColors: Record<Status, string> = {
success: 'green',
warning: 'yellow',
error: 'red',
default: 'gray',
};
// ❌ Incorrect
const getStatusColor = (status: Status): string => {
if (status === 'success') {
return 'green';
} else if (status === 'warning') {
return 'yellow';
} else if (status === 'error') {
return 'red';
} else {
return 'gray';
}
};
```
## Operators and Expressions
### Optional Chaining Over &&
- Use optional chaining for null/undefined checks
- Clearer intent and better type safety
```typescript
// ✅ Correct
const userName = user?.name;
const userAddress = user?.address?.street;
// ❌ Incorrect
const userName = user && user.name;
const userAddress = user && user.address && user.address.street;
```
## Function Design
### Small Focused Functions
- Keep functions small and single-purpose
- Extract complex logic into helper functions
```typescript
// ✅ Correct
const validateUser = (user: User) => {
if (!isValidName(user.name)) return false;
if (!isValidEmail(user.email)) return false;
if (!isValidAge(user.age)) return false;
return true;
};
const isValidName = (name: string) => {
return name.length >= 2 && /^[a-zA-Z\s]*$/.test(name);
};
const isValidEmail = (email: string) => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
};
const isValidAge = (age: number) => {
return age >= 18 && age <= 120;
};
// ❌ Incorrect
const validateUser = (user: User) => {
if (user.name.length < 2 || !/^[a-zA-Z\s]*$/.test(user.name)) return false;
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(user.email)) return false;
if (user.age < 18 || user.age > 120) return false;
return true;
};
```
## Naming and Documentation
### Clear Variable Names
- Use descriptive, intention-revealing names
- Avoid abbreviations unless common
```typescript
// ✅ Correct
const isUserActive = user.status === 'active';
const hasRequiredPermissions = user.permissions.includes('admin');
const userDisplayName = user.name || 'Anonymous';
// ❌ Incorrect
const active = user.status === 'active';
const hasPerm = user.permissions.includes('admin');
const udn = user.name || 'Anonymous';
```
### No Console.logs in Commits
- Remove all console.logs before committing
- Use proper logging/error tracking in production
```typescript
// ❌ Incorrect - Don't commit these
console.log('user:', user);
console.log('debug:', someValue);
// ✅ Correct - Use proper logging
logger.info('User action completed', { userId: user.id });
logger.error('Operation failed', { error });
```
### Minimal Comments
- Write self-documenting code
- Use comments only for complex business logic
```typescript
// ✅ Correct
// Calculate pro-rated amount based on billing cycle
const calculateProRatedAmount = (amount: number, daysLeft: number, totalDays: number) => {
return (amount * daysLeft) / totalDays;
};
// ❌ Incorrect - Unnecessary comments
// Get the user's name
const getUserName = (user: User) => user.name;
// Check if user is active
const isUserActive = (user: User) => user.status === 'active';
```
## Error Handling
### Proper Error Handling
- Use try-catch blocks appropriately
- Provide meaningful error messages
```typescript
// ✅ Correct
const fetchUserData = async (userId: string) => {
try {
const response = await api.get(`/users/${userId}`);
return response.data;
} catch (error) {
logger.error('Failed to fetch user data', {
userId,
error: error instanceof Error ? error.message : 'Unknown error',
});
throw new UserFetchError('Failed to fetch user data');
}
};
// ❌ Incorrect
const fetchUserData = async (userId: string) => {
try {
const response = await api.get(`/users/${userId}`);
return response.data;
} catch (error) {
console.log('error:', error);
throw error;
}
};
```
## Code Organization
### Logical Grouping
- Group related code together
- Maintain consistent organization
```typescript
// ✅ Correct
class UserService {
// Properties
private readonly api: Api;
private readonly logger: Logger;
// Constructor
constructor(api: Api, logger: Logger) {
this.api = api;
this.logger = logger;
}
// Public methods
public async getUser(id: string): Promise<User> {
// Implementation
}
public async updateUser(user: User): Promise<User> {
// Implementation
}
// Private helpers
private validateUser(user: User): boolean {
// Implementation
}
}
```
+207
View File
@@ -0,0 +1,207 @@
# File Structure Guidelines
## Core File Structure Principles
Twenty follows a modular and organized file structure that promotes maintainability and scalability. This document outlines our file organization conventions and best practices.
## Component Organization
### One Component Per File
- Each component should have its own file
- File name should match component name
```typescript
// ✅ Correct
// UserProfile.tsx
export const UserProfile = () => {
return <div>...</div>;
};
// ❌ Incorrect
// users.tsx
export const UserProfile = () => {
return <div>...</div>;
};
export const UserList = () => {
return <div>...</div>;
};
```
## Directory Structure
### Feature Modules
- Place features in `modules/` directory
- Group related components and logic
```
modules/
├── users/
│ ├── components/
│ │ ├── UserList.tsx
│ │ ├── UserCard.tsx
│ │ └── UserProfile.tsx
│ ├── hooks/
│ │ └── useUser.ts
│ ├── states/
│ │ └── userStates.ts
│ └── types/
│ └── user.ts
├── workspace/
│ ├── components/
│ ├── hooks/
│ └── states/
└── settings/
├── components/
├── hooks/
└── states/
```
### Hooks Organization
- Place hooks in `hooks/` directory
- Group by feature or global usage
```
hooks/
├── useClickOutside.ts
├── useDebounce.ts
└── features/
├── users/
│ ├── useUserActions.ts
│ └── useUserData.ts
└── workspace/
└── useWorkspaceSettings.ts
```
### State Management
- Place state definitions in `states/` directory
- Organize by feature
```
states/
├── global/
│ ├── theme.ts
│ └── navigation.ts
├── users/
│ ├── atoms.ts
│ └── selectors.ts
└── workspace/
├── atoms.ts
└── selectors.ts
```
### Types Organization
- Place types in `types/` directory
- Group by domain or feature
```
types/
├── common.ts
├── api.ts
└── features/
├── user.ts
├── workspace.ts
└── settings.ts
```
## Naming Conventions
### Component Files
- Use PascalCase for component files
- Use descriptive, feature-specific names
```
components/
├── UserProfile.tsx
├── UserProfileHeader.tsx
└── UserProfileContent.tsx
```
### Non-Component Files
- Use camelCase for non-component files
- Use clear, descriptive names
```
hooks/
├── useClickOutside.ts
└── useDebounce.ts
utils/
├── dateFormatter.ts
└── stringUtils.ts
```
## Module Structure
### Feature Module Organization
- Consistent structure across features
- Clear separation of concerns
```
modules/users/
├── components/
│ ├── UserList/
│ │ ├── UserList.tsx
│ │ ├── UserListItem.tsx
│ │ └── UserListHeader.tsx
│ └── UserProfile/
│ ├── UserProfile.tsx
│ └── UserProfileHeader.tsx
├── hooks/
│ ├── useUserList.ts
│ └── useUserProfile.ts
├── states/
│ ├── atoms.ts
│ └── selectors.ts
├── types/
│ └── user.ts
└── utils/
└── userFormatter.ts
```
## Best Practices
### Import Organization
- Group imports by type
- Maintain consistent order
```typescript
// External dependencies
import { useState } from 'react';
import { styled } from '@emotion/styled';
// Internal modules
import { useUser } from '~/modules/users/hooks';
import { userState } from '~/modules/users/states';
// Local imports
import { UserAvatar } from './UserAvatar';
import { type UserProfileProps } from './types';
```
### Path Aliases
- Use path aliases for better imports
- Avoid deep relative paths
```typescript
// ✅ Correct
import { Button } from '~/components/Button';
import { useUser } from '~/modules/users/hooks';
// ❌ Incorrect
import { Button } from '../../../components/Button';
import { useUser } from '../../../modules/users/hooks';
```
### Component Co-location
- Keep related files close together
- Use index files for public APIs
```
components/UserProfile/
├── UserProfile.tsx
├── UserProfileHeader.tsx
├── UserProfileContent.tsx
├── styles.ts
├── types.ts
└── index.ts
```
### Test File Location
- Place test files next to implementation
- Use `.test.ts` or `.spec.ts` extension
```
components/
├── UserProfile.tsx
├── UserProfile.test.tsx
├── UserProfile.stories.tsx
└── types.ts
```
+220
View File
@@ -0,0 +1,220 @@
# React Guidelines
## Core React Principles
Twenty follows modern React best practices with a focus on functional components and clean, maintainable code. This document outlines our React conventions and best practices.
## Component Structure
### Functional Components Only
- Use functional components exclusively
- No class components allowed
```typescript
// ✅ Correct
export const UserProfile = ({ user }: UserProfileProps) => {
return (
<StyledContainer>
<h1>{user.name}</h1>
</StyledContainer>
);
};
// ❌ Incorrect
export class UserProfile extends React.Component<UserProfileProps> {
render() {
return (
<StyledContainer>
<h1>{this.props.user.name}</h1>
</StyledContainer>
);
}
}
```
### Named Exports
- Use named exports exclusively
- No default exports
```typescript
// ✅ Correct
export const Button = ({ label }: ButtonProps) => {
return <button>{label}</button>;
};
// ❌ Incorrect
export default function Button({ label }: ButtonProps) {
return <button>{label}</button>;
}
```
## State and Effects
### Event Handlers Over useEffect
- Prefer event handlers for state updates
- Avoid useEffect for state synchronization
```typescript
// ✅ Correct
const UserForm = () => {
const handleSubmit = async (data: FormData) => {
await updateUser(data);
refreshUserList();
};
return <Form onSubmit={handleSubmit} />;
};
// ❌ Incorrect
const UserForm = () => {
useEffect(() => {
if (formData) {
updateUser(formData);
}
}, [formData]);
return <Form />;
};
```
## Component Design
### Small, Focused Components
- Keep components small and single-purpose
- Extract reusable logic into custom hooks
```typescript
// ✅ Correct
const UserCard = ({ user }: UserCardProps) => {
return (
<StyledCard>
<UserAvatar user={user} />
<UserInfo user={user} />
<UserActions user={user} />
</StyledCard>
);
};
// ❌ Incorrect
const UserCard = ({ user }: UserCardProps) => {
return (
<StyledCard>
{/* Too much logic in one component */}
<img src={user.avatar} />
<div>{user.name}</div>
<div>{user.email}</div>
<button onClick={() => handleEdit(user)}>Edit</button>
<button onClick={() => handleDelete(user)}>Delete</button>
{/* More complex logic... */}
</StyledCard>
);
};
```
## Props
### Prop Naming
- Use clear, descriptive prop names
- Follow React conventions (onClick, isActive, etc.)
```typescript
// ✅ Correct
type ButtonProps = {
onClick: () => void;
isDisabled?: boolean;
isLoading?: boolean;
};
// ❌ Incorrect
type ButtonProps = {
clickHandler: () => void;
disabled?: boolean;
loading?: boolean;
};
```
### Prop Destructuring
- Destructure props with proper typing
- Use TypeScript for prop types
```typescript
// ✅ Correct
const Button = ({ onClick, isDisabled, children }: ButtonProps) => {
return (
<button onClick={onClick} disabled={isDisabled}>
{children}
</button>
);
};
// ❌ Incorrect
const Button = (props: ButtonProps) => {
return (
<button onClick={props.onClick} disabled={props.isDisabled}>
{props.children}
</button>
);
};
```
## Performance Optimization
### Memoization
- Use memo for expensive computations
- Avoid premature optimization
```typescript
// ✅ Correct - Complex computation
const MemoizedChart = memo(({ data }: ChartProps) => {
// Complex rendering logic
return <ComplexChart data={data} />;
});
// ❌ Incorrect - Unnecessary memoization
const MemoizedText = memo(({ text }: { text: string }) => {
return <span>{text}</span>;
});
```
### Event Handlers
- Use callback refs for DOM manipulation
- Memoize callbacks when needed
```typescript
// ✅ Correct
const UserList = () => {
const handleScroll = useCallback((event: UIEvent) => {
// Complex scroll handling
}, []);
return <div onScroll={handleScroll}>{/* content */}</div>;
};
```
## Error Handling
### Error Boundaries
- Use error boundaries for component error handling
- Provide meaningful fallback UIs
```typescript
// ✅ Correct
const ErrorFallback = ({ error }: { error: Error }) => (
<StyledError>
<h2>Something went wrong</h2>
<pre>{error.message}</pre>
</StyledError>
);
const SafeComponent = () => (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<ComponentThatMightError />
</ErrorBoundary>
);
```
### Loading States
- Handle loading states gracefully
- Provide meaningful loading indicators
```typescript
// ✅ Correct
const UserProfile = () => {
const { data: user, isLoading, error } = useUser();
if (isLoading) return <LoadingSpinner />;
if (error) return <ErrorMessage error={error} />;
if (!user) return <NotFound />;
return <UserProfileContent user={user} />;
};
```
@@ -0,0 +1,219 @@
# State Management Guidelines
## Core State Management Principles
Twenty uses a combination of Recoil for global state and Apollo Client for server state management. This document outlines our state management conventions and best practices.
## Global State Management
### Recoil Usage
- Use Recoil for global application state
- Keep atoms small and focused
```typescript
// ✅ Correct
// states/theme.ts
export const themeState = atom<'light' | 'dark'>({
key: 'themeState',
default: 'light',
});
// states/user.ts
export const userState = atom<User | null>({
key: 'userState',
default: null,
});
// ❌ Incorrect
// states/globalState.ts
export const globalState = atom({
key: 'globalState',
default: {
theme: 'light',
user: null,
settings: {},
// ... many other unrelated pieces of state
},
});
```
### Atom Organization
- Place atoms in the `states/` directory
- Group related atoms in feature-specific files
```typescript
// states/workspace/atoms.ts
export const workspaceIdState = atom<string>({
key: 'workspaceIdState',
default: '',
});
export const workspaceSettingsState = atom<WorkspaceSettings>({
key: 'workspaceSettingsState',
default: defaultSettings,
});
```
## Server State Management
### Apollo Client Usage
- Use Apollo Client for all GraphQL operations
- Leverage Apollo's caching capabilities
```typescript
// ✅ Correct
const { data, loading } = useQuery(GET_USER_QUERY, {
variables: { id },
fetchPolicy: 'cache-first',
});
// ❌ Incorrect
const [user, setUser] = useState(null);
useEffect(() => {
fetch('/api/user/' + id).then(setUser);
}, [id]);
```
### Query Organization
- Separate operation files
- Use fragments for shared fields
```typescript
// queries/user.ts
export const UserFragment = gql`
fragment UserFields on User {
id
name
email
}
`;
export const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
...UserFields
}
}
${UserFragment}
`;
```
## State Management Best Practices
### Multiple Small Atoms
- Prefer multiple small atoms over prop drilling
- Keep atoms focused on specific features
```typescript
// ✅ Correct
export const selectedViewState = atom<string>({
key: 'selectedViewState',
default: '',
});
export const viewFiltersState = atom<ViewFilters>({
key: 'viewFiltersState',
default: {},
});
// ❌ Incorrect - Prop drilling
const ViewContainer = ({ selectedView, filters, onViewChange }) => {
return (
<ViewHeader view={selectedView} onViewChange={onViewChange}>
<ViewContent>
<ViewFilters filters={filters} />
</ViewContent>
</ViewHeader>
);
};
```
### No useRef for State
- Never use useRef for state management
- Use proper state management tools
```typescript
// ✅ Correct
const [count, setCount] = useState(0);
// or
const [count, setCount] = useRecoilState(countState);
// ❌ Incorrect
const countRef = useRef(0);
```
### Data Fetching
- Extract data fetching to sibling components
- Keep components focused on presentation
```typescript
// ✅ Correct
const UserProfileContainer = () => {
const { data, loading } = useQuery(GET_USER);
if (loading) return <LoadingSpinner />;
return <UserProfile user={data.user} />;
};
const UserProfile = ({ user }: UserProfileProps) => {
return <div>{user.name}</div>;
};
// ❌ Incorrect
const UserProfile = () => {
const { data, loading } = useQuery(GET_USER);
if (loading) return <LoadingSpinner />;
return <div>{data.user.name}</div>;
};
```
### Hook Usage
- Use appropriate hooks for state access
- Choose between useRecoilValue and useRecoilState based on needs
```typescript
// ✅ Correct - Read-only access
const theme = useRecoilValue(themeState);
// ✅ Correct - Read-write access
const [theme, setTheme] = useRecoilState(themeState);
// ❌ Incorrect - Using state setter when only reading
const [theme, _] = useRecoilState(themeState);
```
## Performance Considerations
### Selector Usage
- Use selectors for derived state
- Memoize complex calculations
```typescript
// ✅ Correct
const filteredUsersState = selector({
key: 'filteredUsersState',
get: ({ get }) => {
const users = get(usersState);
const filter = get(userFilterState);
return users.filter(user =>
user.name.toLowerCase().includes(filter.toLowerCase())
);
},
});
// ❌ Incorrect - Calculating in component
const UserList = () => {
const users = useRecoilValue(usersState);
const filter = useRecoilValue(userFilterState);
const filteredUsers = users.filter(user =>
user.name.toLowerCase().includes(filter.toLowerCase())
);
return <List users={filteredUsers} />;
};
```
### Cache Management
- Configure appropriate cache policies
- Handle cache invalidation properly
```typescript
// ✅ Correct
const [updateUser] = useMutation(UPDATE_USER, {
update: (cache, { data }) => {
cache.modify({
id: cache.identify(data.updateUser),
fields: {
name: () => data.updateUser.name,
},
});
},
});
```
+253
View File
@@ -0,0 +1,253 @@
# Testing Guidelines
## Core Testing Principles
Twenty follows a comprehensive testing strategy across all packages, ensuring high-quality, maintainable code. This document outlines our testing conventions and best practices.
## Testing Stack
### Backend Testing
- Primary Framework: Jest
- API Testing: Supertest
- Coverage Requirements: 80% minimum
### Frontend Testing
- Component Testing: Jest + React Testing Library
- Visual Testing: Storybook
- API Mocking: MSW (Mock Service Worker)
### End-to-End Testing
- Framework: Playwright
- Coverage: Critical user journeys
- Cross-browser testing
## Test Organization
### Test File Location
- Co-locate tests with implementation files
- Use consistent naming patterns
```
src/
├── components/
│ ├── UserProfile.tsx
│ ├── UserProfile.test.tsx
│ └── UserProfile.stories.tsx
```
### Test File Naming
- Use `.test.ts(x)` for unit/integration tests
- Use `.spec.ts(x)` for E2E tests
- Use `.stories.tsx` for Storybook stories
## Unit Testing
### Component Testing
- Test behavior, not implementation
- Use React Testing Library best practices
```typescript
// ✅ Correct
test('displays user name when provided', () => {
render(<UserProfile user={{ name: 'John Doe' }} />);
expect(screen.getByText('John Doe')).toBeInTheDocument();
});
// ❌ Incorrect - Testing implementation details
test('sets the text content', () => {
const { container } = render(<UserProfile user={{ name: 'John Doe' }} />);
expect(container.querySelector('h1').textContent).toBe('John Doe');
});
```
### Hook Testing
- Use `renderHook` from @testing-library/react-hooks
- Test all possible states
```typescript
// ✅ Correct
test('useUser hook manages user state', () => {
const { result } = renderHook(() => useUser());
act(() => {
result.current.setUser({ id: '1', name: 'John' });
});
expect(result.current.user).toEqual({ id: '1', name: 'John' });
});
```
### Mocking
- Mock external dependencies
- Use jest.mock for module mocking
```typescript
// ✅ Correct
jest.mock('~/services/api', () => ({
fetchUser: jest.fn().mockResolvedValue({ id: '1', name: 'John' }),
}));
test('fetches and displays user', async () => {
render(<UserProfile userId="1" />);
expect(await screen.findByText('John')).toBeInTheDocument();
});
```
## Integration Testing
### API Testing
- Test complete request/response cycles
- Use Supertest for backend API testing
```typescript
// ✅ Correct
describe('GET /api/users/:id', () => {
it('returns user when found', async () => {
const response = await request(app)
.get('/api/users/1')
.expect(200);
expect(response.body).toEqual({
id: '1',
name: 'John Doe',
});
});
it('returns 404 when user not found', async () => {
await request(app)
.get('/api/users/999')
.expect(404);
});
});
```
## E2E Testing
### Test Structure
- Organize by user journey
- Use page objects for reusability
```typescript
// pages/login.ts
export class LoginPage {
async login(email: string, password: string) {
await this.page.fill('[data-testid="email-input"]', email);
await this.page.fill('[data-testid="password-input"]', password);
await this.page.click('[data-testid="login-button"]');
}
}
// tests/auth.spec.ts
test('user can login successfully', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.login('user@example.com', 'password');
await expect(page).toHaveURL('/dashboard');
});
```
### Test Data
- Use dedicated test environments
- Reset state between tests
```typescript
// ✅ Correct
beforeEach(async () => {
await resetDatabase();
await seedTestData();
});
test('user workflow', async ({ page }) => {
// Test with clean, predictable state
});
```
## Visual Testing
### Storybook Guidelines
- Create stories for all components
- Document component variants
```typescript
// Button.stories.tsx
export default {
title: 'Components/Button',
component: Button,
} as Meta;
export const Primary = {
args: {
variant: 'primary',
label: 'Primary Button',
},
};
export const Secondary = {
args: {
variant: 'secondary',
label: 'Secondary Button',
},
};
```
### Visual Regression
- Use Storybook's visual regression testing
- Review changes carefully
```typescript
// jest.config.js
module.exports = {
preset: 'jest-image-snapshot',
setupFilesAfterEnv: ['<rootDir>/setup-tests.ts'],
};
// Button.visual.test.tsx
describe('Button', () => {
it('matches visual snapshot', async () => {
const image = await page.screenshot();
expect(image).toMatchImageSnapshot();
});
});
```
## Test Quality
### Test Data Attributes
- Use data-testid for test selectors
- Avoid selecting by CSS classes
```typescript
// ✅ Correct
<button data-testid="submit-button">Submit</button>
// In tests
const button = screen.getByTestId('submit-button');
// ❌ Incorrect
const button = container.querySelector('.submit-btn');
```
### Assertion Best Practices
- Use explicit assertions
- Test both positive and negative cases
```typescript
// ✅ Correct
test('form validation', async () => {
render(<UserForm />);
// Negative case
await userEvent.click(screen.getByText('Submit'));
expect(screen.getByText('Name is required')).toBeInTheDocument();
// Positive case
await userEvent.type(screen.getByLabelText('Name'), 'John Doe');
await userEvent.click(screen.getByText('Submit'));
expect(screen.queryByText('Name is required')).not.toBeInTheDocument();
});
```
### Coverage Requirements
- A new feature should have at least 80% coverage
- Focus on critical paths
- Run coverage reports in CI
```typescript
// jest.config.js
module.exports = {
coverageThreshold: {
global: {
statements: 80,
branches: 80,
functions: 80,
lines: 80,
},
},
};
```
+162
View File
@@ -0,0 +1,162 @@
# Translation Guidelines
## Core Translation Principles
Twenty uses Lingui for internationalization (i18n) and Crowdin for translation management. This document outlines our translation workflow and best practices.
## Technology Stack
### Translation Tools
- **Framework**: @lingui/react
- **Translation Management**: Crowdin
- **Workflow**: GitHub Actions for automation
### Package Structure
Translation files are managed in multiple packages:
- `twenty-front`: Frontend translations
- `twenty-server`: Backend translations
- `twenty-emails`: Email template translations
## Translation Process
### Adding New Strings
#### Using Lingui Macros
- Use `<Trans>` for components
- Use `t` macro for strings outside JSX
```typescript
// ✅ Correct - In JSX
import { Trans } from '@lingui/react/macro';
const WelcomeMessage = () => (
<h1>
<Trans>Welcome to Twenty</Trans>
</h1>
);
// ✅ Correct - Outside JSX
import { t } from '@lingui/react/macro';
const getMessage = () => {
return t`Welcome to Twenty`;
};
// ❌ Incorrect - Don't use raw strings
const WelcomeMessage = () => (
<h1>Welcome to Twenty</h1>
);
```
### String Guidelines
#### What to Translate
- User interface text
- Error messages
- Notifications
- Email content
#### What Not to Translate
- Variables
- Test data/mocks
### Translation Workflow
#### 1. Extracting Translations
- Automatically triggered on main branch changes
- Can be manually triggered in GitHub Actions
- Process:
```bash
# Extract new strings
nx run twenty-front:lingui:extract
nx run twenty-server:lingui:extract
nx run twenty-emails:lingui:extract
```
#### 2. Translation Management
- Translations are managed in Crowdin
- Changes are synced every 2 hours
- Process:
1. New strings are uploaded to Crowdin
2. Translators work on translations
3. Translations are pulled back to the repository
#### 3. Compiling Translations
- Happens automatically in CI/CD
- Required before running the application
```bash
# Compile translations
nx run twenty-front:lingui:compile
nx run twenty-server:lingui:compile
nx run twenty-emails:lingui:compile
```
## Best Practices
### String Management
#### Use Placeholders
- Use placeholders for dynamic content
```typescript
// ✅ Correct
<Trans>Hello {userName},</Trans>
// ❌ Incorrect - String concatenation
<Trans>Hello </Trans>{userName},
```
#### Provide Context
- Lingui provides powerfulway to add context for translators but we don't use them as of today.
### Code Organization
#### Translation Files
- Keep translation files organized by feature
- Use consistent naming patterns
```
src/
├── locales/
│ ├── en/
│ │ ├── messages.po
│ │ └── messages.js
│ └── fr/
│ ├── messages.po
│ └── messages.js
```
### Quality Assurance
#### Strict Mode
- Use --strict mode when compiling to identify missing translations
#### Testing Translations
- Test with different locales
- Verify string interpolation
- Check layout with different language lengths
## Automation
### GitHub Actions
#### Pull Workflow
- Runs every 2 hours
- Downloads new translations from Crowdin
- Creates PR if changes detected
- Can be manually triggered with force pull option
#### Push Workflow
- Runs on main branch changes
- Extracts and uploads new strings
- Compiles translations
- Creates PR with changes
### Error Handling
#### Missing Translations
- Development: Shown in original language
- Production: Falls back to default language
- Strict mode in CI catches missing translations
#### Compilation Errors
- Addressed before merging
- PR created for fixing missing translations
- Automated testing in CI pipeline
+172
View File
@@ -0,0 +1,172 @@
# TypeScript Guidelines
## Core TypeScript Principles
Twenty enforces strict TypeScript usage to ensure type safety and maintainable code. This document outlines our TypeScript conventions and best practices.
## Type Safety
### Strict Typing
- **No 'any' type allowed**
- TypeScript strict mode enabled
- noImplicitAny enabled
```typescript
// ✅ Correct
function processUser(user: User) {
return user.name;
}
// ❌ Incorrect
function processUser(user: any) {
return user.name;
}
```
### Type Definitions
#### Types over Interfaces
- Use `type` for all type definitions
- Exception: When extending third-party interfaces
```typescript
// ✅ Correct
type User = {
id: string;
name: string;
email: string;
};
// ❌ Incorrect
interface User {
id: string;
name: string;
email: string;
}
```
### String Literals over Enums
- Use string literal unions instead of enums
- Exception: GraphQL enums
```typescript
// ✅ Correct
type UserRole = 'admin' | 'user' | 'guest';
// ❌ Incorrect
enum UserRole {
Admin = 'admin',
User = 'user',
Guest = 'guest',
}
```
## Naming Conventions
### Component Props
- Suffix component prop types with 'Props'
- Keep props focused and single-purpose
```typescript
// ✅ Correct
type ButtonProps = {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
};
// ❌ Incorrect
type ButtonParameters = {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
};
```
## Type Inference
### Leverage TypeScript Inference
- Use type inference when types are clear
- Explicitly type when inference is ambiguous
```typescript
// ✅ Correct - Clear inference
const users = ['John', 'Jane']; // inferred as string[]
// ✅ Correct - Explicit typing needed
const processUser = (user: User): UserResponse => {
// Complex processing
return response;
};
// ❌ Incorrect - Unnecessary explicit typing
const users: string[] = ['John', 'Jane'];
```
## Best Practices
### Type Guards
- Use type guards for runtime type checking
- Prefer discriminated unions
```typescript
// ✅ Correct
type Success = {
type: 'success';
data: User;
};
type Error = {
type: 'error';
message: string;
};
type Result = Success | Error;
function handleResult(result: Result) {
if (result.type === 'success') {
// TypeScript knows result.data exists
console.log(result.data);
}
}
```
### Generics
- Use generics for reusable type patterns
- Keep generic names descriptive
```typescript
// ✅ Correct
type ApiResponse<TData> = {
data: TData;
status: number;
message: string;
};
// ❌ Incorrect
type ApiResponse<T> = {
data: T;
status: number;
message: string;
};
```
### Type Exports
- Export types when they're used across files
- Keep type definitions close to their usage
```typescript
// types.ts
export type User = {
id: string;
name: string;
};
// UserComponent.tsx
import { type User } from './types';
```
### Utility Types
- Leverage TypeScript utility types
- Create custom utility types for repeated patterns
```typescript
// Built-in utility types
type UserPartial = Partial<User>;
type UserReadonly = Readonly<User>;
// Custom utility types
type NonNullableProperties<T> = {
[P in keyof T]: NonNullable<T[P]>;
};
```
-92
View File
@@ -1,92 +0,0 @@
# Twenty Development Rules
## General
- Twenty is an open source CRM built with Typescript (React, NestJS)
### Main Packages / folders
- packages/twenty-front: Main Frontend (React)
- packages/twenty-server: Main Backend (NestJS)
- packages/twenty-website: Marketing website + docs (NextJS)
- packages/twenty-ui: UI library (React)
- packages/twenty-shared: Shared utils, constants, types
### Development Stack
- Package Manager: yarn
- Monorepo: nx
- Database: PostgreSQL + TypeORM (core, metadata schemas)
- State Management: Recoil
- Data Management: Apollo / GraphQL
- Cache: redis
- Auth: JWT
- Queue: BullMQ
- Storage: S3/local filesystem
- Testing Backend: Jest, Supertest
- Testing Frontend: Jest, Storybook, MSW
- Testing E2E: Playwright
## Styling
- Use @emotion/styled, never CSS classes/Tailwind
- Prefix styled components with 'Styled'
- Keep styled components at top of file
- Use Theme object for colors/spacing/typography
- Use Theme values instead of px/rem
- Use mq helper for media queries
## TypeScript
- No 'any' type - use proper typing
- Use type over interface
- String literals over enums (except GraphQL)
- Props suffix for component props types
- Use type inference when possible
- Enable strict mode and noImplicitAny
## React
- Only functional components
- Named exports only
- No useEffect, prefer event handlers
- Small focused components
- Proper prop naming (onClick, isActive)
- Destructure props with types
## State Management
- Recoil for global state
- Apollo Client for GraphQL/server state
- Atoms in states/ directory
- Multiple small atoms over prop drilling
- No useRef for state
- Extract data fetching to siblings
- useRecoilValue/useRecoilState appropriately
## File Structure
- One component per file
- Features in modules/
- Hooks in hooks/
- States in states/
- Types in types/
- PascalCase components, camelCase others
## Code Style
- Early returns
- No nested ternaries
- No else-if
- Optional chaining over &&
- Small focused functions
- Clear variable names
- No console.logs in commits
- Few comments, prefer code readability
## GraphQL
- Use gql tag
- Separate operation files
- Proper codegen typing
- Consistent naming (getX, updateX)
- Use fragments
- Use generated types
## Testing
- Test every feature
- React Testing Library
- Test behavior not implementation
- Mock external deps
- Use data-testid
- Follow naming conventions
-133
View File
@@ -1,133 +0,0 @@
module.exports = {
root: true,
extends: ['plugin:prettier/recommended'],
plugins: ['@nx', 'prefer-arrow', 'import', 'unused-imports', 'unicorn'],
rules: {
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'no-console': ['warn', { allow: ['group', 'groupCollapsed', 'groupEnd'] }],
'no-control-regex': 0,
'no-debugger': 'error',
'no-duplicate-imports': 'error',
'no-undef': 'off',
'no-unused-vars': 'off',
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: [],
depConstraints: [
{
sourceTag: 'scope:shared',
onlyDependOnLibsWithTags: ['scope:shared'],
},
{
sourceTag: 'scope:backend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:backend'],
},
{
sourceTag: 'scope:frontend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:frontend'],
},
],
},
],
'import/no-relative-packages': 'error',
'import/no-useless-path-segments': 'error',
'import/no-duplicates': ['error', { considerQueryString: true }],
'prefer-arrow/prefer-arrow-functions': [
'error',
{
disallowPrototype: true,
singleReturnOnly: false,
classPropertiesAllowed: false,
},
],
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
},
overrides: [
{
files: ['**/*.ts', '**/*.tsx'],
extends: ['plugin:@nx/typescript'],
rules: {
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/consistent-type-imports': [
'error',
{ prefer: 'no-type-imports' },
],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-empty-interface': [
'error',
{
allowSingleExtends: true,
},
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
},
},
{
files: ['*.js', '*.jsx'],
extends: ['plugin:@nx/javascript'],
rules: {},
},
{
files: ['*.spec.@(ts|tsx|js|jsx)', '*.test.@(ts|tsx|js|jsx)'],
env: {
jest: true,
},
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
{
files: ['**/constants/*.ts', '**/*.constants.ts'],
rules: {
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['UPPER_CASE'],
},
],
'unicorn/filename-case': [
'warn',
{
cases: {
pascalCase: true,
},
},
],
'@nx/workspace-max-consts-per-file': ['error', { max: 1 }],
},
},
{
files: ['*.json'],
parser: 'jsonc-eslint-parser',
},
],
};
+149
View File
@@ -0,0 +1,149 @@
module.exports = {
root: true,
extends: ['plugin:prettier/recommended', 'plugin:lingui/recommended'],
ignorePatterns: ['node_modules'],
plugins: [
'@nx',
'prefer-arrow',
'import',
'unused-imports',
'unicorn',
'lingui',
],
rules: {
'lingui/no-single-variables-to-translate': 'off',
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'no-console': ['warn', { allow: ['group', 'groupCollapsed', 'groupEnd'] }],
'no-control-regex': 0,
'no-debugger': 'error',
'no-duplicate-imports': 'error',
'no-undef': 'off',
'no-unused-vars': 'off',
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: [],
depConstraints: [
{
sourceTag: 'scope:shared',
onlyDependOnLibsWithTags: ['scope:shared'],
},
{
sourceTag: 'scope:backend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:backend'],
},
{
sourceTag: 'scope:frontend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:frontend'],
},
{
sourceTag: 'scope:zapier',
onlyDependOnLibsWithTags: ['scope:shared'],
},
],
},
],
'import/no-relative-packages': 'error',
'import/no-useless-path-segments': 'error',
'import/no-duplicates': ['error', { considerQueryString: true }],
'prefer-arrow/prefer-arrow-functions': [
'error',
{
disallowPrototype: true,
singleReturnOnly: false,
classPropertiesAllowed: false,
},
],
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
},
overrides: [
{
files: ['**/*.ts', '**/*.tsx'],
extends: ['plugin:@nx/typescript'],
rules: {
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/consistent-type-imports': [
'error',
{ prefer: 'no-type-imports' },
],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/no-empty-interface': [
'error',
{
allowSingleExtends: true,
},
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
},
},
{
files: ['*.js', '*.jsx'],
extends: ['plugin:@nx/javascript'],
rules: {},
},
{
files: [
'*.spec.@(ts|tsx|js|jsx)',
'*.integration-spec.@(ts|tsx|js|jsx)',
'*.test.@(ts|tsx|js|jsx)',
],
env: {
jest: true,
},
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
{
files: ['**/constants/*.ts', '**/*.constants.ts'],
rules: {
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['UPPER_CASE'],
},
],
'unicorn/filename-case': [
'warn',
{
cases: {
pascalCase: true,
},
},
],
'@nx/workspace-max-consts-per-file': ['error', { max: 1 }],
},
},
{
files: ['*.json'],
parser: 'jsonc-eslint-parser',
},
],
};
+114 -5
View File
@@ -6,14 +6,74 @@ module.exports = {
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:storybook/recommended',
'plugin:prettier/recommended',
'plugin:lingui/recommended',
'plugin:@nx/typescript'
],
plugins: ['react-hooks', 'react-refresh'],
plugins: ['react-hooks', 'react-refresh', '@nx', 'prefer-arrow', 'import', 'unused-imports', 'unicorn', 'lingui'],
rules: {
'lingui/no-single-variables-to-translate': 'off',
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'no-console': ['warn', { allow: ['group', 'groupCollapsed', 'groupEnd'] }],
'no-control-regex': 0,
'no-debugger': 'error',
'no-duplicate-imports': 'error',
'no-undef': 'off',
'no-unused-vars': 'off',
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: [],
depConstraints: [
{
sourceTag: 'scope:shared',
onlyDependOnLibsWithTags: ['scope:shared'],
},
{
sourceTag: 'scope:backend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:backend'],
},
{
sourceTag: 'scope:frontend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:frontend'],
},
{
sourceTag: 'scope:zapier',
onlyDependOnLibsWithTags: ['scope:shared'],
},
],
},
],
'import/no-relative-packages': 'error',
'import/no-useless-path-segments': 'error',
'import/no-duplicates': ['error', { considerQueryString: true }],
'prefer-arrow/prefer-arrow-functions': [
'error',
{
disallowPrototype: true,
singleReturnOnly: false,
classPropertiesAllowed: false,
},
],
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
},
overrides: [
{
files: ['*.ts', '*.tsx'],
parserOptions: {
project: ['./tsconfig.base.{json,*.json}'],
},
files: ['**/*.ts', '**/*.tsx'],
rules: {
'no-restricted-imports': [
'error',
@@ -37,6 +97,14 @@ module.exports = {
],
},
],
'@typescript-eslint/no-empty-interface': [
'error',
{
allowSingleExtends: true,
},
],
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@nx/workspace-effect-components': 'error',
'@nx/workspace-no-hardcoded-colors': 'error',
'@nx/workspace-matching-state-variable': 'error',
@@ -86,5 +154,46 @@ module.exports = {
],
},
},
{
files: ['*.js', '*.jsx'],
extends: ['plugin:@nx/javascript'],
rules: {},
},
{
files: [
'*.test.@(ts|tsx|js|jsx)',
],
env: {
jest: true,
},
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
{
files: ['**/*.constants.ts'],
rules: {
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['UPPER_CASE'],
},
],
'unicorn/filename-case': [
'warn',
{
cases: {
pascalCase: true,
},
},
],
'@nx/workspace-max-consts-per-file': ['error', { max: 1 }],
},
},
{
files: ['*.json'],
parser: 'jsonc-eslint-parser',
},
],
};
+3 -7
View File
@@ -13,14 +13,10 @@ Good first issues are a great way to start contributing and get familiar with th
## Issue assignment
Having multiple contributors address the same issue can cause frustration.
To avoid conflicts, we follow these guidelines:
1. If a core team member assigned you the issue within the last three days, your PR takes priority.
2. Otherwise, the first submitted PR is prioritized.
3. For "size: long" PRs, the assignment period extends to one week.
Please ensure you're assigned to an issue before starting work.
1. For `Good First Issue` and `Experienced Contributor` issues without `size: long` labels, we'll merge the first PRs that meet our [code quality standards](https://twenty.com/developers). **We don't assign contributors to these issues**. For `priority: high` issues, our core team will step in within days if no adequate contributions are received.
2. For `size: long` Issues, assigned contributors have one week to submit their first draft PR.
## How to Contribute
@@ -67,4 +63,4 @@ git push origin your-branch-name
## Reporting Issues
If you face any issues or have suggestions, please feel free to (create an issue on Twenty's GitHub repository)[https://github.com/twentyhq/twenty/issues/new]. Please provide as much detail as possible.
If you face any issues or have suggestions, please feel free to (create an issue on Twenty's GitHub repository)[https://github.com/twentyhq/twenty/issues/new]. Please provide as much detail as possible.
@@ -2,14 +2,14 @@ name: Nx Affected CI
inputs:
parallel:
required: false
types: [number]
default: 3
default: '3'
tag:
required: false
types: [string]
tasks:
required: true
types: [string]
configuration:
required: false
default: 'ci'
runs:
using: "composite"
@@ -18,4 +18,4 @@ runs:
uses: nrwl/nx-set-shas@v4
- name: Run affected command
shell: bash
run: npx nx affected --nxBail --configuration=ci -t=${{ inputs.tasks }} --parallel=${{ inputs.parallel }} --exclude='*,!tag:${{ inputs.tag }}'
run: npx nx affected --nxBail --configuration=${{ inputs.configuration }} -t=${{ inputs.tasks }} --parallel=${{ inputs.parallel }} --exclude='*,!tag:${{ inputs.tag }}'
@@ -0,0 +1,35 @@
name: Restore cache
inputs:
key:
required: true
description: Prefix to the cache key
additional-paths:
required: false
outputs:
cache-primary-key:
description: actions/cache/restore cache-primary-key outputs proxy
value: ${{ steps.restore-cache.outputs.cache-primary-key }}
cache-hit:
description: String bool indicating whether cache has been directly or indirectly hit
value: ${{ steps.restore-cache.outputs.cache-hit == 'true' || steps.restore-cache.outputs.cache-matched-key != '' }}
runs:
using: composite
steps:
- name: Cache primary key builder
id: cache-primary-key-builder
shell: bash
run: |
echo "CACHE_PRIMARY_KEY_PREFIX=v3-${{ inputs.key }}-${{ github.ref_name }}" >> "${GITHUB_OUTPUT}"
- name: Restore cache
uses: actions/cache/restore@v4
id: restore-cache
with:
key: ${{ steps.cache-primary-key-builder.outputs.CACHE_PRIMARY_KEY_PREFIX }}-${{ github.sha }}
restore-keys: ${{ steps.cache-primary-key-builder.outputs.CACHE_PRIMARY_KEY_PREFIX }}-
path: |
.cache
.nx/cache
node_modules/.cache
packages/*/node_modules/.cache
${{ inputs.additional-paths }}
@@ -0,0 +1,21 @@
name: Save cache
inputs:
key:
required: true
description: Primary key to the cache, should be retrieved from `cache-restore` composite action outputs.
additional-paths:
required: false
runs:
using: "composite"
steps:
- name: Save cache
uses: actions/cache/save@v4
with:
key: ${{ inputs.key }}
path: |
.cache
.nx/cache
node_modules/.cache
packages/*/node_modules/.cache
${{ inputs.additional-paths }}
@@ -1,31 +0,0 @@
name: Restore Tasks Cache CI
inputs:
tag:
required: false
types: [string]
tasks:
required: false
types: [string]
default: all
suffix:
required: false
types: [string]
runs:
using: "composite"
steps:
- name: Compute tasks key
id: tasks-key
shell: bash
run: echo "key=${{ inputs.tasks }}" | tr , - >> $GITHUB_OUTPUT
- name: Restore tasks cache
uses: actions/cache@v3
with:
path: |
.cache
.nx/cache
node_modules/.cache
packages/*/node_modules/.cache
key: tasks-cache-${{ github.ref_name }}-${{ inputs.tag }}-${{ steps.tasks-key.outputs.key }}${{ inputs.suffix }}-${{ github.sha }}
restore-keys: |
tasks-cache-${{ github.ref_name }}-${{ inputs.tag }}-${{ steps.tasks-key.outputs.key }}${{ inputs.suffix }}-
@@ -1,23 +1,43 @@
name: Yarn Install
inputs:
node-version:
required: false
default: '18'
runs:
using: "composite"
steps:
- name: Setup Node.js and get yarn cache
uses: actions/setup-node@v3
with:
node-version: "18"
cache: yarn
- name: Cache node modules
id: node-modules-cache
uses: actions/cache@v3
with:
path: |
node_modules
packages/*/node_modules
key: root-node_modules-${{ hashFiles('yarn.lock') }}
restore-keys: root-node_modules-
- name: Install Dependencies
- name: Cache primary key builder
id: globals
shell: bash
run: yarn --immutable --check-cache
if: steps.node-modules-cache.outputs.cache-hit != 'true'
run: |
echo "ACTION_SHELL=bash" >> "${GITHUB_OUTPUT}"
echo "CACHE_KEY_PREFIX=node_modules-cache-node-${{ inputs.node-version }}-${{ hashFiles('yarn.lock') }}" >> "${GITHUB_OUTPUT}"
echo 'PATH_TO_CACHE<<EOF' >> $GITHUB_OUTPUT
echo "node_modules" >> $GITHUB_OUTPUT
echo "packages/*/node_modules" >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
- name: Setup Node.js and get yarn cache
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- name: Restore node_modules
id: cache-node-modules
uses: actions/cache/restore@v4
with:
key: v3-${{ steps.globals.outputs.CACHE_KEY_PREFIX }}-${{github.sha}}
restore-keys: v3-${{ steps.globals.outputs.CACHE_KEY_PREFIX }}-
path: ${{ steps.globals.outputs.PATH_TO_CACHE }}
- name: Install Dependencies
if: ${{ steps.cache-node-modules.outputs.cache-hit != 'true' && steps.cache-node-modules.outputs.cache-matched-key == '' }}
shell: ${{ steps.globals.outputs.ACTION_SHELL }}
run: |
yarn config set enableHardenedMode true
yarn --immutable --check-cache
- name: Save cache
if: ${{ steps.cache-node-modules.outputs.cache-hit != 'true' && steps.cache-node-modules.outputs.cache-matched-key == '' }}
uses: actions/cache/save@v4
with:
key: ${{ steps.cache-node-modules.outputs.cache-primary-key }}
path: ${{ steps.globals.outputs.PATH_TO_CACHE }}
+27
View File
@@ -0,0 +1,27 @@
name: Changed files reusable workflow
on:
workflow_call:
inputs:
files:
required: true
type: string
outputs:
any_changed:
value: ${{ jobs.changed-files.outputs.any_changed }}
jobs:
changed-files:
timeout-minutes: 5
runs-on: ubuntu-latest
outputs:
any_changed: ${{ steps.changed-files.outputs.any_changed }}
steps:
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v45
with:
files: ${{ inputs.files }}
+19 -18
View File
@@ -3,15 +3,23 @@ on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
package.json
packages/twenty-chrome-extension/**
chrome-extension-build:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 15
runs-on: ubuntu-latest
env:
@@ -25,23 +33,16 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
package.json
packages/twenty-chrome-extension/**
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Chrome Extension / Run build
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx build twenty-chrome-extension
- name: Mark as Valid if No Changes
if: steps.changed-files.outputs.changed != 'true'
run: |
echo "No relevant changes detected. Marking as valid."
ci-chrome-extension-status-check:
if: always() && !cancelled()
timeout-minutes: 1
runs-on: ubuntu-latest
needs: [changed-files-check, chrome-extension-build]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
+133
View File
@@ -0,0 +1,133 @@
name: CI E2E Playwright Tests
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened, labeled]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
packages/**
playwright.config.ts
.github/workflows/ci-e2e.yaml
test:
runs-on: ubuntu-latest
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true' && ( github.event_name == 'push' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-e2e')))
timeout-minutes: 30
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
# https://github.com/actions/runner-images/issues/70#issuecomment-589562148
NODE_OPTIONS: "--max-old-space-size=10240"
services:
postgres:
image: twentycrm/twenty-postgres-spilo
env:
PGUSER_SUPERUSER: postgres
PGPASSWORD_SUPERUSER: postgres
ALLOW_NOSSL: "true"
SPILO_PROVIDER: "local"
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Check system resources
run: |
echo "Available memory:"
free -h
echo "Available disk space:"
df -h
echo "CPU info:"
lscpu
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Build twenty-shared
run: npx nx build twenty-shared
- name: Install Playwright Browsers
run: npx nx setup twenty-e2e-testing
- name: Setup environment files
run: |
cp packages/twenty-front/.env.example packages/twenty-front/.env
npx nx reset:env twenty-server
- name: Build frontend
run: NODE_ENV=production NODE_OPTIONS="--max-old-space-size=10240" npx nx build twenty-front
- name: Build server
run: npx nx build twenty-server
- name: Create and setup database
run: |
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "default";'
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "test";'
npx nx run twenty-server:database:reset
- name: Start server
run: |
npx nx start twenty-server &
echo "Waiting for server to be ready..."
timeout 60 bash -c 'until curl -s http://localhost:3000/health; do sleep 2; done'
- name: Start frontend
run: |
npm_config_yes=true npx serve -s packages/twenty-front/build -l 3001 &
echo "Waiting for frontend to be ready..."
timeout 60 bash -c 'until curl -s http://localhost:3001; do sleep 2; done'
- name: Start worker
run: |
npx nx run twenty-server:worker &
echo "Worker started"
- name: Run Playwright tests
run: npx nx test twenty-e2e-testing
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: packages/twenty-e2e-testing/run_results/
retention-days: 30
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: packages/twenty-e2e-testing/playwright-report/
retention-days: 30
ci-e2e-status-check:
if: always() && !cancelled()
timeout-minutes: 1
runs-on: ubuntu-latest
needs: [changed-files-check, test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
-141
View File
@@ -1,141 +0,0 @@
name: CI E2E Tests
on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
if: github.event_name == 'push' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-e2e'))
timeout-minutes: 30
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
# https://github.com/actions/runner-images/issues/70#issuecomment-589562148
NODE_OPTIONS: "--max-old-space-size=10240"
services:
postgres:
image: twentycrm/twenty-postgres-spilo
env:
PGUSER_SUPERUSER: postgres
PGPASSWORD_SUPERUSER: postgres
ALLOW_NOSSL: "true"
SPILO_PROVIDER: "local"
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Check system resources
run: |
echo "Available memory:"
free -h
echo "Available disk space:"
df -h
echo "CPU info:"
lscpu
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
packages/**
playwright.config.ts
.github/workflows/ci-e2e.yml
- name: Skip if no relevant changes
if: steps.changed-files.outputs.any_changed == 'false'
run: echo "No relevant changes detected. Marking as valid."
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Build twenty-shared
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx build twenty-shared
- name: Setup environment files
if: steps.changed-files.outputs.any_changed == 'true'
run: |
cp packages/twenty-e2e-testing/.env.example packages/twenty-e2e-testing/.env
cp packages/twenty-front/.env.example packages/twenty-front/.env
cp packages/twenty-e2e-testing/.env.example packages/twenty-e2e-testing/.env
npx nx reset:env twenty-server
- name: Build frontend
if: steps.changed-files.outputs.any_changed == 'true'
run: NODE_ENV=production NODE_OPTIONS="--max-old-space-size=10240" npx nx build twenty-front
- name: Build server
if: steps.changed-files.outputs.any_changed == 'true'
run: NODE_ENV=production npx nx build twenty-server
- name: Create and setup database
if: steps.changed-files.outputs.any_changed == 'true'
run: |
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "default";'
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "test";'
npx nx run twenty-server:database:reset
- name: Start server
if: steps.changed-files.outputs.any_changed == 'true'
run: |
npx nx start twenty-server &
echo "Waiting for server to be ready..."
timeout 60 bash -c 'until curl -s http://localhost:3000/health; do sleep 2; done'
- name: Start frontend
if: steps.changed-files.outputs.any_changed == 'true'
run: |
npm_config_yes=true npx serve -s packages/twenty-front/build -l 3001 &
echo "Waiting for frontend to be ready..."
timeout 60 bash -c 'until curl -s http://localhost:3001; do sleep 2; done'
- name: Start worker
if: steps.changed-files.outputs.any_changed == 'true'
run: |
npx nx run twenty-server:worker:ci &
echo "Worker started"
- name: Install Playwright Browsers
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx setup twenty-e2e-testing
- name: Run Playwright tests
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx test twenty-e2e-testing
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: packages/twenty-e2e-testing/run_results/
retention-days: 30
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: packages/twenty-e2e-testing/playwright-report/
retention-days: 30
+62
View File
@@ -0,0 +1,62 @@
name: CI Emails
on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
package.json
packages/twenty-emails/**
emails-test:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 10
runs-on: depot-ubuntu-24.04-8
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
steps:
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Build twenty-emails
run: npx nx build twenty-emails
- name: Run email tests
run: |
# Start the email server in the background
npx nx run twenty-emails:start &
SERVER_PID=$!
# Wait for server to start
sleep 20
# Check if server is running
if ! curl -s http://localhost:4001/preview/test.email > /dev/null; then
echo "Email server failed to start"
kill $SERVER_PID
exit 1
fi
# Kill the server
kill $SERVER_PID
ci-emails-status-check:
if: always() && !cancelled()
timeout-minutes: 1
runs-on: depot-ubuntu-24.04-8
needs: [changed-files-check, emails-test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
+92 -116
View File
@@ -3,17 +3,30 @@ on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
STORYBOOK_BUILD_CACHE_KEY: storybook-build-depot-ubuntu-24.04-8-runner
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
package.json
packages/twenty-front/**
packages/twenty-ui/**
packages/twenty-shared/**
front-sb-build:
needs: [changed-files-check]
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04-8
env:
REACT_APP_SERVER_BASE_URL: http://localhost:3000
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
@@ -26,47 +39,34 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
package.json
packages/twenty-front/**
packages/twenty-ui/**
packages/twenty-shared/**
- name: Skip if no relevant changes
if: steps.changed-files.outputs.any_changed == 'false'
run: echo "No relevant changes. Skipping CI."
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Diagnostic disk space issue
if: steps.changed-files.outputs.any_changed == 'true'
run: df -h
- name: Front / Restore Storybook Task Cache
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/task-cache
- name: Restore storybook build cache
id: restore-storybook-build-cache
uses: ./.github/workflows/actions/restore-cache
with:
tag: scope:frontend
tasks: storybook:build
key: ${{ env.STORYBOOK_BUILD_CACHE_KEY }}
- name: Front / Write .env
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx reset:env twenty-front
- name: Front / Build storybook
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx storybook:build twenty-front
- name: Save storybook build cache
uses: ./.github/workflows/actions/save-cache
with:
key: ${{ steps.restore-storybook-build-cache.outputs.cache-primary-key }}
front-sb-test:
timeout-minutes: 30
runs-on: shipfox-8vcpu-ubuntu-2204
runs-on: depot-ubuntu-24.04-8
needs: front-sb-build
strategy:
fail-fast: false
matrix:
storybook_scope: [pages, modules]
shard: [1, 2, 3, 4]
storybook_scope: [modules, pages, performance]
env:
SHARD_COUNTER: 4
REACT_APP_SERVER_BASE_URL: http://localhost:3000
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
steps:
@@ -74,73 +74,57 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
packages/twenty-front/**
- name: Skip if no relevant changes
if: steps.changed-files.outputs.any_changed == 'false'
run: echo "No relevant changes. Skipping CI."
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Install Playwright
if: steps.changed-files.outputs.any_changed == 'true'
run: cd packages/twenty-front && npx playwright install
- name: Front / Restore Storybook Task Cache
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/task-cache
- name: Restore storybook build cache
uses: ./.github/workflows/actions/restore-cache
with:
tag: scope:frontend
tasks: storybook:build
key: ${{ env.STORYBOOK_BUILD_CACHE_KEY }}
- name: Front / Write .env
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx reset:env twenty-front
- name: Run storybook tests
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx storybook:serve-and-test:static twenty-front --configuration=${{ matrix.storybook_scope }}
front-sb-test-performance:
run: npx nx storybook:serve-and-test:static twenty-front --configuration=${{ matrix.storybook_scope }} --shard=${{ matrix.shard }}/${{ env.SHARD_COUNTER }} --checkCoverage=false
- name: Rename coverage file
run: mv packages/twenty-front/coverage/storybook/coverage-storybook.json packages/twenty-front/coverage/storybook/coverage-shard-${{matrix.shard}}.json
- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
retention-days: 1
name: coverage-artifacts-${{ matrix.storybook_scope }}-${{ github.run_id }}-${{ matrix.shard }}
path: packages/twenty-front/coverage/storybook/coverage-shard-${{matrix.shard}}.json
merge-reports-and-check-coverage:
timeout-minutes: 30
runs-on: shipfox-8vcpu-ubuntu-2204
runs-on: depot-ubuntu-24.04-8
needs: front-sb-test
env:
REACT_APP_SERVER_BASE_URL: http://localhost:3000
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
PATH_TO_COVERAGE: packages/twenty-front/coverage/storybook
strategy:
matrix:
storybook_scope: [modules, pages, performance]
steps:
- name: Fetch local actions
uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
packages/twenty-front/**
- name: Skip if no relevant changes
if: steps.changed-files.outputs.any_changed == 'false'
run: echo "No relevant changes. Skipping CI."
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Install Playwright
if: steps.changed-files.outputs.any_changed == 'true'
run: cd packages/twenty-front && npx playwright install
- name: Front / Write .env
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx reset:env twenty-front
- name: Run storybook tests
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx run twenty-front:storybook:serve-and-test:static:performance
- uses: actions/download-artifact@v4
with:
pattern: coverage-artifacts-${{ matrix.storybook_scope }}-${{ github.run_id }}-*
merge-multiple: true
path: coverage-artifacts
- name: Merge coverage reports
run: |
mkdir -p ${{ env.PATH_TO_COVERAGE }}
npx nyc merge coverage-artifacts ${{ env.PATH_TO_COVERAGE }}/coverage-storybook.json
- name: Checking coverage
run: npx nx storybook:coverage twenty-front --checkCoverage=true --configuration=${{ matrix.storybook_scope }}
front-chromatic-deployment:
timeout-minutes: 30
if: contains(github.event.pull_request.labels.*.name, 'run-chromatic') || github.event_name == 'push'
needs: front-sb-build
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04-8
env:
REACT_APP_SERVER_BASE_URL: http://127.0.0.1:3000
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
@@ -149,41 +133,27 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
packages/twenty-front/**
- name: Skip if no relevant changes
if: steps.changed-files.outputs.any_changed == 'false'
run: echo "No relevant changes. Skipping CI."
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Front / Restore Storybook Task Cache
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/task-cache
- name: Restore storybook build cache
uses: ./.github/workflows/actions/restore-cache
with:
tag: scope:frontend
tasks: storybook:build
key: ${{ env.STORYBOOK_BUILD_CACHE_KEY }}
- name: Front / Write .env
if: steps.changed-files.outputs.any_changed == 'true'
run: |
cd packages/twenty-front
touch .env
echo "REACT_APP_SERVER_BASE_URL: $REACT_APP_SERVER_BASE_URL" >> .env
- name: Publish to Chromatic
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx run twenty-front:chromatic:ci
front-task:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04-8
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
TASK_CACHE_KEY: front-task-${{ matrix.task }}
strategy:
matrix:
task: [lint, typecheck, test]
@@ -196,35 +166,41 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
packages/twenty-front/**
- name: Skip if no relevant changes
if: steps.changed-files.outputs.any_changed == 'false'
run: echo "No relevant changes. Skipping CI."
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Front / Restore ${{ matrix.task }} task cache
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/task-cache
- name: Restore ${{ matrix.task }} cache
id: restore-task-cache
uses: ./.github/workflows/actions/restore-cache
with:
tag: scope:frontend
tasks: ${{ matrix.task }}
key: ${{ env.TASK_CACHE_KEY }}
- name: Reset .env
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:frontend
tasks: reset:env
- name: Run ${{ matrix.task }} task
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:frontend
tasks: ${{ matrix.task }}
- name: Save ${{ matrix.task }} cache
uses: ./.github/workflows/actions/save-cache
with:
key: ${{ steps.restore-task-cache.outputs.cache-primary-key }}
ci-front-status-check:
if: always() && !cancelled()
timeout-minutes: 1
runs-on: depot-ubuntu-24.04-8
needs:
[
changed-files-check,
front-task,
front-chromatic-deployment,
merge-reports-and-check-coverage,
front-sb-test,
front-sb-build,
]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
+107 -69
View File
@@ -5,15 +5,28 @@ on:
- main
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
SERVER_SETUP_CACHE_KEY: server-setup
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
package.json
packages/twenty-server/**
packages/twenty-emails/**
packages/twenty-shared/**
server-setup:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04-8
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
services:
@@ -22,8 +35,8 @@ jobs:
env:
PGUSER_SUPERUSER: postgres
PGPASSWORD_SUPERUSER: postgres
ALLOW_NOSSL: "true"
SPILO_PROVIDER: "local"
ALLOW_NOSSL: 'true'
SPILO_PROVIDER: 'local'
ports:
- 5432:5432
options: >-
@@ -40,52 +53,41 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
package.json
packages/twenty-server/**
packages/twenty-emails/**
packages/twenty-shared/**
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Build twenty-shared
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx build twenty-shared
- name: Server / Restore Task Cache
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/task-cache
- name: Restore server setup
id: restore-server-setup-cache
uses: ./.github/workflows/actions/restore-cache
with:
tag: scope:backend
key: ${{ env.SERVER_SETUP_CACHE_KEY }}
- name: Build twenty-shared
run: npx nx build twenty-shared
- name: Server / Run lint & typecheck
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:backend
tasks: lint,typecheck
- name: Server / Build
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx build twenty-server
- name: Server / Write .env
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx reset:env twenty-server
- name: Server / Create DB
if: steps.changed-files.outputs.any_changed == 'true'
run: |
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "default";'
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "test";'
npx nx run twenty-server:database:init:prod
npx nx run twenty-server:database:migrate:prod
- name: Worker / Run
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx run twenty-server:worker:ci
run: |
timeout 30s npx nx run twenty-server:worker || exit_code=$?
if [ $exit_code -eq 124 ]; then
# If timeout was reached (exit code 124), consider it a success
exit 0
elif [ $exit_code -ne 0 ]; then
# If worker failed for other reasons, fail the build
exit $exit_code
fi
- name: Server / Check for Pending Migrations
if: steps.changed-files.outputs.any_changed == 'true'
run: |
METADATA_MIGRATION_OUTPUT=$(npx nx run twenty-server:typeorm migration:generate metadata-migration-check -d src/database/typeorm/metadata/metadata.datasource.ts || true)
@@ -103,10 +105,26 @@ jobs:
exit 1
fi
- name: GraphQL / Check for Pending Generation
if: steps.changed-files.outputs.any_changed == 'true'
run: |
# Run GraphQL generation commands
npx nx run twenty-front:graphql:generate
npx nx run twenty-front:graphql:generate --configuration=metadata
# Check if any files were modified
if ! git diff --quiet; then
echo "::error::GraphQL schema changes detected. Please run 'npx nx run twenty-front:graphql:generate' and 'npx nx run twenty-front:graphql:generate --configuration=metadata' and commit the changes."
exit 1
fi
- name: Save server setup
uses: ./.github/workflows/actions/save-cache
with:
key: ${{ steps.restore-server-setup-cache.outputs.cache-primary-key }}
server-test:
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04-8
needs: server-setup
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
@@ -115,27 +133,13 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
package.json
packages/twenty-server/**
packages/twenty-emails/**
packages/twenty-shared/**
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Server / Restore Task Cache
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/task-cache
- name: Restore server setup
uses: ./.github/workflows/actions/restore-cache
with:
tag: scope:backend
- name: Server / Run Tests
if: steps.changed-files.outputs.any_changed == 'true'
key: ${{ env.SERVER_SETUP_CACHE_KEY }}
- name: Server / Run Tests
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:backend
@@ -143,7 +147,7 @@ jobs:
server-integration-test:
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04-8
needs: server-setup
services:
postgres:
@@ -151,8 +155,8 @@ jobs:
env:
PGUSER_SUPERUSER: postgres
PGPASSWORD_SUPERUSER: postgres
ALLOW_NOSSL: "true"
SPILO_PROVIDER: "local"
ALLOW_NOSSL: 'true'
SPILO_PROVIDER: 'local'
ports:
- 5432:5432
options: >-
@@ -164,40 +168,74 @@ jobs:
image: redis
ports:
- 6379:6379
clickhouse:
image: clickhouse/clickhouse-server:latest
env:
CLICKHOUSE_PASSWORD: clickhousePassword
CLICKHOUSE_URL: "http://default:clickhousePassword@localhost:8123/twenty"
ports:
- 8123:8123
- 9000:9000
options: >-
--health-cmd "clickhouse-client --host=localhost --port=9000 --user=default --password=clickhousePassword --query='SELECT 1'"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
NODE_ENV: test
ANALYTICS_ENABLED: true
CLICKHOUSE_URL: "http://default:clickhousePassword@localhost:8123/twenty"
CLICKHOUSE_PASSWORD: clickhousePassword
steps:
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
package.json
packages/twenty-server/**
packages/twenty-emails/**
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Server / Restore Task Cache
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/task-cache
- name: Update .env.test for integrations tests
run: |
echo "IS_BILLING_ENABLED=true" >> .env.test
echo "BILLING_STRIPE_API_KEY=test-api-key" >> .env.test
echo "BILLING_STRIPE_BASE_PLAN_PRODUCT_ID=test-base-plan-product-id" >> .env.test
echo "BILLING_STRIPE_WEBHOOK_SECRET=test-webhook-secret" >> .env.test
echo "BILLING_PLAN_REQUIRED_LINK=http://localhost:3001/stripe-redirection" >> .env.test
- name: Restore server setup
uses: ./.github/workflows/actions/restore-cache
with:
tag: scope:backend
key: ${{ env.SERVER_SETUP_CACHE_KEY }}
- name: Server / Build
run: npx nx build twenty-server
- name: Build dependencies
run: |
npx nx build twenty-shared
npx nx build twenty-emails
- name: Server / Create Test DB
run: |
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "test";'
- name: Run ClickHouse migrations
run: npx nx clickhouse:migrate twenty-server
- name: Run ClickHouse seeds
run: npx nx clickhouse:seed twenty-server
- name: Server / Run Integration Tests
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:backend
tasks: "test:integration:with-db-reset"
tasks: 'test:integration'
configuration: 'with-db-reset'
- name: Server / Upload reset-logs file
if: always()
uses: actions/upload-artifact@v4
with:
name: reset-logs
path: reset-logs.log
ci-server-status-check:
if: always() && !cancelled()
timeout-minutes: 1
runs-on: depot-ubuntu-24.04-8
needs: [changed-files-check, server-setup, server-test, server-integration-test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
+17 -12
View File
@@ -3,7 +3,7 @@ on:
push:
branches:
- main
pull_request:
concurrency:
@@ -11,7 +11,14 @@ concurrency:
cancel-in-progress: true
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
packages/twenty-shared/**
shared-test:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
env:
@@ -28,21 +35,19 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
packages/twenty-shared/**
- name: Skip if no relevant changes
if: steps.changed-files.outputs.any_changed == 'false'
run: echo "No relevant changes. Skipping CI."
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Run ${{ matrix.task }} task
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:frontend
tasks: ${{ matrix.task }}
ci-shared-status-check:
if: always() && !cancelled()
timeout-minutes: 1
runs-on: ubuntu-latest
needs: [changed-files-check, shared-test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
+77 -76
View File
@@ -1,92 +1,93 @@
name: 'Test Docker Compose'
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
packages/twenty-docker/**
docker-compose.yml
test:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
packages/twenty-docker/**
docker-compose.yml
- name: Skip if no relevant changes
if: steps.changed-files.outputs.any_changed != 'true'
run: echo "No relevant changes detected. Marking as valid."
- name: Checkout
uses: actions/checkout@v4
- name: Run compose
run: |
echo "Patching docker-compose.yml..."
# change image to localbuild using yq
yq eval 'del(.services.server.image)' -i docker-compose.yml
yq eval '.services.server.build.context = "../../"' -i docker-compose.yml
yq eval '.services.server.build.dockerfile = "./packages/twenty-docker/twenty/Dockerfile"' -i docker-compose.yml
yq eval '.services.server.restart = "no"' -i docker-compose.yml
- name: Run compose
if: steps.changed-files.outputs.any_changed == 'true'
run: |
echo "Patching docker-compose.yml..."
# change image to localbuild using yq
yq eval 'del(.services.server.image)' -i docker-compose.yml
yq eval '.services.server.build.context = "../../"' -i docker-compose.yml
yq eval '.services.server.build.dockerfile = "./packages/twenty-docker/twenty/Dockerfile"' -i docker-compose.yml
yq eval '.services.server.restart = "no"' -i docker-compose.yml
echo "Setting up .env file..."
cp .env.example .env
echo "Generating secrets..."
echo "# === Randomly generated secrets ===" >>.env
echo "APP_SECRET=$(openssl rand -base64 32)" >>.env
echo "PGPASSWORD_SUPERUSER=$(openssl rand -hex 16)" >>.env
yq eval 'del(.services.db.image)' -i docker-compose.yml
yq eval '.services.db.build.context = "../../"' -i docker-compose.yml
yq eval '.services.db.build.dockerfile = "./packages/twenty-docker/twenty-postgres-spilo/Dockerfile"' -i docker-compose.yml
echo "Docker compose up..."
docker compose up -d || {
echo "Docker compose failed to start"
docker compose logs
exit 1
}
docker compose logs db server -f &
pid=$!
echo "Setting up .env file..."
cp .env.example .env
echo "Generating secrets..."
echo "# === Randomly generated secrets ===" >>.env
echo "APP_SECRET=$(openssl rand -base64 32)" >>.env
echo "PGPASSWORD_SUPERUSER=$(openssl rand -base64 32)" >>.env
echo "Waiting for database to start..."
count=0
while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-db-1) = "healthy" ]; do
sleep 1;
count=$((count+1));
if [ $(docker inspect --format='{{.State.Status}}' twenty-db-1) = "exited" ]; then
echo "Database exited"
docker compose logs db
exit 1
fi
if [ $count -gt 300 ]; then
echo "Failed to start database after 5 minutes"
docker compose logs db
exit 1
fi
echo "Still waiting for database... (${count}/60)"
done
echo "Docker compose up..."
docker compose up -d || {
echo "Docker compose failed to start"
docker compose logs
exit 1
}
docker compose logs db server -f &
pid=$!
echo "Waiting for database to start..."
count=0
while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-db-1) = "healthy" ]; do
sleep 1;
count=$((count+1));
if [ $(docker inspect --format='{{.State.Status}}' twenty-db-1) = "exited" ]; then
echo "Database exited"
docker compose logs db
exit 1
fi
if [ $count -gt 300 ]; then
echo "Failed to start database after 5 minutes"
docker compose logs db
exit 1
fi
echo "Still waiting for database... (${count}/60)"
done
echo "Waiting for server to start..."
count=0
while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-server-1) = "healthy" ]; do
sleep 1;
count=$((count+1));
if [ $(docker inspect --format='{{.State.Status}}' twenty-server-1) = "exited" ]; then
echo "Server exited"
docker compose logs server
exit 1
fi
if [ $count -gt 300 ]; then
echo "Failed to start server after 5 minutes"
docker compose logs server
exit 1
fi
echo "Still waiting for server... (${count}/300s)"
done
working-directory: ./packages/twenty-docker/
echo "Waiting for server to start..."
count=0
while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-server-1) = "healthy" ]; do
sleep 1;
count=$((count+1));
if [ $(docker inspect --format='{{.State.Status}}' twenty-server-1) = "exited" ]; then
echo "Server exited"
docker compose logs server
exit 1
fi
if [ $count -gt 300 ]; then
echo "Failed to start server after 5 minutes"
docker compose logs server
exit 1
fi
echo "Still waiting for server... (${count}/300s)"
done
working-directory: ./packages/twenty-docker/
ci-test-docker-compose-status-check:
if: always() && !cancelled()
timeout-minutes: 1
runs-on: ubuntu-latest
needs: [changed-files-check, test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
-26
View File
@@ -1,26 +0,0 @@
name: CI Tinybird
on:
push:
branches:
- main
paths:
- 'package.json'
- 'packages/twenty-tinybird/**'
pull_request:
paths:
- 'package.json'
- 'packages/twenty-tinybird/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
ci:
uses: tinybirdco/ci/.github/workflows/ci.yml@main
with:
data_project_dir: packages/twenty-tinybird
secrets:
tb_admin_token: ${{ secrets.TB_ADMIN_TOKEN }}
tb_host: https://api.eu-central-1.aws.tinybird.co
+1 -1
View File
@@ -21,7 +21,7 @@ concurrency:
jobs:
danger-js:
timeout-minutes: 3
timeout-minutes: 5
runs-on: ubuntu-latest
if: github.event.action != 'closed'
steps:
+25 -18
View File
@@ -5,15 +5,22 @@ on:
- main
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
package.json
packages/twenty-website/**
website-build:
timeout-minutes: 3
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 10
runs-on: ubuntu-latest
services:
postgres:
@@ -21,8 +28,8 @@ jobs:
env:
PGUSER_SUPERUSER: postgres
PGPASSWORD_SUPERUSER: postgres
ALLOW_NOSSL: "true"
SPILO_PROVIDER: "local"
ALLOW_NOSSL: 'true'
SPILO_PROVIDER: 'local'
ports:
- 5432:5432
options: >-
@@ -34,31 +41,31 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: 'package.json, packages/twenty-website/**'
- name: Install dependencies
if: steps.changed-files.outputs.changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Server / Create DB
if: steps.changed-files.outputs.any_changed == 'true'
run: PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "default";'
- name: Website / Run migrations
if: steps.changed-files.outputs.changed == 'true'
run: npx nx database:migrate twenty-website
run: npx nx database:migrate twenty-website
env:
DATABASE_PG_URL: postgres://postgres:postgres@localhost:5432/default
- name: Website / Build Website
if: steps.changed-files.outputs.changed == 'true'
run: npx nx build twenty-website
env:
DATABASE_PG_URL: postgres://postgres:postgres@localhost:5432/default
- name: Mark as VALID
if: steps.changed-files.outputs.changed != 'true' # If no changes, mark as valid
run: echo "No relevant changes detected. CI is valid."
KEYSTATIC_GITHUB_CLIENT_ID: xxx
KEYSTATIC_GITHUB_CLIENT_SECRET: xxx
KEYSTATIC_SECRET: xxx
NEXT_PUBLIC_KEYSTATIC_GITHUB_APP_SLUG: xxx
ci-website-status-check:
if: always() && !cancelled()
timeout-minutes: 10
runs-on: ubuntu-latest
needs: [changed-files-check, website-build]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
+131
View File
@@ -0,0 +1,131 @@
# Pull down translations from Crowdin every two hours or when triggered manually.
# When force_pull input is true, translations will be pulled regardless of compilation status.
name: 'Pull translations from Crowdin'
on:
schedule:
- cron: '0 */2 * * *' # Every two hours.
workflow_dispatch:
inputs:
force_pull:
description: 'Force pull translations regardless of compilation status'
required: false
type: boolean
default: false
workflow_call:
inputs:
force_pull:
description: 'Force pull translations regardless of compilation status'
required: false
type: boolean
default: false
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
pull_translations:
name: Pull translations
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
token: ${{ github.token }}
ref: ${{ github.head_ref || github.ref_name }}
- name: Setup i18n branch
run: |
git fetch origin i18n || true
git checkout -B i18n origin/i18n || git checkout -b i18n
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Build twenty-shared
run: npx nx build twenty-shared
# Strict mode fails if there are missing translations.
- name: Compile translations
id: compile_translations_strict
run: |
npx nx run twenty-server:lingui:compile --strict
npx nx run twenty-emails:lingui:compile --strict
npx nx run twenty-front:lingui:compile --strict
continue-on-error: true
- name: Stash any changes before pulling translations
run: |
git config --global user.name 'github-actions'
git config --global user.email 'github-actions@twenty.com'
git add .
git stash
- name: Pull translations from Crowdin
if: inputs.force_pull || steps.compile_translations_strict.outcome == 'failure'
uses: crowdin/github-action@v2
with:
upload_sources: false
upload_translations: false
download_translations: true
export_only_approved: false
localization_branch_name: i18n
base_url: 'https://twenty.api.crowdin.com'
auto_approve_imported: false
import_eq_suggestions: false
download_sources: false
push_sources: false
skip_untranslated_strings: false
skip_untranslated_files: false
push_translations: true
create_pull_request: false
skip_ref_checkout: true
dryrun_action: false
env:
GITHUB_TOKEN: ${{ github.token }}
CROWDIN_PROJECT_ID: '1'
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
# As the files are extracted from a Docker container, they belong to root:root
# We need to fix this before the next steps
- name: Fix file permissions
run: sudo chown -R runner:docker .
- name: Compile translations
id: compile_translations
if: inputs.force_pull || steps.compile_translations_strict.outcome == 'failure'
run: |
npx nx run twenty-server:lingui:compile
npx nx run twenty-emails:lingui:compile
npx nx run twenty-front:lingui:compile
git status
git config --global user.name 'github-actions'
git config --global user.email 'github-actions@twenty.com'
git add .
if ! git diff --staged --quiet --exit-code; then
git commit -m "chore: compile translations"
echo "changes_detected=true" >> $GITHUB_OUTPUT
else
echo "changes_detected=false" >> $GITHUB_OUTPUT
fi
- name: Push changes
if: steps.compile_translations.outputs.changes_detected == 'true'
run: git push origin HEAD:i18n
- name: Create pull request
if: steps.compile_translations.outputs.changes_detected == 'true'
run: |
if git diff --name-only origin/main..HEAD | grep -q .; then
gh pr create -B main -H i18n --title 'i18n - translations' --body 'Created by Github action' || true
else
echo "No file differences between branches, skipping PR creation"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+104
View File
@@ -0,0 +1,104 @@
name: 'Push translations to Crowdin'
on:
workflow_dispatch:
workflow_call:
push:
branches: ['main']
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
extract_translations:
name: Extract and upload translations
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
token: ${{ github.token }}
ref: main
- name: Setup i18n branch
run: |
git fetch origin i18n || true
git checkout -B i18n origin/i18n || git checkout -b i18n
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Build dependencies
run: npx nx build twenty-shared
- name: Extract translations
run: |
npx nx run twenty-server:lingui:extract
npx nx run twenty-emails:lingui:extract
npx nx run twenty-front:lingui:extract
- name: Check and commit extracted files
id: check_extract_changes
run: |
git config --global user.name 'github-actions'
git config --global user.email 'github-actions@twenty.com'
git add .
if ! git diff --staged --quiet --exit-code; then
git commit -m "chore: extract translations"
echo "changes_detected=true" >> $GITHUB_OUTPUT
else
echo "changes_detected=false" >> $GITHUB_OUTPUT
fi
- name: Compile translations
run: |
npx nx run twenty-server:lingui:compile
npx nx run twenty-emails:lingui:compile
npx nx run twenty-front:lingui:compile
- name: Check and commit compiled files
id: check_compile_changes
run: |
git config --global user.name 'github-actions'
git config --global user.email 'github-actions@twenty.com'
git add .
if ! git diff --staged --quiet --exit-code; then
git commit -m "chore: compile translations"
echo "changes_detected=true" >> $GITHUB_OUTPUT
else
echo "changes_detected=false" >> $GITHUB_OUTPUT
fi
- name: Push changes and create remote branch if needed
if: steps.check_extract_changes.outputs.changes_detected == 'true' || steps.check_compile_changes.outputs.changes_detected == 'true'
run: git push origin HEAD:i18n
- name: Upload missing translations
if: steps.check_extract_changes.outputs.changes_detected == 'true'
uses: crowdin/github-action@v2
with:
upload_sources: true
upload_translations: true
download_translations: false
localization_branch_name: i18n
base_url: 'https://twenty.api.crowdin.com'
env:
# A numeric ID, found at https://crowdin.com/project/<projectName>/tools/api
CROWDIN_PROJECT_ID: 1
# Visit https://crowdin.com/settings#api-key to create this token
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
- name: Create a pull request
if: steps.check_extract_changes.outputs.changes_detected == 'true' || steps.check_compile_changes.outputs.changes_detected == 'true'
run: |
if git diff --name-only origin/main..HEAD | grep -q .; then
gh pr create -B main -H i18n --title 'i18n - translations' --body 'Created by Github action' || true
else
echo "No file differences between branches, skipping PR creation"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+4
View File
@@ -18,6 +18,7 @@
!.yarn/sdks
!.yarn/versions
.vercel
.swc
**/**/logs/**
@@ -40,3 +41,6 @@ dump.rdb
/devenv.nix
/flake.lock
/flake.nix
.crowdin.yml
.react-email/
+1 -1
View File
@@ -1 +1 @@
18.17.1
18.17.1
+21
View File
@@ -60,6 +60,27 @@
"cwd": "${workspaceFolder}",
"internalConsoleOptions": "neverOpen",
"envFile": "${workspaceFolder}/packages/twenty-e2e-testing/.env"
},
{
"type": "node",
"request": "launch",
"name": "twenty-server - debug integration test file (to launch with test file open)",
"runtimeExecutable": "npx",
"runtimeArgs": [
"nx",
"run",
"twenty-server:jest",
"--",
"--config",
"./jest-integration.config.ts",
"${relativeFile}"
],
"cwd": "${workspaceFolder}/packages/twenty-server",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"env": {
"NODE_ENV": "test"
},
}
]
}
+2
View File
@@ -49,4 +49,6 @@
"files.associations": {
".cursorrules": "markdown"
},
"jestrunner.codeLensSelector": "**/*.{test,spec,integration-spec}.{js,jsx,ts,tsx}"
}
}
+4
View File
@@ -1,3 +1,7 @@
enableConstraintsChecks: true
enableHardenedMode: true
enableInlineHunks: true
nodeLinker: node-modules
+4 -1
View File
@@ -17,4 +17,7 @@ postgres-on-docker:
-c "CREATE DATABASE \"test\" WITH OWNER postgres;"
redis-on-docker:
docker run -d --name twenty_redis -p 6379:6379 redis/redis-stack-server:latest
docker run -d --name twenty_redis -p 6379:6379 redis/redis-stack-server:latest
clickhouse-on-docker:
docker run -d --name twenty_clickhouse -p 8123:8123 -p 9000:9000 -e CLICKHOUSE_PASSWORD=devPassword clickhouse/clickhouse-server:latest
+5 -16
View File
@@ -8,7 +8,7 @@
<h2 align="center" >The #1 Open-Source CRM </h3>
<p align="center"><a href="https://twenty.com">🌐 Website</a> · <a href="https://twenty.com/developers">📚 Documentation</a> · <a href="https://discord.gg/cx5n4Jzs57"><img src="./packages/twenty-website/public/images/readme/discord-icon.svg" width="12" height="12"/> Discord</a> · <a href="https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty"><img src="./packages/twenty-website/public/images/readme/figma-icon.png" width="12" height="12"/> Figma</a><p>
<p align="center"><a href="https://twenty.com">🌐 Website</a> · <a href="https://twenty.com/developers">📚 Documentation</a> · <a href="https://github.com/orgs/twentyhq/projects/1"><img src="./packages/twenty-website/public/images/readme/planner-icon.svg" width="12" height="12"/> Roadmap </a> · <a href="https://discord.gg/cx5n4Jzs57"><img src="./packages/twenty-website/public/images/readme/discord-icon.svg" width="12" height="12"/> Discord</a> · <a href="https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty"><img src="./packages/twenty-website/public/images/readme/figma-icon.png" width="12" height="12"/> Figma</a><p>
<br />
@@ -24,22 +24,9 @@
<br>
# Demo
# Installation
<!--
You can use the following url to sign up to the cloud version without providing a credit card:
<a href="https://demo.twenty.com/?billingCheckoutSession={"plan":"PRO","recurringInterval":"MONTHLY","requirePaymentMethod":false,"skipPlanPage":true}">https://demo.twenty.com/?billingCheckoutSession={"plan":"PRO","recurringInterval":"MONTHLY","requirePaymentMethod":false,"skipPlanPage":true}</a>
-->
Go to <a href="https://demo.twenty.com/">demo.twenty.com</a> and login with the following credentials:
```
email: tim@apple.dev
password: Applecar2025
```
See also:
See:
🚀 [Self-hosting](https://twenty.com/developers/section/self-hosting)
🖥️ [Local Setup](https://twenty.com/developers/local-setup)
@@ -158,6 +145,7 @@ Below are a few features we have implemented to date:
- [NestJS](https://nestjs.com/), with [BullMQ](https://bullmq.io/), [PostgreSQL](https://www.postgresql.org/), [Redis](https://redis.io/)
- [React](https://reactjs.org/), with [Recoil](https://recoiljs.org/) and [Emotion](https://emotion.sh/)
- [Greptile](https://greptile.com) for code reviews.
- [Lingui](https://lingui.dev/) and [Crowdin](https://twenty.crowdin.com/twenty) for translations.
# Join the Community
@@ -166,6 +154,7 @@ Below are a few features we have implemented to date:
- Subscribe to releases (watch -> custom -> releases)
- Follow us on [Twitter](https://twitter.com/twentycrm) or [LinkedIn](https://www.linkedin.com/company/twenty/)
- Join our [Discord](https://discord.gg/cx5n4Jzs57)
- Improve translations on [Crowdin](https://twenty.crowdin.com/twenty)
- [Contributions](https://github.com/twentyhq/twenty/contribute) are, of course, most welcome!
+31
View File
@@ -0,0 +1,31 @@
#
# Basic Crowdin CLI configuration
# See https://crowdin.github.io/crowdin-cli/configuration for more information
# See https://support.crowdin.com/developer/configuration-file/ for all available options
#
#
# Defines whether to preserve the original directory structure in the Crowdin project
# Recommended to set to true
#
"preserve_hierarchy": true
#
# Files configuration.
# See https://support.crowdin.com/developer/configuration-file/ for all available options
#
files: [
{
#
# Source files filter
# e.g. "/resources/en/*.json"
#
"source": "**/en.po",
#
# Translation files filter
# e.g. "/resources/%two_letters_code%/%original_file_name%"
#
"translation": "%original_path%/%locale%.po",
}
]
+13 -7
View File
@@ -14,6 +14,7 @@
"!{projectRoot}/**/tsconfig.spec.json",
"!{projectRoot}/**/*.test.(ts|tsx)",
"!{projectRoot}/**/*.spec.(ts|tsx)",
"!{projectRoot}/**/*.integration-spec.ts",
"!{projectRoot}/**/__tests__/*"
],
"production": [
@@ -115,7 +116,7 @@
"outputs": ["{projectRoot}/{options.output-dir}"],
"options": {
"cwd": "{projectRoot}",
"command": "VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true storybook build",
"command": "VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true storybook build --test",
"output-dir": "storybook-static",
"config-dir": ".storybook"
},
@@ -151,12 +152,14 @@
"options": {
"cwd": "{projectRoot}",
"commands": [
"test-storybook --url http://localhost:{args.port} --maxWorkers=3 --coverage --coverageDirectory={args.coverageDir}",
"nx storybook:coverage {projectName} --coverageDir={args.coverageDir}"
"test-storybook --url http://localhost:{args.port} --maxWorkers=3 --coverage --coverageDirectory={args.coverageDir} --shard={args.shard}",
"nx storybook:coverage {projectName} --coverageDir={args.coverageDir} --checkCoverage={args.checkCoverage}"
],
"shard": "1/1",
"parallel": false,
"coverageDir": "coverage/storybook",
"port": 6006
"port": 6006,
"checkCoverage": true
}
},
"storybook:test:no-coverage": {
@@ -183,9 +186,10 @@
"!{projectRoot}/coverage/storybook/coverage-storybook.json"
],
"options": {
"command": "npx nyc report --reporter={args.reporter} --reporter=text-summary -t {args.coverageDir} --report-dir {args.coverageDir} --check-coverage --cwd={projectRoot}",
"command": "npx nyc report --reporter={args.reporter} --reporter=text-summary -t {args.coverageDir} --report-dir {args.coverageDir} --check-coverage={args.checkCoverage} --cwd={projectRoot}",
"coverageDir": "coverage/storybook",
"reporter": "lcov"
"reporter": "lcov",
"checkCoverage": true
},
"configurations": {
"text": { "reporter": "text" }
@@ -195,8 +199,10 @@
"executor": "nx:run-commands",
"options": {
"commands": [
"npx concurrently --kill-others --success=first -n SB,TEST 'nx storybook:serve:static {projectName} --port={args.port} --configuration={args.performance}' 'npx wait-on tcp:{args.port} && nx storybook:test {projectName} --port={args.port} --configuration={args.scope}'"
"npx concurrently --kill-others --success=first -n SB,TEST 'nx storybook:serve:static {projectName} --port={args.port}' 'npx wait-on tcp:{args.port} && nx storybook:test {projectName} --shard={args.shard} --checkCoverage={args.checkCoverage} --port={args.port} --configuration={args.scope}'"
],
"shard": "1/1",
"checkCoverage": true,
"port": 6006
}
},
+21 -12
View File
@@ -1,13 +1,16 @@
{
"private": true,
"dependencies": {
"@air/react-drag-to-select": "^5.0.8",
"@apollo/client": "^3.7.17",
"@apollo/server": "^4.7.3",
"@aws-sdk/client-lambda": "^3.614.0",
"@aws-sdk/client-s3": "^3.363.0",
"@aws-sdk/client-sts": "^3.744.0",
"@aws-sdk/credential-providers": "^3.363.0",
"@blocknote/mantine": "^0.22.0",
"@blocknote/react": "^0.22.0",
"@blocknote/server-util": "0.17.1",
"@codesandbox/sandpack-react": "^2.13.5",
"@dagrejs/dagre": "^1.1.2",
"@emotion/react": "^11.11.1",
@@ -35,21 +38,21 @@
"@nestjs/passport": "^9.0.3",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/serve-static": "^4.0.1",
"@nestjs/terminus": "^9.2.2",
"@nestjs/terminus": "^11.0.0",
"@nestjs/typeorm": "^10.0.0",
"@nx/eslint-plugin": "^17.2.8",
"@octokit/graphql": "^7.0.2",
"@ptc-org/nestjs-query-core": "^4.2.0",
"@ptc-org/nestjs-query-typeorm": "4.2.1-alpha.2",
"@react-email/components": "0.0.12",
"@react-email/render": "0.0.10",
"@react-email/components": "0.0.35",
"@react-email/render": "0.0.17",
"@sentry/node": "^8",
"@sentry/profiling-node": "^8",
"@sentry/react": "^8",
"@sniptt/guards": "^0.2.0",
"@stoplight/elements": "^8.0.5",
"@swc/jest": "^0.2.29",
"@tabler/icons-react": "^2.44.0",
"@tabler/icons-react": "^3.31.0",
"@types/dompurify": "^3.0.5",
"@types/facepaint": "^1.2.5",
"@types/lodash.camelcase": "^4.3.7",
@@ -59,7 +62,7 @@
"@types/nodemailer": "^6.4.14",
"@types/passport-microsoft": "^1.0.3",
"@wyw-in-js/vite": "^0.5.3",
"@xyflow/react": "^12.3.5",
"@xyflow/react": "^12.4.2",
"add": "^2.0.6",
"addressparser": "^1.0.1",
"afterframe": "^1.0.2",
@@ -70,10 +73,11 @@
"bcrypt": "^5.1.1",
"better-sqlite3": "^9.2.2",
"body-parser": "^1.20.2",
"bullmq": "^4.15.0",
"bullmq": "^5.40.0",
"bytes": "^3.1.2",
"class-transformer": "^0.5.1",
"clsx": "^2.1.1",
"cron-validate": "^1.4.5",
"cross-env": "^7.0.3",
"css-loader": "^7.1.2",
"danger-plugin-todos": "^1.3.1",
@@ -88,14 +92,16 @@
"esbuild-plugin-svgr": "^2.1.0",
"facepaint": "^1.2.1",
"file-type": "16.5.4",
"framer-motion": "^10.12.17",
"framer-motion": "^11.18.0",
"googleapis": "105",
"graphiql": "^3.1.1",
"graphql": "16.8.0",
"graphql-fields": "^2.0.3",
"graphql-middleware": "^6.1.35",
"graphql-rate-limit": "^3.3.0",
"graphql-redis-subscriptions": "^2.7.0",
"graphql-scalars": "^1.23.0",
"graphql-sse": "^2.5.4",
"graphql-subscriptions": "2.0.0",
"graphql-tag": "^2.12.6",
"graphql-type-json": "^0.3.2",
@@ -136,8 +142,6 @@
"next-mdx-remote": "^4.4.1",
"nodemailer": "^6.9.8",
"openapi-types": "^12.1.3",
"overlayscrollbars": "^2.6.1",
"overlayscrollbars-react": "^0.5.4",
"passport": "^0.7.0",
"passport-google-oauth20": "^2.0.0",
"passport-jwt": "^4.0.1",
@@ -162,7 +166,7 @@
"react-hotkeys-hook": "^4.4.4",
"react-icons": "^4.12.0",
"react-imask": "^7.6.0",
"react-intersection-observer": "^9.5.2",
"react-intersection-observer": "^9.15.1",
"react-loading-skeleton": "^3.3.1",
"react-phone-number-input": "^3.3.4",
"react-responsive": "^9.0.2",
@@ -179,6 +183,7 @@
"semver": "^7.5.4",
"sharp": "^0.32.1",
"slash": "^5.1.0",
"storybook-addon-mock-date": "^0.6.0",
"stripe": "^17.3.1",
"ts-key-enum": "^2.0.12",
"tslib": "^2.3.0",
@@ -235,7 +240,7 @@
"@stylistic/eslint-plugin": "^1.5.0",
"@swc-node/register": "1.8.0",
"@swc/cli": "^0.3.12",
"@swc/core": "~1.3.100",
"@swc/core": "1.7.42",
"@swc/helpers": "~0.5.2",
"@testing-library/jest-dom": "^6.1.5",
"@testing-library/react": "14.0.0",
@@ -285,6 +290,7 @@
"@typescript-eslint/utils": "6.21.0",
"@vitejs/plugin-react-swc": "^3.5.0",
"@vitest/ui": "1.4.0",
"@yarnpkg/types": "^4.0.0",
"chromatic": "^6.18.0",
"concurrently": "^8.2.2",
"cross-var": "^1.1.0",
@@ -297,6 +303,7 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-lingui": "^0.9.0",
"eslint-plugin-prefer-arrow": "^1.2.3",
"eslint-plugin-prettier": "^5.1.2",
"eslint-plugin-project-structure": "^3.9.1",
@@ -349,7 +356,9 @@
"graphql": "16.8.0",
"type-fest": "4.10.1",
"typescript": "5.3.3",
"prosemirror-model": "1.23.0"
"prosemirror-model": "1.23.0",
"yjs": "13.6.18",
"graphql-redis-subscriptions/ioredis": "^5.6.0"
},
"version": "0.2.1",
"nx": {},
@@ -1,11 +1,16 @@
module.exports = {
extends: ['../../.eslintrc.cjs', '../../.eslintrc.react.cjs'],
ignorePatterns: ['!**/*', 'node_modules', 'dist', '**/generated/*'],
root: true,
extends: ['../../.eslintrc.global.cjs', '../../.eslintrc.react.cjs'],
ignorePatterns: [
'node_modules',
'dist',
'**/generated/*',
],
overrides: [
{
files: ['*.ts', '*.tsx'],
files: ['**/*.ts', '**/*.tsx'],
parserOptions: {
project: ['packages/twenty-chrome-extension/tsconfig.{json,*.json}'],
project: ['packages/twenty-chrome-extension/tsconfig.*.json'],
},
rules: {
'@nx/workspace-explicit-boolean-predicates-in-if': 'warn',
@@ -6,5 +6,8 @@
"type": "module",
"scripts": {
"build": "npx vite build"
},
"dependencies": {
"twenty-shared": "workspace:*"
}
}
@@ -8,7 +8,8 @@
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "{projectRoot}/dist"
}
},
"dependsOn": ["^build"]
},
"start": {
"executor": "nx:run-commands",
@@ -1,5 +1,4 @@
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
// Open options page programmatically in a new tab.
// chrome.runtime.onInstalled.addListener((details) => {
// if (details.reason === 'install') {
@@ -1,5 +1,4 @@
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
interface CustomDiv extends HTMLDivElement {
onClickHandler: (newHandler: () => void) => void;
}
@@ -4,7 +4,7 @@ import extractCompanyLinkedinLink from '~/contentScript/utils/extractCompanyLink
import extractDomain from '~/contentScript/utils/extractDomain';
import { createCompany, fetchCompany } from '~/db/company.db';
import { CompanyInput } from '~/db/types/company.types';
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
export const checkIfCompanyExists = async () => {
const { tab: activeTab } = await chrome.runtime.sendMessage({
@@ -3,7 +3,7 @@ import changeSidePanelUrl from '~/contentScript/utils/changeSidepanelUrl';
import extractFirstAndLastName from '~/contentScript/utils/extractFirstAndLastName';
import { createPerson, fetchPerson } from '~/db/person.db';
import { PersonInput } from '~/db/types/person.types';
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
export const checkIfPersonExists = async () => {
const { tab: activeTab } = await chrome.runtime.sendMessage({
@@ -1,6 +1,6 @@
import { insertButtonForCompany } from '~/contentScript/extractCompanyProfile';
import { insertButtonForPerson } from '~/contentScript/extractPersonProfile';
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
// Inject buttons into the DOM when SPA is reloaded on the resource url.
// e.g. reload the page when on https://www.linkedin.com/in/mabdullahabaid/
@@ -1,5 +1,4 @@
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
const btn = document.getElementById('twenty-settings-btn');
if (!isDefined(btn)) {
const div = document.createElement('div');
@@ -1,5 +1,4 @@
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
const changeSidePanelUrl = async (url: string) => {
if (isDefined(url)) {
chrome.storage.local.set({ navigateSidepanel: 'sidepanel' });
@@ -1,7 +1,4 @@
// Extract "https://www.linkedin.com/company/twenty/" from any of the following urls, which the user can visit while on the company page.
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
// "https://www.linkedin.com/company/twenty/" "https://www.linkedin.com/company/twenty/about/" "https://www.linkedin.com/company/twenty/people/".
const extractCompanyLinkedinLink = (activeTabUrl: string) => {
// Regular expression to match the company ID
@@ -4,8 +4,8 @@ import {
Tokens,
} from '~/db/types/auth.types';
import { EXCHANGE_AUTHORIZATION_CODE } from '~/graphql/auth/mutations';
import { isDefined } from '~/utils/isDefined';
import { callMutation } from '~/utils/requestDb';
import { isDefined } from 'twenty-shared/utils';
export const exchangeAuthorizationCode = async (
exchangeAuthCodeInput: ExchangeAuthCodeInput,
@@ -6,9 +6,9 @@ import {
import { Company, CompanyFilterInput } from '~/generated/graphql';
import { CREATE_COMPANY } from '~/graphql/company/mutations';
import { FIND_COMPANY } from '~/graphql/company/queries';
import { isDefined } from '~/utils/isDefined';
import { callMutation, callQuery } from '../utils/requestDb';
import { isDefined } from 'twenty-shared/utils';
export const fetchCompany = async (
companyfilerInput: CompanyFilterInput,
@@ -6,9 +6,9 @@ import {
import { Person, PersonFilterInput } from '~/generated/graphql';
import { CREATE_PERSON } from '~/graphql/person/mutations';
import { FIND_PERSON } from '~/graphql/person/queries';
import { isDefined } from '~/utils/isDefined';
import { callMutation, callQuery } from '../utils/requestDb';
import { isDefined } from 'twenty-shared/utils';
export const fetchPerson = async (
personFilterData: PersonFilterInput,
@@ -1,8 +1,7 @@
import { ApolloClient, InMemoryCache } from '@apollo/client';
import { Tokens } from '~/db/types/auth.types';
import { RENEW_TOKEN } from '~/graphql/auth/mutations';
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
export const renewToken = async (
appToken: string,
@@ -1,8 +1,7 @@
import { useEffect, useState } from 'react';
import Settings from '~/options/Settings';
import Sidepanel from '~/options/Sidepanel';
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
const App = () => {
const [currentScreen, setCurrentScreen] = useState('');
@@ -1,10 +1,10 @@
import { useEffect, useState } from 'react';
import styled from '@emotion/styled';
import { useEffect, useState } from 'react';
import { MainButton } from '@/ui/input/button/MainButton';
import { TextInput } from '@/ui/input/components/TextInput';
import { clearStore } from '~/utils/apolloClient';
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
const StyledWrapper = styled.div`
align-items: center;
@@ -1,8 +1,8 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import styled from '@emotion/styled';
import { useCallback, useEffect, useRef, useState } from 'react';
import { MainButton } from '@/ui/input/button/MainButton';
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
const StyledIframe = styled.iframe`
display: block;
@@ -42,7 +42,6 @@ const StyledInput = styled.input`
flex: 1;
border: none;
outline: none;
font-family: Arial, sans-serif;
font-size: 14px;
&::placeholder {
@@ -1,8 +1,7 @@
import { useEffect, useState } from 'react';
import styled from '@emotion/styled';
import { motion } from 'framer-motion';
import { isDefined } from '~/utils/isDefined';
import { useEffect, useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
export type ToggleSize = 'small' | 'medium';
@@ -1,8 +1,7 @@
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import { onError } from '@apollo/client/link/error';
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
export const clearStore = () => {
chrome.storage.local.remove([
@@ -1,8 +1,7 @@
import { OperationVariables } from '@apollo/client';
import { DocumentNode } from 'graphql';
import getApolloClient from '~/utils/apolloClient';
import { isDefined } from '~/utils/isDefined';
import { isDefined } from 'twenty-shared/utils';
export const callQuery = async <T>(
query: DocumentNode,
@@ -9,8 +9,8 @@
"skipLibCheck": true,
"esModuleInterop": true,
"paths": {
"@/*": ["packages/twenty-chrome-extension/src/options/modules/*"],
"~/*": ["packages/twenty-chrome-extension/src/*"]
"@/*": ["./src/options/modules/*"],
"~/*": ["./src/*"]
},
/* Bundler mode */
+4 -2
View File
@@ -1,11 +1,13 @@
TAG=latest
#PGUSER_SUPERUSER=postgres
#PGPASSWORD_SUPERUSER=replace_me_with_a_strong_password
#PG_DATABASE_USER=postgres
#PG_DATABASE_PASSWORD=replace_me_with_a_strong_password_without_special_characters
#PG_DATABASE_HOST=db
#PG_DATABASE_PORT=5432
#REDIS_URL=redis://redis:6379
SERVER_URL=http://localhost:3000
SIGN_IN_PREFILLED=false
# Use openssl rand -base64 32 for each secret
# APP_SECRET=replace_me_with_a_random_string
+18 -5
View File
@@ -1,14 +1,27 @@
# Makefile for building Twenty CRM docker images.
# Set the tag and/or target build platform using make command-line variables assignments.
#
# Optional make variables:
# PLATFORM - defaults to 'linux/amd64'
# TAG - defaults to 'latest'
#
# Example: make
# Example: make PLATFORM=linux/aarch64 TAG=my-tag
PLATFORM ?= linux/amd64
TAG ?= latest
prod-build:
@cd ../.. && docker build -f ./packages/twenty-docker/twenty/Dockerfile --tag twenty . && cd -
@cd ../.. && docker build -f ./packages/twenty-docker/twenty/Dockerfile --platform $(PLATFORM) --tag twenty:$(TAG) . && cd -
prod-run:
@docker run -d -p 3000:3000 --name twenty twenty
@docker run -d -p 3000:3000 --name twenty twenty:$(TAG)
prod-postgres-run:
@docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres --name twenty-postgres twenty-postgres
@docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres --name twenty-postgres twenty-postgres:$(TAG)
prod-website-build:
@cd ../.. && docker build -f ./packages/twenty-docker/twenty-website/Dockerfile --tag twenty-website . && cd -
@cd ../.. && docker build -f ./packages/twenty-docker/twenty-website/Dockerfile --platform $(PLATFORM) --tag twenty-website:$(TAG) . && cd -
prod-website-run:
@docker run -d -p 3000:3000 --name twenty-website twenty-website
@docker run -d -p 3000:3000 --name twenty-website twenty-website:$(TAG)
+64 -16
View File
@@ -1,4 +1,3 @@
version: "3.9"
name: twenty
services:
@@ -14,25 +13,49 @@ services:
&& chown -R 1000:1000 /tmp/docker-data"
server:
image: twentycrm/twenty:${TAG}
image: twentycrm/twenty:${TAG:-latest}
volumes:
- server-local-data:/app/packages/twenty-server/${STORAGE_LOCAL_PATH:-.local-storage}
- docker-data:/app/docker-data
ports:
- "3000:3000"
environment:
PORT: 3000
PG_DATABASE_URL: postgres://${PGUSER_SUPERUSER:-postgres}:${PGPASSWORD_SUPERUSER:-postgres}@${PG_DATABASE_HOST:-db:5432}/default
NODE_PORT: 3000
PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default
SERVER_URL: ${SERVER_URL}
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
SIGN_IN_PREFILLED: ${SIGN_IN_PREFILLED}
STORAGE_TYPE: ${STORAGE_TYPE}
STORAGE_S3_REGION: ${STORAGE_S3_REGION}
STORAGE_S3_NAME: ${STORAGE_S3_NAME}
STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT}
APP_SECRET: ${APP_SECRET}
APP_SECRET: ${APP_SECRET:-replace_me_with_a_random_string}
# MESSAGING_PROVIDER_GMAIL_ENABLED: ${MESSAGING_PROVIDER_GMAIL_ENABLED}
# CALENDAR_PROVIDER_GOOGLE_ENABLED: ${CALENDAR_PROVIDER_GOOGLE_ENABLED}
# AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID}
# AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET}
# AUTH_GOOGLE_CALLBACK_URL: ${AUTH_GOOGLE_CALLBACK_URL}
# AUTH_GOOGLE_APIS_CALLBACK_URL: ${AUTH_GOOGLE_APIS_CALLBACK_URL}
# CALENDAR_PROVIDER_MICROSOFT_ENABLED: ${CALENDAR_PROVIDER_MICROSOFT_ENABLED}
# MESSAGING_PROVIDER_MICROSOFT_ENABLED: ${MESSAGING_PROVIDER_MICROSOFT_ENABLED}
# AUTH_MICROSOFT_ENABLED: ${AUTH_MICROSOFT_ENABLED}
# AUTH_MICROSOFT_CLIENT_ID: ${AUTH_MICROSOFT_CLIENT_ID}
# AUTH_MICROSOFT_CLIENT_SECRET: ${AUTH_MICROSOFT_CLIENT_SECRET}
# AUTH_MICROSOFT_CALLBACK_URL: ${AUTH_MICROSOFT_CALLBACK_URL}
# AUTH_MICROSOFT_APIS_CALLBACK_URL: ${AUTH_MICROSOFT_APIS_CALLBACK_URL}
# EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-contact@yourdomain.com}
# EMAIL_FROM_NAME: ${EMAIL_FROM_NAME:-"John from YourDomain"}
# EMAIL_SYSTEM_ADDRESS: ${EMAIL_SYSTEM_ADDRESS:-system@yourdomain.com}
# EMAIL_DRIVER: ${EMAIL_DRIVER:-smtp}
# EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST:-smtp.gmail.com}
# EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT:-465}
# EMAIL_SMTP_USER: ${EMAIL_SMTP_USER:-}
# EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD:-}
depends_on:
change-vol-ownership:
condition: service_completed_successfully
@@ -46,10 +69,12 @@ services:
restart: always
worker:
image: twentycrm/twenty:${TAG}
image: twentycrm/twenty:${TAG:-latest}
volumes:
- server-local-data:/app/packages/twenty-server/${STORAGE_LOCAL_PATH:-.local-storage}
command: ["yarn", "worker:prod"]
environment:
PG_DATABASE_URL: postgres://${PGUSER_SUPERUSER:-postgres}:${PGPASSWORD_SUPERUSER:-postgres}@${PG_DATABASE_HOST:-db:5432}/default
PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default
SERVER_URL: ${SERVER_URL}
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
DISABLE_DB_MIGRATIONS: "true" # it already runs on the server
@@ -59,7 +84,32 @@ services:
STORAGE_S3_NAME: ${STORAGE_S3_NAME}
STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT}
APP_SECRET: ${APP_SECRET}
APP_SECRET: ${APP_SECRET:-replace_me_with_a_random_string}
# MESSAGING_PROVIDER_GMAIL_ENABLED: ${MESSAGING_PROVIDER_GMAIL_ENABLED}
# CALENDAR_PROVIDER_GOOGLE_ENABLED: ${CALENDAR_PROVIDER_GOOGLE_ENABLED}
# AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID}
# AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET}
# AUTH_GOOGLE_CALLBACK_URL: ${AUTH_GOOGLE_CALLBACK_URL}
# AUTH_GOOGLE_APIS_CALLBACK_URL: ${AUTH_GOOGLE_APIS_CALLBACK_URL}
# CALENDAR_PROVIDER_MICROSOFT_ENABLED: ${CALENDAR_PROVIDER_MICROSOFT_ENABLED}
# MESSAGING_PROVIDER_MICROSOFT_ENABLED: ${MESSAGING_PROVIDER_MICROSOFT_ENABLED}
# AUTH_MICROSOFT_ENABLED: ${AUTH_MICROSOFT_ENABLED}
# AUTH_MICROSOFT_CLIENT_ID: ${AUTH_MICROSOFT_CLIENT_ID}
# AUTH_MICROSOFT_CLIENT_SECRET: ${AUTH_MICROSOFT_CLIENT_SECRET}
# AUTH_MICROSOFT_CALLBACK_URL: ${AUTH_MICROSOFT_CALLBACK_URL}
# AUTH_MICROSOFT_APIS_CALLBACK_URL: ${AUTH_MICROSOFT_APIS_CALLBACK_URL}
# EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-contact@yourdomain.com}
# EMAIL_FROM_NAME: ${EMAIL_FROM_NAME:-"John from YourDomain"}
# EMAIL_SYSTEM_ADDRESS: ${EMAIL_SYSTEM_ADDRESS:-system@yourdomain.com}
# EMAIL_DRIVER: ${EMAIL_DRIVER:-smtp}
# EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST:-smtp.gmail.com}
# EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT:-465}
# EMAIL_SMTP_USER: ${EMAIL_SMTP_USER:-}
# EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD:-}
depends_on:
db:
condition: service_healthy
@@ -68,16 +118,14 @@ services:
restart: always
db:
image: twentycrm/twenty-postgres-spilo:${TAG}
image: postgres:16
volumes:
- db-data:/home/postgres/pgdata
- db-data:/var/lib/postgresql/data
environment:
PGUSER_SUPERUSER: ${PGUSER_SUPERUSER:-postgres}
PGPASSWORD_SUPERUSER: ${PGPASSWORD_SUPERUSER:-postgres}
ALLOW_NOSSL: "true"
SPILO_PROVIDER: "local"
POSTGRES_USER: ${PG_DATABASE_USER:-postgres}
POSTGRES_PASSWORD: ${PG_DATABASE_PASSWORD:-postgres}
healthcheck:
test: pg_isready -U ${PGUSER_SUPERUSER:-postgres} -h localhost -d postgres
test: pg_isready -U ${PG_DATABASE_USER:-postgres} -h localhost -d postgres
interval: 5s
timeout: 5s
retries: 10
+3
View File
@@ -1,4 +1,7 @@
# README
DISCLAIMER: The k8s and podman deployments are not maintained by the core team.
These files are provided and maintained by the community. Twenty core team
maintains support for docker deployment.
## Overview
@@ -33,7 +33,7 @@ spec:
image: twentycrm/twenty:latest
imagePullPolicy: Always
env:
- name: PORT
- name: NODE_PORT
value: 3000
- name: SERVER_URL
value: "https://crm.example.com:443"
@@ -45,8 +45,6 @@ spec:
value: "false"
- name: STORAGE_TYPE
value: "local"
- name: "MESSAGE_QUEUE_TYPE"
value: "bull-mq"
- name: "ACCESS_TOKEN_EXPIRES_IN"
value: "7d"
- name: "LOGIN_TOKEN_EXPIRES_IN"
@@ -34,10 +34,6 @@ spec:
value: "false" # it already runs on the server
- name: STORAGE_TYPE
value: "local"
- name: "MESSAGE_QUEUE_TYPE"
value: "bull-mq"
- name: "CACHE_STORAGE_TYPE"
value: "redis"
- name: "REDIS_URL"
value: "redis://twentycrm-redis.twentycrm.svc.cluster.local:6379"
- name: APP_SECRET
@@ -38,13 +38,9 @@ resource "kubernetes_deployment" "twentycrm_server" {
tty = true
env {
name = "PORT"
name = "NODE_PORT"
value = "3000"
}
# env {
# name = "DEBUG_MODE"
# value = false
# }
env {
name = "SERVER_URL"
@@ -68,10 +64,6 @@ resource "kubernetes_deployment" "twentycrm_server" {
name = "STORAGE_TYPE"
value = "local"
}
env {
name = "MESSAGE_QUEUE_TYPE"
value = "bull-mq"
}
env {
name = "ACCESS_TOKEN_EXPIRES_IN"
value = "7d"
@@ -48,11 +48,6 @@ resource "kubernetes_deployment" "twentycrm_worker" {
value = "postgres://twenty:${var.twentycrm_pgdb_admin_password}@${kubernetes_service.twentycrm_db.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local/default"
}
env {
name = "CACHE_STORAGE_TYPE"
value = "redis"
}
env {
name = "REDIS_URL"
value = "redis://${kubernetes_service.twentycrm_redis.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local:6379"
@@ -67,10 +62,6 @@ resource "kubernetes_deployment" "twentycrm_worker" {
name = "STORAGE_TYPE"
value = "local"
}
env {
name = "MESSAGE_QUEUE_TYPE"
value = "bull-mq"
}
env {
name = "APP_SECRET"
+48
View File
@@ -0,0 +1,48 @@
# How to deploy twenty on podman
DISCLAIMER: The k8s and podman deployments are not maintained by the core team.
These files are provided and maintained by the community. Twenty core team
maintains support for docker deployment.
## How to use
1. Edit `.env` file. At the minimum set `POSTGRES_PASSWORD`, `SERVER_URL`, and `APP_SECRET`.
2. Start twenty by running `podman-compose up -d`.
If you need to stop twenty, you can do so by running `podman-compose down`.
### Install systemd service (optional)
If you want to install a systemd service to run twenty, you can use the provided systemd service.
Edit `twentycrm.service` and change these two variables:
WorkingDirectory=/opt/apps/twenty
EnvironmentFile=/opt/apps/twenty/.env
`WorkingDirectory` should be changed to the path in which `podman-compose.yml` is located.
`EnvironmentFile` should be changed to the path in which your `.env`file is located.
You can run the script `install-systemd-user-service` to install the systemd service under the current user.
./install-systemd-user-service
Note: this script will enable the service and also start it. So it will assume that twenty is not currently running.
If you started it previously, bring it down using:
podman-compose down
## Compatibility
These files should be compatible with podman 4.3+.
I have tested this on Debian GNU/Linux 12 (bookworm) and with the podman that is distributed with the official Debian stable mirrors (podman v4.3.1+ds1-8+deb12u1, podman-compose v1.0.3-3).
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
set -e
mkdir -p ~/.config/systemd/user
[ -f twentycrm.service ] || { echo "Error: twentycrm.service not found"; exit 1; }
cp twentycrm.service ~/.config/systemd/user
systemctl --user daemon-reload
systemctl --user enable twentycrm.service
systemctl --user start twentycrm.service
@@ -0,0 +1,71 @@
#!/bin/bash
set -e
if [ ! -f "$(dirname "$0")/.env" ]; then
echo "Error: .env file not found"
exit 1
fi
source "$(dirname "$0")/.env"
## steps to cleanup and start over from scratch - useful when testing
#podman pod stop twenty-pod
#podman pod rm twenty-pod
#podman volume rm twenty-db-data twenty-server-data twenty-redis-data
# end of cleanup
podman volume create twenty-db-data
podman volume create twenty-server-data
podman volume create twenty-redis-data
podman pod create --name twenty-pod -p 127.0.0.1:8080:3000
podman run -d --pod twenty-pod --name twenty-db \
-e POSTGRES_DB=twenty \
-e POSTGRES_USER=twenty \
-e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \
-v twenty-db-data:/var/lib/postgresql/data:Z \
docker.io/library/postgres:16
podman run -d --pod twenty-pod --name twenty-redis \
-v twenty-redis-data:/data:Z \
docker.io/library/redis:latest
podman run -d --pod twenty-pod --name twenty-server \
-e NODE_PORT=3000 \
-e SERVER_URL="$SERVER_URL" \
-e PG_DATABASE_URL="postgresql://twenty:$POSTGRES_PASSWORD@twenty-db:5432/twenty" \
-e REDIS_URL="redis://twenty-redis:6379" \
-e APP_SECRET="$APP_SECRET" \
-e NODE_ENV=production \
-e LOG_LEVEL=info \
-v twenty-server-data:/app/docker-data:Z \
docker.io/twentycrm/twenty:latest
podman run -d --pod twenty-pod --name twenty-worker \
--init \
-e SERVER_URL="$SERVER_URL" \
-e PG_DATABASE_URL="postgresql://twenty:$POSTGRES_PASSWORD@twenty-db:5432/twenty" \
-e REDIS_URL="redis://twenty-redis:6379" \
-e APP_SECRET="$APP_SECRET" \
-e DISABLE_DB_MIGRATIONS=true \
-e NODE_ENV=production \
-e LOG_LEVEL=info \
-v twenty-server-data:/app/docker-data:Z \
docker.io/twentycrm/twenty:latest \
yarn worker:prod
# wait some time, check status
sleep 30
podman ps --pod -f name=twenty-pod
mkdir -p ~/.config/systemd/user
if [ ! -f "twentycrm.service" ]; then
echo "Error: twentycrm.service file not found"
exit 1
fi
cp twentycrm.service ~/.config/systemd/user
systemctl --user daemon-reload
systemctl --user enable twentycrm.service
systemctl --user start twentycrm.service
@@ -0,0 +1,55 @@
version: "3.8"
services:
db:
container_name: twenty-db
image: postgres:16
environment:
POSTGRES_DB: twenty
POSTGRES_USER: twenty
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- twenty-db-data:/var/lib/postgresql/data:Z
redis:
container_name: twenty-redis
image: redis:latest
volumes:
- twenty-redis-data:/data:Z
server:
container_name: twenty-server
image: twentycrm/twenty:latest
environment:
NODE_PORT: "3000"
SERVER_URL: ${SERVER_URL}
PG_DATABASE_URL: "postgresql://twenty:${POSTGRES_PASSWORD}@twenty-db:5432/twenty"
REDIS_URL: "redis://twenty-redis:6379"
APP_SECRET: ${APP_SECRET}
NODE_ENV: production
LOG_LEVEL: info
volumes:
- twenty-server-data:/app/docker-data:Z
ports:
- 127.0.0.1:8080:3000
worker:
container_name: twenty-worker
image: twentycrm/twenty:latest
command: yarn worker:prod
environment:
SERVER_URL: ${SERVER_URL}
PG_DATABASE_URL: "postgresql://twenty:${POSTGRES_PASSWORD}@twenty-db:5432/twenty"
REDIS_URL: "redis://twenty-redis:6379"
APP_SECRET: ${APP_SECRET}
DISABLE_DB_MIGRATIONS: "true"
NODE_ENV: production
LOG_LEVEL: info
volumes:
- twenty-server-data:/app/docker-data:Z
init: true
volumes:
twenty-db-data:
twenty-server-data:
twenty-redis-data:
@@ -0,0 +1,15 @@
[Unit]
Description=TwentyCRM Container Stack via Podman-Compose
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/apps/twenty
EnvironmentFile=/opt/apps/twenty/.env
ExecStart=/usr/bin/podman-compose -f podman-compose.yml up -d
ExecStop=/usr/bin/podman-compose -f podman-compose.yml down
RemainAfterExit=yes
[Install]
WantedBy=default.target
+8 -7
View File
@@ -44,10 +44,10 @@ function on_exit {
trap on_exit EXIT
# Use environment variables VERSION and BRANCH, with defaults if not set
version=${VERSION:-$(curl -s https://api.github.com/repos/twentyhq/twenty/tags | grep '"name":' | head -n 1 | cut -d '"' -f 4)}
branch=${BRANCH:-$version}
version=${VERSION:-$(curl -s "https://hub.docker.com/v2/repositories/twentycrm/twenty/tags" | grep -o '"name":"[^"]*"' | grep -v 'latest' | cut -d'"' -f4 | sort -V | tail -n1)}
branch=${BRANCH:-$(curl -s https://api.github.com/repos/twentyhq/twenty/tags | grep '"name":' | head -n 1 | cut -d '"' -f 4)}
echo "🚀 Using version $version and branch $branch"
echo "🚀 Using docker version $version and Github branch $branch"
dir_name="twenty"
function ask_directory {
@@ -90,10 +90,11 @@ else
fi
# Generate random strings for secrets
echo "# === Randomly generated secrets ===" >>.env
echo "APP_SECRET=$(openssl rand -base64 32)" >>.env
echo "" >>.env
echo "PGPASSWORD_SUPERUSER=$(openssl rand -hex 16)" >>.env
echo "# === Randomly generated secret ===" >> .env
echo "APP_SECRET=$(openssl rand -base64 32)" >> .env
echo "" >> .env
echo "PG_DATABASE_PASSWORD=$(openssl rand -hex 16)" >> .env
echo -e "\t• .env configuration completed"
@@ -8,10 +8,18 @@ COPY ./yarn.lock .
COPY ./.yarnrc.yml .
COPY ./.yarn/releases /app/.yarn/releases
COPY ./tools/eslint-rules /app/tools/eslint-rules
COPY ./packages/twenty-ui/package.json /app/packages/twenty-ui/
COPY ./packages/twenty-shared/package.json /app/packages/twenty-shared/
COPY ./packages/twenty-website/package.json /app/packages/twenty-website/package.json
RUN yarn
ENV KEYSTATIC_GITHUB_CLIENT_ID="<fake build value>"
ENV KEYSTATIC_GITHUB_CLIENT_SECRET="<fake build value>"
ENV KEYSTATIC_SECRET="<fake build value>"
ENV NEXT_PUBLIC_KEYSTATIC_GITHUB_APP_SLUG="<fake build value>"
COPY ./packages/twenty-ui /app/packages/twenty-ui
COPY ./packages/twenty-website /app/packages/twenty-website
RUN npx nx build twenty-website
@@ -26,4 +34,9 @@ WORKDIR /app/packages/twenty-website
LABEL org.opencontainers.image.source=https://github.com/twentyhq/twenty
LABEL org.opencontainers.image.description="This image provides a consistent and reproducible environment for the website."
RUN chown -R 1000 /app
# Use non root user with uid 1000
USER 1000
CMD ["/bin/sh", "-c", "npx nx start"]
+4 -2
View File
@@ -7,6 +7,7 @@ WORKDIR /app
COPY ./package.json ./yarn.lock ./.yarnrc.yml ./tsconfig.base.json ./nx.json /app/
COPY ./.yarn/releases /app/.yarn/releases
COPY ./.prettierrc /app/
COPY ./packages/twenty-emails/package.json /app/packages/twenty-emails/
COPY ./packages/twenty-server/package.json /app/packages/twenty-server/
COPY ./packages/twenty-server/patches /app/packages/twenty-server/patches
@@ -63,8 +64,9 @@ WORKDIR /app/packages/twenty-server
ARG REACT_APP_SERVER_BASE_URL
ENV REACT_APP_SERVER_BASE_URL $REACT_APP_SERVER_BASE_URL
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE $SENTRY_RELEASE
ARG APP_VERSION
ENV APP_VERSION $APP_VERSION
# Copy built applications from previous stages
COPY --chown=1000 --from=twenty-server-build /app /app
+4 -2
View File
@@ -10,12 +10,14 @@ if [ "${DISABLE_DB_MIGRATIONS}" != "true" ] && [ ! -f /app/docker-data/db_status
PGPASS=$(echo $PG_DATABASE_URL | awk -F ':' '{print $3}' | awk -F '@' '{print $1}')
PGHOST=$(echo $PG_DATABASE_URL | awk -F '@' '{print $2}' | awk -F ':' '{print $1}')
PGPORT=$(echo $PG_DATABASE_URL | awk -F ':' '{print $4}' | awk -F '/' '{print $1}')
PGPASSWORD=${PGPASS} psql -h ${PGHOST} -p ${PGPORT} -U ${PGUSER} -d postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'default'" | grep -q 1 || \
PGPASSWORD=${PGPASS} psql -h ${PGHOST} -p ${PGPORT} -U ${PGUSER} -d postgres -c "CREATE DATABASE \"default\""
PGDATABASE=$(echo $PG_DATABASE_URL | awk -F ':' '{print $4}' | awk -F '/' '{print $2}')
PGPASSWORD=${PGPASS} psql -h ${PGHOST} -p ${PGPORT} -U ${PGUSER} -d postgres -tc "SELECT 1 FROM pg_database WHERE datname = '${PGDATABASE}'" | grep -q 1 || \
PGPASSWORD=${PGPASS} psql -h ${PGHOST} -p ${PGPORT} -U ${PGUSER} -d postgres -c "CREATE DATABASE \"${PGDATABASE}\""
# Run setup and migration scripts
NODE_OPTIONS="--max-old-space-size=1500" tsx ./scripts/setup-db.ts
yarn database:migrate:prod
yarn command:prod upgrade
# Mark initialization as done
echo "Successfuly migrated DB!"
+2 -17
View File
@@ -1,21 +1,6 @@
# Note that provide always without trailing forward slash to have expected behaviour
FRONTEND_BASE_URL=http://localhost:3001
BACKEND_BASE_URL=http://localhost:3000
DEFAULT_LOGIN=tim@apple.dev
NEW_WORKSPACE_LOGIN=test@apple.dev
DEMO_DEFAULT_LOGIN=noah@demo.dev
DEFAULT_PASSWORD=Applecar2025
WEBSITE_URL=https://twenty.com
# === DO NOT USE, WORK IN PROGRESS ===
# This URL must have trailing forward slash as all REST API endpoints have object after it
# Documentation for REST API: https://twenty.com/developers/rest-api/core#/
# REST_API_BASE_URL=http://localhost:3000/rest/
# Documentation for GraphQL API: https://twenty.com/developers/graphql/core
# GRAPHQL_BASE_URL=http://localhost:3000/graphql
# Without this key, all API tests will fail, to generate this key
# Log in to Twenty workspace, go to Settings > Developers, generate new key and paste it here
# In order to use it, header Authorization: Bearer token must be used
# This key works for both REST and GraphQL API
# API_DEV_KEY=fill_with_proper_key
WEBSITE_URL=https://twenty.com
@@ -1,33 +0,0 @@
import {
Reporter,
FullConfig,
Suite,
TestCase,
TestResult,
FullResult,
} from '@playwright/test/reporter';
class CustomReporter implements Reporter {
constructor(options: { customOption?: string } = {}) {
console.log(
`my-awesome-reporter setup with customOption set to ${options.customOption}`,
);
}
onBegin(config: FullConfig, suite: Suite) {
console.log(`Starting the run with ${suite.allTests().length} tests`);
}
onTestBegin(test: TestCase) {
console.log(`Starting test ${test.title}`);
}
onTestEnd(test: TestCase, result: TestResult) {
console.log(`Finished test ${test.title}: ${result.status}`);
}
onEnd(result: FullResult) {
console.log(`Finished the run: ${result.status}`);
}
}
export default CustomReporter;
@@ -1,21 +0,0 @@
import * as fs from 'fs';
import path from 'path';
export const envVariables = (variables: string) => {
let payload = `
PG_DATABASE_URL=postgres://postgres:postgres@localhost:5432/default
ACCESS_TOKEN_SECRET=replace_me_with_a_random_string_access
LOGIN_TOKEN_SECRET=replace_me_with_a_random_string_login
REFRESH_TOKEN_SECRET=replace_me_with_a_random_string_refresh
FILE_TOKEN_SECRET=replace_me_with_a_random_string_refresh
REDIS_URL=redis://localhost:6379
`;
payload = payload.concat(variables);
fs.writeFile(
path.join(__dirname, '..', '..', 'twenty-server', '.env'),
payload,
(err) => {
throw err;
},
);
};
@@ -1,13 +0,0 @@
import { exec } from 'child_process';
export async function sh(cmd) {
return new Promise((resolve, reject) => {
exec(cmd, (err, stdout, stderr) => {
if (err) {
reject(err);
} else {
resolve({ stdout, stderr });
}
});
});
}
@@ -0,0 +1,278 @@
import { test as base, expect, Locator, Page } from '@playwright/test';
import { randomUUID } from 'node:crypto';
import { createWorkflow } from '../requests/create-workflow';
import { deleteWorkflow } from '../requests/delete-workflow';
import { destroyWorkflow } from '../requests/destroy-workflow';
import { WorkflowActionType, WorkflowTriggerType } from '../types/workflows';
export class WorkflowVisualizerPage {
#page: Page;
workflowId: string;
workflowName: string;
readonly addStepButton: Locator;
readonly workflowStatus: Locator;
readonly activateWorkflowButton: Locator;
readonly deactivateWorkflowButton: Locator;
readonly addTriggerButton: Locator;
readonly commandMenu: Locator;
readonly stepHeaderInCommandMenu: Locator;
readonly workflowNameLabel: Locator;
readonly triggerNode: Locator;
readonly background: Locator;
readonly useAsDraftButton: Locator;
readonly overrideDraftButton: Locator;
readonly discardDraftButton: Locator;
#actionNames: Record<WorkflowActionType, string> = {
'create-record': 'Create Record',
'update-record': 'Update Record',
'delete-record': 'Delete Record',
code: 'Code',
'send-email': 'Send Email',
};
#createdActionNames: Record<WorkflowActionType, string> = {
'create-record': 'Create Record',
'update-record': 'Update Record',
'delete-record': 'Delete Record',
code: 'Code - Serverless Function',
'send-email': 'Send Email',
};
#triggerNames: Record<WorkflowTriggerType, string> = {
'record-created': 'Record is Created',
'record-updated': 'Record is Updated',
'record-deleted': 'Record is Deleted',
manual: 'Launch manually',
};
#createdTriggerNames: Record<WorkflowTriggerType, string> = {
'record-created': 'Record is Created',
'record-updated': 'Record is Updated',
'record-deleted': 'Record is Deleted',
manual: 'Launch manually',
};
constructor({ page, workflowName }: { page: Page; workflowName: string }) {
this.#page = page;
this.workflowName = workflowName;
this.addStepButton = page.getByLabel('Add a step');
this.workflowStatus = page.getByTestId('workflow-visualizer-status');
this.activateWorkflowButton = page.getByLabel('Activate Workflow', {
exact: true,
});
this.deactivateWorkflowButton = page.getByLabel('Deactivate Workflow', {
exact: true,
});
this.addTriggerButton = page.getByText('Add a Trigger');
this.commandMenu = page.getByTestId('command-menu');
this.stepHeaderInCommandMenu = this.commandMenu.getByTestId(
'workflow-step-header',
);
this.workflowNameLabel = page
.getByTestId('top-bar-title')
.getByText(this.workflowName);
this.triggerNode = this.#page.getByTestId('rf__node-trigger');
this.background = page.locator('.react-flow__pane');
this.useAsDraftButton = page.getByRole('button', { name: 'Use as draft' });
this.overrideDraftButton = page.getByRole('button', {
name: 'Override Draft',
});
this.discardDraftButton = page.getByRole('button', {
name: 'Discard Draft',
});
}
async createOneWorkflow() {
const id = randomUUID();
const response = await createWorkflow({
page: this.#page,
workflowId: id,
workflowName: this.workflowName,
});
expect(response.status()).toBe(200);
const responseBody = await response.json();
expect(responseBody.data.createWorkflow.id).toBe(id);
this.workflowId = id;
}
async waitForWorkflowVisualizerLoad() {
await expect(this.workflowNameLabel).toBeVisible();
}
async goToWorkflowVisualizerPage() {
await this.#page.goto(`/`);
const workflowsLink = this.#page.getByRole('link', { name: 'Workflows' });
await workflowsLink.click();
const workflowLink = this.#page
.getByTestId(`row-id-${this.workflowId}`)
.getByRole('link', { name: this.workflowName });
await workflowLink.click({ force: true });
await this.waitForWorkflowVisualizerLoad();
}
async createInitialTrigger(trigger: WorkflowTriggerType) {
await this.addTriggerButton.click();
const triggerName = this.#triggerNames[trigger];
const createdTriggerName = this.#createdTriggerNames[trigger];
const triggerOption = this.#page.getByText(triggerName);
await triggerOption.click();
await expect(this.triggerNode).toHaveClass(/selected/);
await expect(this.triggerNode).toContainText(createdTriggerName);
}
async createStep(action: WorkflowActionType) {
await this.addStepButton.click();
const actionName = this.#actionNames[action];
const createdActionName = this.#createdActionNames[action];
const actionToCreateOption = this.commandMenu.getByText(actionName);
await actionToCreateOption.click();
const createWorkflowStepResponse = await this.#page.waitForResponse(
(response) => {
if (!response.url().endsWith('/graphql')) {
return false;
}
const requestBody = response.request().postDataJSON();
return requestBody.operationName === 'CreateWorkflowVersionStep';
},
);
const createWorkflowStepResponseBody =
await createWorkflowStepResponse.json();
const createdStepId =
createWorkflowStepResponseBody.data.createWorkflowVersionStep.id;
const createdActionNode = this.#page
.locator('.react-flow__node.selected')
.getByText(createdActionName);
await expect(createdActionNode).toBeVisible();
const selectedNodes = this.#page.locator('.react-flow__node.selected');
await expect(selectedNodes).toHaveCount(1);
return {
createdStepId,
};
}
getStepNode(stepId: string) {
return this.#page.getByTestId(`rf__node-${stepId}`);
}
getDeleteNodeButton(nodeLocator: Locator) {
return nodeLocator.getByRole('button');
}
getAllStepNodes() {
return this.#page
.getByTestId(/^rf__node-.+$/)
.and(this.#page.getByTestId(/^((?!rf__node-trigger).)*$/))
.and(
this.#page.getByTestId(/^((?!rf__node-branch-\d+__create-step).)*$/),
);
}
async deleteStep(stepId: string) {
const stepNode = this.getStepNode(stepId);
await stepNode.click();
await Promise.all([
expect(stepNode).not.toBeVisible(),
this.#page.waitForResponse((response) => {
if (!response.url().endsWith('/graphql')) {
return false;
}
const requestBody = response.request().postDataJSON();
return (
requestBody.operationName === 'DeleteWorkflowVersionStep' &&
requestBody.variables.input.stepId === stepId
);
}),
this.getDeleteNodeButton(stepNode).click(),
]);
}
async deleteTrigger() {
await this.triggerNode.click();
await Promise.all([
expect(this.triggerNode).toContainText('Add a Trigger'),
this.#page.waitForResponse((response) => {
if (!response.url().endsWith('/graphql')) {
return false;
}
const requestBody = response.request().postDataJSON();
return (
requestBody.operationName === 'UpdateOneWorkflowVersion' &&
requestBody.variables.input.trigger === null
);
}),
this.getDeleteNodeButton(this.triggerNode).click(),
]);
}
async closeSidePanel() {
const closeButton = this.#page.getByRole('button', {
name: 'Close command menu',
});
await closeButton.click();
await expect(this.#page.getByTestId('command-menu')).not.toBeVisible();
}
}
export const test = base.extend<{ workflowVisualizer: WorkflowVisualizerPage }>(
{
workflowVisualizer: async ({ page }, use) => {
const workflowVisualizer = new WorkflowVisualizerPage({
page,
workflowName: 'Test Workflow',
});
await workflowVisualizer.createOneWorkflow();
await workflowVisualizer.goToWorkflowVisualizerPage();
await use(workflowVisualizer);
await deleteWorkflow({
page,
workflowId: workflowVisualizer.workflowId,
});
await destroyWorkflow({
page,
workflowId: workflowVisualizer.workflowId,
});
},
},
);
@@ -25,7 +25,7 @@ export const test = base.extend<{ screenshotHook: void }>({
),
});
},
{ auto: true }, // automatic fixture runs with every test
{ auto: true },
],
});
@@ -44,7 +44,7 @@ export class InsertFieldData {
'//label[contains(., "POST CODE")]/../div[last()]/input',
);
this.countrySelect = page.locator(
'//span[contains(., "COUNTRY")]/../div[last()]/input',
'//span[contains(., "COUNTRY")]/../div[last()]/div',
);
this.arrayValueInput = page.locator("//input[@placeholder='Enter value']");
this.arrayAddValueButton = page.locator(
@@ -1,5 +1,55 @@
import { Locator, Page } from '@playwright/test';
export class StripePage {
// TODO: implement all necessary methods (staging/sandbox page - does it differ anyhow from normal page?)
private readonly cardNumberInput: Locator;
private readonly cardExpiryInput: Locator;
private readonly cardCvcInput: Locator;
private readonly cardholderNameInput: Locator;
private readonly startTrialButton: Locator;
private readonly cancelSubscriptionButton: Locator;
private readonly confirmButton: Locator;
private readonly returnToTwentyLink: Locator;
constructor(public readonly page: Page) {
this.cardNumberInput = page.getByPlaceholder('1234 1234 1234 1234');
this.cardExpiryInput = page.getByPlaceholder('MM / YY');
this.cardCvcInput = page.getByPlaceholder('CVC');
this.cardholderNameInput = page.getByPlaceholder('Full name on card');
this.startTrialButton = page.getByTestId('hosted-payment-submit-button');
this.cancelSubscriptionButton = page.locator(
'a[data-test="cancel-subscription"]',
);
this.confirmButton = page.getByTestId('confirm');
this.returnToTwentyLink = page.getByTestId('return-to-business-link');
}
async fillCardNumber(number: string) {
await this.cardNumberInput.fill(number);
}
async fillCardExpiry(expiry: string) {
await this.cardExpiryInput.fill(expiry);
}
async fillCardCvc(cvc: string) {
await this.cardCvcInput.fill(cvc);
}
async fillCardholderName(name: string) {
await this.cardholderNameInput.fill(name);
}
async startTrial() {
await this.startTrialButton.click();
}
async clickCancelSubscription() {
await this.cancelSubscriptionButton.click();
await this.confirmButton.click();
await this.page.getByTestId('cancellation_reason_cancel').click();
}
async returnToTwenty() {
await this.returnToTwentyLink.click();
}
}
@@ -1,4 +1,4 @@
import { Locator, Page } from '@playwright/test';
import { expect, Locator, Page } from '@playwright/test';
export class LoginPage {
private readonly loginWithGoogleButton: Locator;
@@ -35,7 +35,7 @@ export class LoginPage {
name: 'Continue with Google',
});
this.loginWithEmailButton = page.getByRole('button', {
name: 'Continue With Email',
name: 'Continue with Email',
});
this.termsOfServiceLink = page.getByRole('link', {
name: 'Terms of Service',
@@ -98,6 +98,8 @@ export class LoginPage {
}
async typeEmail(email: string) {
await expect(this.emailField).toBeVisible();
await this.emailField.fill(email);
}
@@ -23,7 +23,6 @@ export class MainPage {
private readonly hiddenFieldsButton: Locator;
private readonly editFieldsButton: Locator;
private readonly importButton: Locator;
private readonly exportButton: Locator;
private readonly deletedRecordsButton: Locator;
private readonly createNewRecordButton: Locator;
private readonly addToFavoritesButton: Locator;
@@ -67,16 +66,12 @@ export class MainPage {
this.importButton = page
.getByTestId('tooltip')
.filter({ hasText: /^Import$/ });
this.exportButton = page
.getByTestId('tooltip')
.filter({ hasText: /^Export$/ });
this.deletedRecordsButton = page
.getByTestId('tooltip')
.filter({ hasText: /^Deleted */ });
this.createNewRecordButton = page.getByTestId('add-button');
this.addToFavoritesButton = page.getByText('Add to favorites');
this.deleteFromFavoritesButton = page.getByText('Delete from favorites');
this.exportBottomBarButton = page.getByText('Export');
this.deleteRecordsButton = page.getByText('Delete');
}
@@ -166,10 +161,6 @@ export class MainPage {
await this.importButton.click();
}
async clickExportButton() {
await this.exportButton.click();
}
async clickDeletedRecordsButton() {
await this.deletedRecordsButton.click();
}
@@ -6,6 +6,7 @@ export class AccountsSection {
private readonly addBlocklistField: Locator;
private readonly addBlocklistButton: Locator;
private readonly connectWithGoogleButton: Locator;
private readonly connectWithMicrosoftButton: Locator;
constructor(public readonly page: Page) {
this.page = page;
@@ -22,6 +23,9 @@ export class AccountsSection {
this.connectWithGoogleButton = page.getByRole('button', {
name: 'Connect with Google',
});
this.connectWithMicrosoftButton = page.getByRole('button', {
name: 'Connect with Microsoft',
});
}
async clickAddAccount() {
@@ -51,4 +55,8 @@ export class AccountsSection {
async linkGoogleAccount() {
await this.connectWithGoogleButton.click();
}
async linkMicrosoftAccount() {
await this.connectWithMicrosoftButton.click();
}
}
@@ -0,0 +1,64 @@
import { Locator, Page } from '@playwright/test';
export class APIsSection {
private readonly createAPIKeyButton: Locator;
private readonly regenerateAPIKeyButton: Locator;
private readonly nameOfAPIKeyInput: Locator;
private readonly expirationDateAPIKeySelect: Locator;
private readonly cancelButton: Locator;
private readonly saveButton: Locator;
private readonly deleteButton: Locator;
constructor(public readonly page: Page) {
this.page = page;
this.createAPIKeyButton = page.getByRole('link', {
name: 'Create API Key',
});
this.nameOfAPIKeyInput = page
.getByPlaceholder('E.g. backoffice integration')
.first();
this.expirationDateAPIKeySelect = page.locator(
'div[aria-controls="object-field-type-select-options"]',
);
this.regenerateAPIKeyButton = page.getByRole('button', {
name: 'Regenerate Key',
});
this.cancelButton = page.getByRole('button', { name: 'Cancel' });
this.saveButton = page.getByRole('button', { name: 'Save' });
this.deleteButton = page.getByRole('button', { name: 'Delete' });
}
async createAPIKey() {
await this.createAPIKeyButton.click();
}
async typeAPIKeyName(name: string) {
await this.nameOfAPIKeyInput.clear();
await this.nameOfAPIKeyInput.fill(name);
}
async selectAPIExpirationDate(date: string) {
await this.expirationDateAPIKeySelect.click();
await this.page.getByText(date, { exact: true }).click();
}
async regenerateAPIKey() {
await this.regenerateAPIKeyButton.click();
}
async deleteAPIKey() {
await this.deleteButton.click();
}
async clickCancelButton() {
await this.cancelButton.click();
}
async clickSaveButton() {
await this.saveButton.click();
}
async checkAPIKeyDetails(name: string) {
await this.page.locator(`//a/div[contains(.,'${name}')][first()]`).click();
}
}
@@ -1,123 +0,0 @@
import { Locator, Page } from '@playwright/test';
export class DevelopersSection {
private readonly readDocumentationButton: Locator;
private readonly createAPIKeyButton: Locator;
private readonly regenerateAPIKeyButton: Locator;
private readonly nameOfAPIKeyInput: Locator;
private readonly expirationDateAPIKeySelect: Locator;
private readonly createWebhookButton: Locator;
private readonly webhookURLInput: Locator;
private readonly webhookDescription: Locator;
private readonly webhookFilterObjectSelect: Locator;
private readonly webhookFilterActionSelect: Locator;
private readonly cancelButton: Locator;
private readonly saveButton: Locator;
private readonly deleteButton: Locator;
constructor(public readonly page: Page) {
this.page = page;
this.readDocumentationButton = page.getByRole('link', {
name: 'Read documentation',
});
this.createAPIKeyButton = page.getByRole('link', {
name: 'Create API Key',
});
this.createWebhookButton = page.getByRole('link', {
name: 'Create Webhook',
});
this.nameOfAPIKeyInput = page
.getByPlaceholder('E.g. backoffice integration')
.first();
this.expirationDateAPIKeySelect = page
.locator('div')
.filter({ hasText: /^Never$/ })
.nth(3); // good enough if expiration date will change only 1 time
this.regenerateAPIKeyButton = page.getByRole('button', {
name: 'Regenerate Key',
});
this.webhookURLInput = page.getByPlaceholder('URL');
this.webhookDescription = page.getByPlaceholder('Write a description');
this.webhookFilterObjectSelect = page
.locator('div')
.filter({ hasText: /^All Objects$/ })
.nth(3); // works only for first filter
this.webhookFilterActionSelect = page
.locator('div')
.filter({ hasText: /^All Actions$/ })
.nth(3); // works only for first filter
this.cancelButton = page.getByRole('button', { name: 'Cancel' });
this.saveButton = page.getByRole('button', { name: 'Save' });
this.deleteButton = page.getByRole('button', { name: 'Delete' });
}
async openDocumentation() {
await this.readDocumentationButton.click();
}
async createAPIKey() {
await this.createAPIKeyButton.click();
}
async typeAPIKeyName(name: string) {
await this.nameOfAPIKeyInput.clear();
await this.nameOfAPIKeyInput.fill(name);
}
async selectAPIExpirationDate(date: string) {
await this.expirationDateAPIKeySelect.click();
await this.page.getByText(date, { exact: true }).click();
}
async regenerateAPIKey() {
await this.regenerateAPIKeyButton.click();
}
async deleteAPIKey() {
await this.deleteButton.click();
}
async deleteWebhook() {
await this.deleteButton.click();
}
async createWebhook() {
await this.createWebhookButton.click();
}
async typeWebhookURL(url: string) {
await this.webhookURLInput.fill(url);
}
async typeWebhookDescription(description: string) {
await this.webhookDescription.fill(description);
}
async selectWebhookObject(object: string) {
// TODO: finish
}
async selectWebhookAction(action: string) {
// TODO: finish
}
async deleteWebhookFilter() {
// TODO: finish
}
async clickCancelButton() {
await this.cancelButton.click();
}
async clickSaveButton() {
await this.saveButton.click();
}
async checkAPIKeyDetails(name: string) {
await this.page.locator(`//a/div[contains(.,'${name}')][first()]`).click();
}
async checkWebhookDetails(name: string) {
await this.page.locator(`//a/div[contains(.,'${name}')][first()]`).click();
}
}
@@ -7,11 +7,12 @@ export class ExperienceSection {
private readonly dateFormatDropdown: Locator;
private readonly timeFormatDropdown: Locator;
private readonly searchInput: Locator;
private readonly languageDropdown: Locator;
constructor(public readonly page: Page) {
this.page = page;
this.lightThemeButton = page.getByText('AaLight'); // it works
this.darkThemeButton = page.getByText('AaDark');
this.lightThemeButton = page.locator('div[variant="Light"]').first();
this.darkThemeButton = page.locator('div[variant="Dark"]').first();
this.timezoneDropdown = page.locator(
'//span[contains(., "Time zone")]/../div/div/div',
);
@@ -22,6 +23,9 @@ export class ExperienceSection {
'//span[contains(., "Time format")]/../div/div/div',
);
this.searchInput = page.getByPlaceholder('Search');
this.languageDropdown = page.locator(
'//h2[contains(., "Language")]/../../../div/div/div',
);
}
async changeThemeToLight() {
@@ -52,4 +56,9 @@ export class ExperienceSection {
await this.timeFormatDropdown.click();
await this.page.getByText(timeFormat, { exact: true }).click();
}
async selectLanguage(language: string) {
await this.languageDropdown.click();
await this.page.getByText(language, { exact: true }).click();
}
}
@@ -1,159 +0,0 @@
import { Locator, Page } from '@playwright/test';
export class FunctionsSection {
private readonly newFunctionButton: Locator;
private readonly functionNameInput: Locator;
private readonly functionDescriptionInput: Locator;
private readonly editorTab: Locator;
private readonly codeEditorField: Locator;
private readonly resetButton: Locator;
private readonly publishButton: Locator;
private readonly testButton: Locator;
private readonly testTab: Locator;
private readonly runFunctionButton: Locator;
private readonly inputField: Locator;
private readonly settingsTab: Locator;
private readonly searchVariableInput: Locator;
private readonly addVariableButton: Locator;
private readonly nameVariableInput: Locator;
private readonly valueVariableInput: Locator;
private readonly cancelVariableButton: Locator;
private readonly saveVariableButton: Locator;
private readonly editVariableButton: Locator;
private readonly deleteVariableButton: Locator;
private readonly cancelButton: Locator;
private readonly saveButton: Locator;
private readonly deleteButton: Locator;
constructor(public readonly page: Page) {
this.newFunctionButton = page.getByRole('button', { name: 'New Function' });
this.functionNameInput = page.getByPlaceholder('Name');
this.functionDescriptionInput = page.getByPlaceholder('Description');
this.editorTab = page.getByTestId('tab-editor');
this.codeEditorField = page.getByTestId('dummyInput'); // TODO: fix
this.resetButton = page.getByRole('button', { name: 'Reset' });
this.publishButton = page.getByRole('button', { name: 'Publish' });
this.testButton = page.getByRole('button', { name: 'Test' });
this.testTab = page.getByTestId('tab-test');
this.runFunctionButton = page.getByRole('button', { name: 'Run Function' });
this.inputField = page.getByTestId('dummyInput'); // TODO: fix
this.settingsTab = page.getByTestId('tab-settings');
this.searchVariableInput = page.getByPlaceholder('Search a variable');
this.addVariableButton = page.getByRole('button', { name: 'Add Variable' });
this.nameVariableInput = page.getByPlaceholder('Name').nth(1);
this.valueVariableInput = page.getByPlaceholder('Value');
this.cancelVariableButton = page.locator('.css-uwqduk').first(); // TODO: fix
this.saveVariableButton = page.locator('.css-uwqduk').nth(1); // TODO: fix
this.editVariableButton = page.getByText('Edit', { exact: true });
this.deleteVariableButton = page.getByText('Delete', { exact: true });
this.cancelButton = page.getByRole('button', { name: 'Cancel' });
this.saveButton = page.getByRole('button', { name: 'Save' });
this.deleteButton = page.getByRole('button', { name: 'Delete function' });
}
async clickNewFunction() {
await this.newFunctionButton.click();
}
async typeFunctionName(name: string) {
await this.functionNameInput.fill(name);
}
async typeFunctionDescription(description: string) {
await this.functionDescriptionInput.fill(description);
}
async checkFunctionDetails(name: string) {
await this.page.getByRole('link', { name: `${name} nodejs18.x` }).click();
}
async clickEditorTab() {
await this.editorTab.click();
}
async clickResetButton() {
await this.resetButton.click();
}
async clickPublishButton() {
await this.publishButton.click();
}
async clickTestButton() {
await this.testButton.click();
}
async typeFunctionCode() {
// TODO: finish once utils are merged
}
async clickTestTab() {
await this.testTab.click();
}
async runFunction() {
await this.runFunctionButton.click();
}
async typeFunctionInput() {
// TODO: finish once utils are merged
}
async clickSettingsTab() {
await this.settingsTab.click();
}
async searchVariable(name: string) {
await this.searchVariableInput.fill(name);
}
async addVariable() {
await this.addVariableButton.click();
}
async typeVariableName(name: string) {
await this.nameVariableInput.fill(name);
}
async typeVariableValue(value: string) {
await this.valueVariableInput.fill(value);
}
async editVariable(name: string) {
await this.page
.locator(
`//div[@data-testid='tooltip' and contains(., '${name}')]/../../div[last()]/div/div/button`,
)
.click();
await this.editVariableButton.click();
}
async deleteVariable(name: string) {
await this.page
.locator(
`//div[@data-testid='tooltip' and contains(., '${name}')]/../../div[last()]/div/div/button`,
)
.click();
await this.deleteVariableButton.click();
}
async cancelVariable() {
await this.cancelVariableButton.click();
}
async saveVariable() {
await this.saveVariableButton.click();
}
async clickCancelButton() {
await this.cancelButton.click();
}
async clickSaveButton() {
await this.saveButton.click();
}
async clickDeleteButton() {
await this.deleteButton.click();
}
}
@@ -4,6 +4,8 @@ export class GeneralSection {
private readonly workspaceNameField: Locator;
private readonly supportSwitch: Locator;
private readonly deleteWorkspaceButton: Locator;
private readonly customizeDomainButton: Locator;
private readonly subdomainInput: Locator;
constructor(public readonly page: Page) {
this.page = page;
@@ -12,6 +14,12 @@ export class GeneralSection {
this.deleteWorkspaceButton = page.getByRole('button', {
name: 'Delete workspace',
});
this.customizeDomainButton = page.getByRole('button', {
name: 'Customize domain',
});
this.subdomainInput = page.locator(
'//div[contains(.,".twenty-main.com")]/../input',
);
}
async changeWorkspaceName(workspaceName: string) {
@@ -26,4 +34,10 @@ export class GeneralSection {
async clickDeleteWorkSpaceButton() {
await this.deleteWorkspaceButton.click();
}
async changeSubdomain(subdomain: string) {
await this.customizeDomainButton.click();
await this.subdomainInput.fill(subdomain);
await this.page.getByRole('button', { name: 'Save' }).click();
}
}
@@ -29,6 +29,7 @@ export class NewFieldSection {
private readonly relationFieldLink: Locator;
private readonly relationTypeSelect: Locator;
private readonly objectDestinationSelect: Locator;
private readonly relationIconSelect: Locator;
private readonly relationFieldNameInput: Locator;
private readonly fullNameFieldLink: Locator;
private readonly UUIDFieldLink: Locator;
@@ -225,6 +226,11 @@ export class NewFieldSection {
await this.page.getByTestId('tooltip').filter({ hasText: name }).click();
}
async selectRelationIcon(name: string) {
await this.relationIconSelect.click();
await this.page.getByTitle(name).click();
}
async typeRelationName(name: string) {
await this.relationFieldNameInput.clear();
await this.relationFieldNameInput.fill(name);

Some files were not shown because too many files have changed in this diff Show More