Skip to content

Commit

Permalink
COM-964 Add multiselect to choose test contacts (Depends on: #78) (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
juliawegmayr authored Jan 15, 2025
1 parent dd93185 commit d32e9e8
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changeset/clever-moons-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@comet/brevo-admin": minor
---

Replace the `TextField` with a `FinalFormSelect` component in the `TestEmailCampaignForm`, allowing users to choose contacts directly from the `TestContactList`
1 change: 1 addition & 0 deletions demo/api/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,7 @@ enum SubscribeResponse {
SUCCESSFUL
ERROR_UNKNOWN
ERROR_CONTAINED_IN_ECG_RTR_LIST
ERROR_MAXIMAL_NUMBER_OF_TEST_CONTACTS_REACHED
}

input BrevoContactInput {
Expand Down
36 changes: 32 additions & 4 deletions packages/admin/src/brevoTestContacts/BrevoTestContactsGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ToolbarFillSpace,
ToolbarItem,
ToolbarTitleItem,
Tooltip,
useBufferedRowCount,
useDataGridRemote,
usePersistentColumnState,
Expand Down Expand Up @@ -48,7 +49,20 @@ const deleteBrevoTestContactMutation = gql`
}
`;

function BrevoTestContactsGridToolbar({ intl, scope }: { intl: IntlShape; scope: GQLEmailCampaignContentScopeInput }) {
function BrevoTestContactsGridToolbar({
intl,
scope,
totalCount,
}: {
intl: IntlShape;
scope: GQLEmailCampaignContentScopeInput;
totalCount: number;
}) {
const disableButton = totalCount >= 100;
const tooltipMessage = intl.formatMessage({
id: "cometBrevoModule.brevoTestContact.contactLimitReached",
defaultMessage: "Contact limit of 100 reached. You cannot add more contacts.",
});
return (
<>
<Toolbar>
Expand All @@ -65,9 +79,21 @@ function BrevoTestContactsGridToolbar({ intl, scope }: { intl: IntlShape; scope:
</ToolbarItem>
<ToolbarFillSpace />
<ToolbarActions>
<Button startIcon={<Add />} component={StackLink} pageName="add" payload="add" variant="contained" color="primary">
<FormattedMessage id="cometBrevoModule.brevoTestContact.newContact" defaultMessage="New test contact" />
</Button>
<Tooltip title={disableButton ? tooltipMessage : ""}>
<span>
<Button
startIcon={<Add />}
component={StackLink}
pageName="add"
payload="add"
variant="contained"
color="primary"
disabled={disableButton}
>
<FormattedMessage id="cometBrevoModule.brevoTestContact.newContact" defaultMessage="New test contact" />
</Button>
</span>
</Tooltip>
</ToolbarActions>
</Toolbar>
</>
Expand Down Expand Up @@ -172,6 +198,7 @@ export function BrevoTestContactsGrid({
const rowCount = useBufferedRowCount(data?.brevoTestContacts.totalCount);
if (error) throw error;
const rows = data?.brevoTestContacts.nodes ?? [];
const totalCount = data?.brevoTestContacts.totalCount || 0;

return (
<MainContent fullHeight>
Expand All @@ -197,6 +224,7 @@ export function BrevoTestContactsGrid({
toolbar: {
intl,
scope,
totalCount,
},
}}
/>
Expand Down
62 changes: 41 additions & 21 deletions packages/admin/src/emailCampaigns/form/TestEmailCampaignForm.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,65 @@
import { useApolloClient } from "@apollo/client";
import { Field, FinalForm, FinalFormInput, SaveButton } from "@comet/admin";
import { gql, useApolloClient, useQuery } from "@apollo/client";
import { Field, FinalForm, FinalFormSelect, 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 { useContentScope } from "@comet/cms-admin";
import { Card } from "@mui/material";
import React from "react";
import { FormattedMessage } from "react-intl";

import { GQLBrevoTestContactsSelectListFragment } from "./TestEmailCampaignForm.generated";
import { SendEmailCampaignToTestEmailsMutation } from "./TestEmailCampaignForm.gql";
import { GQLSendEmailCampaignToTestEmailsMutation, GQLSendEmailCampaignToTestEmailsMutationVariables } from "./TestEmailCampaignForm.gql.generated";

interface FormProps {
testEmails: string;
testEmails: string[];
}

interface TestEmailCampaignFormProps {
id?: string;
isSendable?: boolean;
}

const brevoTestContactsSelectFragment = gql`
fragment BrevoTestContactsSelectList on BrevoContact {
id
email
}
`;

const brevoTestContactsSelectQuery = gql`
query BrevoTestContactsGridSelect($offset: Int, $limit: Int, $email: String, $scope: EmailCampaignContentScopeInput!) {
brevoTestContacts(offset: $offset, limit: $limit, email: $email, scope: $scope) {
nodes {
...BrevoTestContactsSelectList
}
totalCount
}
}
${brevoTestContactsSelectFragment}
`;

export const TestEmailCampaignForm = ({ id, isSendable = false }: TestEmailCampaignFormProps) => {
const client = useApolloClient();
const scope = useContentScope();

async function submitTestEmails({ testEmails }: FormProps) {
const emailsArray = testEmails.trim().split("\n");
// Contact creation is limited to 100 at a time. Therefore, 100 contacts are queried without using pagination.
const { data, loading, error } = useQuery(brevoTestContactsSelectQuery, {
variables: { offset: 0, limit: 100, scope },
});

async function submitTestEmails({ testEmails }: FormProps) {
if (id) {
const { data } = await client.mutate<GQLSendEmailCampaignToTestEmailsMutation, GQLSendEmailCampaignToTestEmailsMutationVariables>({
mutation: SendEmailCampaignToTestEmailsMutation,
variables: { id, data: { emails: emailsArray } },
variables: { id, data: { emails: testEmails } },
});
return data?.sendEmailCampaignToTestEmails;
}
}

const emailOptions: string[] = data?.brevoTestContacts?.nodes?.map((contact: GQLBrevoTestContactsSelectListFragment) => contact.email) || [];

return (
<Card sx={{ mt: 4 }}>
<AdminComponentPaper>
Expand All @@ -41,33 +68,26 @@ export const TestEmailCampaignForm = ({ id, isSendable = false }: TestEmailCampa
<FormattedMessage id="cometBrevoModule.emailCampaigns.testEmailCampaign.title" defaultMessage="Send test email campaign" />
}
>
<FinalForm<FormProps> mode="edit" onSubmit={submitTestEmails}>
<FinalForm<FormProps> mode="edit" onSubmit={submitTestEmails} initialValues={{ testEmails: [] }}>
{({ handleSubmit, submitting, values }) => {
return (
<>
<Field
component={FinalFormSelect}
name="testEmails"
label={
<FormattedMessage
id="cometBrevoModule.emailCampaigns.testEmailCampaign.testEmails"
defaultMessage="Email addresses"
/>
}
component={FinalFormInput}
multiline
placeholder={["First test email address", "Second test email address"].join("\n")}
fullWidth
minRows={4}
options={emailOptions}
isLoading={loading}
error={!!error}
value={values.testEmails || []}
getOptionLabel={(option: string) => option}
/>
<FormHelperText sx={{ marginTop: -2, marginBottom: 4 }}>
<Typography sx={{ display: "flex", alignItems: "center" }}>
<FormattedMessage
id="cometBrevoModule.emailCampaigns.testEmailCampaign.oneEmailAddressEachLine"
defaultMessage="One email address each line"
/>
</Typography>
<Typography />
</FormHelperText>
<SaveButton
disabled={!values.testEmails || !isSendable || !id}
saveIcon={<Newsletter />}
Expand Down
9 changes: 9 additions & 0 deletions packages/api/src/brevo-api/brevo-api-contact.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ export class BrevoApiContactsService {
}
}

public async getContactCountByListId(id: number, scope: EmailCampaignScopeInterface): Promise<number> {
try {
const data = await this.getContactsApi(scope).getContactsFromList(id);
return data.body.count;
} catch (error) {
handleBrevoError(error);
}
}

public async findContacts(limit: number, offset: number, scope: EmailCampaignScopeInterface): Promise<BrevoContactInterface[]> {
try {
const data = await this.getContactsApi(scope).getContacts(limit, offset);
Expand Down
6 changes: 6 additions & 0 deletions packages/api/src/brevo-contact/brevo-contact.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,12 @@ export function createBrevoContactResolver({
const targetGroup = await this.targetGroupRepository.findOne(where);
const contact = await this.brevoContactsApiService.getContactInfoByEmail(input.email, scope);

if (targetGroup) {
const numberOfContacts = await this.brevoContactsApiService.getContactCountByListId(targetGroup.brevoId, Scope);
if (numberOfContacts >= 100) {
return SubscribeResponse.ERROR_MAXIMAL_NUMBER_OF_TEST_CONTACTS_REACHED;
}
}
if (contact && targetGroup) {
const listIds: number[] = contact.listIds ? [...contact.listIds] : [];
listIds.push(targetGroup.brevoId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export enum SubscribeResponse {
SUCCESSFUL = "SUCCESSFUL",
ERROR_UNKNOWN = "ERROR_UNKNOWN",
ERROR_CONTAINED_IN_ECG_RTR_LIST = "ERROR_CONTAINED_IN_ECG_RTR_LIST",
ERROR_MAXIMAL_NUMBER_OF_TEST_CONTACTS_REACHED = "ERROR_MAXIMAL_NUMBER_OF_TEST_CONTACTS_REACHED",
}

registerEnumType(SubscribeResponse, {
Expand Down

0 comments on commit d32e9e8

Please sign in to comment.