## Context
This PR introduces view actions for the migration v2. We should be able
to create, update and delete views through the migration runner
independently from object actions (this is not 100% true in this PR
though as I'm still passing the object metadata to build the view)
Note: Once favorite are moved out of the workspace schema, we will have
favorite actions as well, in the meantime I have to inject some code at
the end of the createOne method from the object metadata service
- Removed `IMAPMessageLocator` service which relied on `Message-ID`
header lookups.
We now fetch messages directly by UID, which should eliminate most of
the issues we were hitting.
This had a challenge, `messageIdsToFetch` were flattened and UIDs are
only unique within their own folder.
To preserve context without modifying the core message module, I landed
on using composite keys for IMAP message IDs.
Each UID is now prefixed with its folder name, and we parse it back when
needed to recover the folder.
This feels like a reasonable trade-off since it resolves a lot of the
failures we saw with `Message-ID` lookups.
And Syncs are faster now since there's no double scanning.
- Added `QRESYNC` support for servers that provide it, giving us faster
incremental sync.
- Refactored code to better split concerns.
### Compatibility Test
| Server | Status |
|---------------------|------------|
| Gmail | ✅ Tested |
| Dovecot | ✅ Tested |
| Stalwart | ✅ Tested |
| Titan Email | ✅ Tested |
| FastMail | ✅ Tested |
<img width="804" height="418" alt="image"
src="https://github.com/user-attachments/assets/b414a484-2798-4839-b395-9dd5c153effe"
/>
## Add Morph Relation Field Display Support for Tables (one to many &
many to one)
**Features:**
- Display morph relation fields (one-to-many, many-to-one) in table
cells
- Multi-field record retrieval for improved performance
- Enhanced table cell rendering with morph relation support
**Components Added:**
- `MorphRelationManyToOneFieldDisplay` - Shows many-to-one morph
relations
- `MorphRelationOneToManyFieldDisplay` - Shows one-to-many morph
relations
TODO :
handle notes and tasks case if we choose these kind of objects as
targets/source for a morph relation
---------
Co-authored-by: Charles Bochet <charles@twenty.com>
…PC validation
- Introduced full integration test suite for MCP controller, testing
`POST /mcp` with valid and invalid payloads.
- Added `@IsDefined` validation to ensure the `method` field is required
in JSON-RPC requests.
- Applied `RestApiExceptionFilter` to MCP controller for consistent
error handling.
- Enhanced validation pipe in MCP controller to whitelist and reject
non-whitelisted properties.
- Consolidated exception filters in SSOAuthController.
The code to search variables became too complex. This is mainly because
it tries to handle all use cases at once:
- steps returning records (MANUAL TRIGGER, CREATE RECORD...)
- steps returning record events
- primitive types (code, webhook...)
- forms
To make the code maintainable, let's make a few updates:
- clear schema output types for each steps
- group the output types that are similar and implement a search schema
function for each
- once this is implemented on frontend, let's remove the logic on
backend side. Schema should be recompute and not stored
This PR implement the refacto for steps returning records and events.
## What
Fixed N+1 query issue where each view's name resolution triggered a
separate DB query to fetch objectMetadataId, even though it was already
available in the parent view object.
## How
- Added `objectMetadataLoader` to DataloaderService to batch metadata
lookups
- Updated ViewResolver to use context.loaders (following existing
pattern from other metadata
resolvers)
- Removed unused `getObjectMetadataByViewId` method and its tests
Now uses the already-loaded `view.objectMetadataId` directly instead of
making unnecessary
queries.
Much cleaner!
Fixed issue #13869
Added flag to prevent selection of content inside ScrollWrapper based on
value of preventTextSelection flag this will prevent selection of its
all child. For to select title and description I added custom css for
that to allow selection for title and description.
Demo :
https://github.com/user-attachments/assets/d10a7e5f-6498-4f8d-9aa2-26f48559ce23
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Fix issue: #13742
Step number look better then without number so did't removed that
Added description in H2Title component
Not added new description shown in figma because it is to large and
H2Title truncate after 2 lines
We can add this figma content only if we do not use H2Title component
<img width="719" height="553" alt="image"
src="https://github.com/user-attachments/assets/1aae680f-de4e-424b-baf7-c0d402581d28"
/>
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
…s, and resources
- Removed unused `ObjectMetadataStandardIdToIdMap`.
- Updated Vite config with additional allowed hosts.
- Improved MCP service to handle `ping` method and lists for tools,
prompts, and resources.
- Refactored utility function `isFieldMetadataEntityOfType` for improved
type handling.
- Expanded MCP metadata service to include tools, prompts, and resources
support.
Parallel code path to read and write core views when
IS_CORE_VIEW_ENABLED.
Migrated view key to an enum.
---------
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
## Context
This refactoring improves scalability in the workspace migration runner
in terms of actions. Instead of relying on a switch case and multiple
changes and services + duplicate things between metadata and workspace
schema, we now have a unique module for all kind of actions and a
registry pattern to register them and run them dynamically.
Example on how to add a new "create_role" action with the future design:
```typescript
// packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/role/services/create-role-action-handler.service.ts
export class CreateRoleActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
'create_role',
) {
constructor(
private readonly workspaceSchemaManagerService: WorkspaceSchemaManagerService,
private readonly roleRepository: Repository<Role>,
) {}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<CreateRoleAction>,
): Promise<void> {
this.roleRepository.save({...}); // technically could use the queryRunner from context param directly instead of injecting the repository
}
async executeForWorkspaceSchema(
context: WorkspaceMigrationActionRunnerArgs<CreateRoleAction>,
): Promise<void> {
// this.workspaceSchemaManagerService.tableManager... -> Nothing to do in the workspace schema in the role case
}
}
```
```typescript
// packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts
@Module({
imports: [WorkspaceSchemaManagerModule, +TypeOrmModule.forFeature([Role]),
providers: [
...
+RoleCreateActionService
],
})
export class WorkspaceSchemaMigrationRunnerActionHandlersModule {}
```
```typescript
export type WorkspaceMigrationAction=
| WorkspaceMigrationObjectAction
...
+| WorkspaceMigrationRoleAction;
export type CreateRoleAction = {
type = 'create_role',
role: RoleEntity
};
export type WorkspaceMigrationRoleAction = CreateRoleAction;
```
Closes#13861
`All Objects` has been renamed to `Objects` and `Name` has been replaced
with `All Objects`. There was no specification of whether the `Data full
access` card had to be implemented or not. Do let me know if that needs
to be removed or something needs to be changed in its configuration.
Attaching a loom recording of the changes:
[Loom
Recording](https://www.loom.com/share/42b54e9386b14619bc1118e95eb62293?sid=10ac8e8a-475b-4870-bd36-64742cd8c3c5)
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
On field selection, we need to retrieve the fieldMetadata to set the
filter type. Current code was using the current step filter
fieldMetdataId instead of the new one.
Also adding a special behaviour for Select filter: it behaves as
arrays/multiselect but the opearands are not the same.
---------
Co-authored-by: Charles Bochet <charles@twenty.com>
Closes#13862
The `padding-right` for `StyledCheckboxCell` was previously set to
`16px`, causing it to be pushed in. It has now been reduced to `8px`.
The read column in the table appeared as the third column regardless of
whether update was restricted or not. Now, the read column appears as
the last column if update is restricted, otherwise, read appears before
update column.
Attaching a recording for verification:
[Loom
Recording](https://www.loom.com/share/ebd07db6c4d04900aa18f3a1ba71e770?sid=75b33043-dc80-4e2d-82ae-f183efa6faa2)
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
https://github.com/user-attachments/assets/32d20ca0-fa50-427c-92e8-638884d86de3
- code needs refactoring
- ~~missing stack behaviour (I dont think its easy to add something
similar here, but will give it a try) - I suspect it will look crowded~~
- ~~the notification counter - boards have it on top right, but on
tables we cant do that since the rows could be longer than the scrolling
container , therefore I added it on top left corner~~
- ~~needs to test with large set of data for both boards and tables
(pagination)~~
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>