Commit Graph

228 Commits

Author SHA1 Message Date
9f579c84c1 Fix blocknote slash menu issue (#12578)
Fix #12562
2025-06-12 21:15:51 +02:00
322c8a1852 Upgrade to Node22 (#12488)
BlocknoteJS requires an ESM module where our server is CJS, this forced
us to pin the server-util version, which led us to force the resolution
of several packages, leading to bugs downstream.

From Node 22.12 Node supports requiring ESM modules (available from Node
22.0 with a flag). So I upgrade the module.
I picked Node 22 and not Node 23 or Node 24 because 22 is the LTS and we
don't plan to change node versions frequently.

If you remain on Node 18, things should still mostly work, except if you
edit a Rich Text field.

I also starting changing the default runtime for Serverless Functions
which isn't directly related. This means new serverless functions will
be created on Node 22, but we will still need another PR to migrate
existing serverless functions before September (end of support by AWS).

(In this PR I also remove the upgrade commands from 0.43 since they rely
on Blocknote and I didn't want to have to deal with this)

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-06-06 18:35:30 +02:00
b481abbb0f Begin refactoring AI module (#12464)
Cleaning up to prepare for a few tests
2025-06-05 12:28:42 +02:00
97d4ec96af Fix view filter update and deletion propagation (#12082)
# Introduction

Diff description: ~500 tests and +500 additions

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

## What has been done here
In a nutshell on a field metadata type ( `SELECT MULTI_SELECT` ) update,
we will be browsing all `ViewFilters` in a post hook searching for some
referencing related updated `fieldMetadata` select. In order to update
or delete the `viewFilter` depending on the associated mutations.

## How to test:
- Add FieldMetadata `SELECT | MULTI_SELECT` to an existing or a new
`objectMetadata`
- Create a filtered view on created `fieldMetadata` with any options you
would like
- Remove some options ( in the best of the world some that are selected
by the filter ) from the `fieldMetadata` settings page
- Go back to the filtered view, removed or updated options should have
been hydrated in the `displayValue` and the filtered data should make
sense

## All filtered options are deleted edge case
If an update implies that a viewFilter does not have any existing
related options anymore, then we remove the viewFilter

## Testing
```sh 
PASS  test/integration/metadata/suites/field-metadata/update-one-field-metadata-related-record.integration-spec.ts (27 s)
  update-one-field-metadata-related-record
    SELECT
      ✓ should delete related view filter if all select field options got deleted (2799 ms)
      ✓ should update related multi selected options view filter (1244 ms)
      ✓ should update related solo selected option view filter (1235 ms)
      ✓ should handle partial deletion of selected options in view filter (1210 ms)
      ✓ should handle reordering of options while maintaining view filter values (1487 ms)
      ✓ should handle no changes update of options while maintaining existing view filter values (1174 ms)
      ✓ should handle adding new options while maintaining existing view filter (1174 ms)
      ✓ should update display value with options label if less than 3 options are selected (1249 ms)
      ✓ should throw error if view filter value is not a stringified JSON array (1300 ms)
    MULTI_SELECT
      ✓ should delete related view filter if all select field options got deleted (1127 ms)
      ✓ should update related multi selected options view filter (1215 ms)
      ✓ should update related solo selected option view filter (1404 ms)
      ✓ should handle partial deletion of selected options in view filter (1936 ms)
      ✓ should handle reordering of options while maintaining view filter values (1261 ms)
      ✓ should handle no changes update of options while maintaining existing view filter values (1831 ms)
      ✓ should handle adding new options while maintaining existing view filter (1610 ms)
      ✓ should update display value with options label if less than 3 options are selected (1889 ms)
      ✓ should throw error if view filter value is not a stringified JSON array (1365 ms)

Test Suites: 1 passed, 1 total
Tests:       18 passed, 18 total
Snapshots:   18 passed, 18 total
Time:        27.039 s
```
## Out of scope
- We should handle ViewFilter validation when extracting its definition
from the metadata
https://github.com/twentyhq/core-team-issues/issues/1009

## Concerns
- Are we able through the api to update an RATING fieldMetadata ? ( if
yes than that's an issue and we should handle RATING the same way than
for SELECT and MULTI_SELECT )
- It's not possible to group a view from a MULTI_SELECT field

The above points create a double nor a triple "lecture" to the post hook
effect:
- ViewGroup -> only SELECT
- VIewFilter -> only SELECT || MULTI_SELECT
- Rating nothing
I think we should determine the scope of all of that

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-28 10:22:28 +00:00
524a1d78d2 Refactor drag selection: Replace external library with custom implementation and add auto-scroll (#12134)
Closes #12076
Closes #11764

Replaced the `@air/react-drag-to-select` library with a custom
implementation to get better control over the selection behavior and add
auto-scroll functionality.

**What changed:**
- Removed external drag selection dependency 
- Built custom drag selection from scratch using pointer events --
@charlesBochet
- Added auto-scroll when dragging near container edges
- Fixed boundary detection so selection stays within intended areas
- Added proper `data-select-disable` support for checkboxes and other
non-selectable elements

The new implementation gives us full control over the selection logic
and eliminates the external dependency while adding the auto-scroll
feature that was **not** requested 😂

**Auto Scroll**



https://github.com/user-attachments/assets/3509966d-5b6e-4f6c-a77a-f9a2bf26049f



related to #12076 


https://github.com/user-attachments/assets/2837f80e-728c-4739-a0e2-b8d7bc83a21a

**Also fixed:**
- Record board column height not extending to the bottom (styling issue
I found while working on this)

before:

<img width="1512" alt="Screenshot 2025-05-19 at 23 58 54"
src="https://github.com/user-attachments/assets/602b310f-7ef6-44f6-99e9-da5ff59b31d3"
/>

after:

<img width="1512" alt="Screenshot 2025-05-19 at 23 56 40"
src="https://github.com/user-attachments/assets/1d0ecb5c-49e0-4f03-be3b-154a6f16a7a4"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-26 11:58:22 +02:00
371fdba1f8 Changed the auto matching of columns in import (#12181)
This PR changes the way we do automatching in the import feature.

It uses [Fuse.js](https://www.fusejs.io/) to do a fuzzy text search on
fields and sub-fields.

The labels of sub-fields are now derived from the common config constant
we have for sub-fields.
2025-05-23 18:33:18 +02:00
79b4b3f783 Improve lazy loading (#12186)
WIP, using preview app to test performance (which was very bad)
2025-05-22 15:07:01 +02:00
0553f58c52 Removed use-context-selector completely (#12139)
This PR removes use-context-selector completely, so that any bug
associated with state synchronization between recoil and
use-context-selector disappears.

There might be a slight performance decrease on the table, but since we
have already improved the average performance per line by a lot, and
that the performance bottleneck right now is the fetch more logic and
the windowing solution we use, it is not relevant.

Also the DX has become so hindered by this parallel state logic recently
(think [cache
invalidation](https://martinfowler.com/bliki/TwoHardThings.html)), that
the main benefit we gain from this removal is the DX improvement.

Fixes https://github.com/twentyhq/twenty/issues/12123
Fixes https://github.com/twentyhq/twenty/issues/12109
2025-05-20 13:35:28 +02:00
849a35955a 866 refactor cron trigger only one cron each minutes triggers all cron triggers (#11809)
<img width="1123" alt="image"
src="https://github.com/user-attachments/assets/75447922-81dd-4cfc-805d-f511f73cc778"
/>
2025-04-30 17:08:47 +02:00
a15b87649a Twenty config core implementation (#11595)
closes https://github.com/twentyhq/core-team-issues/issues/760

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-26 09:21:59 +02:00
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
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
587281a541 feat(analytics): add clickhouse (#11174) 2025-04-16 16:33:10 +00: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
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
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
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
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
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
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
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
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
da394ffcdc [FIX] Move preconstruct patch into twenty-shared package (#11124) 2025-03-24 15:51:14 +01:00
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
15a2cb5141 Update playwright (#10927)
Update twenty-e2e-testing to reflect actual state of app
2025-03-19 11:29:36 +01:00
eb73838e5d Fix yarn lock (#10985) 2025-03-18 14:57:06 +01:00
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
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
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
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
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
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
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
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
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
1b98f40f17 feat(custom-domain): enable UI for custom domain (#10062) 2025-02-10 08:43:13 +00:00
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
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
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
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
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
7a0f2f8c0a Add logged out translations (#9983)
Add translation for logged in / sub pages
2025-02-03 22:00:54 +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
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
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
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
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
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](c21ba636d2/packages/features/auth/lib/next-auth-options.ts (L188-L190))
when missing OTP and 2FA is enabled, with a [specific error
code](c21ba636d2/packages/features/auth/lib/ErrorCode.ts (L9))
- [catching the
401](c21ba636d2/apps/web/modules/auth/login-view.tsx (L160))
in the frontend and
[displaying](c21ba636d2/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
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
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