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

741 default instance-wide optout message #882

Merged
merged 5 commits into from
Sep 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions src/api/organization.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const schema = `
people(role: String): [User]
optOuts: [OptOut]
threeClickEnabled: Boolean
optOutMessage: String
textingHoursEnforced: Boolean
textingHoursStart: Int
textingHoursEnd: Int
Expand Down
1 change: 1 addition & 0 deletions src/api/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ const rootSchema = `
editUser(organizationId: String!, userId: Int!, userData:UserInput): User
updateTextingHours( organizationId: String!, textingHoursStart: Int!, textingHoursEnd: Int!): Organization
updateTextingHoursEnforcement( organizationId: String!, textingHoursEnforced: Boolean!): Organization
updateOptOutMessage( organizationId: String!, optOutMessage: String!): Organization
bulkSendMessages(assignmentId: Int!): [CampaignContact]
sendMessage(message:MessageInput!, campaignContactId:String!): CampaignContact,
createOptOut(optOut:OptOutInput!, campaignContactId:String!):CampaignContact,
Expand Down
2 changes: 1 addition & 1 deletion src/containers/AssignmentTexterContact.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export class AssignmentTexterContact extends React.Component {
snackbarError,
snackbarActionTitle,
snackbarOnTouchTap,
optOutMessageText: window.OPT_OUT_MESSAGE,
optOutMessageText: campaign.organization.optOutMessage,
responsePopoverOpen: false,
messageText: this.getStartingMessageText(),
optOutDialogOpen: false,
Expand Down
46 changes: 44 additions & 2 deletions src/containers/Settings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,9 @@ class Settings extends React.Component {

handleCloseTextingHoursDialog = () => this.setState({ textingHoursDialogOpen: false })


renderTextingHoursForm() {
const { organization } = this.props.data
const { textingHoursStart, textingHoursEnd } = organization

const formSchema = yup.object({
textingHoursStart: yup.number().required(),
textingHoursEnd: yup.number().required()
Expand Down Expand Up @@ -114,12 +112,41 @@ class Settings extends React.Component {

render() {
const { organization } = this.props.data
const {optOutMessage } = organization
const formSchema = yup.object({
optOutMessage: yup.string().required()
})

return (
<div>
<Card>
<CardHeader
title='Settings'
/>
<CardText>
<div className={css(styles.section)}>

<GSForm
schema={formSchema}
onSubmit={this.props.mutations.updateOptOutMessage}
defaultValue={{ optOutMessage }}
>

<Form.Field
label='Default Opt-Out Message'
name='optOutMessage'
Copy link
Contributor

Choose a reason for hiding this comment

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

can we add the prop fullWidth here so the user can see the full message (versus having to scroll within the form field) ?

fullWidth
/>

<Form.Button
type='submit'
label={this.props.saveLabel || 'Save Opt-Out Message'}
/>

</GSForm>
</div>
</CardText>

<CardText>
<div className={css(styles.section)}>
<span className={css(styles.sectionLabel)}>
Expand Down Expand Up @@ -199,7 +226,21 @@ const mapMutationsToProps = ({ ownProps }) => ({
organizationId: ownProps.params.organizationId,
textingHoursEnforced
}
}),
updateOptOutMessage: ({optOutMessage}) => ({
mutation: gql`
mutation updateOptOutMessage($optOutMessage: String!, $organizationId: String!) {
updateOptOutMessage(optOutMessage: $optOutMessage, organizationId: $organizationId) {
id
optOutMessage
}
}`,
variables: {
organizationId: ownProps.params.organizationId,
optOutMessage
}
})

})

const mapQueriesToProps = ({ ownProps }) => ({
Expand All @@ -211,6 +252,7 @@ const mapQueriesToProps = ({ ownProps }) => ({
textingHoursEnforced
textingHoursStart
textingHoursEnd
optOutMessage
}
}`,
variables: {
Expand Down
1 change: 1 addition & 0 deletions src/containers/TexterTodo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const mapQueriesToProps = ({ ownProps }) => ({
textingHoursStart
textingHoursEnd
threeClickEnabled
optOutMessage
}
customFields
interactionSteps {
Expand Down
1 change: 1 addition & 0 deletions src/server/api/organization.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const resolvers = {
},
threeClickEnabled: (organization) => organization.features.indexOf('threeClick') !== -1,
textingHoursEnforced: (organization) => organization.texting_hours_enforced,
optOutMessage: (organization) => (organization.features.indexOf('opt_out_message') !== -1 ? JSON.parse(organization.features).opt_out_message : process.env.OPT_OUT_MESSAGE) || 'I\'m opting you out of texts immediately. Have a great day.',
textingHoursStart: (organization) => organization.texting_hours_start,
textingHoursEnd: (organization) => organization.texting_hours_end
}
Expand Down
16 changes: 16 additions & 0 deletions src/server/api/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,22 @@ const rootMutations = {

return await Organization.get(organizationId)
},
updateOptOutMessage: async (
_,
{ organizationId, optOutMessage },
{ user }
) => {
await accessRequired(user, organizationId, 'OWNER')

const organization = await Organization.get(organizationId)
const featuresJSON = JSON.parse(organization.features || '{}')
featuresJSON.opt_out_message = optOutMessage
organization.features = JSON.stringify(featuresJSON)

await organization.save()

return await Organization.get(organizationId)
},
createInvite: async (_, { user }) => {
if ((user && user.is_superadmin) || !process.env.SUPPRESS_SELF_INVITE) {
const inviteInstance = new Invite({
Expand Down
1 change: 0 additions & 1 deletion src/server/middleware/render-index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ export default function renderIndex(html, css, assetMap, store) {
window.BASE_URL="${process.env.BASE_URL || ''}"
window.NOT_IN_USA=${process.env.NOT_IN_USA || 0}
window.ALLOW_SEND_ALL=${process.env.ALLOW_SEND_ALL || 0}
window.OPT_OUT_MESSAGE="${process.env.OPT_OUT_MESSAGE || 'I\'m opting you out of texts immediately. Have a great day.'}"
window.BULK_SEND_CHUNK_SIZE=${process.env.BULK_SEND_CHUNK_SIZE || 0}
window.MAX_MESSAGE_LENGTH=${process.env.MAX_MESSAGE_LENGTH || 99999}
window.TERMS_REQUIRE="${process.env.TERMS_REQUIRE || ''}"
Expand Down