Commit Graph
100 Commits
Author SHA1 Message Date
Jérémy M 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
Jérémy M b71246bc5d feat: put back group by feature flag (#9428)
Rollback and put back view group feature flag to push to prod.
2025-01-07 13:52:42 +01:00
Jérémy M 25083e5405 fix: Group by not visible for table (#9365)
Group by option was not visible on table, this is fixing the issue.
2025-01-06 10:51:26 +00:00
Jérémy MandLucas Bordeau 0f1458cbe9 fix: view group followup (#9162)
This PR fixes all followup that @Bonapara add on Discord.

- [x] When no group by is set, clicking on group by should open the
"field selection" menu
- [x] When closed, chevron should be "chevron-right" instead of
"chevron-up"
- [x] Sort : Add ability to switch from alphabetical to manual when
moving a option in sort alphabetical
- [x] Add subtext for group by and sort
- [x] Group by menu display bug
- [x] Changing the sort should not close the menu
- [x] Group by Activation -> shows empty state + is slow
- [x] Switching from Kanban view Settings to Table Options menu displays
an empty menu
- [x] Unnecessary spacing under groups
- [x] When no "select" are set on an object, redirect the user directly
to the new Select field page
- [x] Sort : Default should be manual
- [x] Hidding "no value" displays all options and remove the "hide empty
group" toggle
- [x] Hide Empty group option disappeared
- [x] Group by should not be persisted on "Locked/Main view" (**For now
we just disable the group by on main view**)
- [x] Hide Empty group should not be activated by default on
Opportunities Kanban view
- [ ] Animate the group opening/closing (**We'll be done later**)

Performance improvement:

https://github.com/user-attachments/assets/fd2acf66-0e56-45d0-8b2f-99c62e57d6f7

https://github.com/user-attachments/assets/80f1a2e1-9f77-4923-b85d-acb9cad96886

Also fix #9036

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-01-02 16:40:28 +01:00
Jérémy M 01fc70da0f fix: 3 first columns should be sticky view group (#9123)
Fix #9113 

<img width="591" alt="Screenshot 2024-12-18 at 3 33 05 PM"
src="https://github.com/user-attachments/assets/df55eff3-7b0d-4cf0-881b-167e1bf2f97b"
/>

<img width="543" alt="Screenshot 2024-12-18 at 3 34 37 PM"
src="https://github.com/user-attachments/assets/76fe06e1-0a46-4130-921d-1d480306bda2"
/>
2024-12-18 16:35:08 +01:00
Jérémy M ae044c2fc8 fix: view group wrong cursor (#9119)
Wrong cursor was shown on `Load more` and `Add new` row in view group
mode
2024-12-18 12:54:09 +01:00
Jérémy MandMarie 3b48920314 feat: NoValue is bot properly created the backend (#9110)
`No Value` view groups wasn't properly created when we select a group by
field metadata, this PR fix the issue.
Also a script is added to backfill the current view groups.

---------

Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
2024-12-18 12:26:38 +01:00
Jérémy M 1f4d1358a1 fix: add create cursor util (#9086)
Followup of #9053
2024-12-17 12:05:55 +01:00
Jérémy M 1851bb8476 feat: hide empty record group default true (#9090)
Fix #8969 

Previously we were putting hide default record group to `false` in
record group mode.
Also the mode was saved in the current view by changing the visibility
boolean of each record group.
As we want to hide by default, this PR instead is using a different
logic so it's totally based on the front-end side.
2024-12-17 11:54:41 +01:00
Jérémy M 9e9c1bdff1 feat: record group insert at bottom when created (#9053)
Fix #9050 

When we add a new record in a record group this one should be added at
them bottom.
2024-12-16 14:57:16 +01:00
Jérémy MandCharles Bochet 07aaf0801c fix: can't properly drag and drop in empty record group (#9039)
Fix #8968 

Fix issue with drag and drop when record group are empty.
Happy to discuss the implementation, as it's limited to the
`@hello-pangea/dnd` api.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-12-13 09:37:23 +01:00
Jérémy M 5f2a39d9e9 fix: group by sort options should have a checkmark when selected (#9038)
Fix #8966 

This PR is adding a checkmark beside the selected sort option in the
`Options` dropdown menu.

<img width="225" alt="Screenshot 2024-12-12 at 12 03 18 PM"
src="https://github.com/user-attachments/assets/81783bc0-5aea-4f0d-9327-c70f3e70edb6"
/>
2024-12-12 11:18:53 +00:00
Jérémy M d7da73f0ec feat: record group add new (#8925)
Fix #8757

This PR is adding the Add new button on view groups.
Also this PR fix an issue where the pending record can be draggable, and
is causing error.

<img width="1119" alt="Screenshot 2024-12-10 at 4 24 43 PM"
src="https://github.com/user-attachments/assets/4fd01e99-c85e-4a06-a733-cbf3cc32957d">

It also start to issues with the way we're using Context.
We're initializing pretty much all Context like this:

```typescript
export const RecordTableContext = createContext<RecordTableContextProps>(
   {} as RecordTableContextProps,
 );
```

This is causing issues when by mistake we use the context like this
outside the Provider hierarchy:

```typescript
const context = useContext(RecordTableContext);
```

This is going to fail silently, and all the context variables become
undefined...

To fix this I've introduced an util called `createRequiredContext`, this
one is returning an array containing the provider and the hook to
retrieve the context.
The context is initialized to undefined inside this utility, this way we
can check if the value has been initialized with the provider to check
if we're inside it. It'll throw an error if this one is used outside the
provider.
The return values are properly typed, so `undefined` is not added to the
value of the Context.

I'll create a followup ticket to use this new utility function, if
that's ok and replace it everywhere in the codebase.
We can also consider adding a eslint rule to warn about the use of
`createContext` directly.
2024-12-12 11:50:13 +01:00
Jérémy MandCharles Bochet 7ab00a4c82 feat: record group fetch more (#8868)
Fix #8756 

This PR is adding a load more button when we're grouping by a field in
table view.
Only 8 records are printed at first, and a click on `Load more` is
needed to show more records.

<img width="1347" alt="Screenshot 2024-12-04 at 11 54 15 AM"
src="https://github.com/user-attachments/assets/4ad6ad4f-8de9-424d-b7b6-5f82f28c53df">
<img width="1352" alt="Screenshot 2024-12-04 at 11 54 23 AM"
src="https://github.com/user-attachments/assets/2a94b4ac-7285-4ba2-9cff-d2f653e36302">

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-12-05 10:51:56 +01:00
Jérémy M 2fa5fb7de7 fix: record group issues (#8854)
This PR is fixing the following issues with record groups:

- [x] [Backend] - Only update view groups when a field is edited if this
one already has view groups
- [x] [Backend] - Editing a Select field metadata option brake view
groups
- [x] [Frontend] - Changing the group by field from one to another brake
record group and doesn't remove the previous ones
- [x] [Frontend & Backend] - Mark `kanbanFieldMetadataId` as deprecated
in favour of `viewGroups.fieldMetadataId`

Also the following has been checked:

- [x] Properly displayed a table with only one view groups
- [x] Properly displayed a table without view groups
2024-12-04 16:03:25 +01:00
Jérémy M a2d55a8694 feat: table record group (#8781)
Fix #8401 #8402

This PR is only taking care or displaying properly the record group on
the table.
Record-reorder within group has also been prepared.
Start of collapsible animation has been done, but not working for now.

<img width="1381" alt="Screenshot 2024-11-28 at 2 52 07 PM"
src="https://github.com/user-attachments/assets/514bb3e6-3475-4c47-a91c-64f7d20bbe73">
2024-11-29 13:04:27 +01:00
Jérémy M 812ed6ed69 feat: record board component state refactor (#8779)
Fix #8758 

This PR is migrating the recoil component state from v1 to v2 for board.
It also now share some states and logics between board and table,
further can be done later.
Lastly this PR fix an issue since the PR #8613 that was treating
no-value as a normal record-group.
2024-11-28 13:44:21 +01:00
Jérémy MandCharles Bochet 2968085e73 Feat: revamp group by settings (#8503)
This PR fix #8202 that is revamping the `Options` settings for board and
table.

<img width="221" alt="Screenshot 2024-11-15 at 11 47 52 AM"
src="https://github.com/user-attachments/assets/0b143c95-810d-408b-b19e-c2678cd5653a">
<img width="214" alt="Screenshot 2024-11-15 at 11 47 59 AM"
src="https://github.com/user-attachments/assets/3468734a-8174-4e36-a8ee-08dad6c56227">
<img width="210" alt="Screenshot 2024-11-15 at 11 48 10 AM"
src="https://github.com/user-attachments/assets/300628f5-6645-4f1c-af8a-befce2714716">
<img width="212" alt="Screenshot 2024-11-15 at 11 48 37 AM"
src="https://github.com/user-attachments/assets/37a3db40-2146-45eb-bea4-44e1041f5bcf">
<img width="214" alt="Screenshot 2024-11-15 at 11 48 44 AM"
src="https://github.com/user-attachments/assets/42d2adcc-8f03-4f28-928b-d3c3d54d388a">
<img width="213" alt="Screenshot 2024-11-15 at 11 48 51 AM"
src="https://github.com/user-attachments/assets/90824568-b979-46a7-9841-ab8b9978e138">
<img width="211" alt="Screenshot 2024-11-15 at 11 49 00 AM"
src="https://github.com/user-attachments/assets/fa22446a-b1db-4d97-9a45-0778bf09ae3c">

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-11-20 17:03:18 +01:00
Jérémy M fb0221b4c1 feat: default record group table (#8397)
This PR is preparing states to we'll be able to handle view groups
correctly with table data.
RowIds are now stores in 2 component states, one storing ids by view
group and another storing all the rowIds.
We're doing that because some other state like focus, or select must not
be scoped by view group id.
2024-11-18 15:36:40 +01:00
Jérémy M ffd790c8fd fix: don't use previous view group state when creating a new view (#8370)
When creating a new view we don't want to use view-groups from previous
view.
2024-11-06 16:33:51 +01:00
Jérémy MandCharles Bochet ac7d740135 fix: when field metadata SELECT type is edited update view groups (#8344)
Co-authored-by: Charles Bochet <charles@twenty.com>
2024-11-06 11:41:44 +01:00
Jérémy M 258fd07839 feat: use new component state api for record table (#8143)
This PR drop the use of the old component state api in favour of the new
component state api V2.
2024-11-04 12:07:07 +01:00
Jérémy M 3fbd312141 fix: no more dashed line (#8254)
Fix bug introduced by #8152 where `<Tag />` component doesn't have
dashed lines anymore.
<img width="114" alt="Screenshot 2024-10-31 at 3 10 10 PM"
src="https://github.com/user-attachments/assets/25c9cb91-7be2-407b-9f07-a3811fb2d082">
<img width="134" alt="Screenshot 2024-10-31 at 3 10 03 PM"
src="https://github.com/user-attachments/assets/c44a551f-0e02-4fd4-b779-2076df513b03">
2024-10-31 15:32:51 +01:00
Jérémy MandLucas Bordeau e8d96cfd10 feat: view groups (#7176)
Fix #4244 and #4356

This pull request introduces the new "view groups" capability, enabling
the reordering, hiding, and showing of columns in Kanban mode. The core
enhancement includes the addition of a new entity named `ViewGroup`,
which manages column behaviors and interactions.

#### Key Changes:
1. **ViewGroup Entity**:  
The newly added `ViewGroup` entity is responsible for handling the
organization and state of columns.
This includes:
   - The ability to reorder columns.
- The option to hide or show specific columns based on user preferences.

#### Conclusion:
This PR adds a significant new feature that enhances the flexibility of
Kanban views through the `ViewGroup` entity.
We'll later add the view group logic to table view too.

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2024-10-24 15:38:52 +02:00
Jérémy MandCharles Bochet eef7f1661d feat: add integration tests (#6923)
### Summary

This PR introduces several integration tests, a mix of manually written
tests and those generated using the `generate-integration-tests` Python
script located in the `scripts` folder.

### Tests Added:
- **Authentication tests**: Validating login, registration, and token
handling.
- **FindMany queries**: Fetching multiple records for all existing
entities that do not require input arguments.

### How the Integration Tests Work:
- A `setupTest` function is called during the Jest test run. This
function initializes a test instance of the application and exposes it
on a dedicated port.
- Since tests are executed in isolated workers, they do not have direct
access to the in-memory app instance. Instead, the tests query the
application through the exposed port.
- A static accessToken is used, this one as a big expiration time so it
will never expire (365 years)
- The queries are executed, and the results are validated against
expected outcomes.

### Current State and Next Steps:
- These tests currently run using the existing development seed data. We
plan to introduce more comprehensive test data using `faker` to improve
coverage.
- At the moment, the only mutation tests implemented are for
authentication. Future updates should include broader mutation testing
for other entities.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-09-20 11:02:52 +02:00
db54469c8a feat: soft delete (#6576)
Implement soft delete on standards and custom objects.
This is a temporary solution, when we drop `pg_graphql` we should rely
on the `softDelete` functions of TypeORM.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2024-08-16 21:20:02 +02:00
Jérémy M 11a41b3d97 feat: created by email calendar (#6536)
This PR is a followup of #6324 to add support of EMAIL and CALENDAR
source for the created by composite field.
2024-08-07 15:03:06 +02:00
6432ad39b9 feat: add new ACTOR field type and createdBy standard fields (#6324)
This pull request introduces a new `FieldMetadataType` called `ACTOR`.
The primary objective of this new type is to add an extra column to the
following objects: `person`, `company`, `opportunity`, `note`, `task`,
and all custom objects.

This composite type contains three properties:

- `source`
    ```typescript
    export enum FieldActorSource {
      EMAIL = 'EMAIL',
      CALENDAR = 'CALENDAR',
      API = 'API',
      IMPORT = 'IMPORT',
      MANUAL = 'MANUAL',
    }
    ```
- `workspaceMemberId`
- This property can be `undefined` in some cases and refers to the
member who created the record.
- `name`
- Serves as a fallback if the `workspaceMember` is deleted and is used
for other source types like `API`.

### Functionality

The pre-hook system has been updated to allow real-time argument
updates. When a record is created, a pre-hook can now compute and update
the arguments accordingly. This enhancement enables the `createdBy`
field to be populated with the correct values based on the
`authContext`.

The `authContext` now includes:
- An optional User entity
- An optional ApiKey entity
- The workspace entity

This provides access to the necessary data for the `createdBy` field.

In the GraphQL API, only the `source` can be specified in the
`createdBy` input. This allows the front-end to specify the source when
creating records from a CSV file.

### Front-End Handling

On the front-end, `orderBy` and `filter` are only applied to the name
property of the `ACTOR` composite type. Currently, we are unable to
apply these operations to the workspace member relation. This means that
if a workspace member changes their first name or last name, there may
be a mismatch because the name will differ from the new one. The name
displayed on the screen is based on the workspace member entity when
available.

### Missing Components

Currently, this PR does not include a `createdBy` value for the `MAIL`
and `CALENDAR` sources. These records are created in a job, and at
present, we only have access to the workspaceId within the job. To
address this, we should use a function similar to
`loadServiceWithContext`, which was recently removed from `TwentyORM`.
This function would allow us to pass the `authContext` to the jobs
without disrupting existing jobs.
Another PR will be created to handle these cases.

### Related Issues

Fixes issue #5155.

### Additional Notes

This PR doesn't include the migrations of the current records and views.
Everything works properly when the database is reset but this part is
still missing for now. We'll add that in another PR.

- There is a minor issue: front-end tests are broken since this commit:
[https://github.com/twentyhq/twenty/commit/80c0fc7ff108d61c0e8d89fd334da64bd224f7aa](https://github.com/twentyhq/twenty/commit/80c0fc7ff108d61c0e8d89fd334da64bd224f7aa).

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2024-08-03 15:43:31 +02:00
Jérémy MandCharles Bochet d0201e17ac Fix: query runner orm (#6397)
Fix WorkspaceQueryRunner events using TwentyORM

Fix #6057

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-07-25 13:21:57 +02:00
Jérémy MandCharles Bochet de20c564c7 feat: add eslint rule for enforcing WorkspaceService naming convention (#6308)
### Description

This PR introduces a custom ESLint rule named
`inject-workspace-repository`. The purpose of this rule is to enforce
naming conventions for files and classes that use the
`@InjectWorkspaceRepository` decorator or include services ending with
`WorkspaceService` in their constructors.

### Rule Overview

The new ESLint rule checks for the following conditions:

1. **File Naming**:
- Only file ending with `.service.ts` or `.workspace-service.ts` are
checked.
- If a file contains a class using the `@InjectWorkspaceRepository`
decorator or a service ending with `WorkspaceService` in the
constructor, the file name must end with `.workspace-service.ts`.

2. **Class Naming**:
- Classes that use the `@InjectWorkspaceRepository` decorator or include
services ending with `WorkspaceService` in their constructors must have
names that end with `WorkspaceService`.

### How It Works

The rule inspects each TypeScript file to ensure that the naming
conventions are adhered to. It specifically looks for:

- Constructor parameters with the `@InjectWorkspaceRepository`
decorator.
- Constructor parameters with a type annotation ending with
`WorkspaceService`.

When such parameters are found, it checks the class name and the file
name to ensure they conform to the expected patterns.

### Example Code

#### Valid Cases

1. **Correct File and Class Name with Decorator**:
    ```typescript
    // Filename: my.workspace-service.ts
    class MyWorkspaceService {
      constructor(@InjectWorkspaceRepository() private repository) {}
    }
    ```

2. **Service Dependency**:
    ```typescript
    // Filename: another.workspace-service.ts
    class AnotherWorkspaceService {
      constructor(private myWorkspaceService: MyWorkspaceService) {}
    }
    ```

#### Invalid Cases

1. **Incorrect Class Name**:
    ```typescript
    // Filename: my.workspace-service.ts
    class MyService {
      constructor(@InjectWorkspaceRepository() private repository) {}
    }
    // Error: Class name should end with 'WorkspaceService'.
    ```

2. **Incorrect File Name**:
    ```typescript
    // Filename: my.service.ts
    class MyWorkspaceService {
      constructor(@InjectWorkspaceRepository() private repository) {}
    }
    // Error: File name should end with '.workspace-service.ts'.
    ```

3. **Incorrect File and Class Name**:
    ```typescript
    // Filename: my.service.ts
    class MyService {
      constructor(@InjectWorkspaceRepository() private repository) {}
    }
    // Error: Class name should end with 'WorkspaceService'.
    // Error: File name should end with '.workspace-service.ts'.
    ```

4. **Incorrect File Type**:
    ```typescript
    // Filename: another.service.ts
    class AnotherService {
      constructor(private myWorkspaceService: MyWorkspaceService) {}
    }
    // Error: Class name should end with 'WorkspaceService'.
    // Error: File name should end with '.workspace-service.ts'.

    ```

5. **Incorrect Class Name with Dependency**:
    ```typescript
    // Filename: another.workspace-service.ts
    class AnotherService {
      constructor(private myWorkspaceService: MyWorkspaceService) {}
    }
    // Error: Class name should end with 'WorkspaceService'.
    ```

### First step

This rule is only a warning for now, and then we'll migrate all the code
that need to be migrated and move from `warn` to `error`.

Fix #6309

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-07-19 19:17:57 +02:00
088d061b3e feat: twenty orm for standard and custom objects (#6178)
### Overview

This PR builds upon #5153, adding the ability to get a repository for
custom objects. The `entitySchema` is now generated for both standard
and custom objects based on metadata stored in the database instead of
the decorated `WorkspaceEntity` in the code. This change ensures that
standard objects with custom fields and relations can also support
custom objects.

### Implementation Details

#### Key Changes:

- **Dynamic Schema Generation:** The `entitySchema` for standard and
custom objects is now dynamically generated from the metadata stored in
the database. This shift allows for greater flexibility and
adaptability, particularly for standard objects with custom fields and
relations.
  
- **Custom Object Repository Retrieval:** A repository for a custom
object can be retrieved using `TwentyORMManager` based on the object's
name. Here's an example of how this can be achieved:

  ```typescript
const repository = await this.twentyORMManager.getRepository('custom');
  /*
* `repository` variable will be typed as follows, ensuring that standard
fields and relations are properly typed:
   * const repository: WorkspaceRepository<CustomWorkspaceEntity & {
   *    [key: string]: any;
   * }>
   */
  const res = await repository.find({});
  ```

Fix #6179

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Weiko <corentin@twenty.com>
2024-07-19 18:23:52 +02:00
Jérémy M cfb36ec0fb feat: bump yarn to last stable version (#6081)
This PR bump yarn version to latest stable version
2024-07-19 15:38:03 +02:00
Jérémy M 5df0ea6466 fix: message queue injection issue (#6126) 2024-07-04 12:22:58 +02:00
Jérémy M 921b311c65 fix: small PR fixes workspace-sync-fields (#6107)
Small fixes of PR #6069
2024-07-03 19:19:37 +02:00
Jérémy MandMarie 5b26452649 feat: refactor workspace sync fields (#6069)
This PR was first here to fix the issue related to ticket #5004, after
some testing it seems that changing the name of a relation is actually
properly working, if we rename `ONE-TO-MANY` side, the only things that
is going to be updated is the FieldMetadata as the `joinColumn` is
stored on the opposite object.
For `MANY-TO-ONE` relations, the `joinColumn` migration is properly
generated. We need to take care that if we rename a side of a relation,
sometimes the opposite side doesn't have `inverseSideFieldKey`
implemented and used by default the name of the opposite object, so this
is going to throw an error as the field can't be found in the object.

---------

Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
2024-07-02 17:21:13 +02:00
Jérémy M 632e34fc7b fix: message cleaner find operator (#6080)
This PR fix an issue with the `IsNull()` find operator applied on
one-to-many relation, this one is not supported by TypeORM.
We can instead filter by an empty array to retrieve object with empty
relations.
2024-07-01 11:23:22 +02:00
Jérémy M 13f213a05e feat: message cleaner drop repository (#6052)
This PR use the new `TwentyORM` for the message-cleaner module by using
the new injection system with `@InjectWorkspaceRepository`.
2024-06-30 21:57:18 +02:00
Jérémy M 95c5602a4e feat: manually implement joinColumn (#6022)
This PR introduce a new decorator named `@WorkspaceJoinColumn`, the goal
of this one is to manually declare the join columns inside the workspace
entities, so we don't have to rely on `ObjectRecord` type.

This decorator can be used that way:

```typescript
  @WorkspaceRelation({
    standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.company,
    type: RelationMetadataType.MANY_TO_ONE,
    label: 'Company',
    description: 'ActivityTarget company',
    icon: 'IconBuildingSkyscraper',
    inverseSideTarget: () => CompanyWorkspaceEntity,
    inverseSideFieldKey: 'activityTargets',
  })
  @WorkspaceIsNullable()
  company: Relation<CompanyWorkspaceEntity> | null;

  // The argument is the name of the relation above
  @WorkspaceJoinColumn('company')
  companyId: string | null;
```
2024-06-27 11:41:22 +02:00
Jérémy MandWeiko 7c2e745b45 feat: Dynamic hook registration for WorkspaceQueryHooks (#6008)
#### Overview

This PR introduces a new API for dynamically registering and executing
pre and post query hooks in the Workspace Query Hook system using the
`@WorkspaceQueryHook` decorator. This approach eliminates the need for
manual provider registration, and fix the issue of `undefined` or `null`
repository using `@InjectWorkspaceRepository`.

#### New API

**Define a Hook**

Use the `@WorkspaceQueryHook` decorator to define pre or post hooks:

```typescript
@WorkspaceQueryHook({
  key: `calendarEvent.findMany`,
  scope: Scope.REQUEST,
})
export class CalendarEventFindManyPreQueryHook implements WorkspaceQueryHookInstance {
  async execute(userId: string, workspaceId: string, payload: FindManyResolverArgs): Promise<void> {
    if (!payload?.filter?.id?.eq) {
      throw new BadRequestException('id filter is required');
    }

    // Implement hook logic here
  }
}
```

This API simplifies the registration and execution of query hooks,
providing a more flexible and maintainable approach.

---------

Co-authored-by: Weiko <corentin@twenty.com>
2024-06-25 12:41:46 +02:00
0b4bfce324 feat: drop calendar repository (#5824)
This PR is replacing and removing all the raw queries and repositories
with the new `TwentyORM` and injection system using
`@InjectWorkspaceRepository`.
Some logic that was contained inside repositories has been moved to the
services.
In this PR we're only replacing repositories for calendar feature.

---------

Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2024-06-22 09:26:58 +02:00
Jérémy MandWeiko d99b9d1d6b feat: Enhancements to MessageQueue Module with Decorators (#5657)
### Overview

This PR introduces significant enhancements to the MessageQueue module
by integrating `@Processor`, `@Process`, and `@InjectMessageQueue`
decorators. These changes streamline the process of defining and
managing queue processors and job handlers, and also allow for
request-scoped handlers, improving compatibility with services that rely
on scoped providers like TwentyORM repositories.

### Key Features

1. **Decorator-based Job Handling**: Use `@Processor` and `@Process`
decorators to define job handlers declaratively.
2. **Request Scope Support**: Job handlers can be scoped per request,
enhancing integration with request-scoped services.

### Usage

#### Defining Processors and Job Handlers

The `@Processor` decorator is used to define a class that processes jobs
for a specific queue. The `@Process` decorator is applied to methods
within this class to define specific job handlers.

##### Example 1: Specific Job Handlers

```typescript
import { Processor, Process, InjectMessageQueue } from 'src/engine/integrations/message-queue';

@Processor('taskQueue')
export class TaskProcessor {

  @Process('taskA')
  async handleTaskA(job: { id: string, data: any }) {
    console.log(`Handling task A with data:`, job.data);
    // Logic for task A
  }

  @Process('taskB')
  async handleTaskB(job: { id: string, data: any }) {
    console.log(`Handling task B with data:`, job.data);
    // Logic for task B
  }
}
```

In the example above, `TaskProcessor` is responsible for processing jobs
in the `taskQueue`. The `handleTaskA` method will only be called for
jobs with the name `taskA`, while `handleTaskB` will be called for
`taskB` jobs.

##### Example 2: General Job Handler

```typescript
import { Processor, Process, InjectMessageQueue } from 'src/engine/integrations/message-queue';

@Processor('generalQueue')
export class GeneralProcessor {

  @Process()
  async handleAnyJob(job: { id: string, name: string, data: any }) {
    console.log(`Handling job ${job.name} with data:`, job.data);
    // Logic for any job
  }
}
```

In this example, `GeneralProcessor` handles all jobs in the
`generalQueue`, regardless of the job name. The `handleAnyJob` method
will be invoked for every job added to the `generalQueue`.

#### Adding Jobs to a Queue

You can use the `@InjectMessageQueue` decorator to inject a queue into a
service and add jobs to it.

##### Example:

```typescript
import { Injectable } from '@nestjs/common';
import { InjectMessageQueue, MessageQueue } from 'src/engine/integrations/message-queue';

@Injectable()
export class TaskService {
  constructor(
    @InjectMessageQueue('taskQueue') private readonly taskQueue: MessageQueue,
  ) {}

  async addTaskA(data: any) {
    await this.taskQueue.add('taskA', data);
  }

  async addTaskB(data: any) {
    await this.taskQueue.add('taskB', data);
  }
}
```

In this example, `TaskService` adds jobs to the `taskQueue`. The
`addTaskA` and `addTaskB` methods add jobs named `taskA` and `taskB`,
respectively, to the queue.

#### Using Scoped Job Handlers

To utilize request-scoped job handlers, specify the scope in the
`@Processor` decorator. This is particularly useful for services that
use scoped repositories like those in TwentyORM.

##### Example:

```typescript
import { Processor, Process, InjectMessageQueue, Scope } from 'src/engine/integrations/message-queue';

@Processor({ name: 'scopedQueue', scope: Scope.REQUEST })
export class ScopedTaskProcessor {

  @Process('scopedTask')
  async handleScopedTask(job: { id: string, data: any }) {
    console.log(`Handling scoped task with data:`, job.data);
    // Logic for scoped task, which might use request-scoped services
  }
}
```

Here, the `ScopedTaskProcessor` is associated with `scopedQueue` and
operates with request scope. This setup is essential when the job
handler relies on services that need to be instantiated per request,
such as scoped repositories.

### Migration Notes

- **Decorators**: Refactor job handlers to use `@Processor` and
`@Process` decorators.
- **Request Scope**: Utilize the scope option in `@Processor` if your
job handlers depend on request-scoped services.

Fix #5628

---------

Co-authored-by: Weiko <corentin@twenty.com>
2024-06-17 09:49:37 +02:00
Jérémy MandQuentin Galliano 04edf2bf7b feat: add resolve absolute path util (#5836)
Add a new util called `resolveAbsolutePath` to allow providing absolute
path for environment variable like `STORAGE_LOCAL_PATH`.
If the path in the env start with `/` we'll not prefix it with
`process.cwd()`.

Also we're using a static path for the old `db_initialized` file now
named `db_status` and stop using the env variable for this file as this
one shouldn't ne stored in the `STORAGE_LOCAL_PATH`.

Fix #4794

---------

Co-authored-by: Quentin Galliano <qgalliano@gmail.com>
2024-06-12 21:17:31 +02:00
Jérémy M 453525ca25 fix: workspace health showing error for multi select (#5547)
Fix `workspace:health` command not working properly with `MULTI_SELECT`
field metadata type.
2024-05-23 12:02:40 +02:00
Jérémy M bb6df43d17 fix: twentyORM datasource configuration for ssl (#5529)
We need to specify ssl configuration for TwentyORM datasources when
needed, otherwise connection will be broken.
2024-05-22 11:11:05 +02:00
Jérémy M 66a23a852f fix: unwanted change moving back datetime to date (#5499)
Moving back datetime to date, due to an unwanted change.
2024-05-21 13:29:59 +02:00
Jérémy M 8b5f79ddbf fix: multiple twenty orm issues & show an example of use (#5439)
This PR is fixing some issues and adding enhancement in TwentyORM:

- [x] Composite fields in nested relations are not formatted properly
- [x] Passing operators like `Any` in `where` condition is breaking the
query
- [x] Ability to auto load workspace-entities based on a regex path

I've also introduced an example of use for `CalendarEventService`:


https://github.com/twentyhq/twenty/pull/5439/files#diff-3a7dffc0dea57345d10e70c648e911f98fe237248bcea124dafa9c8deb1db748R15
2024-05-20 11:01:47 +02:00
Jérémy MandWeiko f0383e3147 feat: twenty orm sync (#5266)
This PR is updating all object metadata entities with the new
decorators, and deleting the old ones.
This way we can use the new TwentyORM with all the standard objects.

---------

Co-authored-by: Weiko <corentin@twenty.com>
2024-05-15 16:58:47 +02:00
Jérémy M b207d10312 feat: extend twenty orm (#5238)
This PR is a follow up of PR #5153.
This one introduce some changes on how we're querying composite fields.
We can do:

```typescript
export class CompanyService {
  constructor(
    @InjectWorkspaceRepository(CompanyObjectMetadata)
    private readonly companyObjectMetadataRepository: WorkspaceRepository<CompanyObjectMetadata>,
  ) {}

  async companies(): Promise<CompanyObjectMetadata[]> {
    // Old way
    // const companiesFilteredByLinkLabel = await this.companyObjectMetadataRepository.find({
    //   where: { xLinkLabel: 'MyLabel' },
    // });
    // Result will return xLinkLabel property

    // New way
    const companiesFilteredByLinkLabel = await this.companyObjectMetadataRepository.find({
      where: { xLink: { label:  'MyLabel' } },
    });
    // Result will return { xLink: { label: 'MyLabel' } } property instead of  { xLinkLabel: 'MyLabel' }

    return companiesFilteredByLinkLabel;
  }
}
```

Also we can now inject `TwentyORMManage` class to manually create a
repository based on a given `workspaceId` using
`getRepositoryForWorkspace` function that way:

```typescript
export class CompanyService {
  constructor(
    // TwentyORMModule should be initialized
    private readonly twentyORMManager,
  ) {}

  async companies(): Promise<CompanyObjectMetadata[]> {
    const repository = await this.twentyORMManager.getRepositoryForWorkspace(
      '8bb6e872-a71f-4341-82b5-6b56fa81cd77',
      CompanyObjectMetadata,
    );

    const companies = await repository.find();

    return companies;
  }
}
```
2024-05-06 14:12:11 +02:00
Jérémy MandWeiko e2185448ed Feat/twenty orm (#5153)
## Introduction

This PR introduces "TwentyORM," a custom ORM module designed to
streamline database interactions within our workspace schema, reducing
the need for raw SQL queries. The API mirrors TypeORM's to provide a
familiar interface while integrating enhancements specific to our
project's needs.

To facilitate this integration, new decorators prefixed with `Workspace`
have been implemented. These decorators are used to define entity
metadata more explicitly and are critical in constructing our schema
dynamically.

## New Features

- **Custom ORM System**: Named "TwentyORM," which aligns closely with
TypeORM for ease of use but is tailored to our application's specific
requirements.
- **Decorator-Driven Configuration**: Entities are now configured with
`Workspace`-prefixed decorators that clearly define schema mappings and
relationships directly within the entity classes.
- **Injectable Repositories**: Repositories can be injected similarly to
TypeORM, allowing for flexible and straightforward data management.

## Example Implementations

### Decorated Entity Definitions

Entities are defined with new decorators that outline table and field
metadata, relationships, and constraints. Here are examples of these
implementations:

#### Company Metadata Object

```typescript
@WorkspaceObject({
  standardId: STANDARD_OBJECT_IDS.company,
  namePlural: 'companies',
  labelSingular: 'Company',
  labelPlural: 'Companies',
  description: 'A company',
  icon: 'IconBuildingSkyscraper',
})
export class CompanyObjectMetadata extends BaseObjectMetadata {
  @WorkspaceField({
    standardId: COMPANY_STANDARD_FIELD_IDS.name,
    type: FieldMetadataType.TEXT,
    label: 'Name',
    description: 'The company name',
    icon: 'IconBuildingSkyscraper',
  })
  name: string;

  @WorkspaceField({
    standardId: COMPANY_STANDARD_FIELD_IDS.xLink,
    type: FieldMetadataType.LINK,
    label: 'X',
    description: 'The company Twitter/X account',
    icon: 'IconBrandX',
  })
  @WorkspaceIsNullable()
  xLink: LinkMetadata;

  @WorkspaceField({
    standardId: COMPANY_STANDARD_FIELD_IDS.position,
    type: FieldMetadataType.POSITION,
    label: 'Position',
    description: 'Company record position',
    icon: 'IconHierarchy2',
  })
  @WorkspaceIsSystem()
  @WorkspaceIsNullable()
  position: number;

  @WorkspaceRelation({
    standardId: COMPANY_STANDARD_FIELD_IDS.accountOwner,
    label: 'Account Owner',
    description: 'Your team member responsible for managing the company account',
    type: RelationMetadataType.MANY_TO_ONE,
    inverseSideTarget: () => WorkspaceMemberObjectMetadata,
    inverseSideFieldKey: 'accountOwnerForCompanies',
    onDelete: RelationOnDeleteAction.SET_NULL,
  })
  @WorkspaceIsNullable()
  accountOwner: WorkspaceMemberObjectMetadata;
}
```

#### Workspace Member Metadata Object

```typescript
@WorkspaceObject({
  standardId: STANDARD_OBJECT_IDS.workspaceMember,
  namePlural: 'workspaceMembers',
  labelSingular: 'Workspace Member',
  labelPlural: 'Workspace Members',
  description: 'A workspace member',
  icon: 'IconUserCircle',
})
@WorkspaceIsSystem()
@WorkspaceIsNotAuditLogged()
export class WorkspaceMemberObjectMetadata extends BaseObjectMetadata {
  @WorkspaceField({
    standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.name,
    type: FieldMetadataType.FULL_NAME,
    label: 'Name',
    description: 'Workspace member name',
    icon: 'IconCircleUser',
  })
  name: FullNameMetadata;

  @WorkspaceRelation({
    standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.accountOwnerForCompanies,
    label: 'Account Owner For Companies',
    description: 'Account owner for companies',
    icon: 'IconBriefcase',
    type: RelationMetadataType.ONE_TO_MANY,
    inverseSideTarget: () => CompanyObjectMetadata,
    inverseSideFieldKey: 'accountOwner',
    onDelete: RelationOnDeleteAction.SET_NULL,
  })
  accountOwnerForCompanies: Relation

<CompanyObjectMetadata[]>;
}
```

### Injectable Repository Usage

Repositories can be directly injected into services, allowing for
streamlined query operations:

```typescript
export class CompanyService {
  constructor(
    @InjectWorkspaceRepository(CompanyObjectMetadata)
    private readonly companyObjectMetadataRepository: WorkspaceRepository<CompanyObjectMetadata>,
  ) {}

  async companies(): Promise<CompanyObjectMetadata[]> {
    // Example queries demonstrating simple and relation-loaded operations
    const simpleCompanies = await this.companyObjectMetadataRepository.find({});
    const companiesWithOwners = await this.companyObjectMetadataRepository.find({
      relations: ['accountOwner'],
    });
    const companiesFilteredByLinkLabel = await this.companyObjectMetadataRepository.find({
      where: { xLinkLabel: 'MyLabel' },
    });

    return companiesFilteredByLinkLabel;
  }
}
```

## Conclusions

This PR sets the foundation for a decorator-driven ORM layer that
simplifies data interactions and supports complex entity relationships
while maintaining clean and manageable code architecture. This is not
finished yet, and should be extended.
All the standard objects needs to be migrated and all the module using
the old decorators too.

---------

Co-authored-by: Weiko <corentin@twenty.com>
2024-04-29 16:47:42 +02:00
Jérémy M 35717fce8b feat: sync command missing ability to rename standard object (#4819)
We've introduced in PR #4373 standard ids to be able to rename standard
fields and objects.
Fields part was working properly, but objects part was not yet
implemented.
This PR is adding the missing parts to make it work.
2024-04-09 10:20:34 +02:00
Jérémy MandCharles Bochet 5019b5febc feat: drop target column map (#4670)
This PR is dropping the column `targetColumnMap` of fieldMetadata
entities.
The goal of this column was to properly map field to their respecting
column in the table.
We decide to drop it and instead compute the column name on the fly when
we need it, as it's more easier to support.
Some parts of the code has been refactored to try making implementation
of composite type more easier to understand and maintain.

Fix #3760

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-04-08 16:00:28 +02:00
Jérémy M 04c06e3f91 fix: isIconDisplayedOnHoverOnly marked as required (#4805)
Fix PR #4676, `isIconDisplayedOnHoverOnly` should be provided or not
marked as required
2024-04-04 14:38:54 +02:00
Jérémy M 5c0b65eecb feat: simplification of default-value specification in FieldMetadata (#4592)
* feat: wip refactor default-value

* feat: health check to migrate default value

* fix: tests

* fix: refactor defaultValue to make it more clean

* fix: unit tests

* fix: front-end default value
2024-03-27 10:56:04 +01:00
Jérémy M 3acec7731c Fix/enum bug (#4659)
* fix: sever not throwing when enum contains two identical values

* fix: enum column name cannot be change

* fix: put field create/update inside transactions

* fix: check for options duplicate values front-end

* fix: missing commit transaction
2024-03-26 16:16:29 +01:00
Jérémy MandCharles Bochet d1ab063000 feat: use ApolloFactory for metadata client (#4608)
Co-authored-by: Charles Bochet <charles@twenty.com>
2024-03-25 19:15:46 +01:00
Jérémy M 04c5d066f8 fix: create deterministic uuids for standards relation on custom object (#4642)
* fix: create deterministic uuids for standards relation on custom object

* fix: remove check if standardId already exist to override old ones
2024-03-25 16:58:58 +01:00
Jérémy M e5c1309e8c feat: wip server folder structure (#4573)
* feat: wip server folder structure

* fix: merge

* fix: wrong merge

* fix: remove unused file

* fix: comment

* fix: lint

* fix: merge

* fix: remove console.log

* fix: metadata graphql arguments broken
2024-03-20 16:23:46 +01:00
Jérémy MandCharles Bochet 94487f6737 feat: refactor folder structure (#4498)
* feat: wip refactor folder structure

* Fix

* fix position

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-03-15 14:40:58 +01:00
Jérémy M d8b370720c feat: wip sync standard id (#4373)
* feat: wip sync standard id

feat: implement standardId for sync command

* fix: rebase

* fix: tests

* fix: deterministic uuid

* fix: sync custom not working

* fix: create custom not adding standardId

* fix: readability
2024-03-13 12:06:10 +01:00
Jérémy MandCharles Bochet af6ffbcc68 feat: standard fields on custom (#4332)
* feat: add ability to sync standard fields on custom object

* fix: clean

* fix: wrong compute during object creation

* fix: missing cascade delete

* fix: remove unused injected class

* fix: naming

* fix: rename factory to paramsFactory and clean

* fix: rename ExtendCustomObjectMetadata to BaseCustomObjectMetadata

* fix: partial fix inconsistent label and description

* Fixes

* Fix

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-03-07 17:21:50 +01:00
Jérémy M c3a024b047 feat: sync all workspaces (#4353) 2024-03-07 15:40:09 +01:00
Jérémy MandThaïs Guigon e69c462b70 feat: allow backend to rename field of custom object (#4097)
* feat: allow backend to rename field of custom object

* feat: allow custom field label edition in Settings

Closes #4080

* fix: avoid renaming standard fields

---------

Co-authored-by: Thaïs Guigon <guigon.thais@gmail.com>
2024-02-21 18:59:51 +01:00
Jérémy M e3e940327e fix: workspace health undefined relation (#4107) 2024-02-21 15:36:18 +01:00
Jérémy M 3914e8d77c fix: sync and health (#4095)
* fix: throw error if we try to create a migration without columnName

* fix: typeorm save for update breaking everything
2024-02-20 17:55:23 +01:00
Jérémy M 22e8a3ba77 fix: unwanted comment on graphQL input (#4071) 2024-02-20 16:13:18 +01:00
Jérémy M 2f9e503a8b fix: ignore enum options sync for now (#4056) 2024-02-19 17:29:30 +01:00
Jérémy M e293abe332 Fix/workspace health type (#4053)
* fix: memory issue with truncate command

* fix: LINK doesn't have any default value

* fix: Cannot convert LINK to column type.

* fix: handle old column type and add a warn to fix them manually
2024-02-19 17:28:40 +01:00
Jérémy M 44ac16c82e fix: impact too many records (#3993)
* fix: impact too many records

* fix: change env name

* fix: remove env name from error
2024-02-16 11:17:37 +01:00
Jérémy M c2c14d79a9 fix: workspace cache version (#3999) 2024-02-16 11:06:51 +01:00
Jérémy M f47159d84d fix: invalidate cache when no record inside workspace cache version (#3994)
* fix: invalidate cache when no record inside workspace cache version

* fix: use getVersion
2024-02-16 10:37:25 +01:00
Jérémy M 34d02cf4ed feat: add default value for some type of fields (#3991)
feat: add default value for some kind of fields
2024-02-16 10:34:42 +01:00
Jérémy M 990cb107a1 feat: workspace health target column map fix (#3932)
* feat: workspace health fix target column map

* fix: remove log

* feat: refactor health fixer

* fix: default-value issue and health check not working with composite

* fix: enhance target column map fix

* feat: create workspace migrations for target-column-map issues

* feat: enhance workspace-health issue detection
2024-02-15 18:04:12 +01:00
Jérémy M 8ce7020b12 feat: sync metadata can alter and update a field (#3944) 2024-02-13 19:36:58 +01:00
Jérémy M 35fce6a6b4 feat: health check enum (#3913)
* feat: health check enum

* fix: cleaner if condition
2024-02-12 17:32:05 +01:00
Jérémy M b0b033aec9 fix: workspace health (#3916)
* fix: workspace health applying migrations multiple times

* fix: remove log

* fix: use logger
2024-02-12 16:17:17 +01:00
Jérémy M 2560ce25e0 feat: workspace health default-value fix (#3894)
* feat: workspace health default-value fix

* fix: rename function regarding review
2024-02-09 14:16:11 +01:00
Jérémy MandCharles Bochet 7ec968d5a2 feat: workspace health type fix (#3890)
* feat: workspace health type fix

* Fix

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-02-08 18:59:17 +01:00
Jérémy M d3fe1b9e31 feat: workspace:health nullable fix (#3882) 2024-02-08 18:22:29 +01:00
Jérémy M 6e3a8e3461 Feat/workspace health core fix (#3863)
* feat: add deletion support on sync metadata command

* fix: remove debug

* feat: wip workspace health command add --fix option

fix: remove test

* feat: core of --fix option for workspace-health
2024-02-07 18:27:35 +01:00
Jérémy M a908353955 feat: add deletion support on sync metadata command (#3826)
* feat: add deletion support on sync metadata command

* fix: remove debug
2024-02-07 15:38:23 +01:00
Jérémy Mandcorentin a802338996 fix: options value can't contain special characters (#3738)
* fix: options value can't contain special characters

* add tests for formatFieldMetadataItemInput util

* fix test

* fix: add emoji test

---------

Co-authored-by: corentin <corentin@twenty.com>
2024-02-05 15:12:08 +01:00
Jérémy M 5fd982b009 feat: execute pending migrations command (#3767) 2024-02-02 11:10:26 +01:00
Jérémy M 25f4a80c7c fix: exception handler (#3768)
* fix: user is not sent to sentry

* fix: too much exceptions thrown
2024-02-02 09:26:48 +01:00
Jérémy M 9799326533 fix: logs folder doesn't exist (#3759) 2024-02-01 16:47:36 +01:00
Jérémy M 3c89a97a9f feat: add dry-run option to sync-metadata command (#3758)
* feat: add dry-run option to sync-metadata command

* feat: save metadata logs in dry-run mode
2024-02-01 16:35:32 +01:00
Jérémy M cdc51add7d feat: add user to sentry (#3467)
* feat: wip add user to sentry

* feat: wip interceptor

* feat: wip add user to sentry

* feat: add user into sentry errors

* fix: hide stack trace in production

* fix: properly log commands and handle exceptions

* fix: filter command exceptions

* feat: handle jobs errors
2024-02-01 16:14:08 +01:00
Jérémy M 8abd5be4b5 fix: sync metadata shouldn't remove non custom fields (#3750)
* fix: sync metadata shouldn't remove non custom fields

* fix: filter out custom relations
2024-02-01 14:25:50 +01:00
Jérémy M fc01c8cd4f fix: grapQL errors are not detailed enough (#3622) 2024-02-01 09:45:58 +01:00
Jérémy M 73f6876641 feat: workspace sync (#3505)
* feat: wip workspace sync

* feat: wip lot of debugging

* feat: refactor and fix sync

* fix: clean

fix: clean

* feat: add simple comparator tests

* fix: remove debug

* feat: wip drop table

* fix: main merge

* fix: some issues, and prepare storage system to handle complex deletion

* feat: wip clean and fix

* fix: reflect issue when using array instead of map and clean

* fix: test & sync

* fix: yarn files

* fix: unecesary if-else

* fix: if condition not needed

* fix: remove debug

* fix: replace EQUAL by SKIP

* fix: sync metadata relation not applied properly

* fix: lint issues

* fix: merge issue
2024-01-30 14:40:55 +01:00
Jérémy MandCharles Bochet da8dd671d1 fix: rating type issues (#3638)
* fix: rating type issues

* fix: rebase

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-01-30 09:57:30 +01:00
Jérémy M 6f98d1847f Fix/nested filter (#3624)
* fix: typo

* fix: relation type shouldn't be exposed in filter
2024-01-25 16:15:46 +01:00
Jérémy M 4b7e42c38e feat: workspace health relation (#3466)
feat: add check relation health
2024-01-17 17:05:35 +01:00
Jérémy M 3e8f4ec2c5 fix: auth user decorator cannot destruct property of undefined (#3394)
* fix: auth user decorator cannot destruct property of undefined

* fix: change naming
2024-01-12 12:12:33 +01:00
Jérémy M d0ed9ee2e0 feat: pagination with total count (#3384)
* feat: add totalCount

* feat: add command for production to fix existing tables
2024-01-12 10:41:38 +01:00
Jérémy M 5f0c9f67c9 feat: workspace health (#3344)
* feat: wip workspace health

* feat: split structure and metadata check

* feat: check default value structure health

* feat: check targetColumnMap structure health

* fix: composite types doesn't have default value properly defined

* feat: check default value structure health

* feat: check options structure health

* fix: verbose option not working properly

* fix: word issue

* fix: tests

* fix: remove console.log

* fix: TRUE and FALSE instead of YES and NO

* fix: fieldMetadataType instead of type
2024-01-11 16:41:25 +01:00
Jérémy M 1aa0f86724 feat: use apollo playground in debug mode (#3295) 2024-01-11 10:21:51 +01:00
Jérémy M 2dae94dec6 fix: pg_graphql performance (#3204) 2024-01-02 16:06:15 +01:00
d532f22fbb feat: migration can be applied on a specific schema & some enhancements (#2998)
* fix: remove old metadata seed files

* feat: wip standard to core relation

* fix: lint

* fix: merge

* fix: remove debug files

* feat: add feature flag for core object metadata

* fix: remove debug

* feat: always disable the standard core relation

* fix: missing feature flag

* fix: remove debug

* fix: feature flag doesn't seems to disable relation

* fix: delete .vscode folder, change this in another PR

* Update packages/twenty-server/src/workspace/workspace-sync-metadata/reflective-metadata.factory.ts

Co-authored-by: Weiko <corentin@twenty.com>

* Update packages/twenty-server/src/workspace/workspace-sync-metadata/reflective-metadata.factory.ts

Co-authored-by: Weiko <corentin@twenty.com>

* Update packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync.metadata.service.ts

Co-authored-by: Weiko <corentin@twenty.com>

* fix: remove optional fields from metadata entities

* fix: renamed variable

* fix: put back CursorScalarType

* fix: delete test command

* fix: remove unused workspace standard migration command

* fix: drop core object metadata declaration

* fix: rename variable

* fix: drop creation of core datasource

* fix: remove feature flag

* fix: drop support of standard to core relations

* feat: add user email field on workspace-member standard object

* fix: update seed accordingly

* fix: missing remove command file

* fix: datasource label should remain nullable

* fix: better asserts

* Remove unused code

* Remove unused code

---------

Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2023-12-21 19:15:05 +01:00
Jérémy M 3234134a30 fix: composite type migrations not well formatted (#3088) 2023-12-21 19:00:33 +01:00
Jérémy M d59a37129f fix: sentry doesn't catch exceptions from flexible backend (#3074)
* fix: sentry doesn't catch exceptions from flexible backend

* fix: send remaining errors to Sentry

* fix: missing debug

* feat: use an util exception handler instead of Nest.JS class
2023-12-20 12:04:59 +01:00