diff --git a/package-lock.json b/package-lock.json index 1024acddd..8626319f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bfx-report-ui", - "version": "2.39.0", + "version": "2.41.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bfx-report-ui", - "version": "2.39.0", + "version": "2.41.0", "license": "Apache-2.0", "dependencies": { "@bitfinex/lib-js-util-base": "git+https://github.com/bitfinexcom/lib-js-util-base.git", @@ -7524,9 +7524,10 @@ "license": "MIT" }, "node_modules/ejs": { - "version": "3.1.9", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" }, diff --git a/package.json b/package.json index d014159be..b03fea7bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bfx-report-ui", - "version": "2.41.0", + "version": "2.42.0", "description": "Report page to overview the user actions in Bitfinex and download related csv files", "repository": { "type": "git", diff --git a/public/locales/en/translations.json b/public/locales/en/translations.json index c5e64dcf4..5f2f58634 100644 --- a/public/locales/en/translations.json +++ b/public/locales/en/translations.json @@ -53,6 +53,16 @@ "invalidToken": "Invalid token, please try again", "loginSessionExpired": "Your login session has expired, please try again" }, + "ttlSelect": { + "title": "Auth Token TTL", + "1day": "1 Day", + "2days": "2 Days", + "3days": "3 Days", + "4days": "4 Days", + "5days": "5 Days", + "6days": "6 Days", + "7days": "7 Days" + }, "apiKey": "API Key", "apiSecret": "API Secret", "accWithApiKey": "Add account with API key", diff --git a/src/components/Preferences/Preferences.js b/src/components/Preferences/Preferences.js index 40d33a562..a2b40bad1 100644 --- a/src/components/Preferences/Preferences.js +++ b/src/components/Preferences/Preferences.js @@ -15,6 +15,7 @@ import ThemeSwitcher from 'ui/ThemeSwitcher' import TimezonePicker from 'ui/TimezonePicker' import TableScrollPref from 'ui/TableScrollPref' import ShowMilliseconds from 'ui/ShowMilliseconds' +import TokenTTLSelector from 'ui/TokenTTLSelector' import DateFormatSelector from 'ui/DateFormatSelector' import SyncAfterUpdatePref from 'ui/SyncAfterUpdatePref' import TimeRangePreservePref from 'ui/TimeRangePreservePref' @@ -77,6 +78,12 @@ const Preferences = ({
{t('preferences.dateformat')}
+ {showFrameworkMode && ( +
+
{t('auth.ttlSelect.title')}
+ +
+ )}
{t('preferences.milliseconds')} diff --git a/src/state/auth/actions.js b/src/state/auth/actions.js index 5b4ab5116..ffc9616ba 100644 --- a/src/state/auth/actions.js +++ b/src/state/auth/actions.js @@ -224,6 +224,13 @@ export function disableAuthBtn(payload) { } } +export function setAuthTokenTTL(payload) { + return { + type: types.SET_TOKEN_TTL, + payload, + } +} + export default { checkAuth, addUser, @@ -251,4 +258,5 @@ export default { deleteAccount, syncAfterUpdate, disableAuthBtn, + setAuthTokenTTL, } diff --git a/src/state/auth/constants.js b/src/state/auth/constants.js index b5bfb5e4a..32625b3f3 100644 --- a/src/state/auth/constants.js +++ b/src/state/auth/constants.js @@ -25,7 +25,9 @@ export default { DELETE_ACCOUNT: 'BITFINEX/AUTH/ACCOUNT/DELETE', SET_SYNC_AFTER_UPDATE: 'BITFINEX/SYNC/SYNC_AFTER_UPDATE/SET', DISABLE_AUTH_BUTTON: 'BITFINEX/AUTH/BUTTON/DISABLE', + SET_TOKEN_TTL: 'BITFINEX/AUTH/TOKEN_TTL/SET', WS_SIGN_IN: 'ws_signIn', LOGIN_2FA_OTP: 'otp', + DEFAULT_TOKEN_TTL: 86400, // 24h } diff --git a/src/state/auth/reducer.js b/src/state/auth/reducer.js index ebc3dbfdd..bc34874bf 100644 --- a/src/state/auth/reducer.js +++ b/src/state/auth/reducer.js @@ -57,6 +57,7 @@ const initialState = { userShouldReLogin: '', shouldNotSyncOnStartupAfterUpdate: false, isAuthBtnDisabled: false, + authTokenTTLSec: types.DEFAULT_TOKEN_TTL, } export function authReducer(state = initialState, action) { @@ -154,6 +155,11 @@ export function authReducer(state = initialState, action) { ...state, isAuthBtnDisabled: payload, } + case types.SET_TOKEN_TTL: + return { + ...state, + authTokenTTLSec: payload, + } case types.HIDE_AUTH: return { ...state, diff --git a/src/state/auth/saga.js b/src/state/auth/saga.js index b98c4ea05..a04aad811 100644 --- a/src/state/auth/saga.js +++ b/src/state/auth/saga.js @@ -513,6 +513,24 @@ function* handleSyncAfterUpdate({ payload }) { } } +function* handleUpdateTokenTTL({ payload }) { + try { + const auth = yield select(selectAuth) + const params = { authTokenTTLSec: payload } + const { error } = yield makeFetchCall('updateUser', params, auth) + + if (error) { + yield put(updateErrorStatus({ + id: 'status.fail', + topic: 'auth.updateUser', + detail: error?.message ?? JSON.stringify(error), + })) + } + } catch (fail) { + yield put(updateAuthErrorStatus(fail)) + } +} + export default function* authSaga() { yield takeLatest(types.CHECK_AUTH, checkAuth) yield takeLatest(types.FETCH_USERS, fetchUsers) @@ -528,5 +546,6 @@ export default function* authSaga() { yield takeLatest(types.REMOVE_USER, removeUser) yield takeLatest(types.AUTH_EXPIRED, handleExpiredAuth) yield takeLatest(types.SET_SYNC_AFTER_UPDATE, handleSyncAfterUpdate) + yield takeLatest(types.SET_TOKEN_TTL, handleUpdateTokenTTL) yield fork(tokenRefreshSaga) } diff --git a/src/state/auth/selectors.js b/src/state/auth/selectors.js index 97a5f5369..9a638978c 100644 --- a/src/state/auth/selectors.js +++ b/src/state/auth/selectors.js @@ -3,6 +3,8 @@ import _first from 'lodash/first' import _filter from 'lodash/filter' import { isEqual } from '@bitfinex/lib-js-util-base' +import types from './constants' + const getAuth = state => state.auth export const getAuthStatus = state => getAuth(state).authStatus @@ -23,6 +25,7 @@ export const getIsSubAccsAvailable = state => _first( )?.isApiKeysAuth ?? true export const getLocalUsername = state => getAuth(state)?.localUsername ?? null export const getIsAuthBtnDisabled = state => getAuth(state)?.isAuthBtnDisabled ?? false +export const getAuthTokenTTL = state => getAuth(state)?.authTokenTTLSec ?? types.DEFAULT_TOKEN_TTL export const getAuthData = state => { const { @@ -110,4 +113,5 @@ export default { getLocalUsername, getShouldNotSyncOnStartupAfterUpdate, getIsAuthBtnDisabled, + getAuthTokenTTL, } diff --git a/src/ui/DataTable/DataTable.js b/src/ui/DataTable/DataTable.js index f4754393b..5f55e02f9 100644 --- a/src/ui/DataTable/DataTable.js +++ b/src/ui/DataTable/DataTable.js @@ -4,14 +4,16 @@ import React, { useMemo, useState, useEffect, + useCallback, } from 'react' import { useTranslation } from 'react-i18next' import { useDispatch, useSelector } from 'react-redux' import PropTypes from 'prop-types' import classNames from 'classnames' -import { Menu } from '@blueprintjs/core' +import { Menu, MenuItem } from '@blueprintjs/core' import { Column, + ColumnHeaderCell, CopyCellsMenuItem, Table, } from '@blueprintjs/table' @@ -84,6 +86,33 @@ const DataTable = ({ const getCellData = (rowIndex, columnIndex) => tableColumns[columnIndex]?.copyText(rowIndex) + const columnWidthReset = useCallback(() => { + setUseCustomColsWidth(false) + dispatch(setColumnsWidth({ section })) + }, [dispatch]) + + const columnHeaderCellRenderer = (name, headerClassName) => { + const menuRenderer = () => ( + <> + {enableColumnResizing && ( + + + + )} + + ) + return ( + + ) + } + const renderBodyContextMenu = (context) => { const isSingleColumnSelected = singleColumnSelectedCheck(context) const hasNumericValue = columnHasNumericValueCheck(context, tableColumns) @@ -99,11 +128,6 @@ const DataTable = ({ } } - const columnWidthReset = () => { - setUseCustomColsWidth(false) - dispatch(setColumnsWidth({ section })) - } - return ( columnHeaderCellRenderer( + column?.nameStr ?? t(column.name), + column?.className ?? 'align-right', + ) + } /> ))} diff --git a/src/ui/DataTable/_DataTable.scss b/src/ui/DataTable/_DataTable.scss index bc08582b2..56d42de2d 100644 --- a/src/ui/DataTable/_DataTable.scss +++ b/src/ui/DataTable/_DataTable.scss @@ -63,6 +63,16 @@ .cell-no-data { color: var(--color2); } + + .bp3-table-thead { + .bp3-table-header { + .bp3-table-column-name { + .bp3-table-th-menu-container{ + display: none; + } + } + } + } } .bp3-table { diff --git a/src/ui/Select/Select.js b/src/ui/Select/Select.js index 8803a8ce1..ea506586a 100644 --- a/src/ui/Select/Select.js +++ b/src/ui/Select/Select.js @@ -59,7 +59,7 @@ class Select extends PureComponent { } itemRenderer = (item, { modifiers, handleClick }) => { - const { active, disabled } = modifiers + const { disabled } = modifiers const { value } = this.props let options = {} @@ -82,7 +82,7 @@ class Select extends PureComponent { return ( [ + { value: 86400, label: t('auth.ttlSelect.1day') }, + { value: 172800, label: t('auth.ttlSelect.2days') }, + { value: 259200, label: t('auth.ttlSelect.3days') }, + { value: 345600, label: t('auth.ttlSelect.4days') }, + { value: 432000, label: t('auth.ttlSelect.5days') }, + { value: 518400, label: t('auth.ttlSelect.6days') }, + { value: 604800, label: t('auth.ttlSelect.7days') }, +] + +const ExportTypeSelector = () => { + const { t } = useTranslation() + const dispatch = useDispatch() + const authTokenTTL = useSelector(getAuthTokenTTL) + const items = useMemo(() => getItems(t), [t]) + + const handleChange = useCallback((value) => { + dispatch(setAuthTokenTTL(value)) + }, [dispatch]) + + return ( +