Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] Change message timestamp format #3119

Merged
merged 9 commits into from
Dec 23, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion kafka-ui-react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"ajv": "^8.6.3",
"babel-jest": "^29.0.3",
"classnames": "^2.2.6",
"dayjs": "^1.11.2",
"fetch-mock": "^9.11.0",
"jest": "^29.0.3",
"jest-watch-typeahead": "^2.0.0",
Expand Down
6 changes: 0 additions & 6 deletions kafka-ui-react-app/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import React from 'react';
import styled from 'styled-components';
import useDataSaver from 'lib/hooks/useDataSaver';
import { TopicMessage } from 'generated-sources';
import { useTimeFormat } from 'lib/hooks/useTimeFormat';
import MessageToggleIcon from 'components/common/Icons/MessageToggleIcon';
import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
import { Dropdown, DropdownItem } from 'components/common/Dropdown';
import { formatTimestamp } from 'lib/dateTimeHelpers';

import MessageContent from './MessageContent/MessageContent';
import * as S from './MessageContent/MessageContent.styled';
Expand Down Expand Up @@ -58,7 +58,6 @@ const Message: React.FC<Props> = ({
Headers: headers,
Timestamp: timestamp,
};
const formatTimestamp = useTimeFormat();

const savedMessage = JSON.stringify(savedMessageJson, null, '\t');
const { copyToClipboard, saveFile } = useDataSaver(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import EditorViewer from 'components/common/EditorViewer/EditorViewer';
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
import { useTimeFormat } from 'lib/hooks/useTimeFormat';
import { SchemaType, TopicMessageTimestampTypeEnum } from 'generated-sources';
import { formatTimestamp } from 'lib/dateTimeHelpers';

import * as S from './MessageContent.styled';

Expand All @@ -27,8 +27,6 @@ const MessageContent: React.FC<MessageContentProps> = ({
timestamp,
timestampType,
}) => {
const formatTimestamp = useTimeFormat();

const [activeTab, setActiveTab] = React.useState<Tab>('content');

const activeTabContent = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import React from 'react';
import { TopicMessage, TopicMessageTimestampTypeEnum } from 'generated-sources';
import Message, {
PreviewFilter,
Props,
} from 'components/Topics/Topic/Messages/Message';
import Message, { Props } from 'components/Topics/Topic/Messages/Message';
import { screen } from '@testing-library/react';
import { render } from 'lib/testHelpers';
import userEvent from '@testing-library/user-event';
import { formatTimestamp } from 'lib/dateTimeHelpers';

const messageContentText = 'messageContentText';
const format = 'DD.MM.YYYY HH:mm:ss';

jest.mock(
'components/Topics/Topic/Messages/MessageContent/MessageContent',
Expand All @@ -33,9 +29,6 @@ describe('Message component', () => {
headers: { header: 'test' },
};

const mockKeyFilters: PreviewFilter[] = [];
const mockContentFilters: PreviewFilter[] = [];

const renderComponent = (
props: Partial<Props> = {
message: mockMessage,
Expand All @@ -46,8 +39,8 @@ describe('Message component', () => {
<tbody>
<Message
message={props.message || mockMessage}
keyFilters={mockKeyFilters}
contentFilters={mockContentFilters}
keyFilters={[]}
contentFilters={[]}
/>
</tbody>
</table>
Expand All @@ -58,7 +51,7 @@ describe('Message component', () => {
expect(screen.getByText(mockMessage.content as string)).toBeInTheDocument();
expect(screen.getByText(mockMessage.key as string)).toBeInTheDocument();
expect(
screen.getByText(formatTimestamp(mockMessage.timestamp, format))
screen.getByText(formatTimestamp(mockMessage.timestamp))
).toBeInTheDocument();
expect(screen.getByText(mockMessage.offset.toString())).toBeInTheDocument();
expect(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import * as Metrics from 'components/common/Metrics';
import { useTimeFormat } from 'lib/hooks/useTimeFormat';
import { TopicAnalysisStats } from 'generated-sources';
import { formatTimestamp } from 'lib/dateTimeHelpers';

const Total: React.FC<TopicAnalysisStats> = ({
totalMsgs,
Expand All @@ -14,8 +14,6 @@ const Total: React.FC<TopicAnalysisStats> = ({
approxUniqKeys,
approxUniqValues,
}) => {
const formatTimestamp = useTimeFormat();

return (
<Metrics.Section title="Messages">
<Metrics.Indicator label="Total number">{totalMsgs}</Metrics.Indicator>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import {
Label,
} from 'components/common/PropertiesList/PropertiesList.styled';
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
import { useTimeFormat } from 'lib/hooks/useTimeFormat';
import { calculateTimer } from 'lib/dateTimeHelpers';
import { calculateTimer, formatTimestamp } from 'lib/dateTimeHelpers';
import { Action, ResourceType } from 'generated-sources';
import { ActionButton } from 'components/common/ActionComponent';

Expand All @@ -24,8 +23,6 @@ import SizeStats from './Indicators/SizeStats';
import PartitionTable from './PartitionTable';

const Metrics: React.FC = () => {
const formatTimestamp = useTimeFormat();

const params = useAppParams<RouteParamsClusterTopic>();

const [isAnalyzing, setIsAnalyzing] = useState(true);
Expand Down Expand Up @@ -68,7 +65,13 @@ const Metrics: React.FC = () => {
</ActionButton>
<List>
<Label>Started at</Label>
<span>{formatTimestamp(data.progress.startedAt, 'hh:mm:ss a')}</span>
<span>
{formatTimestamp(data.progress.startedAt, {
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
})}
</span>
<Label>Passed since start</Label>
<span>{calculateTimer(data.progress.startedAt as number)}</span>
<Label>Scanned messages</Label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ import {
List,
Label,
} from 'components/common/PropertiesList/PropertiesList.styled';
import { useTimeFormat } from 'lib/hooks/useTimeFormat';
import { TopicAnalysisStats } from 'generated-sources';
import { formatTimestamp } from 'lib/dateTimeHelpers';

import * as S from './Statistics.styles';

const PartitionInfoRow: React.FC<{ row: Row<TopicAnalysisStats> }> = ({
row,
}) => {
const formatTimestamp = useTimeFormat();

const {
totalMsgs,
minTimestamp,
Expand Down
3 changes: 1 addition & 2 deletions kafka-ui-react-app/src/components/Version/Version.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import WarningIcon from 'components/common/Icons/WarningIcon';
import { gitCommitPath } from 'lib/paths';
import { useTimeFormat } from 'lib/hooks/useTimeFormat';
import { useActuatorInfo } from 'lib/hooks/api/actuatorInfo';
import { BUILD_VERSION_PATTERN } from 'lib/constants';
import { useLatestVersion } from 'lib/hooks/api/latestVersion';
import { formatTimestamp } from 'lib/dateTimeHelpers';

import * as S from './Version.styled';
import compareVersions from './compareVersions';
Expand All @@ -15,7 +15,6 @@ export interface VesionProps {
}

const Version: React.FC = () => {
const formatTimestamp = useTimeFormat();
const { data: actuatorInfo = {} } = useActuatorInfo();
const { data: latestVersionInfo = {} } = useLatestVersion();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,11 @@ import { screen } from '@testing-library/dom';
import Version from 'components/Version/Version';
import { render } from 'lib/testHelpers';
import { formatTimestamp } from 'lib/dateTimeHelpers';
import { useTimeFormat } from 'lib/hooks/api/timeFormat';
import { useActuatorInfo } from 'lib/hooks/api/actuatorInfo';
import { useLatestVersion } from 'lib/hooks/api/latestVersion';
import { actuatorInfoPayload } from 'lib/fixtures/actuatorInfo';
import { latestVersionPayload } from 'lib/fixtures/latestVersion';
import { defaultGlobalSettingsValue } from 'components/contexts/GlobalSettingsContext';

jest.mock('lib/hooks/api/timeFormat', () => ({
useTimeFormat: jest.fn(),
}));
jest.mock('lib/hooks/api/actuatorInfo', () => ({
useActuatorInfo: jest.fn(),
}));
Expand All @@ -21,24 +16,14 @@ jest.mock('lib/hooks/api/latestVersion', () => ({
}));

describe('Version Component', () => {
const { timeStampFormat } = defaultGlobalSettingsValue;

const versionTag = 'v0.5.0';
const snapshotTag = 'test-SNAPSHOT';
const commitTag = 'befd3b328e2c9c7df57b0c5746561b2f7fee8813';

const actuatorVersionPayload = actuatorInfoPayload(versionTag);
const formattedTimestamp = formatTimestamp(
actuatorVersionPayload.build.time,
timeStampFormat
);
const formattedTimestamp = formatTimestamp(actuatorVersionPayload.build.time);

beforeEach(() => {
(useTimeFormat as jest.Mock).mockImplementation(() => ({
data: {
timeStampFormat,
},
}));
(useActuatorInfo as jest.Mock).mockImplementation(() => ({
data: actuatorVersionPayload,
}));
Expand Down
13 changes: 0 additions & 13 deletions kafka-ui-react-app/src/components/__tests__/App.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,18 @@ import React from 'react';
import { screen } from '@testing-library/react';
import App from 'components/App';
import { render } from 'lib/testHelpers';
import { useTimeFormat } from 'lib/hooks/api/timeFormat';
import { defaultGlobalSettingsValue } from 'components/contexts/GlobalSettingsContext';
import { useGetUserInfo } from 'lib/hooks/api/roles';

jest.mock('components/Nav/Nav', () => () => <div>Navigation</div>);

jest.mock('components/Version/Version', () => () => <div>Version</div>);

jest.mock('components/NavBar/NavBar', () => () => <div>NavBar</div>);

jest.mock('lib/hooks/api/timeFormat', () => ({
...jest.requireActual('lib/hooks/api/timeFormat'),
useTimeFormat: jest.fn(),
}));

jest.mock('lib/hooks/api/roles', () => ({
useGetUserInfo: jest.fn(),
}));

describe('App', () => {
beforeEach(() => {
(useTimeFormat as jest.Mock).mockImplementation(() => ({
data: defaultGlobalSettingsValue,
}));

(useGetUserInfo as jest.Mock).mockImplementation(() => ({
data: {},
}));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
import React from 'react';
import { useTimeFormat } from 'lib/hooks/api/timeFormat';

interface GlobalSettingsContextValue {
timeStampFormat: string;
}

export const defaultGlobalSettingsValue = {
timeStampFormat: 'DD.MM.YYYY HH:mm:ss',
};

export const GlobalSettingsContext =
React.createContext<GlobalSettingsContextValue>(defaultGlobalSettingsValue);
// This is here for future global code settings modification , it does not do anything now
export const GlobalSettingsContext = React.createContext<boolean>(true);

export const GlobalSettingsProvider: React.FC<
React.PropsWithChildren<unknown>
> = ({ children }) => {
const { data } = useTimeFormat();

return (
<GlobalSettingsContext.Provider
value={{
timeStampFormat:
data?.timeStampFormat || defaultGlobalSettingsValue.timeStampFormat,
}}
>
<GlobalSettingsContext.Provider value={false}>
{children}
</GlobalSettingsContext.Provider>
);
Expand Down
25 changes: 17 additions & 8 deletions kafka-ui-react-app/src/lib/dateTimeHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import dayjs from 'dayjs';

export const formatTimestamp = (
timestamp: number | string | Date | undefined,
format?: string
timestamp?: number | string | Date,
format: Intl.DateTimeFormatOptions = { hour12: false }
): string => {
if (!timestamp) {
return '';
}

return dayjs(timestamp).format(format);
// empty array gets the default one from the browser
const date = new Date(timestamp);

// invalid date
if (Number.isNaN(date.getTime())) {
return '';
}

// browser support
const language = navigator.language || navigator.languages[0];
return date.toLocaleString(language || [], format);
};

export const formatMilliseconds = (input = 0) => {
Expand Down Expand Up @@ -36,10 +44,11 @@ export const formatMilliseconds = (input = 0) => {
export const passedTime = (value: number) => (value < 10 ? `0${value}` : value);

export const calculateTimer = (startedAt: number) => {
const now = new Date().getTime();
const nowDate = new Date();
const now = nowDate.getTime();
const newDate = now - startedAt;
const minutes = dayjs(newDate).minute();
const second = dayjs(newDate).second();
const minutes = nowDate.getMinutes();
const second = nowDate.getSeconds();

return newDate > 0 ? `${passedTime(minutes)}:${passedTime(second)}` : '00:00';
};
3 changes: 0 additions & 3 deletions kafka-ui-react-app/src/lib/fixtures/timeFormat.ts

This file was deleted.

23 changes: 23 additions & 0 deletions kafka-ui-react-app/src/lib/hooks/__tests__/dateTimeHelpers.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { formatTimestamp } from 'lib/dateTimeHelpers';

describe('dateTimeHelpers', () => {
describe('formatTimestamp', () => {
it('should check the empty case', () => {
expect(formatTimestamp('')).toBe('');
});

it('should check the invalid case', () => {
expect(formatTimestamp('invalid')).toBe('');
});

it('should output the correct date', () => {
const date = new Date();
expect(formatTimestamp(date)).toBe(
date.toLocaleString([], { hour12: false })
);
expect(formatTimestamp(date.getTime())).toBe(
date.toLocaleString([], { hour12: false })
);
});
});
});
Loading