From 3e1e2b4831c0ec2c995ea14a104d66db22ddd995 Mon Sep 17 00:00:00 2001 From: Jose Sousa Date: Mon, 23 Nov 2020 18:59:13 +0000 Subject: [PATCH 1/9] chore: title and sidebar moved to app.js --- new-lamassu-admin/src/App.js | 62 ++++++++++- .../src/pages/OperatorInfo/OperatorInfo.js | 100 ------------------ new-lamassu-admin/src/routing/routes.js | 68 +++++++++++- 3 files changed, 122 insertions(+), 108 deletions(-) delete mode 100644 new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js diff --git a/new-lamassu-admin/src/App.js b/new-lamassu-admin/src/App.js index 0ff35c15..fe50fead 100644 --- a/new-lamassu-admin/src/App.js +++ b/new-lamassu-admin/src/App.js @@ -1,4 +1,5 @@ import CssBaseline from '@material-ui/core/CssBaseline' +import Grid from '@material-ui/core/Grid' import { StylesProvider, jssPreset, @@ -8,12 +9,24 @@ import { import { create } from 'jss' import extendJss from 'jss-plugin-extend' import React, { createContext, useContext, useState } from 'react' -import { useLocation, BrowserRouter as Router } from 'react-router-dom' +import { + useLocation, + useHistory, + BrowserRouter as Router +} from 'react-router-dom' +import Sidebar from 'src/components/layout/Sidebar' +import TitleSection from 'src/components/layout/TitleSection' import ApolloProvider from 'src/utils/apollo' import Header from './components/layout/Header' -import { tree, Routes } from './routing/routes' +import { + getTitle, + tree, + hasSidebar, + Routes, + getSidebarData +} from './routing/routes' import global from './styling/global' import theme from './styling/theme' import { backgroundColor, mainWidth } from './styling/variables' @@ -46,6 +59,18 @@ const useStyles = makeStyles({ flex: 1, display: 'flex', flexDirection + }, + grid: { + flex: 1, + height: '100%' + }, + contentWithSidebar: { + flex: 1, + marginLeft: 48, + paddingTop: 15 + }, + contentWithoutSidebar: { + width: mainWidth } }) @@ -54,15 +79,46 @@ const AppContext = createContext() const Main = () => { const classes = useStyles() const location = useLocation() + const history = useHistory() const { wizardTested } = useContext(AppContext) + const route = location.pathname + + const title = getTitle(route) + const sidebar = hasSidebar(route) + const sidebarData = sidebar ? getSidebarData(route) : [] + const is404 = location.pathname === '/404' + const isSelected = it => location.pathname === it.route + + const onClick = it => history.push(it.route) + + const contentClassName = sidebar + ? classes.contentWithSidebar + : classes.contentWithoutSidebar + return (
{!is404 && wizardTested &&
}
- + {title && !is404 && wizardTested && ( + + )} + + + {sidebar && !is404 && wizardTested && ( + it.label} + onClick={onClick} + /> + )} +
+ +
+
) diff --git a/new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js b/new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js deleted file mode 100644 index 794530d2..00000000 --- a/new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js +++ /dev/null @@ -1,100 +0,0 @@ -import { makeStyles } from '@material-ui/core' -import Grid from '@material-ui/core/Grid' -import React from 'react' -import { - Route, - Switch, - Redirect, - useLocation, - useHistory -} from 'react-router-dom' - -import Sidebar from 'src/components/layout/Sidebar' -import TitleSection from 'src/components/layout/TitleSection' - -import CoinAtmRadar from './CoinATMRadar' -import ContactInfo from './ContactInfo' -import ReceiptPrinting from './ReceiptPrinting' -import TermsConditions from './TermsConditions' - -const styles = { - grid: { - flex: 1, - height: '100%' - }, - content: { - flex: 1, - marginLeft: 48, - paddingTop: 15 - } -} - -const useStyles = makeStyles(styles) - -const innerRoutes = [ - { - label: 'Contact information', - route: '/settings/operator-info/contact-info', - component: ContactInfo - }, - { - label: 'Receipt', - route: '/settings/operator-info/receipt-printing', - component: ReceiptPrinting - }, - { - label: 'Coin ATM Radar', - route: '/settings/operator-info/coin-atm-radar', - component: CoinAtmRadar - }, - { - label: 'Terms & Conditions', - route: '/settings/operator-info/terms-conditions', - component: TermsConditions - } -] - -const Routes = ({ wizard }) => ( - - - - {innerRoutes.map(({ route, component: Page, key }) => ( - - - - ))} - -) - -const OperatorInfo = ({ wizard = false }) => { - const classes = useStyles() - const history = useHistory() - const location = useLocation() - - const isSelected = it => location.pathname === it.route - - const onClick = it => history.push(it.route) - - return ( - <> - - - it.label} - onClick={onClick} - /> -
- -
-
- - ) -} - -export default OperatorInfo diff --git a/new-lamassu-admin/src/routing/routes.js b/new-lamassu-admin/src/routing/routes.js index 404ade02..b7918eb7 100644 --- a/new-lamassu-admin/src/routing/routes.js +++ b/new-lamassu-admin/src/routing/routes.js @@ -20,7 +20,10 @@ import MachineLogs from 'src/pages/MachineLogs' import CashCassettes from 'src/pages/Maintenance/CashCassettes' import MachineStatus from 'src/pages/Maintenance/MachineStatus' import Notifications from 'src/pages/Notifications/Notifications' -import OperatorInfo from 'src/pages/OperatorInfo/OperatorInfo' +import CoinAtmRadar from 'src/pages/OperatorInfo/CoinATMRadar' +import ContactInfo from 'src/pages/OperatorInfo/ContactInfo' +import ReceiptPrinting from 'src/pages/OperatorInfo/ReceiptPrinting' +import TermsConditions from 'src/pages/OperatorInfo/TermsConditions' import ServerLogs from 'src/pages/ServerLogs' import Services from 'src/pages/Services/Services' import TokenManagement from 'src/pages/TokenManagement/TokenManagement' @@ -125,7 +128,36 @@ const tree = [ key: namespaces.OPERATOR_INFO, label: 'Operator Info', route: '/settings/operator-info', - component: OperatorInfo + children: [ + { + key: 'contact-info', + label: 'Contact information', + title: 'Operator information', + route: '/settings/operator-info/contact-info', + component: ContactInfo + }, + { + key: 'receipt-printing', + label: 'Receipt', + title: 'Operator information', + route: '/settings/operator-info/receipt-printing', + component: ReceiptPrinting + }, + { + key: 'coin-atm-radar', + label: 'Coin ATM Radar', + title: 'Operator information', + route: '/settings/operator-info/coin-atm-radar', + component: CoinAtmRadar + }, + { + key: 'terms-conditions', + label: 'Terms & Conditions', + title: 'Operator information', + route: '/settings/operator-info/terms-conditions', + component: TermsConditions + } + ] } ] }, @@ -181,10 +213,33 @@ const tree = [ ] const map = R.map(R.when(R.has('children'), R.prop('children'))) -const leafRoutes = R.compose(R.flatten, map)(tree) -const parentRoutes = R.filter(R.has('children'))(tree) +const mappedRoutes = R.compose(R.flatten, map)(tree) +const parentRoutes = R.filter(R.has('children'))(tree).concat( + R.filter(R.has('children'))(mappedRoutes) +) +const leafRoutes = R.compose(R.flatten, map)(mappedRoutes) +const thirdLevelRoutes = R.compose( + R.flatten, + R.map(R.prop('children')), + R.filter(R.has('children')) +)(mappedRoutes) const flattened = R.concat(leafRoutes, parentRoutes) +const getTitle = route => + R.prop('title', R.find(R.propEq('route', route))(flattened)) + +const hasSidebar = route => R.any(r => r.route === route, thirdLevelRoutes) + +const getSidebarData = route => { + const parentRoute = R.dropLast( + 1, + R.dropLastWhile(x => x !== '/', route) + ) + const parent = R.find(R.propEq('route', parentRoute))(flattened) + + return parent?.children +} + const Routes = () => { const history = useHistory() const location = useLocation() @@ -201,6 +256,9 @@ const Routes = () => { + + + {flattened.map(({ route, component: Page, key }) => ( @@ -215,4 +273,4 @@ const Routes = () => { ) } -export { tree, Routes } +export { getTitle, tree, getSidebarData, hasSidebar, Routes } From 7b1564c56978375c050e0593870a7c16c0d0bf69 Mon Sep 17 00:00:00 2001 From: Jose Sousa Date: Wed, 25 Nov 2020 10:52:51 +0000 Subject: [PATCH 2/9] fix: redirect to third level --- new-lamassu-admin/src/App.js | 17 +++----- new-lamassu-admin/src/routing/routes.js | 52 ++++++++++++------------- 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/new-lamassu-admin/src/App.js b/new-lamassu-admin/src/App.js index fe50fead..66e2ba1a 100644 --- a/new-lamassu-admin/src/App.js +++ b/new-lamassu-admin/src/App.js @@ -20,13 +20,7 @@ import TitleSection from 'src/components/layout/TitleSection' import ApolloProvider from 'src/utils/apollo' import Header from './components/layout/Header' -import { - getTitle, - tree, - hasSidebar, - Routes, - getSidebarData -} from './routing/routes' +import { tree, hasSidebar, Routes, getParent } from './routing/routes' import global from './styling/global' import theme from './styling/theme' import { backgroundColor, mainWidth } from './styling/variables' @@ -84,9 +78,8 @@ const Main = () => { const route = location.pathname - const title = getTitle(route) const sidebar = hasSidebar(route) - const sidebarData = sidebar ? getSidebarData(route) : [] + const parent = sidebar ? getParent(route) : {} const is404 = location.pathname === '/404' @@ -102,14 +95,14 @@ const Main = () => {
{!is404 && wizardTested &&
}
- {title && !is404 && wizardTested && ( - + {sidebar && !is404 && wizardTested && ( + )} {sidebar && !is404 && wizardTested && ( it.label} onClick={onClick} diff --git a/new-lamassu-admin/src/routing/routes.js b/new-lamassu-admin/src/routing/routes.js index b7918eb7..de280ba2 100644 --- a/new-lamassu-admin/src/routing/routes.js +++ b/new-lamassu-admin/src/routing/routes.js @@ -128,32 +128,32 @@ const tree = [ key: namespaces.OPERATOR_INFO, label: 'Operator Info', route: '/settings/operator-info', + title: 'Operator Information', + get component() { + return () => + }, children: [ { key: 'contact-info', label: 'Contact information', - title: 'Operator information', route: '/settings/operator-info/contact-info', component: ContactInfo }, { key: 'receipt-printing', label: 'Receipt', - title: 'Operator information', route: '/settings/operator-info/receipt-printing', component: ReceiptPrinting }, { key: 'coin-atm-radar', label: 'Coin ATM Radar', - title: 'Operator information', route: '/settings/operator-info/coin-atm-radar', component: CoinAtmRadar }, { key: 'terms-conditions', label: 'Terms & Conditions', - title: 'Operator information', route: '/settings/operator-info/terms-conditions', component: TermsConditions } @@ -214,31 +214,32 @@ const tree = [ const map = R.map(R.when(R.has('children'), R.prop('children'))) const mappedRoutes = R.compose(R.flatten, map)(tree) -const parentRoutes = R.filter(R.has('children'))(tree).concat( - R.filter(R.has('children'))(mappedRoutes) +const parentRoutes = R.filter(R.has('children'))(mappedRoutes).concat( + R.filter(R.has('children'))(tree) ) const leafRoutes = R.compose(R.flatten, map)(mappedRoutes) -const thirdLevelRoutes = R.compose( - R.flatten, - R.map(R.prop('children')), - R.filter(R.has('children')) -)(mappedRoutes) + const flattened = R.concat(leafRoutes, parentRoutes) -const getTitle = route => - R.prop('title', R.find(R.propEq('route', route))(flattened)) - -const hasSidebar = route => R.any(r => r.route === route, thirdLevelRoutes) - -const getSidebarData = route => { - const parentRoute = R.dropLast( - 1, - R.dropLastWhile(x => x !== '/', route) +const hasSidebar = route => + R.any(r => r.route === route)( + R.compose( + R.flatten, + R.map(R.prop('children')), + R.filter(R.has('children')) + )(mappedRoutes) ) - const parent = R.find(R.propEq('route', parentRoute))(flattened) - return parent?.children -} +const getParent = route => + R.find( + R.propEq( + 'route', + R.dropLast( + 1, + R.dropLastWhile(x => x !== '/', route) + ) + ) + )(flattened) const Routes = () => { const history = useHistory() @@ -256,9 +257,6 @@ const Routes = () => { - - - {flattened.map(({ route, component: Page, key }) => ( @@ -273,4 +271,4 @@ const Routes = () => { ) } -export { getTitle, tree, getSidebarData, hasSidebar, Routes } +export { tree, getParent, hasSidebar, Routes } From 35e71b95369eb3948245fea7731589ac5d675c24 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Wed, 25 Nov 2020 19:00:50 +0000 Subject: [PATCH 3/9] feat: Add restart services button in machine admin actions --- .../pages/Maintenance/MachineDetailsCard.js | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js index d04dc8fa..f755dd3f 100644 --- a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js +++ b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js @@ -128,19 +128,19 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { /> { setErrorMessage(null) machineAction({ variables: { deviceId: machine.deviceId, - action: `${action?.command}`.toLowerCase(), - ...(action?.command === 'Rename' && { newName: value }) + action: `${action?.command}`, + ...(action?.command === 'rename' && { newName: value }) } }) }} @@ -174,7 +174,8 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { InverseIcon={EditReversedIcon} onClick={() => setAction({ - command: 'Rename', + command: 'rename', + humanReadable: 'Rename', confirmationMessage: 'Write the new name for this machine' }) }> @@ -188,7 +189,8 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { disabled={loading} onClick={() => setAction({ - command: 'Unpair' + command: 'unpair', + humanReadable: 'Unpair' }) }> Unpair @@ -201,26 +203,42 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { disabled={loading} onClick={() => setAction({ - command: 'Reboot' + command: 'reboot', + humanReadable: 'Reboot' }) }> Reboot setAction({ - command: 'Shutdown', + command: 'shutdown', + humanReadable: 'Shutdown', message: 'In order to bring it back online, the machine will need to be visited and its power reset.' }) }> Shutdown + + setAction({ + command: 'restartServices', + humanReadable: 'Restart services for' + }) + }> + Restart Services +
From 179a0270e5a9b668aacf5258c9905b44bb1b96a6 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Mon, 30 Nov 2020 11:53:24 +0000 Subject: [PATCH 4/9] fix: rename humanReadable to display --- .../src/pages/Maintenance/MachineDetailsCard.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js index f755dd3f..4abaea31 100644 --- a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js +++ b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js @@ -128,7 +128,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { /> { onClick={() => setAction({ command: 'rename', - humanReadable: 'Rename', + display: 'Rename', confirmationMessage: 'Write the new name for this machine' }) }> @@ -190,7 +190,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { onClick={() => setAction({ command: 'unpair', - humanReadable: 'Unpair' + display: 'Unpair' }) }> Unpair @@ -204,7 +204,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { onClick={() => setAction({ command: 'reboot', - humanReadable: 'Reboot' + display: 'Reboot' }) }> Reboot @@ -218,7 +218,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { onClick={() => setAction({ command: 'shutdown', - humanReadable: 'Shutdown', + display: 'Shutdown', message: 'In order to bring it back online, the machine will need to be visited and its power reset.' }) @@ -234,7 +234,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { onClick={() => setAction({ command: 'restartServices', - humanReadable: 'Restart services for' + display: 'Restart services for' }) }> Restart Services From e11d894bd61e6da7860773679a6a8da3e1c2879d Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Wed, 25 Nov 2020 17:05:31 +0000 Subject: [PATCH 5/9] feat: Changed add machine button to be according to spec --- new-lamassu-admin/src/components/layout/Header.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/new-lamassu-admin/src/components/layout/Header.js b/new-lamassu-admin/src/components/layout/Header.js index 97ae6995..e3ce2d77 100644 --- a/new-lamassu-admin/src/components/layout/Header.js +++ b/new-lamassu-admin/src/components/layout/Header.js @@ -3,9 +3,11 @@ import classnames from 'classnames' import React, { memo, useState } from 'react' import { NavLink, useHistory } from 'react-router-dom' -import { Link } from 'src/components/buttons' +import ActionButton from 'src/components/buttons/ActionButton' import { H4 } from 'src/components/typography' import AddMachine from 'src/pages/AddMachine' +import { ReactComponent as AddIconReverse } from 'src/styling/icons/button/add/white.svg' +import { ReactComponent as AddIcon } from 'src/styling/icons/button/add/zodiac.svg' import { ReactComponent as Logo } from 'src/styling/icons/menu/logo.svg' import styles from './Header.styles' @@ -76,9 +78,14 @@ const Header = memo(({ tree }) => { ))} - setOpen(true)}> - Add Machine - + setOpen(true)}> + Add machine + From d5f3763e918b1d25cd5d857513d704fc5fcb91e8 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Wed, 25 Nov 2020 19:08:23 +0000 Subject: [PATCH 6/9] fix: Removed useless className --- new-lamassu-admin/src/components/layout/Header.js | 1 - 1 file changed, 1 deletion(-) diff --git a/new-lamassu-admin/src/components/layout/Header.js b/new-lamassu-admin/src/components/layout/Header.js index e3ce2d77..d21acb46 100644 --- a/new-lamassu-admin/src/components/layout/Header.js +++ b/new-lamassu-admin/src/components/layout/Header.js @@ -79,7 +79,6 @@ const Header = memo(({ tree }) => { ))} Date: Tue, 1 Dec 2020 14:32:21 +0000 Subject: [PATCH 7/9] feat: Customer transactions fetching with dataloader library --- lib/new-admin/graphql/schema.js | 5 ++- lib/new-admin/transactions.js | 57 +++++++++++++++++++++++++++++++-- package-lock.json | 5 +++ package.json | 1 + 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index d299dd1e..9aa3b63d 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -3,6 +3,7 @@ const { parseAsync } = require('json2csv') const { GraphQLDateTime } = require('graphql-iso-date') const { GraphQLJSON, GraphQLJSONObject } = require('graphql-type-json') const got = require('got') +const DataLoader = require('dataloader') const machineLoader = require('../../machine-loader') const customers = require('../../customers') @@ -265,6 +266,8 @@ const typeDefs = gql` } ` +const transactionsLoader = new DataLoader(ids => transactions.getCustomerTransactionsBatch(ids)) + const notify = () => got.post('http://localhost:3030/dbChange') .catch(e => console.error('Error: lamassu-server not responding')) @@ -273,7 +276,7 @@ const resolvers = { JSONObject: GraphQLJSONObject, Date: GraphQLDateTime, Customer: { - transactions: parent => transactions.getCustomerTransactions(parent.id) + transactions: parent => transactionsLoader.load(parent.id) }, Query: { countries: () => countries, diff --git a/lib/new-admin/transactions.js b/lib/new-admin/transactions.js index 657ab4ea..519271a4 100644 --- a/lib/new-admin/transactions.js +++ b/lib/new-admin/transactions.js @@ -67,7 +67,6 @@ function batch (from = new Date(0).toISOString(), until = new Date().toISOString function getCustomerTransactions (customerId) { const packager = _.flow(it => { - console.log() return it }, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames) @@ -110,6 +109,60 @@ function getCustomerTransactions (customerId) { .then(packager) } +async function getCustomerTransactionsBatch(ids) { + const packager = _.flow(it => { + return it + }, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames) + + const cashInSql = `select 'cashIn' as tx_class, txs.*, + c.phone as customer_phone, + c.id_card_data_number as customer_id_card_data_number, + c.id_card_data_expiration as customer_id_card_data_expiration, + c.id_card_data as customer_id_card_data, + c.name as customer_name, + c.front_camera_path as customer_front_camera_path, + c.id_card_photo_path as customer_id_card_photo_path, + ((not txs.send_confirmed) and (txs.created <= now() - interval $2)) as expired + from cash_in_txs as txs + left outer join customers c on txs.customer_id = c.id + where c.id::text LIKE ANY($1) + order by created desc limit $3` + + const cashOutSql = `select 'cashOut' as tx_class, + txs.*, + actions.tx_hash, + c.phone as customer_phone, + c.id_card_data_number as customer_id_card_data_number, + c.id_card_data_expiration as customer_id_card_data_expiration, + c.id_card_data as customer_id_card_data, + c.name as customer_name, + c.front_camera_path as customer_front_camera_path, + c.id_card_photo_path as customer_id_card_photo_path, + (extract(epoch from (now() - greatest(txs.created, txs.confirmed_at))) * 1000) >= $3 as expired + from cash_out_txs txs + inner join cash_out_actions actions on txs.id = actions.tx_id + and actions.action = 'provisionAddress' + left outer join customers c on txs.customer_id = c.id + where c.id::text LIKE ANY ($1) + order by created desc limit $2` + + const cashIns = await db.any(cashInSql, [ids, cashInTx.PENDING_INTERVAL, NUM_RESULTS]) + const cashOuts = await db.any(cashOutSql, [ids, NUM_RESULTS, REDEEMABLE_AGE]) + const transactions = await packager([...cashIns, ...cashOuts]) + + + const transactionMap = {} + transactions.forEach(transaction => { + if(!transactionMap[transaction.customerId]) { + transactionMap[transaction.customerId] = [transaction] + } + else { + transactionMap[transaction.customerId].push(transaction) + } + }) + return ids.map(id => transactionMap[id]) +} + function single (txId) { const packager = _.flow(_.compact, _.map(camelize), addNames) @@ -156,4 +209,4 @@ function cancel (txId) { .then(() => single(txId)) } -module.exports = { batch, getCustomerTransactions, single, cancel } +module.exports = { batch, getCustomerTransactions, single, cancel, getCustomerTransactionsBatch } diff --git a/package-lock.json b/package-lock.json index 58fcbfc0..f10f1027 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3390,6 +3390,11 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==" }, + "dataloader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.0.0.tgz", + "integrity": "sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ==" + }, "date-fns": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", diff --git a/package.json b/package.json index 9fb7380f..ddb3615a 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "console-log-level": "^1.4.0", "cookie-parser": "^1.4.3", "cors": "^2.8.5", + "dataloader": "^2.0.0", "ethereumjs-tx": "^1.3.3", "ethereumjs-util": "^5.2.0", "ethereumjs-wallet": "^0.6.3", From ed4e654036c30fc0fb7a1c4ea2a24e2a9948798e Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Wed, 2 Dec 2020 16:01:33 +0000 Subject: [PATCH 8/9] Chore: remove unused code and use lodash --- lib/new-admin/transactions.js | 69 +++++------------------------------ 1 file changed, 9 insertions(+), 60 deletions(-) diff --git a/lib/new-admin/transactions.js b/lib/new-admin/transactions.js index 519271a4..68fef36e 100644 --- a/lib/new-admin/transactions.js +++ b/lib/new-admin/transactions.js @@ -65,51 +65,7 @@ function batch (from = new Date(0).toISOString(), until = new Date().toISOString .then(packager) } -function getCustomerTransactions (customerId) { - const packager = _.flow(it => { - return it - }, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames) - - const cashInSql = `select 'cashIn' as tx_class, txs.*, - c.phone as customer_phone, - c.id_card_data_number as customer_id_card_data_number, - c.id_card_data_expiration as customer_id_card_data_expiration, - c.id_card_data as customer_id_card_data, - c.name as customer_name, - c.front_camera_path as customer_front_camera_path, - c.id_card_photo_path as customer_id_card_photo_path, - ((not txs.send_confirmed) and (txs.created <= now() - interval $2)) as expired - from cash_in_txs as txs - left outer join customers c on txs.customer_id = c.id - where c.id = $1 - order by created desc limit $3` - - const cashOutSql = `select 'cashOut' as tx_class, - txs.*, - actions.tx_hash, - c.phone as customer_phone, - c.id_card_data_number as customer_id_card_data_number, - c.id_card_data_expiration as customer_id_card_data_expiration, - c.id_card_data as customer_id_card_data, - c.name as customer_name, - c.front_camera_path as customer_front_camera_path, - c.id_card_photo_path as customer_id_card_photo_path, - (extract(epoch from (now() - greatest(txs.created, txs.confirmed_at))) * 1000) >= $3 as expired - from cash_out_txs txs - inner join cash_out_actions actions on txs.id = actions.tx_id - and actions.action = 'provisionAddress' - left outer join customers c on txs.customer_id = c.id - where c.id = $1 - order by created desc limit $2` - - return Promise.all([ - db.any(cashInSql, [customerId, cashInTx.PENDING_INTERVAL, NUM_RESULTS]), - db.any(cashOutSql, [customerId, NUM_RESULTS, REDEEMABLE_AGE]) - ]) - .then(packager) -} - -async function getCustomerTransactionsBatch(ids) { +function getCustomerTransactionsBatch (ids) { const packager = _.flow(it => { return it }, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames) @@ -146,21 +102,14 @@ async function getCustomerTransactionsBatch(ids) { where c.id::text LIKE ANY ($1) order by created desc limit $2` - const cashIns = await db.any(cashInSql, [ids, cashInTx.PENDING_INTERVAL, NUM_RESULTS]) - const cashOuts = await db.any(cashOutSql, [ids, NUM_RESULTS, REDEEMABLE_AGE]) - const transactions = await packager([...cashIns, ...cashOuts]) - - - const transactionMap = {} - transactions.forEach(transaction => { - if(!transactionMap[transaction.customerId]) { - transactionMap[transaction.customerId] = [transaction] - } - else { - transactionMap[transaction.customerId].push(transaction) - } + return Promise.all([ + db.any(cashInSql, [ids, cashInTx.PENDING_INTERVAL, NUM_RESULTS]), + db.any(cashOutSql, [ids, NUM_RESULTS, REDEEMABLE_AGE]) + ]) + .then(packager).then(transactions => { + const transactionMap = _.groupBy('customerId', transactions) + return ids.map(id => transactionMap[id]) }) - return ids.map(id => transactionMap[id]) } function single (txId) { @@ -209,4 +158,4 @@ function cancel (txId) { .then(() => single(txId)) } -module.exports = { batch, getCustomerTransactions, single, cancel, getCustomerTransactionsBatch } +module.exports = { batch, single, cancel, getCustomerTransactionsBatch } From 0b02c7feae03c0eeb0765cc5390430846dd32d9a Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Fri, 4 Dec 2020 13:43:06 +0000 Subject: [PATCH 9/9] Fix: fix query --- lib/new-admin/transactions.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/new-admin/transactions.js b/lib/new-admin/transactions.js index 68fef36e..79285e06 100644 --- a/lib/new-admin/transactions.js +++ b/lib/new-admin/transactions.js @@ -1,4 +1,5 @@ const _ = require('lodash/fp') +const pgp = require('pg-promise')() const db = require('../db') const machineLoader = require('../machine-loader') @@ -81,7 +82,7 @@ function getCustomerTransactionsBatch (ids) { ((not txs.send_confirmed) and (txs.created <= now() - interval $2)) as expired from cash_in_txs as txs left outer join customers c on txs.customer_id = c.id - where c.id::text LIKE ANY($1) + where c.id IN ($1^) order by created desc limit $3` const cashOutSql = `select 'cashOut' as tx_class, @@ -99,12 +100,11 @@ function getCustomerTransactionsBatch (ids) { inner join cash_out_actions actions on txs.id = actions.tx_id and actions.action = 'provisionAddress' left outer join customers c on txs.customer_id = c.id - where c.id::text LIKE ANY ($1) + where c.id IN ($1^) order by created desc limit $2` - return Promise.all([ - db.any(cashInSql, [ids, cashInTx.PENDING_INTERVAL, NUM_RESULTS]), - db.any(cashOutSql, [ids, NUM_RESULTS, REDEEMABLE_AGE]) + db.any(cashInSql, [_.map(pgp.as.text, ids).join(','), cashInTx.PENDING_INTERVAL, NUM_RESULTS]), + db.any(cashOutSql, [_.map(pgp.as.text, ids).join(','), NUM_RESULTS, REDEEMABLE_AGE]) ]) .then(packager).then(transactions => { const transactionMap = _.groupBy('customerId', transactions)