Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

COM-964 Add multiselect to choose test contacts (Depends on: #78) #101

Draft
wants to merge 51 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
695545f
add test-contacts page in admin
Aug 26, 2024
63bd0a3
add service for creating a test list, if it doesn't exist yet
Aug 28, 2024
2cbe582
add service for creating a test contact
Aug 28, 2024
b1331ee
add brevoTestContacts resolver
Aug 28, 2024
c4cc0b1
create BrevoTestContactsPage
Aug 28, 2024
771377b
generate schema
Aug 28, 2024
480872b
add check if contacts are manuallyAssigned in checkIfContactIsInTarge…
Aug 29, 2024
be3d7c6
correct imports of gql types
Aug 29, 2024
4abc9db
do not display test list in target groups
Aug 29, 2024
07c8bbe
remove possibility to block a test contact from BrevoTestContactsGrid
Aug 30, 2024
54c8df9
add column isTestList and check for its value instead of using the title
Aug 30, 2024
e9908c1
filter targetGroups
Aug 30, 2024
dcf1553
add alert to test contact page
Aug 30, 2024
044a76f
remove unneccessary functions and correct messages
Aug 30, 2024
a925614
if contact exists update contact when creating a test contact
Sep 2, 2024
cc42326
add delete functions
Sep 2, 2024
b13d3be
fix checkIfContactIsInTargetGroup by checking by attributes
Sep 3, 2024
fbeba8f
refactor BrevoTestContactInput
Sep 3, 2024
177dcf4
fix input2state
Sep 10, 2024
3383910
pass [testTargetGroupForScope.brevoId] directly instead of using a va…
Sep 11, 2024
b200c40
remove unused assignedContactsTargetGroupBrevoId
Sep 11, 2024
ddd0d1a
remove comment in BrevoContactForm
Sep 11, 2024
0228014
remove targetId from brevoTestContacts query
Sep 11, 2024
c479a82
correct migration to not nullable and default false
Sep 11, 2024
0f06467
refactor initialValues in BrevoContactForm and BrevoTestContactForm
Sep 11, 2024
b70810e
drop default after setting all rows to false
Sep 17, 2024
451562a
re-add optional to values in input2State
Sep 17, 2024
9a7f2b3
add changeset
Sep 17, 2024
840dbf6
correct changeset
Sep 17, 2024
563adf5
replace BaseBrevoContactFormvalues with EditBrevoContactFormValuesWit…
Sep 19, 2024
7610abf
add scope to test list name
Sep 23, 2024
2670c81
correct naming
Sep 23, 2024
4cf161e
correct migration
Sep 25, 2024
5a1b538
use stringify for test list name
Sep 25, 2024
e5a45fe
correct major to minor version in changeset
Sep 27, 2024
f72fdf0
fix migration
Sep 27, 2024
3cef417
use IsUndefinable() decorator instead of IsOptional()
Sep 27, 2024
abab3a9
correct filter value in TargetGroupsGrid
Sep 27, 2024
c9a0e63
correct check in which contact is included for deleting testContacts
Oct 1, 2024
3112855
add isTestList to targetGroupService
Oct 1, 2024
28dc9e2
Merge branch 'main' into add-test-contact-list
Oct 16, 2024
1461f67
fix brevo contact resolver by returning false if no contact is found
Oct 16, 2024
f8412a1
add check if contact is in test list for updating contacts
Oct 18, 2024
e5badee
add permission for test contacts
Oct 18, 2024
d728211
re-add branch to input2State
Oct 18, 2024
51c898c
remove isTestList from TargetGroupsGrid query
Oct 18, 2024
fd436ca
re-add gqlFilter to TargetGroupsGrid
Oct 28, 2024
205b281
add filter for isTestList in TargetGroups
Oct 28, 2024
ebfe653
remove custom filter logic
Nov 4, 2024
1e2790a
refactor testEmail field from textfield to selectfield
Sep 25, 2024
fbd842d
add changeset
Sep 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/chilly-dogs-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@comet/brevo-admin": minor
"@comet/brevo-api": minor
---

Adds `createBrevoTestContactsPage` for creating a test contacts page, that is indepent from the main list.

Remove `email` and `redirectionUrl` from `brevoContactsPageAttributesConfig`
5 changes: 5 additions & 0 deletions .changeset/nice-rings-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@comet/brevo-admin": minor
---

Replace the TextField input for adding contacts with a FinalFormSelect component, allowing users to choose contacts directly from the TestContactList
11 changes: 10 additions & 1 deletion demo/admin/src/Routes.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MasterLayout, RouteWithErrorBoundary } from "@comet/admin";
import { Domain } from "@comet/admin-icons";
import { createBrevoContactsPage, createEmailCampaignsPage, createTargetGroupsPage } from "@comet/brevo-admin";
import { createBrevoContactsPage, createBrevoTestContactsPage, createEmailCampaignsPage, createTargetGroupsPage } from "@comet/brevo-admin";
import { ContentScopeIndicator, createRedirectsPage, DamPage, PagesPage, PublisherPage, SitePreview } from "@comet/cms-admin";
import { getBrevoContactConfig } from "@src/common/brevoModuleConfig/brevoContactsPageAttributesConfig";
import { pageTreeCategories, urlParamToCategory } from "@src/pageTree/pageTreeCategories";
Expand Down Expand Up @@ -33,6 +33,14 @@ export const Routes: React.FC = () => {
input2State: brevoContactConfig.input2State,
});

