feat: correct timezone offset on downloaded logs
This commit is contained in:
parent
ac3dcef35a
commit
a0c77b4939
7 changed files with 74 additions and 16 deletions
|
|
@ -1,18 +1,30 @@
|
||||||
const { parseAsync } = require('json2csv')
|
const { parseAsync } = require('json2csv')
|
||||||
|
const moment = require('moment')
|
||||||
|
const _ = require('lodash/fp')
|
||||||
|
|
||||||
const logs = require('../../../logs')
|
const logs = require('../../../logs')
|
||||||
const serverLogs = require('../../services/server-logs')
|
const serverLogs = require('../../services/server-logs')
|
||||||
|
|
||||||
|
const dateFormat = (timezone, logs) => _.map(log => {
|
||||||
|
const offset = timezone.split(':')[1]
|
||||||
|
return {
|
||||||
|
...log,
|
||||||
|
timestamp: moment.utc(log.timestamp).utcOffset(parseInt(offset)).format('YYYY-MM-DDTHH:mm:ss.SSS')
|
||||||
|
}
|
||||||
|
}, logs)
|
||||||
|
|
||||||
const resolvers = {
|
const resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
machineLogs: (...[, { deviceId, from, until, limit, offset }]) =>
|
machineLogs: (...[, { deviceId, from, until, limit, offset }]) =>
|
||||||
logs.simpleGetMachineLogs(deviceId, from, until, limit, offset),
|
logs.simpleGetMachineLogs(deviceId, from, until, limit, offset),
|
||||||
machineLogsCsv: (...[, { deviceId, from, until, limit, offset }]) =>
|
machineLogsCsv: (...[, { deviceId, from, until, limit, offset, timezone }]) =>
|
||||||
logs.simpleGetMachineLogs(deviceId, from, until, limit, offset).then(parseAsync),
|
logs.simpleGetMachineLogs(deviceId, from, until, limit, offset)
|
||||||
|
.then(res => parseAsync(dateFormat(timezone, res))),
|
||||||
serverLogs: (...[, { from, until, limit, offset }]) =>
|
serverLogs: (...[, { from, until, limit, offset }]) =>
|
||||||
serverLogs.getServerLogs(from, until, limit, offset),
|
serverLogs.getServerLogs(from, until, limit, offset),
|
||||||
serverLogsCsv: (...[, { from, until, limit, offset }]) =>
|
serverLogsCsv: (...[, { from, until, limit, offset, timezone }]) =>
|
||||||
serverLogs.getServerLogs(from, until, limit, offset).then(parseAsync)
|
serverLogs.getServerLogs(from, until, limit, offset)
|
||||||
|
.then(res => parseAsync(dateFormat(timezone, res)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
const DataLoader = require('dataloader')
|
const DataLoader = require('dataloader')
|
||||||
const { parseAsync } = require('json2csv')
|
const { parseAsync } = require('json2csv')
|
||||||
|
const moment = require('moment')
|
||||||
|
const _ = require('lodash/fp')
|
||||||
|
|
||||||
const filters = require('../../filters')
|
const filters = require('../../filters')
|
||||||
const transactions = require('../../services/transactions')
|
const transactions = require('../../services/transactions')
|
||||||
|
|
@ -18,6 +20,15 @@ const txLogFields = ['txClass', 'id', 'deviceId', 'toAddress', 'cryptoAtoms',
|
||||||
'customerIdCardDataExpiration', 'customerIdCardData', 'customerName',
|
'customerIdCardDataExpiration', 'customerIdCardData', 'customerName',
|
||||||
'customerFrontCameraPath', 'customerIdCardPhotoPath', 'expired', 'machineName']
|
'customerFrontCameraPath', 'customerIdCardPhotoPath', 'expired', 'machineName']
|
||||||
|
|
||||||
|
const dateFormat = (timezone, logs) => _.map(log => {
|
||||||
|
const offset = timezone.split(':')[1]
|
||||||
|
return {
|
||||||
|
...log,
|
||||||
|
created: moment.utc(log.created).utcOffset(parseInt(offset)).format('YYYY-MM-DDTHH:mm:ss.SSS'),
|
||||||
|
sendTime: moment.utc(log.sendTime).utcOffset(parseInt(offset)).format('YYYY-MM-DDTHH:mm:ss.SSS')
|
||||||
|
}
|
||||||
|
}, logs)
|
||||||
|
|
||||||
const resolvers = {
|
const resolvers = {
|
||||||
Customer: {
|
Customer: {
|
||||||
transactions: parent => transactionsLoader.load(parent.id)
|
transactions: parent => transactionsLoader.load(parent.id)
|
||||||
|
|
@ -30,11 +41,11 @@ const resolvers = {
|
||||||
transactions.batch(from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status),
|
transactions.batch(from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status),
|
||||||
transactionsCsv: (...[, { from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status }]) =>
|
transactionsCsv: (...[, { from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status }]) =>
|
||||||
transactions.batch(from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status)
|
transactions.batch(from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status)
|
||||||
.then(data => parseAsync(data, {fields: tx_logFields})),
|
.then(data => parseAsync(data, { fields: tx_logFields, transforms: dateFormat(timezone, data) })),
|
||||||
transactionCsv: (...[, { id, txClass }]) =>
|
transactionCsv: (...[, { id, txClass }]) =>
|
||||||
transactions.getTx(id, txClass).then(parseAsync),
|
transactions.getTx(id, txClass).then(data => parseAsync(data)),
|
||||||
txAssociatedDataCsv: (...[, { id, txClass }]) =>
|
txAssociatedDataCsv: (...[, { id, txClass }]) =>
|
||||||
transactions.getTxAssociatedData(id, txClass).then(parseAsync),
|
transactions.getTxAssociatedData(id, txClass).then(data => parseAsync(data)),
|
||||||
transactionFilters: () => filters.transaction()
|
transactionFilters: () => filters.transaction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@ const typeDef = gql`
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
machineLogs(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): [MachineLog] @auth
|
machineLogs(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): [MachineLog] @auth
|
||||||
machineLogsCsv(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): String @auth
|
machineLogsCsv(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int, timezone: String): String @auth
|
||||||
serverLogs(from: Date, until: Date, limit: Int, offset: Int): [ServerLog] @auth
|
serverLogs(from: Date, until: Date, limit: Int, offset: Int): [ServerLog] @auth
|
||||||
serverLogsCsv(from: Date, until: Date, limit: Int, offset: Int): String @auth
|
serverLogsCsv(from: Date, until: Date, limit: Int, offset: Int, timezone: String): String @auth
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import { ReactComponent as Arrow } from 'src/styling/icons/arrow/download_logs.s
|
||||||
import { ReactComponent as DownloadInverseIcon } from 'src/styling/icons/button/download/white.svg'
|
import { ReactComponent as DownloadInverseIcon } from 'src/styling/icons/button/download/white.svg'
|
||||||
import { ReactComponent as Download } from 'src/styling/icons/button/download/zodiac.svg'
|
import { ReactComponent as Download } from 'src/styling/icons/button/download/zodiac.svg'
|
||||||
import { primaryColor, offColor, zircon } from 'src/styling/variables'
|
import { primaryColor, offColor, zircon } from 'src/styling/variables'
|
||||||
|
import { formatDate } from 'src/utils/timezones'
|
||||||
|
|
||||||
import Popper from './Popper'
|
import Popper from './Popper'
|
||||||
import DateRangePicker from './date-range-picker/DateRangePicker'
|
import DateRangePicker from './date-range-picker/DateRangePicker'
|
||||||
|
|
@ -129,7 +130,14 @@ const useStyles = makeStyles(styles)
|
||||||
const ALL = 'all'
|
const ALL = 'all'
|
||||||
const RANGE = 'range'
|
const RANGE = 'range'
|
||||||
|
|
||||||
const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => {
|
const LogsDownloaderPopover = ({
|
||||||
|
name,
|
||||||
|
query,
|
||||||
|
args,
|
||||||
|
title,
|
||||||
|
getLogs,
|
||||||
|
timezone
|
||||||
|
}) => {
|
||||||
const [selectedRadio, setSelectedRadio] = useState(ALL)
|
const [selectedRadio, setSelectedRadio] = useState(ALL)
|
||||||
const [range, setRange] = useState({ from: null, until: null })
|
const [range, setRange] = useState({ from: null, until: null })
|
||||||
const [anchorEl, setAnchorEl] = useState(null)
|
const [anchorEl, setAnchorEl] = useState(null)
|
||||||
|
|
@ -183,7 +191,7 @@ const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => {
|
||||||
|
|
||||||
const createLogsFile = (logs, range) => {
|
const createLogsFile = (logs, range) => {
|
||||||
const formatDateFile = date => {
|
const formatDateFile = date => {
|
||||||
return moment(date).format('YYYY-MM-DD_HH-mm')
|
return formatDate(date, timezone, 'YYYY-MM-DD_HH-mm')
|
||||||
}
|
}
|
||||||
|
|
||||||
const blob = new window.Blob([logs], {
|
const blob = new window.Blob([logs], {
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,14 @@ const GET_MACHINE_LOGS_CSV = gql`
|
||||||
$limit: Int
|
$limit: Int
|
||||||
$from: DateTime
|
$from: DateTime
|
||||||
$until: DateTime
|
$until: DateTime
|
||||||
|
$timezone: String
|
||||||
) {
|
) {
|
||||||
machineLogsCsv(
|
machineLogsCsv(
|
||||||
deviceId: $deviceId
|
deviceId: $deviceId
|
||||||
limit: $limit
|
limit: $limit
|
||||||
from: $from
|
from: $from
|
||||||
until: $until
|
until: $until
|
||||||
|
timezone: $timezone
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
@ -114,8 +116,9 @@ const Logs = () => {
|
||||||
title="Download logs"
|
title="Download logs"
|
||||||
name={selected.name}
|
name={selected.name}
|
||||||
query={GET_MACHINE_LOGS_CSV}
|
query={GET_MACHINE_LOGS_CSV}
|
||||||
args={{ deviceId }}
|
args={{ deviceId, timezone }}
|
||||||
getLogs={logs => R.path(['machineLogsCsv'])(logs)}
|
getLogs={logs => R.path(['machineLogsCsv'])(logs)}
|
||||||
|
timezone={timezone}
|
||||||
/>
|
/>
|
||||||
<Info3>{saveMessage}</Info3>
|
<Info3>{saveMessage}</Info3>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,18 @@ const SHOW_ALL = { code: 'SHOW_ALL', display: 'Show all' }
|
||||||
const NUM_LOG_RESULTS = 500
|
const NUM_LOG_RESULTS = 500
|
||||||
|
|
||||||
const GET_CSV = gql`
|
const GET_CSV = gql`
|
||||||
query ServerData($limit: Int, $from: DateTime, $until: DateTime) {
|
query ServerData(
|
||||||
serverLogsCsv(limit: $limit, from: $from, until: $until)
|
$limit: Int
|
||||||
|
$from: DateTime
|
||||||
|
$until: DateTime
|
||||||
|
$timezone: String
|
||||||
|
) {
|
||||||
|
serverLogsCsv(
|
||||||
|
limit: $limit
|
||||||
|
from: $from
|
||||||
|
until: $until
|
||||||
|
timezone: $timezone
|
||||||
|
)
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -138,8 +148,10 @@ const Logs = () => {
|
||||||
title="Download logs"
|
title="Download logs"
|
||||||
name="server-logs"
|
name="server-logs"
|
||||||
query={GET_CSV}
|
query={GET_CSV}
|
||||||
|
args={{ timezone }}
|
||||||
logs={data.serverLogs}
|
logs={data.serverLogs}
|
||||||
getLogs={logs => R.path(['serverLogsCsv'])(logs)}
|
getLogs={logs => R.path(['serverLogsCsv'])(logs)}
|
||||||
|
timezone={timezone}
|
||||||
/>
|
/>
|
||||||
<Info3>{saveMessage}</Info3>
|
<Info3>{saveMessage}</Info3>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,18 @@ const GET_DATA = gql`
|
||||||
`
|
`
|
||||||
|
|
||||||
const GET_TRANSACTIONS_CSV = gql`
|
const GET_TRANSACTIONS_CSV = gql`
|
||||||
query transactions($limit: Int, $from: DateTime, $until: DateTime) {
|
query transactions(
|
||||||
transactionsCsv(limit: $limit, from: $from, until: $until)
|
$limit: Int
|
||||||
|
$from: DateTime
|
||||||
|
$until: DateTime
|
||||||
|
$timezone: String
|
||||||
|
) {
|
||||||
|
transactionsCsv(
|
||||||
|
limit: $limit
|
||||||
|
from: $from
|
||||||
|
until: $until
|
||||||
|
timezone: $timezone
|
||||||
|
)
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -271,7 +281,9 @@ const Transactions = () => {
|
||||||
title="Download logs"
|
title="Download logs"
|
||||||
name="transactions"
|
name="transactions"
|
||||||
query={GET_TRANSACTIONS_CSV}
|
query={GET_TRANSACTIONS_CSV}
|
||||||
|
args={{ timezone }}
|
||||||
getLogs={logs => R.path(['transactionsCsv'])(logs)}
|
getLogs={logs => R.path(['transactionsCsv'])(logs)}
|
||||||
|
timezone={timezone}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue