mirror of
https://github.com/twentyhq/twenty.git
synced 2026-04-20 15:02:18 -04:00
## Summary - **Inline email reply**: Replace external email client redirects (Gmail/Outlook deeplinks) with an in-app email composer. Users can reply to email threads directly from the email thread widget or via the command menu. - **SendEmail GraphQL mutation**: New backend mutation that reuses `EmailComposerService` for body sanitization, recipient validation, and SMTP dispatch via the existing outbound messaging infrastructure. - **Side panel compose page**: Command menu "Reply" action now opens a side-panel compose email page with pre-filled To, Subject, and In-Reply-To fields. ### Backend - `SendEmailResolver` with `SendEmailInput` / `SendEmailOutputDTO` - `SendEmailModule` wired into `CoreEngineModule` - Reuses `EmailComposerService` + `MessagingMessageOutboundService` ### Frontend - `EmailComposer` / `EmailComposerFields` components - `useSendEmail`, `useReplyContext`, `useEmailComposerState` hooks - `useOpenComposeEmailInSidePanel` + `SidePanelComposeEmailPage` - `EmailThreadWidget` inline Reply bar with toggle composer - `ReplyToEmailThreadCommand` now opens side-panel instead of external links ### Seeds - Added `handle` field to message participant seeds for realistic email addresses - Seed `connectedAccount` and `messageChannel` in correct batch order ## Test plan - [ ] Open an email thread on a person/company record → verify "Reply..." bar appears below the last message - [ ] Click "Reply..." → composer opens inline with pre-filled To and Subject - [ ] Type a message and click Send → email is sent via SMTP, composer closes - [ ] Use command menu Reply action → side panel opens with compose email page - [ ] Verify Send/Cancel buttons work correctly in side panel - [ ] Test with Cc/Bcc toggle in composer fields - [ ] Verify error handling: invalid recipients, missing connected account Made with [Cursor](https://cursor.com) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
56 lines
2.0 KiB
JavaScript
56 lines
2.0 KiB
JavaScript
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
|
|
module.exports = {
|
|
schema:
|
|
(process.env.REACT_APP_SERVER_BASE_URL ?? 'http://localhost:3000') +
|
|
'/metadata',
|
|
documents: [
|
|
'./src/modules/auth/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/users/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/views/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/ai/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/applications/graphql/**/*.{ts,tsx}',
|
|
|
|
'./src/modules/workspace/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/workspace-member/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/workspace-invitation/graphql/**/*.{ts,tsx}',
|
|
|
|
'./src/modules/settings/**/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/logic-functions/graphql/**/*.{ts,tsx}',
|
|
|
|
'./src/modules/databases/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/analytics/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/object-metadata/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/navigation-menu-item/**/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/command-menu-item/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/attachments/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/file/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/onboarding/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/front-components/graphql/**/*.{ts,tsx}',
|
|
|
|
'./src/modules/page-layout/widgets/**/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/activities/emails/graphql/mutations/**/*.{ts,tsx}',
|
|
|
|
'./src/modules/dashboards/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/page-layout/graphql/**/*.{ts,tsx}',
|
|
'./src/modules/marketplace/graphql/**/*.{ts,tsx}',
|
|
'!./src/**/*.test.{ts,tsx}',
|
|
'!./src/**/*.stories.{ts,tsx}',
|
|
'!./src/**/__mocks__/*.ts',
|
|
],
|
|
overwrite: true,
|
|
generates: {
|
|
'./src/generated-metadata/graphql.ts': {
|
|
plugins: ['typescript', 'typescript-operations', 'typed-document-node'],
|
|
config: {
|
|
skipTypename: false,
|
|
scalars: {
|
|
DateTime: 'string',
|
|
UUID: 'string',
|
|
},
|
|
namingConvention: { enumValues: 'keep' },
|
|
},
|
|
},
|
|
},
|
|
};
|