diff --git a/packages/admin/src/emailCampaigns/form/EmailCampaignForm.tsx b/packages/admin/src/emailCampaigns/form/EmailCampaignForm.tsx
index 9cc80b03..8e11db66 100644
--- a/packages/admin/src/emailCampaigns/form/EmailCampaignForm.tsx
+++ b/packages/admin/src/emailCampaigns/form/EmailCampaignForm.tsx
@@ -52,6 +52,7 @@ import {
GQLUpdateEmailCampaignMutationVariables,
} from "./EmailCampaignForm.gql.generated";
import { SendManagerFields } from "./SendManagerFields";
+import { TestEmailCampaignForm } from "./TestEmailCampaignForm";
interface FormProps {
id?: string;
@@ -287,7 +288,13 @@ export function EmailCampaignForm({ id, EmailCampaignContentBlock, scope, previe
scheduledAt: state.scheduledAt,
}}
>
-
+
+
),
},
diff --git a/packages/admin/src/emailCampaigns/form/SendEmailCampaignNowDialog.tsx b/packages/admin/src/emailCampaigns/form/SendEmailCampaignNowDialog.tsx
new file mode 100644
index 00000000..076b7b9a
--- /dev/null
+++ b/packages/admin/src/emailCampaigns/form/SendEmailCampaignNowDialog.tsx
@@ -0,0 +1,34 @@
+import { CancelButton, SaveButton } from "@comet/admin";
+import { Dialog, DialogActions, DialogContent, DialogTitle } from "@mui/material";
+import React from "react";
+import { FormattedMessage } from "react-intl";
+
+interface SendEmailCampaignNowDialogProps {
+ dialogOpen: boolean;
+ handleNoClick: () => void;
+ handleYesClick: () => void;
+}
+
+const SendEmailCampaignNowDialog = ({ dialogOpen, handleNoClick, handleYesClick }: SendEmailCampaignNowDialogProps) => {
+ return (
+
+ );
+};
+
+export { SendEmailCampaignNowDialog };
diff --git a/packages/admin/src/emailCampaigns/form/SendManagerFields.gql.ts b/packages/admin/src/emailCampaigns/form/SendManagerFields.gql.ts
index 1fe7a6d7..08c6538c 100644
--- a/packages/admin/src/emailCampaigns/form/SendManagerFields.gql.ts
+++ b/packages/admin/src/emailCampaigns/form/SendManagerFields.gql.ts
@@ -10,3 +10,9 @@ export const targetGroupsSelectQuery = gql`
}
}
`;
+
+export const sendEmailCampaignNowMutation = gql`
+ mutation SendEmailCampaignNow($id: ID!) {
+ sendEmailCampaignNow(id: $id)
+ }
+`;
diff --git a/packages/admin/src/emailCampaigns/form/SendManagerFields.tsx b/packages/admin/src/emailCampaigns/form/SendManagerFields.tsx
index 38283864..85c016c5 100644
--- a/packages/admin/src/emailCampaigns/form/SendManagerFields.tsx
+++ b/packages/admin/src/emailCampaigns/form/SendManagerFields.tsx
@@ -1,18 +1,27 @@
-import { useQuery } from "@apollo/client";
-import { Field, FinalFormSelect } from "@comet/admin";
+import { useMutation, useQuery } from "@apollo/client";
+import { Field, FinalFormSelect, SaveButton } from "@comet/admin";
import { FinalFormDateTimePicker } from "@comet/admin-date-time";
+import { Newsletter } from "@comet/admin-icons";
import { AdminComponentPaper, AdminComponentSectionGroup } from "@comet/blocks-admin";
import { ContentScopeInterface } from "@comet/cms-admin";
import { Card, MenuItem } from "@mui/material";
import * as React from "react";
import { FormattedMessage } from "react-intl";
-import { targetGroupsSelectQuery } from "./SendManagerFields.gql";
-import { GQLTargetGroupsSelectQuery, GQLTargetGroupsSelectQueryVariables } from "./SendManagerFields.gql.generated";
+import { SendEmailCampaignNowDialog } from "./SendEmailCampaignNowDialog";
+import { sendEmailCampaignNowMutation, targetGroupsSelectQuery } from "./SendManagerFields.gql";
+import {
+ GQLSendEmailCampaignNowMutation,
+ GQLSendEmailCampaignNowMutationVariables,
+ GQLTargetGroupsSelectQuery,
+ GQLTargetGroupsSelectQueryVariables,
+} from "./SendManagerFields.gql.generated";
interface SendManagerFieldsProps {
disableScheduling?: boolean;
scope: ContentScopeInterface;
+ id?: string;
+ isSendable: boolean;
}
const validateScheduledAt = (value: Date, now: Date) => {
@@ -28,12 +37,19 @@ const validateScheduledAt = (value: Date, now: Date) => {
}
};
-export const SendManagerFields = ({ disableScheduling, scope }: SendManagerFieldsProps) => {
+export const SendManagerFields = ({ disableScheduling, scope, id, isSendable }: SendManagerFieldsProps) => {
+ const [isSendEmailCampaignNowDialogOpen, setIsSendEmailCampaignNowDialogOpen] = React.useState(false);
+
const { data: targetGroups } = useQuery(targetGroupsSelectQuery, {
variables: { scope },
fetchPolicy: "network-only",
});
+ const [sendEmailCampaignNow, { loading: sendEmailCampaignNowLoading, error: sendEmailCampaignNowError }] = useMutation<
+ GQLSendEmailCampaignNowMutation,
+ GQLSendEmailCampaignNowMutationVariables
+ >(sendEmailCampaignNowMutation);
+
const now = new Date();
return (
@@ -66,6 +82,38 @@ export const SendManagerFields = ({ disableScheduling, scope }: SendManagerField
)}
+
+ }
+ saving={sendEmailCampaignNowLoading}
+ hasErrors={!!sendEmailCampaignNowError}
+ savingItem={}
+ errorItem={
+
+ }
+ onClick={() => {
+ setIsSendEmailCampaignNowDialogOpen(true);
+ }}
+ >
+
+
+ {
+ setIsSendEmailCampaignNowDialogOpen(false);
+ }}
+ handleYesClick={async () => {
+ if (id) {
+ await sendEmailCampaignNow({ variables: { id } });
+ setIsSendEmailCampaignNowDialogOpen(false);
+ }
+ }}
+ />
diff --git a/packages/admin/src/emailCampaigns/form/TestEmailCampaignForm.gql.ts b/packages/admin/src/emailCampaigns/form/TestEmailCampaignForm.gql.ts
new file mode 100644
index 00000000..a4d4669f
--- /dev/null
+++ b/packages/admin/src/emailCampaigns/form/TestEmailCampaignForm.gql.ts
@@ -0,0 +1,7 @@
+import { gql } from "@apollo/client";
+
+export const SendEmailCampaignToTestEmailsMutation = gql`
+ mutation SendEmailCampaignToTestEmails($id: ID!, $data: SendTestEmailCampaignArgs!) {
+ sendEmailCampaignToTestEmails(id: $id, data: $data)
+ }
+`;
diff --git a/packages/admin/src/emailCampaigns/form/TestEmailCampaignForm.tsx b/packages/admin/src/emailCampaigns/form/TestEmailCampaignForm.tsx
new file mode 100644
index 00000000..ac66004d
--- /dev/null
+++ b/packages/admin/src/emailCampaigns/form/TestEmailCampaignForm.tsx
@@ -0,0 +1,114 @@
+import { useApolloClient } from "@apollo/client";
+import { Field, FinalForm, FinalFormInput, SaveButton } from "@comet/admin";
+import { Newsletter } from "@comet/admin-icons";
+import { AdminComponentPaper, AdminComponentSectionGroup } from "@comet/blocks-admin";
+import { Card, FormHelperText, Typography } from "@mui/material";
+import React from "react";
+import { FormattedMessage } from "react-intl";
+
+import { SendEmailCampaignToTestEmailsMutation } from "./TestEmailCampaignForm.gql";
+import { GQLSendEmailCampaignToTestEmailsMutation, GQLSendEmailCampaignToTestEmailsMutationVariables } from "./TestEmailCampaignForm.gql.generated";
+
+interface FormProps {
+ testEmails: string;
+}
+
+interface TestEmailCampaignFormProps {
+ id?: string;
+ isSendable?: boolean;
+}
+
+export const TestEmailCampaignForm = ({ id, isSendable = false }: TestEmailCampaignFormProps) => {
+ const client = useApolloClient();
+
+ async function submitTestEmails({ testEmails }: FormProps) {
+ const emailsArray = testEmails.trim().split("\n");
+
+ if (id) {
+ const { data } = await client.mutate({
+ mutation: SendEmailCampaignToTestEmailsMutation,
+ variables: { id, data: { emails: emailsArray } },
+ });
+ return data?.sendEmailCampaignToTestEmails;
+ }
+ }
+
+ return (
+
+
+
+ }
+ >
+
+ mode="edit"
+ onSubmit={submitTestEmails}
+ onAfterSubmit={() => {
+ // override default behavior
+ }}
+ >
+ {({ handleSubmit, submitting, values }) => {
+ return (
+ <>
+
+ }
+ component={FinalFormInput}
+ multiline
+ placeholder={["First test email address", "Second test email address"].join("\n")}
+ fullWidth
+ minRows={4}
+ />
+
+
+
+
+
+
+ }
+ onClick={handleSubmit}
+ saving={submitting}
+ errorItem={
+
+ }
+ successItem={
+
+ }
+ savingItem={
+
+ }
+ >
+
+
+ >
+ );
+ }}
+
+
+
+
+ );
+};
diff --git a/packages/api/src/email-campaign/email-campaign.resolver.ts b/packages/api/src/email-campaign/email-campaign.resolver.ts
index f7d9c2dd..68ca8bc3 100644
--- a/packages/api/src/email-campaign/email-campaign.resolver.ts
+++ b/packages/api/src/email-campaign/email-campaign.resolver.ts
@@ -173,7 +173,21 @@ export function createEmailCampaignsResolver({
@Mutation(() => Boolean)
async sendEmailCampaignNow(@Args("id", { type: () => ID }) id: string): Promise {
- return this.campaignsService.sendEmailCampaignNow(id);
+ const campaignSent = await this.campaignsService.sendEmailCampaignNow(id);
+
+ if (campaignSent) {
+ const campaign = await this.repository.findOneOrFail(id);
+
+ wrap(campaign).assign({
+ scheduledAt: new Date(),
+ });
+
+ await this.entityManager.flush();
+
+ return true;
+ }
+
+ return false;
}
@Mutation(() => Boolean)
diff --git a/packages/api/src/email-campaign/email-campaigns.service.ts b/packages/api/src/email-campaign/email-campaigns.service.ts
index 822351e8..378eeab6 100644
--- a/packages/api/src/email-campaign/email-campaigns.service.ts
+++ b/packages/api/src/email-campaign/email-campaigns.service.ts
@@ -125,6 +125,6 @@ export class EmailCampaignsService {
} while (currentOffset < totalContacts);
}
- return campaign.brevoId ? this.brevoApiCampaignService.sendBrevoCampaign(campaign.brevoId) : false;
+ return false;
}
}