-
Notifications
You must be signed in to change notification settings - Fork 17
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
feat(campaign-exports): send one email after multiple campaign exports #1661
base: main
Are you sure you want to change the base?
Changes from 31 commits
7dea763
2977ef0
bb4ea78
a79b4ef
3aae8c5
506b02d
10a567e
99abef1
ddc3d28
7f19a3d
ee721c1
cea4766
bef6de3
4add064
67ac4d3
4807092
ebd991a
d14b20c
e847c34
abb78ff
7ef2246
b5bc27a
45ea951
338b169
dd93365
b8348d0
16c9467
3c541f1
f8c9de5
1ed058b
46db8cc
e6d2859
9eb66c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,8 +63,22 @@ mutation ExportCampaign($options: CampaignExportInput!) { | |
} | ||
} | ||
|
||
mutation CopyCampaigns($templateId: String!, $quantity: Int!, $targetOrgId: String) { | ||
copyCampaigns(sourceCampaignId: $templateId, quantity: $quantity, targetOrgId: $targetOrgId) { | ||
mutation ExportCampaigns($options: MultipleCampaignExportInput!) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: move mutations to be below queries |
||
exportCampaigns(options: $options) { | ||
id | ||
} | ||
} | ||
|
||
mutation CopyCampaigns( | ||
$templateId: String! | ||
$quantity: Int! | ||
$targetOrgId: String | ||
) { | ||
copyCampaigns( | ||
sourceCampaignId: $templateId | ||
quantity: $quantity | ||
targetOrgId: $targetOrgId | ||
) { | ||
id | ||
} | ||
} | ||
|
@@ -82,7 +96,6 @@ query GetCampaignSyncConfigs($campaignId: String!) { | |
} | ||
} | ||
|
||
|
||
query GetSyncTargets($campaignId: String!) { | ||
campaign(id: $campaignId) { | ||
id | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import Snackbar from "@material-ui/core/Snackbar"; | ||
import Alert from "@material-ui/lab/Alert"; | ||
import React from "react"; | ||
|
||
interface Props { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. required: export props, and name |
||
open: boolean; | ||
errorMessage: string | null; | ||
onClose: () => void; | ||
} | ||
|
||
const ExportCampaignDataSnackbar: React.FC<Props> = ({ | ||
open, | ||
errorMessage, | ||
onClose | ||
}) => { | ||
return errorMessage ? ( | ||
<Snackbar open={open} autoHideDuration={5000} onClose={onClose}> | ||
<Alert severity="error">{errorMessage}</Alert> | ||
</Snackbar> | ||
) : ( | ||
<Snackbar | ||
open={open} | ||
message="Exports started - we'll e-mail you when they're done" | ||
autoHideDuration={5000} | ||
onClose={onClose} | ||
/> | ||
); | ||
}; | ||
|
||
export default ExportCampaignDataSnackbar; |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,140 @@ | ||||||
import Button from "@material-ui/core/Button"; | ||||||
import Dialog from "@material-ui/core/Dialog"; | ||||||
import DialogActions from "@material-ui/core/DialogActions"; | ||||||
import DialogContent from "@material-ui/core/DialogContent"; | ||||||
import DialogContentText from "@material-ui/core/DialogContentText"; | ||||||
import DialogTitle from "@material-ui/core/DialogTitle"; | ||||||
import Divider from "@material-ui/core/Divider"; | ||||||
import Typography from "@material-ui/core/Typography"; | ||||||
import { useExportCampaignsMutation } from "@spoke/spoke-codegen"; | ||||||
import React, { useState } from "react"; | ||||||
|
||||||
import { CampaignExportModalContent } from "../containers/AdminCampaignStats/components/CampaignExportModal"; | ||||||
|
||||||
export type CampaignDetailsForExport = { | ||||||
id: string; | ||||||
title: string; | ||||||
}; | ||||||
interface Props { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. required: export props, and name |
||||||
campaignDetailsForExport: CampaignDetailsForExport[]; | ||||||
open: boolean; | ||||||
onClose: () => void; | ||||||
onError: (errorMessage: string) => void; | ||||||
onComplete(): void; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: consistent function typing
Suggested change
|
||||||
} | ||||||
|
||||||
const ExportMultipleCampaignDataDialog: React.FC<Props> = ({ | ||||||
campaignDetailsForExport, | ||||||
open, | ||||||
onClose, | ||||||
onError, | ||||||
onComplete | ||||||
}) => { | ||||||
const [exportCampaign, setExportCampaign] = useState<boolean>(true); | ||||||
const [exportMessages, setExportMessages] = useState<boolean>(true); | ||||||
const [exportOptOut, setExportOptOut] = useState<boolean>(false); | ||||||
const [exportFiltered, setExportFiltered] = useState<boolean>(false); | ||||||
|
||||||
const [exportCampaignsMutation] = useExportCampaignsMutation(); | ||||||
|
||||||
const handleChange = ( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: rename to |
||||||
setStateFunction: React.Dispatch<React.SetStateAction<boolean>> | ||||||
) => (event: React.ChangeEvent<HTMLInputElement>) => { | ||||||
setStateFunction(event.target.checked); | ||||||
}; | ||||||
|
||||||
const handleExportClick = async () => { | ||||||
const campaignIds = campaignDetailsForExport.map( | ||||||
(campaign: CampaignDetailsForExport) => campaign.id | ||||||
); | ||||||
const result = await exportCampaignsMutation({ | ||||||
variables: { | ||||||
options: { | ||||||
campaignIds, | ||||||
spokeOptions: { | ||||||
campaign: exportCampaign, | ||||||
messages: exportMessages, | ||||||
optOuts: exportOptOut, | ||||||
filteredContacts: exportFiltered | ||||||
} | ||||||
} | ||||||
} | ||||||
}); | ||||||
if (result.errors) { | ||||||
const message = result.errors.map((e) => e.message).join(", "); | ||||||
return onError(message); | ||||||
} | ||||||
onComplete(); | ||||||
}; | ||||||
|
||||||
return ( | ||||||
<Dialog | ||||||
onClose={onClose} | ||||||
aria-labelledby="export-multiple-campaign-data" | ||||||
open={open} | ||||||
fullWidth | ||||||
maxWidth="sm" | ||||||
> | ||||||
<DialogTitle id="export-multiple-campaign-data"> | ||||||
<Typography variant="h6" style={{ margin: "4px", cursor: "pointer" }}> | ||||||
Export Campaigns | ||||||
</Typography> | ||||||
</DialogTitle> | ||||||
<CampaignExportModalContent | ||||||
exportCampaign={exportCampaign} | ||||||
exportMessages={exportMessages} | ||||||
exportOptOut={exportOptOut} | ||||||
exportFiltered={exportFiltered} | ||||||
handleChange={handleChange} | ||||||
setExportCampaign={setExportCampaign} | ||||||
setExportMessages={setExportMessages} | ||||||
setExportOptOut={setExportOptOut} | ||||||
setExportFiltered={setExportFiltered} | ||||||
/> | ||||||
<Divider variant="middle" /> | ||||||
<DialogContent> | ||||||
<DialogContentText> | ||||||
<Typography variant="subtitle1" style={{ margin: "4px" }}> | ||||||
Selected campaigns: | ||||||
</Typography> | ||||||
{campaignDetailsForExport.map( | ||||||
(campaign: CampaignDetailsForExport) => { | ||||||
return ( | ||||||
<div | ||||||
key={campaign.id} | ||||||
style={{ | ||||||
display: "flex", | ||||||
alignItems: "center", | ||||||
margin: "4px" | ||||||
}} | ||||||
> | ||||||
<Typography variant="body1" style={{ margin: "4px" }}> | ||||||
{campaign.title} | ||||||
</Typography> | ||||||
<Typography | ||||||
variant="body1" | ||||||
style={{ marginLeft: "4px", color: "#666666" }} | ||||||
> | ||||||
ID: {campaign.id} | ||||||
</Typography> | ||||||
</div> | ||||||
); | ||||||
Comment on lines
+102
to
+121
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: pull this up into its own component
Comment on lines
+102
to
+121
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: pull this up into its own component |
||||||
} | ||||||
)} | ||||||
</DialogContentText> | ||||||
</DialogContent> | ||||||
<DialogActions> | ||||||
<Button onClick={onClose}>Cancel</Button> | ||||||
<Button | ||||||
color="primary" | ||||||
disabled={campaignDetailsForExport.length < 1} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: pull |
||||||
onClick={handleExportClick} | ||||||
> | ||||||
Export data | ||||||
</Button> | ||||||
</DialogActions> | ||||||
</Dialog> | ||||||
); | ||||||
}; | ||||||
|
||||||
export default ExportMultipleCampaignDataDialog; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: fix indentation