Shaheer Kochai b333aa3775
Feat: Timezone picker feature (#6474)
* feat: time picker hint and timezone picker UI with basic functionality + helper to get timezones

* feat: add support for esc keypress to close the timezone picker

* chore: add the selected timezone as url param and close timezone picker on select

* fix: overall improvement + add searchIndex to timezone

* feat: timezone preferences UI

* chore: improve timezone utils

* chore: change timezone item from div to button

* feat: display timezone in timepicker input

* chore: fix the typo

* fix: don't focus on time picker when timezone is clicked

* fix: fix the issue of timezone breaking for browser and utc timezones

* fix: display the timezone in timepicker hint 'You are at'

* feat: timezone basic functionality (#6492)

* chore: change div to fragment + change type to any as the ESLint complains otherwise

* chore: manage etc timezone filtering with an arg

* chore: update timezone wrapper class name

* fix: add timezone support to downloaded logs

* feat: add current timezone to dashboard list and configure metadata modal

* fix: add pencil icon next to timezone hint + change the copy to Current timezone

* fix: properly handle the escape button behavior for timezone picker

* chore: replace @vvo/tzdb with native Intl API for timezones

* feat: lightmode for timezone picker and timezone adaptation components

* fix: use normald tz in browser timezone

* fix: timezone picker lightmode fixes

* feat: display selected time range in 12 hour format

* chore: remove unnecessary optional chaining

* fix: fix the typo in css variable

* chore: add em dash and change icon for timezone hint in date/time picker

* chore: move pen line icon to the right of timezone offset

* fix: fix the failing tests

* feat: handle switching off the timezone adaptation
2024-12-16 11:27:20 +05:30

145 lines
3.6 KiB
TypeScript

import './useTableView.styles.scss';
import Convert from 'ansi-to-html';
import { Typography } from 'antd';
import { ColumnsType } from 'antd/es/table';
import cx from 'classnames';
import { unescapeString } from 'container/LogDetailedView/utils';
import dompurify from 'dompurify';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { FlatLogData } from 'lib/logs/flatLogData';
import { useTimezone } from 'providers/Timezone';
import { useMemo } from 'react';
import { FORBID_DOM_PURIFY_TAGS } from 'utils/app';
import LogStateIndicator from '../LogStateIndicator/LogStateIndicator';
import { getLogIndicatorTypeForTable } from '../LogStateIndicator/utils';
import {
defaultListViewPanelStyle,
defaultTableStyle,
getDefaultCellStyle,
} from './config';
import { TableBodyContent } from './styles';
import {
ColumnTypeRender,
UseTableViewProps,
UseTableViewResult,
} from './types';
const convert = new Convert();
export const useTableView = (props: UseTableViewProps): UseTableViewResult => {
const {
logs,
fields,
linesPerRow,
fontSize,
appendTo = 'center',
isListViewPanel,
} = props;
const isDarkMode = useIsDarkMode();
const flattenLogData = useMemo(() => logs.map((log) => FlatLogData(log)), [
logs,
]);
const { formatTimezoneAdjustedTimestamp } = useTimezone();
const columns: ColumnsType<Record<string, unknown>> = useMemo(() => {
const fieldColumns: ColumnsType<Record<string, unknown>> = fields
.filter((e) => e.name !== 'id')
.map(({ name }) => ({
title: name,
dataIndex: name,
key: name,
render: (field): ColumnTypeRender<Record<string, unknown>> => ({
props: {
style: isListViewPanel
? defaultListViewPanelStyle
: getDefaultCellStyle(isDarkMode),
},
children: (
<Typography.Paragraph
ellipsis={{ rows: linesPerRow }}
className={cx('paragraph', fontSize)}
>
{field}
</Typography.Paragraph>
),
}),
}));
if (isListViewPanel) {
return [...fieldColumns];
}
return [
{
title: 'timestamp',
dataIndex: 'timestamp',
key: 'timestamp',
// https://github.com/ant-design/ant-design/discussions/36886
render: (field, item): ColumnTypeRender<Record<string, unknown>> => {
const date =
typeof field === 'string'
? formatTimezoneAdjustedTimestamp(field, 'YYYY-MM-DD HH:mm:ss.SSS')
: formatTimezoneAdjustedTimestamp(
field / 1e6,
'YYYY-MM-DD HH:mm:ss.SSS',
);
return {
children: (
<div className="table-timestamp">
<LogStateIndicator
type={getLogIndicatorTypeForTable(item)}
fontSize={fontSize}
/>
<Typography.Paragraph ellipsis className={cx('text', fontSize)}>
{date}
</Typography.Paragraph>
</div>
),
};
},
},
...(appendTo === 'center' ? fieldColumns : []),
{
title: 'body',
dataIndex: 'body',
key: 'body',
render: (field): ColumnTypeRender<Record<string, unknown>> => ({
props: {
style: defaultTableStyle,
},
children: (
<TableBodyContent
dangerouslySetInnerHTML={{
__html: convert.toHtml(
dompurify.sanitize(unescapeString(field), {
FORBID_TAGS: [...FORBID_DOM_PURIFY_TAGS],
}),
),
}}
fontSize={fontSize}
linesPerRow={linesPerRow}
isDarkMode={isDarkMode}
/>
),
}),
},
...(appendTo === 'end' ? fieldColumns : []),
];
}, [
fields,
isListViewPanel,
appendTo,
isDarkMode,
linesPerRow,
fontSize,
formatTimezoneAdjustedTimestamp,
]);
return { columns, dataSource: flattenLogData };
};