From cba18edc95dc7874a74a74d118199c2e22b1e8c3 Mon Sep 17 00:00:00 2001 From: Nikola Ubavic <53820106+ubavic@users.noreply.github.com> Date: Mon, 7 Mar 2022 23:42:29 +0100 Subject: [PATCH 1/5] feat: twilio setup in notifications --- .../src/pages/Notifications/Notifications.js | 48 ++++++++++++- .../src/pages/Notifications/sections/Setup.js | 72 +++++++++++++++---- 2 files changed, 107 insertions(+), 13 deletions(-) diff --git a/new-lamassu-admin/src/pages/Notifications/Notifications.js b/new-lamassu-admin/src/pages/Notifications/Notifications.js index df3dfbcc..b1def515 100644 --- a/new-lamassu-admin/src/pages/Notifications/Notifications.js +++ b/new-lamassu-admin/src/pages/Notifications/Notifications.js @@ -3,7 +3,11 @@ import gql from 'graphql-tag' import * as R from 'ramda' import React, { useState } from 'react' +import Modal from 'src/components/Modal' import TitleSection from 'src/components/layout/TitleSection' +import { P } from 'src/components/typography' +import FormRenderer from 'src/pages/Services/FormRenderer' +import twilioSchema from 'src/pages/Services/schemas/twilio' import { fromNamespace, toNamespace, namespaces } from 'src/utils/config' import Section from '../../components/layout/Section' @@ -28,6 +32,7 @@ const GET_INFO = gql` code display } + accounts } ` @@ -37,6 +42,12 @@ const SAVE_CONFIG = gql` } ` +const SAVE_ACCOUNT = gql` + mutation Save($accounts: JSONObject) { + saveAccounts(accounts: $accounts) + } +` + const FIELDS_WIDTH = 130 const Notifications = ({ @@ -52,6 +63,7 @@ const Notifications = ({ const [section, setSection] = useState(null) const [error, setError] = useState(null) const [editingKey, setEditingKey] = useState(null) + const [smsSetupPopup, setSmsSetupPopup] = useState(false) const { data, loading } = useQuery(GET_INFO) @@ -61,9 +73,16 @@ const Notifications = ({ onError: error => setError(error) }) + const [saveAccount] = useMutation(SAVE_ACCOUNT, { + onCompleted: () => setSmsSetupPopup(false), + refetchQueries: ['getData'], + onError: error => setError(error) + }) + const config = fromNamespace(SCREEN_KEY)(data?.config) const machines = data?.machines const cryptoCurrencies = data?.cryptoCurrencies + const twilioAvailable = R.has('twilio', data?.accounts || {}) const currency = R.path(['fiatCurrency'])( fromNamespace(namespaces.LOCALE)(data?.config) @@ -83,6 +102,14 @@ const Notifications = ({ setEditingKey(state ? key : null) } + const twilioSave = it => { + setError(null) + R.compose(save(null), toNamespace('sms'))({ active: true }) + return saveAccount({ + variables: { accounts: { twilio: it } } + }) + } + const isEditing = key => editingKey === key const isDisabled = key => editingKey && editingKey !== key @@ -97,7 +124,9 @@ const Notifications = ({ setEditing, setSection, machines, - cryptoCurrencies + cryptoCurrencies, + twilioAvailable, + setSmsSetupPopup } return ( @@ -140,6 +169,23 @@ const Notifications = ({ )} )} + {smsSetupPopup && ( + setSmsSetupPopup(false)} + open={true}> +

+ In order for the SMS notifications to work, you'll first need to + configure Twilio. +

+ +
+ )} ) ) diff --git a/new-lamassu-admin/src/pages/Notifications/sections/Setup.js b/new-lamassu-admin/src/pages/Notifications/sections/Setup.js index 2cef2b38..a56f2221 100644 --- a/new-lamassu-admin/src/pages/Notifications/sections/Setup.js +++ b/new-lamassu-admin/src/pages/Notifications/sections/Setup.js @@ -26,25 +26,33 @@ const sizes = { active: 263 } -const Row = ({ namespace, forceDisable, shouldUpperCase }) => { - const { data: rawData, save: rawSave } = useContext(NotificationsCtx) - - const save = R.compose(rawSave(null), toNamespace(namespace)) - const data = fromNamespace(namespace)(rawData) - +const Row = ({ + namespace, + data, + forceDisable, + save, + shouldUpperCase, + onActivation +}) => { const disabled = forceDisable || !data || !data.active const Cell = ({ name, disabled }) => { const value = !!(data && data[name]) + const onChange = event => { + if (name === 'active' && value === false) { + if (!onActivation()) return + } + + save({ [name]: event.target.checked }) + } + return ( { - save({ [name]: event.target.checked }) - }} + onChange={onChange} value={value} /> @@ -71,7 +79,40 @@ const useStyles = makeStyles({ width: 930 } }) + const Setup = ({ wizard, forceDisable }) => { + const { + data: rawData, + save: rawSave, + twilioAvailable, + setSmsSetupPopup + } = useContext(NotificationsCtx) + + const namespaces = [ + { + name: 'email', + forceDisable: forceDisable, + shouldUpperCase: false, + onActivation: () => true + }, + { + name: 'sms', + forceDisable: forceDisable, + shouldUpperCase: true, + onActivation: () => { + if (twilioAvailable) return true + setSmsSetupPopup(true) + return false + } + }, + { + name: 'notificationCenter', + forceDisable: forceDisable, + shouldUpperCase: false, + onActivation: () => true + } + ] + const widthAdjust = wizard ? 20 : 0 const classes = useStyles() return ( @@ -85,9 +126,16 @@ const Setup = ({ wizard, forceDisable }) => { ))} - - - + {namespaces.map(namespace => ( + + ))} ) From 4517a373cc3cdec20a2379d8ad4a1c46b028f4c4 Mon Sep 17 00:00:00 2001 From: Nikola Ubavic <53820106+ubavic@users.noreply.github.com> Date: Tue, 8 Mar 2022 13:04:20 +0100 Subject: [PATCH 2/5] feat: twilio setup in compliance --- .../src/pages/Triggers/Triggers.js | 54 ++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/new-lamassu-admin/src/pages/Triggers/Triggers.js b/new-lamassu-admin/src/pages/Triggers/Triggers.js index 525134b5..7ba90185 100644 --- a/new-lamassu-admin/src/pages/Triggers/Triggers.js +++ b/new-lamassu-admin/src/pages/Triggers/Triggers.js @@ -5,11 +5,14 @@ import gql from 'graphql-tag' import * as R from 'ramda' import React, { useState } from 'react' +import Modal from 'src/components/Modal' import { HoverableTooltip } from 'src/components/Tooltip' -import { Link } from 'src/components/buttons' +import { Link, SupportLinkButton } from 'src/components/buttons' import { Switch } from 'src/components/inputs' import TitleSection from 'src/components/layout/TitleSection' import { P, Label2 } from 'src/components/typography' +import FormRenderer from 'src/pages/Services/FormRenderer' +import twilioSchema from 'src/pages/Services/schemas/twilio' import { ReactComponent as ReverseCustomInfoIcon } from 'src/styling/icons/circle buttons/filter/white.svg' import { ReactComponent as CustomInfoIcon } from 'src/styling/icons/circle buttons/filter/zodiac.svg' import { ReactComponent as ReverseSettingsIcon } from 'src/styling/icons/circle buttons/settings/white.svg' @@ -23,6 +26,12 @@ import AdvancedTriggers from './components/AdvancedTriggers' import { fromServer } from './helper' const useStyles = makeStyles(styles) +const SAVE_ACCOUNT = gql` + mutation Save($accounts: JSONObject) { + saveAccounts(accounts: $accounts) + } +` + const SAVE_CONFIG = gql` mutation Save($config: JSONObject) { saveConfig(config: $config) @@ -32,6 +41,7 @@ const SAVE_CONFIG = gql` const GET_CONFIG = gql` query getData { config + accounts } ` @@ -55,6 +65,8 @@ const Triggers = () => { const [error, setError] = useState(null) const [subMenu, setSubMenu] = useState(false) + const [twilioSetupPopup, setTwilioSetupPopup] = useState(false) + const customInfoRequests = R.path(['customInfoRequests'])(customInfoReqData) ?? [] const enabledCustomInfoRequests = R.filter(R.propEq('enabled', true))( @@ -72,6 +84,12 @@ const Triggers = () => { onError: error => setError(error) }) + const [saveAccount] = useMutation(SAVE_ACCOUNT, { + onCompleted: () => setTwilioSetupPopup(false), + refetchQueries: () => ['getData'], + onError: error => setError(error) + }) + const addressReuseSave = rawConfig => { const config = toNamespace('compliance')(rawConfig) return saveConfig({ variables: { config } }) @@ -98,6 +116,17 @@ const Triggers = () => { const loading = configLoading || customInfoLoading + const twilioSave = it => { + setError(null) + return saveAccount({ + variables: { accounts: { twilio: it } } + }) + } + const addNewTriger = () => { + if (!R.has('twilio', data?.accounts || {})) setTwilioSetupPopup(true) + else toggleWizard('newTrigger')() + } + return ( <> { )} {!loading && !subMenu && !R.isEmpty(triggers) && ( - toggleWizard('newTrigger')()}> + + Add new trigger @@ -191,6 +220,27 @@ const Triggers = () => { save={saveConfig} data={data}> )} + {twilioSetupPopup && ( + setTwilioSetupPopup(false)} + open={true}> +

+ In order for compliance triggers to work, you'll first need to + configure Twilio. +

+ + +
+ )} ) } From c4ca91b59be9f01854b063dc53b9bf658b4cc752 Mon Sep 17 00:00:00 2001 From: Nikola Ubavic <53820106+ubavic@users.noreply.github.com> Date: Tue, 8 Mar 2022 14:40:24 +0100 Subject: [PATCH 3/5] feat: mailgun setup in notifications --- .../src/pages/Notifications/Notifications.js | 119 ++++++++++++------ .../src/pages/Notifications/sections/Setup.js | 10 +- 2 files changed, 86 insertions(+), 43 deletions(-) diff --git a/new-lamassu-admin/src/pages/Notifications/Notifications.js b/new-lamassu-admin/src/pages/Notifications/Notifications.js index b1def515..993fbc51 100644 --- a/new-lamassu-admin/src/pages/Notifications/Notifications.js +++ b/new-lamassu-admin/src/pages/Notifications/Notifications.js @@ -11,6 +11,7 @@ import twilioSchema from 'src/pages/Services/schemas/twilio' import { fromNamespace, toNamespace, namespaces } from 'src/utils/config' import Section from '../../components/layout/Section' +import mailgunSchema from '../Services/schemas/mailgun' import NotificationsCtx from './NotificationsContext' import CryptoBalanceAlerts from './sections/CryptoBalanceAlerts' @@ -64,6 +65,7 @@ const Notifications = ({ const [error, setError] = useState(null) const [editingKey, setEditingKey] = useState(null) const [smsSetupPopup, setSmsSetupPopup] = useState(false) + const [emailSetupPopup, setEmailSetupPopup] = useState(false) const { data, loading } = useQuery(GET_INFO) @@ -74,7 +76,10 @@ const Notifications = ({ }) const [saveAccount] = useMutation(SAVE_ACCOUNT, { - onCompleted: () => setSmsSetupPopup(false), + onCompleted: () => { + setSmsSetupPopup(false) + setEmailSetupPopup(false) + }, refetchQueries: ['getData'], onError: error => setError(error) }) @@ -83,6 +88,7 @@ const Notifications = ({ const machines = data?.machines const cryptoCurrencies = data?.cryptoCurrencies const twilioAvailable = R.has('twilio', data?.accounts || {}) + const mailgunAvailable = R.has('mailgun', data?.accounts || {}) const currency = R.path(['fiatCurrency'])( fromNamespace(namespaces.LOCALE)(data?.config) @@ -110,6 +116,14 @@ const Notifications = ({ }) } + const mailgunSave = it => { + setError(null) + R.compose(save(null), toNamespace('email'))({ active: true }) + return saveAccount({ + variables: { accounts: { mailgun: it } } + }) + } + const isEditing = key => editingKey === key const isDisabled = key => editingKey && editingKey !== key @@ -126,49 +140,55 @@ const Notifications = ({ machines, cryptoCurrencies, twilioAvailable, - setSmsSetupPopup + setSmsSetupPopup, + mailgunAvailable, + setEmailSetupPopup } return ( !loading && ( - - {displayTitle && } - {displaySetup && ( -
- -
- )} - {displayTransactionAlerts && ( -
- -
- )} - {displayFiatAlerts && ( -
- - {displayOverrides && ( - - )} -
- )} - {displayCryptoAlerts && ( -
- - {displayOverrides && ( - - )} -
- )} + <> + + {displayTitle && } + {displaySetup && ( +
+ +
+ )} + {displayTransactionAlerts && ( +
+ +
+ )} + {displayFiatAlerts && ( +
+ + {displayOverrides && ( + + )} +
+ )} + {displayCryptoAlerts && ( +
+ + {displayOverrides && ( + + )} +
+ )} +
{smsSetupPopup && ( )} -
+ {emailSetupPopup && ( + setEmailSetupPopup(false)} + open={true}> +

+ In order for the mail notifications to work, you'll first need to + configure Mailgun. +

+ +
+ )} + ) ) } diff --git a/new-lamassu-admin/src/pages/Notifications/sections/Setup.js b/new-lamassu-admin/src/pages/Notifications/sections/Setup.js index a56f2221..2e8d7583 100644 --- a/new-lamassu-admin/src/pages/Notifications/sections/Setup.js +++ b/new-lamassu-admin/src/pages/Notifications/sections/Setup.js @@ -85,7 +85,9 @@ const Setup = ({ wizard, forceDisable }) => { data: rawData, save: rawSave, twilioAvailable, - setSmsSetupPopup + setSmsSetupPopup, + mailgunAvailable, + setEmailSetupPopup } = useContext(NotificationsCtx) const namespaces = [ @@ -93,7 +95,11 @@ const Setup = ({ wizard, forceDisable }) => { name: 'email', forceDisable: forceDisable, shouldUpperCase: false, - onActivation: () => true + onActivation: () => { + if (mailgunAvailable) return true + setEmailSetupPopup(true) + return false + } }, { name: 'sms', From 3311c6c5fbcd08204b5355eddc0e1881ef497c40 Mon Sep 17 00:00:00 2001 From: Nikola Ubavic <53820106+ubavic@users.noreply.github.com> Date: Mon, 14 Mar 2022 12:03:00 +0100 Subject: [PATCH 4/5] fix: chain saves --- .../src/pages/Notifications/Notifications.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/new-lamassu-admin/src/pages/Notifications/Notifications.js b/new-lamassu-admin/src/pages/Notifications/Notifications.js index 993fbc51..9247c986 100644 --- a/new-lamassu-admin/src/pages/Notifications/Notifications.js +++ b/new-lamassu-admin/src/pages/Notifications/Notifications.js @@ -110,18 +110,16 @@ const Notifications = ({ const twilioSave = it => { setError(null) - R.compose(save(null), toNamespace('sms'))({ active: true }) - return saveAccount({ + saveAccount({ variables: { accounts: { twilio: it } } - }) + }).then(() => R.compose(save(null), toNamespace('sms'))({ active: true })) } const mailgunSave = it => { setError(null) - R.compose(save(null), toNamespace('email'))({ active: true }) - return saveAccount({ + saveAccount({ variables: { accounts: { mailgun: it } } - }) + }).then(() => R.compose(save(null), toNamespace('email'))({ active: true })) } const isEditing = key => editingKey === key From b54f76e610cb484bb4e0e49b87309af9d40ffe45 Mon Sep 17 00:00:00 2001 From: Nikola Ubavic <53820106+ubavic@users.noreply.github.com> Date: Mon, 14 Mar 2022 13:34:03 +0100 Subject: [PATCH 5/5] fix: return --- new-lamassu-admin/src/pages/Notifications/Notifications.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/new-lamassu-admin/src/pages/Notifications/Notifications.js b/new-lamassu-admin/src/pages/Notifications/Notifications.js index 9247c986..b79eb9a7 100644 --- a/new-lamassu-admin/src/pages/Notifications/Notifications.js +++ b/new-lamassu-admin/src/pages/Notifications/Notifications.js @@ -110,14 +110,14 @@ const Notifications = ({ const twilioSave = it => { setError(null) - saveAccount({ + return saveAccount({ variables: { accounts: { twilio: it } } }).then(() => R.compose(save(null), toNamespace('sms'))({ active: true })) } const mailgunSave = it => { setError(null) - saveAccount({ + return saveAccount({ variables: { accounts: { mailgun: it } } }).then(() => R.compose(save(null), toNamespace('email'))({ active: true })) }