const BrevoTestContactsPage = createBrevoTestContactsPage({
scopeParts: ["domain", "language"],
additionalAttributesFragment: brevoContactConfig.additionalAttributesFragment,
additionalGridFields: brevoContactConfig.additionalGridFields,
additionalFormFields: brevoContactConfig.additionalFormFields,
input2State: brevoContactConfig.input2State,
});

const TargetGroupsPage = createTargetGroupsPage({
scopeParts: ["domain", "language"],
additionalFormFields: additionalFormConfig.additionalFormFields,
Expand Down Expand Up @@ -94,6 +102,7 @@ export const Routes: React.FC = () => {
/>

<RouteWithErrorBoundary path={`${match.path}/newsletter/contacts`} component={BrevoContactsPage} />
<RouteWithErrorBoundary path={`${match.path}/newsletter/test-contacts`} component={BrevoTestContactsPage} />
<RouteWithErrorBoundary path={`${match.path}/newsletter/target-groups`} component={TargetGroupsPage} />
<RouteWithErrorBoundary path={`${match.path}/newsletter/email-campaigns`} component={EmailCampaignsPage} />

Expand Down
4 changes: 4 additions & 0 deletions demo/admin/src/common/MasterMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ export const MasterMenu: React.FC = () => {
primary={intl.formatMessage({ id: "menu.newsletter.contacts", defaultMessage: "Contacts" })}
to={`${match.url}/newsletter/contacts`}
/>
<MenuItemRouterLink
primary={intl.formatMessage({ id: "menu.newsletter.testContacts", defaultMessage: "Test contacts" })}
to={`${match.url}/newsletter/test-contacts`}
/>
<MenuItemRouterLink
primary={intl.formatMessage({ id: "menu.newsletter.targetGroups", defaultMessage: "Target groups" })}
to={`${match.url}/newsletter/target-groups`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ export const getBrevoContactConfig = (
name: string;
};
input2State: (values?: AdditionalFormConfigInputProps) => {
email: string;
redirectionUrl: string;
attributes: { BRANCH?: Array<GQLBrevoContactBranch>; SALUTATION?: GQLBrevoContactSalutation; FIRSTNAME?: string; LASTNAME?: string };
};
exportFields: {
Expand Down Expand Up @@ -140,8 +138,6 @@ export const getBrevoContactConfig = (
),
input2State: (values?: AdditionalFormConfigInputProps) => {
return {
email: values?.email ?? "",
redirectionUrl: values?.redirectionUrl ?? "",
attributes: {
BRANCH: values?.attributes?.BRANCH ?? [],
SALUTATION: values?.attributes?.SALUTATION,
Expand Down
11 changes: 11 additions & 0 deletions demo/api/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ type TargetGroup implements DocumentInterface {
createdAt: DateTime!
title: String!
isMainList: Boolean!
isTestList: Boolean!
brevoId: Int!
totalSubscribers: Int!
totalContactsBlocked: Int!
Expand Down Expand Up @@ -528,6 +529,7 @@ type Query {
mainMenu(scope: PageTreeNodeScopeInput!): [PageTreeNode!]!
brevoContact(id: Int!, scope: EmailCampaignContentScopeInput!): BrevoContact!
brevoContacts(targetGroupId: ID, email: String, scope: EmailCampaignContentScopeInput!, offset: Int! = 0, limit: Int! = 25): PaginatedBrevoContacts!
brevoTestContacts(targetGroupId: ID, email: String, scope: EmailCampaignContentScopeInput!, offset: Int! = 0, limit: Int! = 25): PaginatedBrevoContacts!
manuallyAssignedBrevoContacts(offset: Int! = 0, limit: Int! = 25, targetGroupId: ID!, email: String): PaginatedBrevoContacts!
emailCampaign(id: ID!): EmailCampaign!
emailCampaigns(scope: EmailCampaignContentScopeInput!, search: String, filter: EmailCampaignFilter, sort: [EmailCampaignSort!], offset: Int! = 0, limit: Int! = 25): PaginatedEmailCampaigns!
Expand Down Expand Up @@ -687,6 +689,7 @@ input TargetGroupFilter {
createdAt: DateFilter
updatedAt: DateFilter
title: StringFilter
isTestList: BooleanFilter
and: [TargetGroupFilter!]
or: [TargetGroupFilter!]
}
Expand Down Expand Up @@ -739,7 +742,9 @@ type Mutation {
deleteDamFolder(id: ID!): Boolean!
updateBrevoContact(id: Int!, scope: EmailCampaignContentScopeInput!, input: BrevoContactUpdateInput!): BrevoContact!
createBrevoContact(scope: EmailCampaignContentScopeInput!, input: BrevoContactInput!): SubscribeResponse!
createBrevoTestContact(scope: EmailCampaignContentScopeInput!, input: BrevoTestContactInput!): SubscribeResponse!
deleteBrevoContact(id: Int!, scope: EmailCampaignContentScopeInput!): Boolean!
deleteBrevoTestContact(id: Int!, scope: EmailCampaignContentScopeInput!): Boolean!
subscribeBrevoContact(input: SubscribeInput!, scope: EmailCampaignContentScopeInput!): SubscribeResponse!
createEmailCampaign(scope: EmailCampaignContentScopeInput!, input: EmailCampaignInput!): EmailCampaign!
updateEmailCampaign(id: ID!, input: EmailCampaignUpdateInput!, lastUpdatedAt: DateTime): EmailCampaign!
Expand Down Expand Up @@ -896,6 +901,12 @@ input BrevoContactInput {
attributes: BrevoContactAttributesInput
}

input BrevoTestContactInput {
email: String!
blocked: Boolean!
attributes: BrevoContactAttributesInput
}

input SubscribeInput {
email: String!
redirectionUrl: String!
Expand Down
38 changes: 22 additions & 16 deletions packages/admin/src/brevoContacts/form/BrevoContactForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ import {
} from "./BrevoContactForm.gql.generated";

export type EditBrevoContactFormValues = {
[key: string]: unknown;
};

type EditBrevoContactFormValuesWithAttributes = EditBrevoContactFormValues & {
email: string;
redirectionUrl: string;
[key: string]: unknown;
};

interface FormProps {
Expand All @@ -59,14 +62,11 @@ export function BrevoContactForm({ id, scope, input2State, additionalFormFields,
const stackApi = useStackApi();
const client = useApolloClient();
const mode = id ? "edit" : "add";
const formApiRef = useFormApiRef<EditBrevoContactFormValues>();
const formApiRef = useFormApiRef<EditBrevoContactFormValuesWithAttributes>();

const brevoContactFormFragment = gql`
fragment BrevoContactForm on BrevoContact {
email
createdAt
emailBlacklisted
smsBlacklisted
${additionalAttributesFragment ? "...".concat(additionalAttributesFragment?.name) : ""}
}
${additionalAttributesFragment?.fragment ?? ""}
Expand All @@ -76,18 +76,20 @@ export function BrevoContactForm({ id, scope, input2State, additionalFormFields,
id ? { variables: { id, scope } } : { skip: true },
);

const initialValues = React.useMemo<Partial<EditBrevoContactFormValues>>(() => {
let additionalInitialValues = {};
const initialValues = React.useMemo<Partial<EditBrevoContactFormValuesWithAttributes>>(() => {
let baseInitialValues = {
email: "",
redirectionUrl: "",
};

if (input2State) {
additionalInitialValues = input2State({ email: "", redirectionUrl: "", ...data?.brevoContact });
baseInitialValues = {
...baseInitialValues,
...input2State(data?.brevoContact),
};
}
return data?.brevoContact
? {
email: data.brevoContact.email,
...additionalInitialValues,
}
: additionalInitialValues;

return data?.brevoContact?.email ? { ...baseInitialValues, email: data.brevoContact.email } : baseInitialValues;
}, [data?.brevoContact, input2State]);

const saveConflict = useFormSaveConflict({
Expand All @@ -112,7 +114,11 @@ export function BrevoContactForm({ id, scope, input2State, additionalFormFields,
},
});

const handleSubmit = async (state: EditBrevoContactFormValues, form: FormApi<EditBrevoContactFormValues>, event: FinalFormSubmitEvent) => {
const handleSubmit = async (
state: EditBrevoContactFormValuesWithAttributes,
form: FormApi<EditBrevoContactFormValuesWithAttributes>,
event: FinalFormSubmitEvent,
) => {
if (await saveConflict.checkForConflicts()) {
throw new Error("Conflicts detected");
}
Expand Down Expand Up @@ -159,7 +165,7 @@ export function BrevoContactForm({ id, scope, input2State, additionalFormFields,
}

return (
<FinalForm<EditBrevoContactFormValues> apiRef={formApiRef} onSubmit={handleSubmit} mode={mode} initialValues={initialValues}>
<FinalForm<EditBrevoContactFormValuesWithAttributes> apiRef={formApiRef} onSubmit={handleSubmit} mode={mode} initialValues={initialValues}>
{({ values }) => (
<EditPageLayout>
{saveConflict.dialogs}
Expand Down
Loading
Loading