diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql index 614e41286c..809184eb59 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql @@ -188,6 +188,7 @@ enum EngineComponentKey { COMPOSE_CAMPAIGN SEND_MESSAGE_CAMPAIGN SEND_MESSAGE_CAMPAIGN_TEST + EMAIL_BLOCK_SETTINGS GO_TO_PEOPLE GO_TO_COMPANIES GO_TO_DASHBOARDS @@ -3726,6 +3727,7 @@ enum FileFolder { Dependencies Workflow EmailAttachment + EmailImage AppTarball GeneratedSdkClient Dpa diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts index db2fd54918..bf6a8c689d 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts @@ -136,7 +136,7 @@ export interface CommandMenuItem { __typename: 'CommandMenuItem' } -export type EngineComponentKey = 'NAVIGATE_TO_NEXT_RECORD' | 'NAVIGATE_TO_PREVIOUS_RECORD' | 'CREATE_NEW_RECORD' | 'DELETE_RECORDS' | 'RESTORE_RECORDS' | 'DESTROY_RECORDS' | 'ADD_TO_FAVORITES' | 'REMOVE_FROM_FAVORITES' | 'EXPORT_NOTE_TO_PDF' | 'EXPORT_RECORDS' | 'UPDATE_MULTIPLE_RECORDS' | 'MERGE_MULTIPLE_RECORDS' | 'IMPORT_RECORDS' | 'EXPORT_VIEW' | 'SEE_DELETED_RECORDS' | 'CREATE_NEW_VIEW' | 'HIDE_DELETED_RECORDS' | 'EDIT_RECORD_PAGE_LAYOUT' | 'EDIT_DASHBOARD_LAYOUT' | 'SAVE_DASHBOARD_LAYOUT' | 'CANCEL_DASHBOARD_LAYOUT' | 'DUPLICATE_DASHBOARD' | 'ACTIVATE_WORKFLOW' | 'DEACTIVATE_WORKFLOW' | 'DISCARD_DRAFT_WORKFLOW' | 'TEST_WORKFLOW' | 'SEE_ACTIVE_VERSION_WORKFLOW' | 'SEE_RUNS_WORKFLOW' | 'SEE_VERSIONS_WORKFLOW' | 'ADD_NODE_WORKFLOW' | 'TIDY_UP_WORKFLOW' | 'DUPLICATE_WORKFLOW' | 'SEE_VERSION_WORKFLOW_RUN' | 'SEE_WORKFLOW_WORKFLOW_RUN' | 'STOP_WORKFLOW_RUN' | 'RETRY_WORKFLOW_RUN' | 'SEE_RUNS_WORKFLOW_VERSION' | 'SEE_WORKFLOW_WORKFLOW_VERSION' | 'USE_AS_DRAFT_WORKFLOW_VERSION' | 'SEE_VERSIONS_WORKFLOW_VERSION' | 'SEARCH_RECORDS' | 'SEARCH_RECORDS_FALLBACK' | 'ASK_AI' | 'VIEW_PREVIOUS_AI_CHATS' | 'NAVIGATION' | 'TRIGGER_WORKFLOW_VERSION' | 'FRONT_COMPONENT_RENDERER' | 'REPLY_TO_EMAIL_THREAD' | 'COMPOSE_EMAIL' | 'COMPOSE_CAMPAIGN' | 'SEND_MESSAGE_CAMPAIGN' | 'SEND_MESSAGE_CAMPAIGN_TEST' | 'GO_TO_PEOPLE' | 'GO_TO_COMPANIES' | 'GO_TO_DASHBOARDS' | 'GO_TO_OPPORTUNITIES' | 'GO_TO_SETTINGS' | 'GO_TO_TASKS' | 'GO_TO_NOTES' | 'GO_TO_WORKFLOWS' | 'GO_TO_RUNS' | 'DELETE_SINGLE_RECORD' | 'DELETE_MULTIPLE_RECORDS' | 'RESTORE_SINGLE_RECORD' | 'RESTORE_MULTIPLE_RECORDS' | 'DESTROY_SINGLE_RECORD' | 'DESTROY_MULTIPLE_RECORDS' | 'EXPORT_FROM_RECORD_INDEX' | 'EXPORT_FROM_RECORD_SHOW' | 'EXPORT_MULTIPLE_RECORDS' +export type EngineComponentKey = 'NAVIGATE_TO_NEXT_RECORD' | 'NAVIGATE_TO_PREVIOUS_RECORD' | 'CREATE_NEW_RECORD' | 'DELETE_RECORDS' | 'RESTORE_RECORDS' | 'DESTROY_RECORDS' | 'ADD_TO_FAVORITES' | 'REMOVE_FROM_FAVORITES' | 'EXPORT_NOTE_TO_PDF' | 'EXPORT_RECORDS' | 'UPDATE_MULTIPLE_RECORDS' | 'MERGE_MULTIPLE_RECORDS' | 'IMPORT_RECORDS' | 'EXPORT_VIEW' | 'SEE_DELETED_RECORDS' | 'CREATE_NEW_VIEW' | 'HIDE_DELETED_RECORDS' | 'EDIT_RECORD_PAGE_LAYOUT' | 'EDIT_DASHBOARD_LAYOUT' | 'SAVE_DASHBOARD_LAYOUT' | 'CANCEL_DASHBOARD_LAYOUT' | 'DUPLICATE_DASHBOARD' | 'ACTIVATE_WORKFLOW' | 'DEACTIVATE_WORKFLOW' | 'DISCARD_DRAFT_WORKFLOW' | 'TEST_WORKFLOW' | 'SEE_ACTIVE_VERSION_WORKFLOW' | 'SEE_RUNS_WORKFLOW' | 'SEE_VERSIONS_WORKFLOW' | 'ADD_NODE_WORKFLOW' | 'TIDY_UP_WORKFLOW' | 'DUPLICATE_WORKFLOW' | 'SEE_VERSION_WORKFLOW_RUN' | 'SEE_WORKFLOW_WORKFLOW_RUN' | 'STOP_WORKFLOW_RUN' | 'RETRY_WORKFLOW_RUN' | 'SEE_RUNS_WORKFLOW_VERSION' | 'SEE_WORKFLOW_WORKFLOW_VERSION' | 'USE_AS_DRAFT_WORKFLOW_VERSION' | 'SEE_VERSIONS_WORKFLOW_VERSION' | 'SEARCH_RECORDS' | 'SEARCH_RECORDS_FALLBACK' | 'ASK_AI' | 'VIEW_PREVIOUS_AI_CHATS' | 'NAVIGATION' | 'TRIGGER_WORKFLOW_VERSION' | 'FRONT_COMPONENT_RENDERER' | 'REPLY_TO_EMAIL_THREAD' | 'COMPOSE_EMAIL' | 'COMPOSE_CAMPAIGN' | 'SEND_MESSAGE_CAMPAIGN' | 'SEND_MESSAGE_CAMPAIGN_TEST' | 'EMAIL_BLOCK_SETTINGS' | 'GO_TO_PEOPLE' | 'GO_TO_COMPANIES' | 'GO_TO_DASHBOARDS' | 'GO_TO_OPPORTUNITIES' | 'GO_TO_SETTINGS' | 'GO_TO_TASKS' | 'GO_TO_NOTES' | 'GO_TO_WORKFLOWS' | 'GO_TO_RUNS' | 'DELETE_SINGLE_RECORD' | 'DELETE_MULTIPLE_RECORDS' | 'RESTORE_SINGLE_RECORD' | 'RESTORE_MULTIPLE_RECORDS' | 'DESTROY_SINGLE_RECORD' | 'DESTROY_MULTIPLE_RECORDS' | 'EXPORT_FROM_RECORD_INDEX' | 'EXPORT_FROM_RECORD_SHOW' | 'EXPORT_MULTIPLE_RECORDS' export type CommandMenuItemAvailabilityType = 'GLOBAL' | 'GLOBAL_OBJECT_CONTEXT' | 'RECORD_SELECTION' | 'FALLBACK' @@ -3187,7 +3187,7 @@ export interface Mutation { __typename: 'Mutation' } -export type FileFolder = 'CorePicture' | 'AgentChat' | 'BuiltLogicFunction' | 'BuiltFrontComponent' | 'PublicAsset' | 'Source' | 'FilesField' | 'Dependencies' | 'Workflow' | 'EmailAttachment' | 'AppTarball' | 'GeneratedSdkClient' | 'Dpa' +export type FileFolder = 'CorePicture' | 'AgentChat' | 'BuiltLogicFunction' | 'BuiltFrontComponent' | 'PublicAsset' | 'Source' | 'FilesField' | 'Dependencies' | 'Workflow' | 'EmailAttachment' | 'EmailImage' | 'AppTarball' | 'GeneratedSdkClient' | 'Dpa' export type RunAgentMessageRole = 'user' | 'assistant' @@ -9184,6 +9184,7 @@ export const enumEngineComponentKey = { COMPOSE_CAMPAIGN: 'COMPOSE_CAMPAIGN' as const, SEND_MESSAGE_CAMPAIGN: 'SEND_MESSAGE_CAMPAIGN' as const, SEND_MESSAGE_CAMPAIGN_TEST: 'SEND_MESSAGE_CAMPAIGN_TEST' as const, + EMAIL_BLOCK_SETTINGS: 'EMAIL_BLOCK_SETTINGS' as const, GO_TO_PEOPLE: 'GO_TO_PEOPLE' as const, GO_TO_COMPANIES: 'GO_TO_COMPANIES' as const, GO_TO_DASHBOARDS: 'GO_TO_DASHBOARDS' as const, @@ -9860,6 +9861,7 @@ export const enumFileFolder = { Dependencies: 'Dependencies' as const, Workflow: 'Workflow' as const, EmailAttachment: 'EmailAttachment' as const, + EmailImage: 'EmailImage' as const, AppTarball: 'AppTarball' as const, GeneratedSdkClient: 'GeneratedSdkClient' as const, Dpa: 'Dpa' as const diff --git a/packages/twenty-emails/src/common-style.ts b/packages/twenty-emails/src/common-style.ts index 0fe58a1255..5dd76e1fbc 100644 --- a/packages/twenty-emails/src/common-style.ts +++ b/packages/twenty-emails/src/common-style.ts @@ -26,7 +26,7 @@ const colors = { blue40: '#5e90f2', }; -export const emailTheme = { +export const canvasTheme = { font: { colors: { highlighted: grayScale.gray60, diff --git a/packages/twenty-emails/src/components/BaseHead.tsx b/packages/twenty-emails/src/components/BaseHead.tsx index a911533f6e..61680ce5dc 100644 --- a/packages/twenty-emails/src/components/BaseHead.tsx +++ b/packages/twenty-emails/src/components/BaseHead.tsx @@ -1,16 +1,16 @@ import { Font, Head } from 'react-email'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; export const BaseHead = () => { return ( Twenty email ); diff --git a/packages/twenty-emails/src/components/CallToAction.tsx b/packages/twenty-emails/src/components/CallToAction.tsx index ff384d243a..bce63c056f 100644 --- a/packages/twenty-emails/src/components/CallToAction.tsx +++ b/packages/twenty-emails/src/components/CallToAction.tsx @@ -1,18 +1,18 @@ import { type JSX } from 'react'; import { Button } from 'react-email'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; const callToActionStyle = { display: 'inline-flex', padding: '8px 32px', - borderRadius: emailTheme.border.radius.md, - border: `1px solid ${emailTheme.background.transparent.light}`, - background: emailTheme.background.button, - boxShadow: `0px 2px 4px 0px ${emailTheme.background.transparent.light}, 0px 0px 4px 0px ${emailTheme.background.transparent.medium}`, - color: emailTheme.font.colors.inverted, - fontSize: emailTheme.font.size.md, - fontWeight: emailTheme.font.weight.bold, + borderRadius: canvasTheme.border.radius.md, + border: `1px solid ${canvasTheme.background.transparent.light}`, + background: canvasTheme.background.button, + boxShadow: `0px 2px 4px 0px ${canvasTheme.background.transparent.light}, 0px 0px 4px 0px ${canvasTheme.background.transparent.medium}`, + color: canvasTheme.font.colors.inverted, + fontSize: canvasTheme.font.size.md, + fontWeight: canvasTheme.font.weight.bold, width: 'auto', }; diff --git a/packages/twenty-emails/src/components/HighlightedContainer.tsx b/packages/twenty-emails/src/components/HighlightedContainer.tsx index 599cd18211..3b53f96eee 100644 --- a/packages/twenty-emails/src/components/HighlightedContainer.tsx +++ b/packages/twenty-emails/src/components/HighlightedContainer.tsx @@ -1,16 +1,16 @@ import { Column, Container, Row } from 'react-email'; import React, { type JSX } from 'react'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; type HighlightedContainerProps = { children: JSX.Element | JSX.Element[] | string; }; const highlightedContainerStyle = { - background: emailTheme.background.colors.highlight, - border: `1px solid ${emailTheme.border.color.highlighted}`, - borderRadius: emailTheme.border.radius.md, + background: canvasTheme.background.colors.highlight, + border: `1px solid ${canvasTheme.border.color.highlighted}`, + borderRadius: canvasTheme.border.radius.md, padding: '24px 48px', } as React.CSSProperties; diff --git a/packages/twenty-emails/src/components/HighlightedText.tsx b/packages/twenty-emails/src/components/HighlightedText.tsx index 9ca8c04a9f..76b07a85ae 100644 --- a/packages/twenty-emails/src/components/HighlightedText.tsx +++ b/packages/twenty-emails/src/components/HighlightedText.tsx @@ -1,15 +1,15 @@ import { Text } from 'react-email'; import { type JSX } from 'react'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; const highlightedStyle = { - borderRadius: emailTheme.border.radius.sm, - background: emailTheme.background.colors.highlight, + borderRadius: canvasTheme.border.radius.sm, + background: canvasTheme.background.colors.highlight, padding: '4px 8px', - fontSize: emailTheme.font.size.lg, - fontWeight: emailTheme.font.weight.bold, - color: emailTheme.font.colors.highlighted, + fontSize: canvasTheme.font.size.lg, + fontWeight: canvasTheme.font.weight.bold, + color: canvasTheme.font.colors.highlighted, }; type HighlightedTextProps = { diff --git a/packages/twenty-emails/src/components/Link.tsx b/packages/twenty-emails/src/components/Link.tsx index d7ea615593..a265e96cf2 100644 --- a/packages/twenty-emails/src/components/Link.tsx +++ b/packages/twenty-emails/src/components/Link.tsx @@ -1,7 +1,7 @@ import { type JSX } from 'react'; import { Link as EmailLink } from 'react-email'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; const linkStyle = { textDecoration: 'underline', @@ -19,7 +19,7 @@ export const Link = ({ value, href, color }: LinkProps) => { href={href} style={{ ...linkStyle, - color: color ?? emailTheme.font.colors.tertiary, + color: color ?? canvasTheme.font.colors.tertiary, }} > {value} diff --git a/packages/twenty-emails/src/components/MainText.tsx b/packages/twenty-emails/src/components/MainText.tsx index fe8f09a46f..b30aa071e9 100644 --- a/packages/twenty-emails/src/components/MainText.tsx +++ b/packages/twenty-emails/src/components/MainText.tsx @@ -1,18 +1,18 @@ import { type JSX } from 'react'; import { Text } from 'react-email'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; type MainTextProps = { children: JSX.Element | JSX.Element[] | string; }; const mainTextStyle = { - fontFamily: emailTheme.font.family, - fontSize: emailTheme.font.size.md, - fontWeight: emailTheme.font.weight.regular, - color: emailTheme.font.colors.primary, - lineHeight: emailTheme.font.lineHeight, + fontFamily: canvasTheme.font.family, + fontSize: canvasTheme.font.size.md, + fontWeight: canvasTheme.font.weight.regular, + color: canvasTheme.font.colors.primary, + lineHeight: canvasTheme.font.lineHeight, }; export const MainText = ({ children }: MainTextProps) => { diff --git a/packages/twenty-emails/src/components/ShadowText.tsx b/packages/twenty-emails/src/components/ShadowText.tsx index 138e23e6c7..147899ce50 100644 --- a/packages/twenty-emails/src/components/ShadowText.tsx +++ b/packages/twenty-emails/src/components/ShadowText.tsx @@ -1,18 +1,18 @@ import { type JSX } from 'react'; import { Text } from 'react-email'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; type ShadowTextProps = { children: JSX.Element | JSX.Element[] | string; }; const shadowTextStyle = { - fontSize: emailTheme.font.size.sm, - fontWeight: emailTheme.font.weight.regular, - color: emailTheme.font.colors.tertiary, + fontSize: canvasTheme.font.size.sm, + fontWeight: canvasTheme.font.weight.regular, + color: canvasTheme.font.colors.tertiary, margin: '0 0 12px 0', - lineHeight: emailTheme.font.lineHeight, + lineHeight: canvasTheme.font.lineHeight, }; export const ShadowText = ({ children }: ShadowTextProps) => { diff --git a/packages/twenty-emails/src/components/SubTitle.tsx b/packages/twenty-emails/src/components/SubTitle.tsx index fdfd4b2b58..e5b5443ade 100644 --- a/packages/twenty-emails/src/components/SubTitle.tsx +++ b/packages/twenty-emails/src/components/SubTitle.tsx @@ -1,17 +1,17 @@ import { type JSX } from 'react'; import { Heading } from 'react-email'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; type SubTitleProps = { value: JSX.Element | JSX.Element[] | string; }; const subTitleStyle = { - fontFamily: emailTheme.font.family, - fontSize: emailTheme.font.size.lg, - fontWeight: emailTheme.font.weight.bold, - color: emailTheme.font.colors.highlighted, + fontFamily: canvasTheme.font.family, + fontSize: canvasTheme.font.size.lg, + fontWeight: canvasTheme.font.weight.bold, + color: canvasTheme.font.colors.highlighted, }; export const SubTitle = ({ value }: SubTitleProps) => { diff --git a/packages/twenty-emails/src/components/Title.tsx b/packages/twenty-emails/src/components/Title.tsx index fc8336b8c6..a4320d70d5 100644 --- a/packages/twenty-emails/src/components/Title.tsx +++ b/packages/twenty-emails/src/components/Title.tsx @@ -1,17 +1,17 @@ import { type JSX } from 'react'; import { Heading } from 'react-email'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; type TitleProps = { value: JSX.Element | JSX.Element[] | string; }; const titleStyle = { - fontFamily: emailTheme.font.family, - fontSize: emailTheme.font.size.xl, - fontWeight: emailTheme.font.weight.bold, - color: emailTheme.font.colors.highlighted, + fontFamily: canvasTheme.font.family, + fontSize: canvasTheme.font.size.xl, + fontWeight: canvasTheme.font.weight.bold, + color: canvasTheme.font.colors.highlighted, }; export const Title = ({ value }: TitleProps) => { diff --git a/packages/twenty-emails/src/emails/send-invite-link.email.tsx b/packages/twenty-emails/src/emails/send-invite-link.email.tsx index a4c8e58a67..d29b3ba13e 100644 --- a/packages/twenty-emails/src/emails/send-invite-link.email.tsx +++ b/packages/twenty-emails/src/emails/send-invite-link.email.tsx @@ -1,6 +1,6 @@ import { Trans } from '@lingui/react'; import { Img } from 'react-email'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; import { BaseEmail } from 'src/components/BaseEmail'; import { CallToAction } from 'src/components/CallToAction'; @@ -55,7 +55,7 @@ export const SendInviteLinkEmail = ({ ), 1: , diff --git a/packages/twenty-emails/src/emails/validate-approved-access-domain.email.tsx b/packages/twenty-emails/src/emails/validate-approved-access-domain.email.tsx index 95d3480d20..05104d01b2 100644 --- a/packages/twenty-emails/src/emails/validate-approved-access-domain.email.tsx +++ b/packages/twenty-emails/src/emails/validate-approved-access-domain.email.tsx @@ -1,6 +1,6 @@ import { Trans } from '@lingui/react'; import { Img } from 'react-email'; -import { emailTheme } from 'src/common-style'; +import { canvasTheme } from 'src/common-style'; import { BaseEmail } from 'src/components/BaseEmail'; import { CallToAction } from 'src/components/CallToAction'; @@ -56,7 +56,7 @@ export const SendApprovedAccessDomainValidation = ({ ), 1: , diff --git a/packages/twenty-emails/src/utils/email-renderer/email-renderer.tsx b/packages/twenty-emails/src/utils/email-renderer/email-renderer.tsx index 4ae8fda576..d63b68042f 100644 --- a/packages/twenty-emails/src/utils/email-renderer/email-renderer.tsx +++ b/packages/twenty-emails/src/utils/email-renderer/email-renderer.tsx @@ -1,23 +1,61 @@ -import { Body, Head, Html } from 'react-email'; +import { type ReactNode } from 'react'; +import { Body, Container, Head, Html } from 'react-email'; import { type JSONContent } from '@tiptap/core'; +import { type CanvasTheme, resolveCanvasTheme } from 'twenty-shared/utils'; import { mappedNodeContent } from 'src/utils/email-renderer/renderers/render-node'; +const BASE_STYLE_RESET = `blockquote,h1,h2,h3,img,li,ol,p,ul{margin-top:0;margin-bottom:0}`; + +const themedBody = (theme: CanvasTheme, children: ReactNode) => ( + + + {children} + + +); + export const reactMarkupFromJSON = (json: JSONContent | string) => { if (typeof json === 'string') { return json; } const jsxNodes = mappedNodeContent(json); + const canvasTheme = resolveCanvasTheme(json.attrs?.canvasTheme); + return (