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

feat(campaign-exports): send one email after multiple campaign exports #1661

Open
wants to merge 33 commits into
base: main
Choose a base branch
from

Conversation

henryk1229
Copy link
Contributor

@henryk1229 henryk1229 commented Aug 11, 2023

Description

This pr refactors the export-multiple-campaigns task so that when admins export multiple campaigns at once, only one email is sent to them, with links for each campaign exported. It branches off of #1641 - that should be reviewed and merged first, then we can rebase and review this pr more easily.

Motivation and Context

It closes #1660

How Has This Been Tested?

Locally, and with mailtrap

Screenshots (if appropriate):

Documentation Changes

Checklist:

  • My change requires a change to the documentation.
  • I have included updates for the documentation accordingly.

@henryk1229 henryk1229 marked this pull request as ready for review September 12, 2023 15:43
Copy link
Member

@bchrobot bchrobot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@@ -215,6 +215,11 @@ const rootSchema = `
vanOptions: ExportForVanInput
}

input MultipleCampaignExportInput {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: fix indentation

Suggested change
input MultipleCampaignExportInput {
input MultipleCampaignExportInput {


const [exportCampaignsMutation] = useExportCampaignsMutation();

const handleChange = (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: rename to handleChangeFactory to make it clear that this creates handlers rather than handling change itself

open: boolean;
onClose: () => void;
onError: (errorMessage: string) => void;
onComplete(): void;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: consistent function typing

Suggested change
onComplete(): void;
onComplete: () => void;

Comment on lines +102 to +121
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>
);
Copy link
Member

Choose a reason for hiding this comment

The 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
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>
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: pull this up into its own component

};
});

// map fetched export urls to campaignMetaData
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove extra space

Suggested change
// map fetched export urls to campaignMetaData
// map fetched export urls to campaignMetaData

campaignExport.exportUrls;
}

try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: what is the try / finally here accomplishing? The finally block will be executed even if an error is thrown in try but in this case the finally block is logging a success?

Comment on lines +103 to +104
// wait for all campaign exports to process
const exportsStillProcessing = rows.length !== campaignIds.length;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: create a new issue for handling errors in bulk-export-campaigns child jobs and link here as future work?

My understanding is that if a bulk-export-campaigns job encounters a terminal failure and never reaches status = 100 then email-export-campaigns will just keep running every 4 minutes?

control={
<Switch
checked={exportCampaign}
onChange={handleChange(setExportCampaign)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Required: move the handleChange() factory to the parent component and only pass down the setExport* callbacks as props

</InputAdornment>
)
}}
onChange={(ev) => debounceSearchTerm(ev.target.value)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: prefer named callback function

@@ -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!) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: move mutations to be below queries

import Alert from "@material-ui/lab/Alert";
import React from "react";

interface Props {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required: export props, and name ExportCampaignDataSnackbarProps, more details in https://github.com/politics-rewired/Spoke/blob/main/conventions.md

id: string;
title: string;
};
interface Props {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required: export props, and name ExportMultipleCampaignDataDialogProps, more details in https://github.com/politics-rewired/Spoke/blob/main/conventions.md

@@ -4,6 +4,7 @@ import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: update file to tsx, and functional component

@@ -19,6 +19,79 @@ interface CampaignExportModalProps {
onComplete(): void;
}

interface CampaignExportModalContentProps {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required: export props

status: string;
};

interface CampaignHeaderProps {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required: export props


const DEBOUNCE_INTERVAL = 500;

interface Props {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required: export props, update name


interface Props {
interface Props extends CampaignOperations {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required: export props, update name

export const isCampaignGroupsPermissionError = (gqlError: GraphQLError) => {
return (
gqlError.path &&
gqlError.path[gqlError.path.length - 1] === "campaignGroups" &&
gqlError.extensions.code === "FORBIDDEN"
);
};

type MakeCampaignTagsFn = (props: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required: use interface for props, export, and update name

[id: string]: CampaignExportDetails;
};

interface Props {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required: export props, update name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

campaign-exports: send one email per bulk export operation
4 participants