Skip to content

Commit 6b9242e

Browse files
committed
[PLAT-18701] Convert timestamps to user selected timezone
Summary: This diff adds a custom hook for pulling the user's selected timezone and converting user facing timestamps to that timezone prior to displaying them. Test Plan: Verify the timestamp strings under different timezone choices. {F402421} {F402422} {F402423} {F402424} Reviewers: rmadhavan, kkannan Reviewed By: rmadhavan Differential Revision: https://phorge.dev.yugabyte.com/D47310
1 parent b788847 commit 6b9242e

File tree

6 files changed

+31
-14
lines changed

6 files changed

+31
-14
lines changed

managed/ui/src/components/JWTToken/JWTToken.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { YBLabel, YBTextarea } from '../../redesign/components';
66
import { YBCopyButton } from '../common/descriptors';
77
import YBLogoWithText from '../common/YBLogo/images/yb_yblogo_text.svg';
88
import { isEmptyString, isNonEmptyString } from '../../utils/ObjectUtils';
9-
import { formatDatetime } from '../../redesign/helpers/DateUtils';
9+
import { useFormatDatetime } from '../../redesign/helpers/DateUtils';
1010

1111
const useStyles = makeStyles((theme: Theme) => ({
1212
oidcJWTInfo: {
@@ -48,6 +48,7 @@ const useStyles = makeStyles((theme: Theme) => ({
4848

4949
export const JWTToken: FC<any> = () => {
5050
const { t } = useTranslation();
51+
const formatDatetime = useFormatDatetime();
5152
const helperClasses = useStyles();
5253
const oidcJWTToken = Cookies.get('jwt_token');
5354
const expiryDate = Cookies.get('expiration');

managed/ui/src/components/queries/QueryInfoSidePanel.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ import { adaptHistogramData } from './helpers/utils';
3131
import { parseFloatIfDefined } from '../xcluster/ReplicationUtils';
3232
import { QueryApi } from '../../redesign/helpers/constants';
3333
import {
34-
formatDatetime,
3534
YB_LIVE_QUERY_TIMESTAMP_FORMAT,
36-
YBTimeFormats
35+
YBTimeFormats,
36+
useFormatDatetime
3737
} from '../../redesign/helpers/DateUtils';
3838

3939
interface QueryInfoSidePanelBaseProps {
@@ -182,10 +182,10 @@ export const QueryInfoSidePanel = ({
182182
isConnectionPoolEnabled
183183
}: QueryInfoSidePanelProps) => {
184184
const [currentTab, setCurrentTab] = useState<QueryInfoTab>(DEFAULT_TAB);
185-
const currentUserTimezone = useSelector((state: any) => state.customer.currentUser.data.timezone);
186185
const { t, i18n } = useTranslation('translation', {
187186
keyPrefix: TRANSLATION_KEY_PREFIX
188187
});
188+
const formatDatetime = useFormatDatetime();
189189
const classes = useStyles();
190190
const theme = useTheme();
191191
const handleTabChange = (_event: React.ChangeEvent<{}>, newTab: QueryInfoTab) => {
@@ -195,12 +195,12 @@ export const QueryInfoSidePanel = ({
195195
i18n.exists(`${TRANSLATION_KEY_PREFIX}.${key}`) ? t(key) : fallback;
196196

197197
const formatQueryData = (
198-
ysqlSlowQueryKey:
198+
ysqlQueryKey:
199199
| YsqlLiveQueryPrimitiveFields
200200
| YcqlLiveQueryPrimitiveFields
201201
| YsqlSlowQueryPrimitiveFields
202202
): string => {
203-
const queryDataEntry = queryData?.[ysqlSlowQueryKey];
203+
const queryDataEntry = queryData?.[ysqlQueryKey];
204204

205205
// The following formatters expect only string or finite number types.
206206
// This guard is used to catch undefined values or unhandled types.
@@ -214,18 +214,17 @@ export const QueryInfoSidePanel = ({
214214
return NO_DATA_PLACEHOLDER_TEXT;
215215
}
216216

217-
if ((DURATION_FIELDS as readonly string[]).includes(ysqlSlowQueryKey)) {
217+
if ((DURATION_FIELDS as readonly string[]).includes(ysqlQueryKey)) {
218218
const duration = parseFloatIfDefined(queryDataEntry);
219219
return duration === undefined || isNaN(duration)
220220
? NO_DATA_PLACEHOLDER_TEXT
221221
: `${duration?.toFixed(DURATION_FIELD_DECIMALS)} ms`;
222222
}
223223

224-
if ((TIMESTAMP_FIELDS as readonly string[]).includes(ysqlSlowQueryKey)) {
224+
if ((TIMESTAMP_FIELDS as readonly string[]).includes(ysqlQueryKey)) {
225225
return formatDatetime(
226226
queryDataEntry,
227227
YBTimeFormats.YB_DEFAULT_TIMESTAMP,
228-
currentUserTimezone,
229228
YB_LIVE_QUERY_TIMESTAMP_FORMAT
230229
);
231230
}

managed/ui/src/components/queries/SlowQueries.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useSelector } from 'react-redux';
55
import { Alert } from 'react-bootstrap';
66
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
77
import { toast } from 'react-toastify';
8-
import { Box, Typography, useTheme } from '@material-ui/core';
8+
import { Box, Typography } from '@material-ui/core';
99

1010
import { useSlowQueriesApi, filterBySearchTokens } from './helpers/queriesHelper';
1111
import { resetSlowQueries } from '../../actions/universe';
@@ -20,7 +20,7 @@ import {
2020
PG_15_VERSION_THRESHOLD_STABLE,
2121
QueryType
2222
} from './helpers/constants';
23-
import { formatDatetime } from '../../redesign/helpers/DateUtils';
23+
import { useFormatDatetime } from '../../redesign/helpers/DateUtils';
2424
import {
2525
compareYBSoftwareVersionsWithReleaseTrack,
2626
getPrimaryCluster
@@ -97,7 +97,7 @@ const SlowQueriesComponent = () => {
9797
const [selectedRow, setSelectedRow] = useState([]);
9898
const [panelState, setPanelState] = useState(PANEL_STATE.INITIAL);
9999
const [searchTokens, setSearchTokens] = useState([]);
100-
const theme = useTheme();
100+
const formatDatetime = useFormatDatetime();
101101
let initialColumns = initialQueryColumns;
102102
try {
103103
const cachedColumns = localStorage.getItem('__yb_slow_query_columns__');

managed/ui/src/redesign/components/YBMetrics/YBMetricGraph.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414

1515
import { CHART_RESIZE_DEBOUNCE } from '../../helpers/constants';
1616
import { YBMetricGraphTitle } from './YBMetricGraphTitle';
17-
import { formatDatetime, YBTimeFormats } from '../../helpers/DateUtils';
17+
import { useFormatDatetime, YBTimeFormats } from '../../helpers/DateUtils';
1818
import { YBMetricGraphData } from './types';
1919
import { getUniqueTraceId, getUniqueTraceName } from './utils';
2020

@@ -50,6 +50,7 @@ type YBMetricGraphProps =
5050
export const YBMetricGraph = (props: YBMetricGraphProps) => {
5151
const { graphHeaderAccessor, metric, metricSettings, referenceLines, title, unit } = props;
5252
const theme = useTheme();
53+
const formatDatetime = useFormatDatetime();
5354
const traceStrokes = Object.values(theme.palette.chart.stroke);
5455
const unitSuffix = unit ? ` ${unit}` : '';
5556

managed/ui/src/redesign/features/continuous-backup/ContinuousBackupCard.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
ConfigureContinuousBackupModal,
1515
ConfigureContinuousBackupOperation
1616
} from './ConfigureContinuousBackupModal';
17-
import { formatDatetime } from '../../helpers/DateUtils';
17+
import { useFormatDatetime } from '../../helpers/DateUtils';
1818
import { DeleteContinuousBackupConfigModal } from './DeleteContinuousBackupConfigModal';
1919

2020
interface ContinuousBackupCardProps {
@@ -106,6 +106,7 @@ export const ContinuousBackupCard = ({ continuousBackupConfig }: ContinuousBacku
106106
);
107107
const [isDeleteContinuousBackupModalOpen, setIsDeleteContinuousBackupModalOpen] = useState(false);
108108
const { t } = useTranslation('translation', { keyPrefix: TRANSLATION_KEY_PREFIX });
109+
const formatDatetime = useFormatDatetime();
109110
const classes = useStyles();
110111

111112
const openConfigureContinuousBackupModal = () => setIsConfigureContinuousBackupModalOpen(true);

managed/ui/src/redesign/helpers/DateUtils.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,21 @@ export const formatDatetime = (
6969
return timezone ? momentObj.tz(timezone).format(timeFormat) : momentObj.format(timeFormat);
7070
};
7171

72+
/**
73+
* Custom hook that returns a function to format datetime with user timezone from Redux
74+
*/
75+
export const useFormatDatetime = () => {
76+
const userTimezone = useSelector((state: any) => state.customer?.currentUser?.data?.timezone);
77+
78+
return (
79+
date: moment.MomentInput,
80+
timeFormat: YBTimeFormats = YBTimeFormats.YB_DEFAULT_TIMESTAMP,
81+
inputTimeFormat?: string
82+
): string => {
83+
return formatDatetime(date, timeFormat, userTimezone, inputTimeFormat);
84+
};
85+
};
86+
7287
type FormatDateProps = {
7388
date: Date | string | number;
7489
timeFormat: YBTimeFormats;

0 commit comments

Comments
 (0)