From 5ed84b7cdbaa034d1de44b39006dd7b3221e6e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Oliveira?= Date: Mon, 12 Apr 2021 09:48:47 +0100 Subject: [PATCH] feat: advanced options screen triggers --- ...5-add-default-advanced-trigger-settings.js | 16 ++ .../src/pages/Triggers/Triggers.js | 154 +++++++++++------- .../Triggers/components/AdvancedTriggers.js | 109 +++++++++++++ .../src/pages/Triggers/components/helper.js | 116 +++++++++++++ .../src/pages/Triggers/helper.js | 4 +- new-lamassu-admin/src/utils/config.js | 3 +- 6 files changed, 337 insertions(+), 65 deletions(-) create mode 100644 migrations/1617983833835-add-default-advanced-trigger-settings.js create mode 100644 new-lamassu-admin/src/pages/Triggers/components/AdvancedTriggers.js create mode 100644 new-lamassu-admin/src/pages/Triggers/components/helper.js diff --git a/migrations/1617983833835-add-default-advanced-trigger-settings.js b/migrations/1617983833835-add-default-advanced-trigger-settings.js new file mode 100644 index 00000000..6dccd54a --- /dev/null +++ b/migrations/1617983833835-add-default-advanced-trigger-settings.js @@ -0,0 +1,16 @@ +const db = require('./db') + + +exports.up = function (next) { + + const sql2 = [`insert into user_config (type, data, valid, schema_version) values ('config', '{"config":{ + "triggersConfig_expirationTime": "Forever", + "triggersConfig_automation": "Automatic" + } }', true, 2)`] + + db.multi(sql2, next) +} + +exports.down = function (next) { + next() +} \ No newline at end of file diff --git a/new-lamassu-admin/src/pages/Triggers/Triggers.js b/new-lamassu-admin/src/pages/Triggers/Triggers.js index 3d18a541..0353142e 100644 --- a/new-lamassu-admin/src/pages/Triggers/Triggers.js +++ b/new-lamassu-admin/src/pages/Triggers/Triggers.js @@ -11,10 +11,13 @@ import { Table as EditableTable } from 'src/components/editableTable' import { Switch } from 'src/components/inputs' import TitleSection from 'src/components/layout/TitleSection' import { P, Label2, H2 } from 'src/components/typography' +import { ReactComponent as ReverseListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/white.svg' +import { ReactComponent as ListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/zodiac.svg' import { fromNamespace, toNamespace, namespaces } from 'src/utils/config' import styles from './Triggers.styles' import Wizard from './Wizard' +import AdvancedTriggers from './components/AdvancedTriggers' import { Schema, getElements, sortBy, fromServer, toServer } from './helper' const useStyles = makeStyles(styles) @@ -34,6 +37,7 @@ const GET_INFO = gql` const Triggers = () => { const classes = useStyles() const [wizard, setWizard] = useState(false) + const [advancedSettings, setAdvancedSettings] = useState(false) const { data, loading } = useQuery(GET_INFO) const triggers = fromServer(data?.config?.triggers ?? []) @@ -74,72 +78,96 @@ const Triggers = () => { return ( <> - - - -

Reject reused addresses

- { - addressReuseSave({ rejectAddressReuse: event.target.checked }) - }} - value={rejectAddressReuse} - /> - - {rejectAddressReuse ? 'On' : 'Off'} - - -

- This option requires a user to scan a different cryptocurrency - address if they attempt to scan one that had been previously - used for a transaction in your network -

-
+ + {!advancedSettings && ( + + +

Reject reused addresses

+ { + addressReuseSave({ rejectAddressReuse: event.target.checked }) + }} + value={rejectAddressReuse} + /> + + {rejectAddressReuse ? 'On' : 'Off'} + + +

+ This option requires a user to scan a different cryptocurrency + address if they attempt to scan one that had been previously + used for a transaction in your network +

+
+
-
-
- - {!loading && !R.isEmpty(triggers) && ( - setWizard(true)}> - + Add new trigger - )} - - - {wizard && ( - setWizard(null)} - /> + + {!advancedSettings && ( + <> + + {!loading && !R.isEmpty(triggers) && ( + setWizard(true)}> + + Add new trigger + + )} + + + {wizard && ( + setWizard(null)} + /> + )} + {!loading && R.isEmpty(triggers) && ( + +

+ It seems there are no active compliance triggers on your network +

+ +
+ )} + )} - {!loading && R.isEmpty(triggers) && ( - -

- It seems there are no active compliance triggers on your network -

- -
+ {advancedSettings && ( + )} ) diff --git a/new-lamassu-admin/src/pages/Triggers/components/AdvancedTriggers.js b/new-lamassu-admin/src/pages/Triggers/components/AdvancedTriggers.js new file mode 100644 index 00000000..502db4a9 --- /dev/null +++ b/new-lamassu-admin/src/pages/Triggers/components/AdvancedTriggers.js @@ -0,0 +1,109 @@ +import { useMutation, useQuery } from '@apollo/react-hooks' +import gql from 'graphql-tag' +import * as R from 'ramda' +import React, { memo, useState } from 'react' + +import { Table as EditableTable } from 'src/components/editableTable' +import Section from 'src/components/layout/Section' +import { fromNamespace, toNamespace, namespaces } from 'src/utils/config' + +import { + defaultSchema, + overridesSchema, + defaults, + overridesDefaults, + getDefaultSettings, + getOverrides +} from './helper' + +const SAVE_CONFIG = gql` + mutation Save($config: JSONObject) { + saveConfig(config: $config) + } +` + +const GET_INFO = gql` + query getData { + config + } +` + +const AdvancedTriggersSettings = memo(() => { + const SCREEN_KEY = namespaces.TRIGGERS + const [error, setError] = useState(null) + const [isEditingDefault, setEditingDefault] = useState(false) + const [isEditingOverrides, setEditingOverrides] = useState(false) + + const { data } = useQuery(GET_INFO) + + const [saveConfig] = useMutation(SAVE_CONFIG, { + refetchQueries: () => ['getData'], + onError: error => setError(error) + }) + + const saveDefaults = it => { + const newConfig = toNamespace(SCREEN_KEY)(it.triggersConfig[0]) + setError(null) + return saveConfig({ + variables: { config: newConfig } + }) + } + + const saveOverrides = it => { + const config = toNamespace(SCREEN_KEY)(it) + setError(null) + return saveConfig({ variables: { config } }) + } + + const requirementsData = + data?.config && fromNamespace(SCREEN_KEY)(data?.config) + const requirementsDefaults = + requirementsData && !R.isEmpty(requirementsData) + ? requirementsData + : defaults + const requirementsOverrides = requirementsData?.overrides ?? [] + + const onEditingDefault = (it, editing) => setEditingDefault(editing) + const onEditingOverrides = (it, editing) => setEditingOverrides(editing) + + return ( + <> +
+ +
+
+ +
+ + ) +}) + +export default AdvancedTriggersSettings diff --git a/new-lamassu-admin/src/pages/Triggers/components/helper.js b/new-lamassu-admin/src/pages/Triggers/components/helper.js new file mode 100644 index 00000000..a35e7607 --- /dev/null +++ b/new-lamassu-admin/src/pages/Triggers/components/helper.js @@ -0,0 +1,116 @@ +import * as Yup from 'yup' + +import Autocomplete from 'src/components/inputs/formik/Autocomplete.js' +import { getView, requirementOptions } from 'src/pages/Triggers/helper' + +const defaultSchema = Yup.object().shape({ + expirationTime: Yup.string() + .label('Expiration time') + .required(), + automation: Yup.string() + .label('Automation') + .matches(/(Manual|Automatic)/) + .required() +}) + +const overridesSchema = Yup.object().shape({ + id: Yup.string() + .label('Requirement') + .required(), + expirationTime: Yup.string() + .label('Expiration time') + .required(), + automation: Yup.string() + .label('Automation') + .matches(/(Manual|Automatic)/) + .required() +}) + +const getDefaultSettings = () => { + return [ + { + name: 'expirationTime', + header: 'Expiration Time', + width: 196, + size: 'sm', + editable: false + }, + { + name: 'automation', + header: 'Automation', + width: 196, + size: 'sm', + input: Autocomplete, + inputProps: { + options: [ + { code: 'Automatic', display: 'Automatic' }, + { code: 'Manual', display: 'Manual' } + ], + labelProp: 'display', + valueProp: 'code' + } + } + ] +} + +const getOverrides = () => { + return [ + { + name: 'requirement', + header: 'Requirement', + width: 196, + size: 'sm', + view: getView(requirementOptions, 'display'), + input: Autocomplete, + inputProps: { + options: requirementOptions, + labelProp: 'display', + valueProp: 'code' + } + }, + { + name: 'expirationTime', + header: 'Expiration Time', + width: 196, + size: 'sm', + editable: false + }, + { + name: 'automation', + header: 'Automation', + width: 196, + size: 'sm', + input: Autocomplete, + inputProps: { + options: [ + { code: 'Automatic', display: 'Automatic' }, + { code: 'Manual', display: 'Manual' } + ], + labelProp: 'display', + valueProp: 'code' + } + } + ] +} + +const defaults = [ + { + expirationTime: 'Forever', + automation: 'Automatic' + } +] + +const overridesDefaults = { + requirement: '', + expirationTime: 'Forever', + automation: 'Automatic' +} + +export { + defaultSchema, + overridesSchema, + defaults, + overridesDefaults, + getDefaultSettings, + getOverrides +} diff --git a/new-lamassu-admin/src/pages/Triggers/helper.js b/new-lamassu-admin/src/pages/Triggers/helper.js index be00ec90..d9affe61 100644 --- a/new-lamassu-admin/src/pages/Triggers/helper.js +++ b/new-lamassu-admin/src/pages/Triggers/helper.js @@ -715,5 +715,7 @@ export { requirements, sortBy, fromServer, - toServer + toServer, + getView, + requirementOptions } diff --git a/new-lamassu-admin/src/utils/config.js b/new-lamassu-admin/src/utils/config.js index 12f4ba7c..df0b9da6 100644 --- a/new-lamassu-admin/src/utils/config.js +++ b/new-lamassu-admin/src/utils/config.js @@ -9,7 +9,8 @@ const namespaces = { COMMISSIONS: 'commissions', RECEIPT: 'receipt', COIN_ATM_RADAR: 'coinAtmRadar', - TERMS_CONDITIONS: 'termsConditions' + TERMS_CONDITIONS: 'termsConditions', + TRIGGERS: 'triggersConfig' } const mapKeys = R.curry((fn, obj) =>