Add child folders support for Microsoft#15114
Conversation
There was a problem hiding this comment.
Greptile Overview
Greptile Summary
This PR adds comprehensive child folder support to Twenty's messaging system, particularly for Microsoft 365 integration. The changes enable hierarchical folder discovery and proper nested data loading for message folders.
On the frontend, the SettingsAccountsMessageFoldersCard component is enhanced to properly fetch nested MessageChannel data using the useGenerateDepthRecordGqlFieldsFromObject hook with depth 1. This ensures that child folder relationships are included in GraphQL queries rather than just loading top-level data.
The backend Microsoft folder service receives a major enhancement with recursive folder traversal capabilities. The new fetchFoldersRecursively method systematically discovers all nested folders by making targeted API calls to Microsoft Graph's child folder endpoints. The implementation includes robust pagination handling through fetchFolderPage that processes OData nextLink responses, ensuring scalability for accounts with extensive folder hierarchies.
The MicrosoftGraphFolder type is extended to include childFolderCount and parentFolderId fields, providing the metadata necessary for proper hierarchy management. This addresses a significant limitation where enterprise users with complex nested folder structures were missing visibility into their child folders, bringing the Microsoft integration to feature parity with expected email client functionality.
Important Files Changed
Changed Files
| Filename | Score | Overview |
|---|---|---|
| packages/twenty-front/src/modules/settings/accounts/components/message-folders/SettingsAccountsMessageFoldersCard.tsx | 5/5 | Added depth-based GraphQL field generation to properly load nested folder relationships |
| packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/microsoft/microsoft-get-all-folders.service.ts | 4/5 | Implemented recursive folder discovery with pagination handling for Microsoft Graph API |
Confidence score: 4/5
- This PR is safe to merge with minimal risk as it implements well-structured recursive logic with proper error handling
- Score reflects solid implementation following established patterns, though the recursive nature introduces complexity that requires careful testing
- Pay close attention to the Microsoft service file to ensure the recursive logic handles edge cases and doesn't cause performance issues with deeply nested folder structures
Sequence Diagram
sequenceDiagram
participant User
participant FoldersCard as "SettingsAccountsMessageFoldersCard"
participant GraphQL as "GraphQL API"
participant MicrosoftService as "MicrosoftGetAllFoldersService"
participant MicrosoftClient as "Microsoft Graph Client"
participant Database as "Database"
User->>FoldersCard: "View message folders"
FoldersCard->>GraphQL: "useFindOneRecord(messageChannel)"
GraphQL->>Database: "Query message channel with folders"
Database-->>GraphQL: "Return message channel data"
GraphQL-->>FoldersCard: "Return messageChannel with messageFolders"
Note over MicrosoftService: Background sync process
MicrosoftService->>MicrosoftClient: "fetchFoldersRecursively()"
MicrosoftClient->>MicrosoftService: "GET /me/mailFolders"
MicrosoftClient-->>MicrosoftService: "Return parent folders"
loop For each folder with childFolderCount > 0
MicrosoftService->>MicrosoftClient: "GET /me/mailFolders/{parentId}/childFolders"
MicrosoftClient-->>MicrosoftService: "Return child folders"
end
MicrosoftService->>Database: "Store all folders (parent + children)"
Database-->>MicrosoftService: "Folders stored"
User->>FoldersCard: "Search folders"
FoldersCard->>FoldersCard: "Filter messageFolders by search term"
User->>FoldersCard: "Toggle all folders"
FoldersCard->>GraphQL: "updateOneRecord() for each folder"
loop For each folder
GraphQL->>Database: "Update folder.isSynced"
Database-->>GraphQL: "Update confirmed"
end
GraphQL-->>FoldersCard: "All updates completed"
User->>FoldersCard: "Toggle individual folder"
FoldersCard->>GraphQL: "updateOneRecord(folder.id, {isSynced: !folder.isSynced})"
GraphQL->>Database: "Update specific folder sync status"
Database-->>GraphQL: "Update confirmed"
GraphQL-->>FoldersCard: "Update completed"
2 files reviewed, no comments
|
🚀 Preview Environment Ready! Your preview environment is available at: http://bore.pub:7520 This environment will automatically shut down when the PR is closed or after 5 hours. |
|
Thanks @neo773 for your contribution! |

No description provided.