feat: antd is updated from v4 to v5 (#2012)

* feat: v5 is in progress

* feat: antdv5 is updated

* fix: build is fixed

* fix: default config is over written by custom one

* chore: onchange handler is updated

* chore: overflow is hidden in the layout

* Update index.tsx

* fix: import is fixed

* chore: un used import is fixed

* fix: dark mode is updated in service map

* fix: config dropdown is updated

* fix: logs types is updated

* fix: copy clipboard notification is updated

* chore: layout changes are updated

* chore: colors is updated

* chore: action width is updated

Co-authored-by: Pranay Prateek <pranay@signoz.io>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
This commit is contained in:
Palash Gupta 2023-01-11 14:39:06 +05:30 committed by GitHub
parent ca77820e9d
commit 2f5908a3dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
79 changed files with 4321 additions and 4185 deletions

View File

@ -27,8 +27,8 @@
"author": "",
"license": "ISC",
"dependencies": {
"@ant-design/colors": "^6.0.0",
"@ant-design/icons": "^4.6.2",
"@ant-design/colors": "6.0.0",
"@ant-design/icons": "4.8.0",
"@grafana/data": "^8.4.3",
"@monaco-editor/react": "^4.3.1",
"@testing-library/jest-dom": "^5.11.4",
@ -36,7 +36,7 @@
"@testing-library/user-event": "^12.1.10",
"@welldone-software/why-did-you-render": "^6.2.1",
"@xstate/react": "^3.0.0",
"antd": "4.19.2",
"antd": "5.0.5",
"axios": "^0.21.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.6.0",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,8 @@
import { ConfigProvider } from 'antd';
import NotFound from 'components/NotFound';
import Spinner from 'components/Spinner';
import AppLayout from 'container/AppLayout';
import { useThemeConfig } from 'hooks/useDarkMode';
import history from 'lib/history';
import React, { Suspense } from 'react';
import { Route, Router, Switch } from 'react-router-dom';
@ -9,22 +11,23 @@ import PrivateRoute from './Private';
import routes from './routes';
function App(): JSX.Element {
const themeConfig = useThemeConfig();
return (
<ConfigProvider theme={themeConfig}>
<Router history={history}>
<PrivateRoute>
<AppLayout>
<Suspense fallback={<Spinner size="large" tip="Loading..." />}>
<Switch>
{routes.map(({ path, component, exact }) => {
return (
{routes.map(({ path, component, exact }) => (
<Route
key={`${path}`}
exact={exact}
path={path}
component={component}
/>
);
})}
))}
<Route path="*" component={NotFound} />
</Switch>
@ -32,6 +35,7 @@ function App(): JSX.Element {
</AppLayout>
</PrivateRoute>
</Router>
</ConfigProvider>
);
}

View File

@ -1,9 +0,0 @@
import generatePicker from 'antd/es/date-picker/generatePicker';
import { Dayjs } from 'dayjs';
// included in antd
// eslint-disable-next-line import/no-extraneous-dependencies
import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
const DatePicker = generatePicker<Dayjs>(dayjsGenerateConfig);
export default DatePicker;

View File

@ -1,8 +1,6 @@
import MEditor, { EditorProps } from '@monaco-editor/react';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import AppReducer from 'types/reducer/app';
function Editor({
value,
@ -12,7 +10,7 @@ function Editor({
height,
options,
}: MEditorProps): JSX.Element {
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
return (
<MEditor
theme={isDarkMode ? 'vs-dark' : 'vs-light'}

View File

@ -23,10 +23,8 @@ import {
} from 'chart.js';
import * as chartjsAdapter from 'chartjs-adapter-date-fns';
import annotationPlugin from 'chartjs-plugin-annotation';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React, { useCallback, useEffect, useRef } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import AppReducer from 'types/reducer/app';
import { hasData } from './hasData';
import { legend } from './Plugin';
@ -67,8 +65,9 @@ function Graph({
staticLine,
containerHeight,
}: GraphProps): JSX.Element {
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const chartRef = useRef<HTMLCanvasElement>(null);
const isDarkMode = useIsDarkMode();
const currentTheme = isDarkMode ? 'dark' : 'light';
const xAxisTimeUnit = useXAxisTimeUnit(data); // Computes the relevant time unit for x axis by analyzing the time stamp data

View File

@ -1,29 +1,27 @@
import { Popover } from 'antd';
import React from 'react';
import { notification, Popover } from 'antd';
import React, { useCallback, useEffect } from 'react';
import { useCopyToClipboard } from 'react-use';
interface CopyClipboardHOCProps {
textToCopy: string;
children: React.ReactNode;
}
function CopyClipboardHOC({
textToCopy,
children,
}: CopyClipboardHOCProps): JSX.Element {
const [, setCopy] = useCopyToClipboard();
const [value, setCopy] = useCopyToClipboard();
useEffect(() => {
if (value.value) {
notification.success({
message: 'Copied to clipboard',
});
}
}, [value]);
const onClick = useCallback((): void => {
setCopy(textToCopy);
}, [setCopy, textToCopy]);
return (
<span
style={{
margin: 0,
padding: 0,
cursor: 'pointer',
}}
onClick={(): void => setCopy(textToCopy)}
onKeyDown={(): void => setCopy(textToCopy)}
role="button"
tabIndex={0}
>
<span onClick={onClick} onKeyDown={onClick} role="button" tabIndex={0}>
<Popover
placement="top"
content={<span style={{ fontSize: '0.9rem' }}>Copy to clipboard</span>}
@ -34,4 +32,9 @@ function CopyClipboardHOC({
);
}
interface CopyClipboardHOCProps {
textToCopy: string;
children: React.ReactNode;
}
export default CopyClipboardHOC;

View File

@ -14,7 +14,7 @@ import { ILogsReducer } from 'types/reducer/logs';
import AddToQueryHOC from '../AddToQueryHOC';
import CopyClipboardHOC from '../CopyClipboardHOC';
import { Container } from './styles';
import { Container, Text, TextContainer } from './styles';
import { isValidLogField } from './util';
interface LogFieldProps {
@ -23,21 +23,17 @@ interface LogFieldProps {
}
function LogGeneralField({ fieldKey, fieldValue }: LogFieldProps): JSX.Element {
return (
<div
style={{
display: 'flex',
overflow: 'hidden',
width: '100%',
}}
>
<Typography.Text type="secondary">{fieldKey}</Typography.Text>
<TextContainer>
<Text ellipsis type="secondary">
{fieldKey}
</Text>
<CopyClipboardHOC textToCopy={fieldValue}>
<Typography.Text ellipsis>
{': '}
{fieldValue}
</Typography.Text>
</CopyClipboardHOC>
</div>
</TextContainer>
);
}
function LogSelectedField({

View File

@ -1,4 +1,4 @@
import { Card } from 'antd';
import { Card, Typography } from 'antd';
import styled, { keyframes } from 'styled-components';
const fadeInAnimation = keyframes`
@ -16,3 +16,16 @@ export const Container = styled(Card)`
animation-duration: 0.2s;
animation-timing-function: ease-in;
`;
export const Text = styled(Typography.Text)`
&&& {
min-width: 1.5rem;
white-space: nowrap;
}
`;
export const TextContainer = styled.div`
display: flex;
overflow: hidden;
width: 100%;
`;

View File

@ -11,7 +11,7 @@ function CustomModal({
return (
<Modal
title={title}
visible={isModalVisible}
open={isModalVisible}
footer={footer}
closable={closable}
>

View File

@ -3,4 +3,5 @@ export enum LOCALSTORAGE {
IS_LOGGED_IN = 'IS_LOGGED_IN',
AUTH_TOKEN = 'AUTH_TOKEN',
REFRESH_AUTH_TOKEN = 'REFRESH_AUTH_TOKEN',
THEME = 'THEME',
}

View File

@ -1,5 +1,5 @@
import { Button } from 'antd';
import { NotificationInstance } from 'antd/lib/notification';
import { NotificationInstance } from 'antd/es/notification/interface';
import deleteChannel from 'api/channels/delete';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';

View File

@ -3,9 +3,10 @@ import styled from 'styled-components';
export const Layout = styled(LayoutComponent)`
&&& {
min-height: 92vh;
display: flex;
position: relative;
min-height: calc(100vh - 4rem);
overflow: hidden;
}
`;

View File

@ -1,13 +1,12 @@
import { Menu, Space } from 'antd';
import Spinner from 'components/Spinner';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React, { Suspense, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { ConfigProps } from 'types/api/dynamicConfigs/getDynamicConfigs';
import AppReducer from 'types/reducer/app';
import ErrorLink from './ErrorLink';
import LinkContainer from './Link';
import { MenuItem } from './styles';
function HelpToolTip({ config }: HelpToolTipProps): JSX.Element {
const sortedConfig = useMemo(
@ -15,10 +14,10 @@ function HelpToolTip({ config }: HelpToolTipProps): JSX.Element {
[config.components],
);
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
return (
<Menu.ItemGroup>
<Menu>
{sortedConfig.map((item) => {
const iconName = `${isDarkMode ? item.darkIcon : item.lightIcon}`;
@ -28,19 +27,19 @@ function HelpToolTip({ config }: HelpToolTipProps): JSX.Element {
return (
<ErrorLink key={item.text + item.href}>
<Suspense fallback={<Spinner height="5vh" />}>
<Menu.Item>
<MenuItem>
<LinkContainer href={item.href}>
<Space size="small" align="start">
<Component />
{item.text}
</Space>
</LinkContainer>
</Menu.Item>
</MenuItem>
</Suspense>
</ErrorLink>
);
})}
</Menu.ItemGroup>
</Menu>
);
}

View File

@ -0,0 +1,10 @@
import { Menu } from 'antd';
import styled from 'styled-components';
export const MenuItem = styled(Menu.Item)`
&&& {
height: 1.75rem;
display: flex;
align-items: center;
}
`;

View File

@ -5,6 +5,7 @@ import {
QuestionCircleOutlined,
} from '@ant-design/icons';
import { Dropdown, Menu, Space } from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React, { useMemo, useState } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
@ -15,9 +16,8 @@ import HelpToolTip from './Config';
function DynamicConfigDropdown({
frontendId,
}: DynamicConfigDropdownProps): JSX.Element {
const { configs, isDarkMode } = useSelector<AppState, AppReducer>(
(state) => state.app,
);
const { configs } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
const [isHelpDropDownOpen, setIsHelpDropDownOpen] = useState<boolean>(false);
const config = useMemo(

View File

@ -1,5 +1,4 @@
import { Select } from 'antd';
import FormItem from 'antd/lib/form/FormItem';
import { Form, Select } from 'antd';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { AlertDef, Labels } from 'types/api/alerts/def';
@ -31,7 +30,7 @@ function BasicInfo({ alertDef, setAlertDef }: BasicInfoProps): JSX.Element {
<>
<StepHeading> {t('alert_form_step3')} </StepHeading>
<FormContainer>
<FormItem
<Form.Item
label={t('field_severity')}
labelAlign="left"
name={['labels', 'severity']}
@ -54,9 +53,9 @@ function BasicInfo({ alertDef, setAlertDef }: BasicInfoProps): JSX.Element {
<Option value="warning">{t('option_warning')}</Option>
<Option value="info">{t('option_info')}</Option>
</SeveritySelect>
</FormItem>
</Form.Item>
<FormItem label={t('field_alert_name')} labelAlign="left" name="alert">
<Form.Item label={t('field_alert_name')} labelAlign="left" name="alert">
<InputSmall
onChange={(e): void => {
setAlertDef({
@ -65,8 +64,8 @@ function BasicInfo({ alertDef, setAlertDef }: BasicInfoProps): JSX.Element {
});
}}
/>
</FormItem>
<FormItem
</Form.Item>
<Form.Item
label={t('field_alert_desc')}
labelAlign="left"
name={['annotations', 'description']}
@ -82,7 +81,7 @@ function BasicInfo({ alertDef, setAlertDef }: BasicInfoProps): JSX.Element {
});
}}
/>
</FormItem>
</Form.Item>
<FormItemMedium label={t('field_labels')}>
<LabelSelect
onSetLabels={(l: Labels): void => {

View File

@ -1,5 +1,5 @@
import { ExclamationCircleOutlined, SaveOutlined } from '@ant-design/icons';
import { FormInstance, Modal, notification, Typography } from 'antd';
import { Col, FormInstance, Modal, notification, Typography } from 'antd';
import saveAlertApi from 'api/alerts/save';
import testAlertApi from 'api/alerts/testAlert';
import ROUTES from 'constants/routes';
@ -34,7 +34,6 @@ import {
MainFormContainer,
PanelContainer,
StyledLeftContainer,
StyledRightContainer,
} from './styles';
import useDebounce from './useDebounce';
import UserGuide from './UserGuide';
@ -535,9 +534,9 @@ function FormAlertRules({
</ButtonContainer>
</MainFormContainer>
</StyledLeftContainer>
<StyledRightContainer flex="1 1 300px">
<Col flex="1 1 300px">
<UserGuide queryType={queryCategory} />
</StyledRightContainer>
</Col>
</PanelContainer>
</>
);

View File

@ -4,13 +4,11 @@ import {
} from '@ant-design/icons';
import { useMachine } from '@xstate/react';
import { Button, Input, message, Modal } from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { map } from 'lodash-es';
import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { Labels } from 'types/api/alerts/def';
import AppReducer from 'types/reducer/app';
import { v4 as uuid } from 'uuid';
import { ResourceAttributesFilterMachine } from './Labels.machine';
@ -29,7 +27,8 @@ function LabelSelect({
initialValues,
}: LabelSelectProps): JSX.Element | null {
const { t } = useTranslation('alerts');
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
const [currentVal, setCurrentVal] = useState('');
const [staging, setStaging] = useState<string[]>([]);
const [queries, setQueries] = useState<ILabelRecord[]>(

View File

@ -9,19 +9,15 @@ import {
Select,
Typography,
} from 'antd';
import FormItem from 'antd/lib/form/FormItem';
import TextArea from 'antd/lib/input/TextArea';
import styled from 'styled-components';
const { TextArea } = Input;
const { Item } = Form;
export const PanelContainer = styled(Row)`
flex-wrap: nowrap;
`;
export const StyledRightContainer = styled(Col)`
&&& {
}
`;
export const StyledLeftContainer = styled(Col)`
&&& {
margin-right: 1rem;
@ -111,7 +107,7 @@ export const TextareaMedium = styled(TextArea)`
width: 70%;
`;
export const FormItemMedium = styled(FormItem)`
export const FormItemMedium = styled(Item)`
width: 70%;
`;

View File

@ -1,5 +1,5 @@
import { convertTimeToRelevantUnit } from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React from 'react';
import { toFixed } from 'utils/toFixed';
@ -14,7 +14,7 @@ interface SpanLengthProps {
function SpanLength(props: SpanLengthProps): JSX.Element {
const { width, leftOffset, bgColor, inMsCount } = props;
const { isDarkMode } = useThemeMode();
const isDarkMode = useIsDarkMode();
const { time, timeUnitName } = convertTimeToRelevantUnit(inMsCount);
return (
<SpanWrapper>

View File

@ -1,10 +1,10 @@
import { CaretDownFilled, CaretRightFilled } from '@ant-design/icons';
import { Col } from 'antd';
import { Col, Typography } from 'antd';
import { StyledCol, StyledRow } from 'components/Styled';
import { IIntervalUnit } from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants';
import React, { useEffect, useRef, useState } from 'react';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { ITraceTree } from 'types/api/trace/getTraceItem';
import { ITraceMetaData } from '..';
@ -19,6 +19,7 @@ import {
styles,
Wrapper,
} from './styles';
import { getIconStyles } from './utils';
function Trace(props: TraceProps): JSX.Element {
const {
@ -42,7 +43,8 @@ function Trace(props: TraceProps): JSX.Element {
isMissing,
} = props;
const { isDarkMode } = useThemeMode();
const isDarkMode = useIsDarkMode();
const [isOpen, setOpen] = useState<boolean>(activeSpanPath[level] === id);
const localTreeExpandInteraction = useRef<boolean | 0>(0); // Boolean is for the state of the expansion whereas the number i.e. 0 is for skipping the user interaction.
@ -111,6 +113,18 @@ function Trace(props: TraceProps): JSX.Element {
const width = (value * 1e2) / (globalSpread * 1e6);
const panelWidth = SPAN_DETAILS_LEFT_COL_WIDTH - level * (16 + 1) - 48;
const iconStyles = useMemo(() => getIconStyles(isDarkMode), [isDarkMode]);
const icon = useMemo(
() =>
isOpen ? (
<CaretDownFilled style={iconStyles} />
) : (
<CaretRightFilled style={iconStyles} />
),
[isOpen, iconStyles],
);
return (
<Wrapper
onMouseEnter={onMouseEnterHandler}
@ -136,10 +150,8 @@ function Trace(props: TraceProps): JSX.Element {
isDarkMode={isDarkMode}
onClick={onClickTreeExpansion}
>
{totalSpans}
<CaretContainer>
{isOpen ? <CaretDownFilled /> : <CaretRightFilled />}
</CaretContainer>
<Typography>{totalSpans}</Typography>
<CaretContainer>{icon}</CaretContainer>
</CardComponent>
)}
</Col>

View File

@ -0,0 +1,3 @@
export const getIconStyles = (isDarkMode: boolean): Record<string, string> => ({
color: isDarkMode ? 'white' : 'black',
});

View File

@ -572,7 +572,7 @@ function GeneralSettings({
onOkHandler(category.name.toLowerCase() as TTTLType)
}
centered
visible={category.save.modal}
open={category.save.modal}
confirmLoading={category.save.apiLoading}
>
<Typography>

View File

@ -183,7 +183,7 @@ function GridCardGraph({
<Modal
destroyOnClose
onCancel={(): void => onToggleModal(setDeleteModal)}
visible={deleteModal}
open={deleteModal}
title="Delete"
height="10vh"
onOk={onDeleteHandler}
@ -196,7 +196,7 @@ function GridCardGraph({
title="View"
footer={[]}
centered
visible={modal}
open={modal}
onCancel={(): void => onToggleModal(setModal)}
width="85%"
destroyOnClose

View File

@ -1,5 +1,6 @@
import { PlusOutlined, SaveFilled } from '@ant-design/icons';
import useComponentPermission from 'hooks/useComponentPermission';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React from 'react';
import { Layout } from 'react-grid-layout';
import { useSelector } from 'react-redux';
@ -27,7 +28,7 @@ function GraphLayout({
setLayout,
}: GraphLayoutProps): JSX.Element {
const { role } = useSelector<AppState, AppReducer>((state) => state.app);
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
const [saveLayoutPermission, addPanelPermission] = useComponentPermission(
['save_layout', 'add_panel'],

View File

@ -3,67 +3,39 @@ import {
CaretUpFilled,
LogoutOutlined,
} from '@ant-design/icons';
import {
Avatar,
Divider,
Dropdown,
Layout,
Menu,
Space,
Typography,
} from 'antd';
import { Divider, Dropdown, Menu, Space, Typography } from 'antd';
import { Logout } from 'api/utils';
import ROUTES from 'constants/routes';
import Config from 'container/ConfigDropdown';
import setTheme, { AppMode } from 'lib/theme/setTheme';
import { useIsDarkMode, useThemeMode } from 'hooks/useDarkMode';
import React, { Dispatch, SetStateAction, useCallback, useState } from 'react';
import { connect, useSelector } from 'react-redux';
import { useSelector } from 'react-redux';
import { NavLink } from 'react-router-dom';
import { bindActionCreators } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import { ToggleDarkMode } from 'store/actions';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import AppReducer from 'types/reducer/app';
import CurrentOrganization from './CurrentOrganization';
import ManageLicense from './ManageLicense';
import SignedInAS from './SignedInAs';
import {
AvatarWrapper,
Container,
Header,
IconContainer,
LogoutContainer,
NavLinkWrapper,
ToggleButton,
} from './styles';
function HeaderContainer({ toggleDarkMode }: Props): JSX.Element {
const { isDarkMode, user, currentVersion } = useSelector<AppState, AppReducer>(
function HeaderContainer(): JSX.Element {
const { user, currentVersion } = useSelector<AppState, AppReducer>(
(state) => state.app,
);
const isDarkMode = useIsDarkMode();
const { toggleTheme } = useThemeMode();
const [isUserDropDownOpen, setIsUserDropDownOpen] = useState<boolean>(false);
const onToggleThemeHandler = useCallback(() => {
const preMode: AppMode = isDarkMode ? 'lightMode' : 'darkMode';
setTheme(preMode);
const id: AppMode = preMode;
const { head } = document;
const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = !isDarkMode ? '/css/antd.dark.min.css' : '/css/antd.min.css';
link.media = 'all';
link.id = id;
head.appendChild(link);
link.onload = (): void => {
toggleDarkMode();
const prevNode = document.getElementById('appMode');
prevNode?.remove();
};
}, [toggleDarkMode, isDarkMode]);
const onToggleHandler = useCallback(
(functionToExecute: Dispatch<SetStateAction<boolean>>) => (): void => {
functionToExecute((state) => !state);
@ -100,15 +72,18 @@ function HeaderContainer({ toggleDarkMode }: Props): JSX.Element {
);
return (
<Layout.Header>
<Header>
<Container>
<NavLink to={ROUTES.APPLICATION}>
<Space align="center" direction="horizontal">
<NavLinkWrapper>
<img src={`/signoz.svg?currentVersion=${currentVersion}`} alt="SigNoz" />
<Typography.Title style={{ margin: 0, color: '#DBDBDB' }} level={4}>
<Typography.Title
style={{ margin: 0, color: 'rgb(219, 219, 219)' }}
level={4}
>
SigNoz
</Typography.Title>
</Space>
</NavLinkWrapper>
</NavLink>
<Space style={{ height: '100%' }} align="center">
@ -116,7 +91,7 @@ function HeaderContainer({ toggleDarkMode }: Props): JSX.Element {
<ToggleButton
checked={isDarkMode}
onChange={onToggleThemeHandler}
onChange={toggleTheme}
defaultChecked={isDarkMode}
checkedChildren="🌜"
unCheckedChildren="🌞"
@ -129,7 +104,7 @@ function HeaderContainer({ toggleDarkMode }: Props): JSX.Element {
visible={isUserDropDownOpen}
>
<Space>
<Avatar shape="circle">{user?.name[0]}</Avatar>
<AvatarWrapper shape="circle">{user?.name[0]}</AvatarWrapper>
<IconContainer>
{!isUserDropDownOpen ? <CaretDownFilled /> : <CaretUpFilled />}
</IconContainer>
@ -137,20 +112,8 @@ function HeaderContainer({ toggleDarkMode }: Props): JSX.Element {
</Dropdown>
</Space>
</Container>
</Layout.Header>
</Header>
);
}
interface DispatchProps {
toggleDarkMode: () => void;
}
const mapDispatchToProps = (
dispatch: ThunkDispatch<unknown, unknown, AppActions>,
): DispatchProps => ({
toggleDarkMode: bindActionCreators(ToggleDarkMode, dispatch),
});
type Props = DispatchProps;
export default connect(null, mapDispatchToProps)(HeaderContainer);
export default HeaderContainer;

View File

@ -1,10 +1,14 @@
import { Switch, Typography } from 'antd';
import { Avatar, Layout, Switch, Typography } from 'antd';
import styled from 'styled-components';
export const Header = styled(Layout.Header)`
background: #1f1f1f !important;
`;
export const Container = styled.div`
display: flex;
justify-content: space-between;
height: 100%;
height: 4rem;
`;
export const AvatarContainer = styled.div`
@ -66,3 +70,15 @@ export const ToggleButton = styled(Switch)<DarkModeProps>`
export const IconContainer = styled.div`
color: white;
`;
export const NavLinkWrapper = styled.div`
display: flex;
align-items: center;
justify-content: center;
height: 100%;
gap: 0.5rem;
`;
export const AvatarWrapper = styled(Avatar)`
background-color: rgba(255, 255, 255, 0.25);
`;

View File

@ -1,4 +1,4 @@
import { NotificationInstance } from 'antd/lib/notification/index';
import { NotificationInstance } from 'antd/es/notification/interface';
import deleteAlerts from 'api/alerts/delete';
import { State } from 'hooks/useFetch';
import React, { useState } from 'react';

View File

@ -1,7 +1,7 @@
/* eslint-disable react/display-name */
import { PlusOutlined } from '@ant-design/icons';
import { notification, Typography } from 'antd';
import Table, { ColumnsType } from 'antd/lib/table';
import { notification, Table, Typography } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import TextToolTip from 'components/TextToolTip';
import ROUTES from 'constants/routes';
import useComponentPermission from 'hooks/useComponentPermission';

View File

@ -131,7 +131,7 @@ function ImportJSON({
return (
<Modal
visible={isImportJSONModalVisible}
open={isImportJSONModalVisible}
centered
maskClosable
destroyOnClose

View File

@ -5,10 +5,7 @@ import { RefSelectProps } from 'antd/lib/select';
import history from 'lib/history';
import { filter, map } from 'lodash-es';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { Dashboard } from 'types/api/dashboard/getAll';
import AppReducer from 'types/reducer/app';
import { v4 as uuidv4 } from 'uuid';
import { DashboardSearchAndFilter } from './Dashboard.machine';
@ -30,7 +27,6 @@ function SearchFilter({
searchData: Dashboard[];
filterDashboards: (filteredDashboards: Dashboard[]) => void;
}): JSX.Element {
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const [category, setCategory] = useState<TCategory>();
const [optionsData, setOptionsData] = useState<IOptionsData>(
OptionsSchemas.attribute,
@ -154,14 +150,8 @@ function SearchFilter({
};
return (
<SearchContainer isDarkMode={isDarkMode}>
<div
style={{
maxWidth: '70%',
display: 'flex',
overflowX: 'auto',
}}
>
<SearchContainer>
<div>
{map(queries, (query) => (
<QueryChip key={query.id} queryData={query} onRemove={removeQueryById} />
))}

View File

@ -2,10 +2,7 @@ import { grey } from '@ant-design/colors';
import { Tag } from 'antd';
import styled from 'styled-components';
export const SearchContainer = styled.div<{
isDarkMode: boolean;
}>`
background: ${({ isDarkMode }): string => (isDarkMode ? '#000' : '#fff')};
export const SearchContainer = styled.div`
width: 100%;
display: flex;
align-items: center;

View File

@ -45,7 +45,7 @@ function TableView({ logData }: TableViewProps): JSX.Element | null {
const columns = [
{
title: 'Action',
width: 75,
width: 100,
render: (fieldData: Record<string, string>): JSX.Element | null => {
const fieldKey = fieldData.field.split('.').slice(-1);
if (!RESTRICTED_FIELDS.includes(fieldKey[0])) {

View File

@ -1,20 +1,22 @@
import { Drawer, Tabs } from 'antd';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Dispatch } from 'redux';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import { SET_DETAILED_LOG_DATA } from 'types/actions/logs';
import { ILogsReducer } from 'types/reducer/logs';
import JSONView from './JsonView';
import TableView from './TableView';
const { TabPane } = Tabs;
function LogDetailedView(): JSX.Element {
const { detailedLog } = useSelector<AppState, ILogsReducer>(
(state) => state.logs,
);
const dispatch = useDispatch();
const dispatch = useDispatch<Dispatch<AppActions>>();
const onDrawerClose = (): void => {
dispatch({
type: SET_DETAILED_LOG_DATA,
@ -23,30 +25,25 @@ function LogDetailedView(): JSX.Element {
};
return (
<div style={{}}>
<Drawer
width="60%"
title="Log Details"
placement="right"
closable
mask={false}
onClose={onDrawerClose}
visible={detailedLog !== null}
getContainer={false}
open={detailedLog !== null}
style={{ overscrollBehavior: 'contain' }}
destroyOnClose
>
{detailedLog && (
<Tabs defaultActiveKey="1">
<TabPane tab="Table" key="1">
<TableView logData={detailedLog} />
</TabPane>
<TabPane tab="JSON" key="2">
<JSONView logData={detailedLog} />
</TabPane>
<Tabs.TabPane tab="Table" key="1">
{detailedLog && <TableView logData={detailedLog} />}
</Tabs.TabPane>
<Tabs.TabPane tab="JSON" key="2">
{detailedLog && <JSONView logData={detailedLog} />}
</Tabs.TabPane>
</Tabs>
)}
</Drawer>
</div>
);
}

View File

@ -7,6 +7,7 @@ import {
import { Button, Popover, Select, Space } from 'antd';
import { LiveTail } from 'api/logs/livetail';
import dayjs from 'dayjs';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { throttle } from 'lodash-es';
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
@ -19,7 +20,6 @@ import {
TOGGLE_LIVE_TAIL,
} from 'types/actions/logs';
import { TLogsLiveTailState } from 'types/api/logs/liveTail';
import AppReducer from 'types/reducer/app';
import { GlobalReducer } from 'types/reducer/globalTime';
import { ILogsReducer } from 'types/reducer/logs';
@ -35,7 +35,8 @@ function LogLiveTail(): JSX.Element {
liveTailStartRange,
logs,
} = useSelector<AppState, ILogsReducer>((state) => state.logs);
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
const { selectedAutoRefreshInterval } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);

View File

@ -1,9 +1,7 @@
import { LoadingOutlined } from '@ant-design/icons';
import { Button, Popover, Spin } from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import AppReducer from 'types/reducer/app';
import { Field } from './styles';
@ -26,7 +24,7 @@ export function FieldItem({
iconHoverText,
}: FieldItemProps): JSX.Element {
const [isHovered, setIsHovered] = useState(false);
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
return (
<Field
onMouseEnter={(): void => {

View File

@ -2,7 +2,7 @@
import { Typography } from 'antd';
import LogItem from 'components/Logs/LogItem';
import Spinner from 'components/Spinner';
import { map } from 'lodash-es';
import map from 'lodash-es/map';
import React, { memo } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
@ -22,14 +22,7 @@ function LogsTable(): JSX.Element {
return (
<Container flex="auto">
<Heading>
<Typography.Text
style={{
fontSize: '1rem',
fontWeight: 400,
}}
>
Event
</Typography.Text>
<Typography.Text>Event</Typography.Text>
</Heading>
{Array.isArray(logs) && logs.length > 0 ? (
map(logs, (log) => <LogItem key={log.id} logData={log} />)

View File

@ -10,7 +10,6 @@ import { useDispatch, useSelector } from 'react-redux';
import { ResetInitialData } from 'store/actions/metrics/resetInitialData';
import { SetResourceAttributeQueries } from 'store/actions/metrics/setResourceAttributeQueries';
import { AppState } from 'store/reducers';
import AppReducer from 'types/reducer/app';
import MetricReducer from 'types/reducer/metrics';
import { v4 as uuid } from 'uuid';
@ -38,7 +37,6 @@ function ResourceAttributesFilter(): JSX.Element | null {
};
}, [dispatch]);
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const { resourceAttributeQueries } = useSelector<AppState, MetricReducer>(
(state) => state.metrics,
);
@ -156,7 +154,7 @@ function ResourceAttributesFilter(): JSX.Element | null {
}
return (
<SearchContainer isDarkMode={isDarkMode} disabled={disabled}>
<SearchContainer disabled={disabled}>
<div
style={{
maxWidth: disabled ? '100%' : '70%',

View File

@ -3,10 +3,8 @@ import { Tag } from 'antd';
import styled from 'styled-components';
export const SearchContainer = styled.div<{
isDarkMode: boolean;
disabled: boolean;
}>`
background: ${({ isDarkMode }): string => (isDarkMode ? '#000' : '#fff')};
width: 100%;
display: flex;
align-items: center;

View File

@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { notification } from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
import history from 'lib/history';
import React, { useCallback } from 'react';
import { connect, useSelector } from 'react-redux';
@ -11,7 +12,6 @@ import {
} from 'store/actions/dashboard/toggleAddWidget';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import AppReducer from 'types/reducer/app';
import DashboardReducer from 'types/reducer/dashboards';
import menuItems, { ITEMS } from './menuItems';
@ -50,7 +50,7 @@ function DashboardGraphSlider({ toggleAddWidget }: Props): JSX.Element {
},
[data, toggleAddWidget],
);
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
const fillColor: React.CSSProperties['color'] = isDarkMode ? 'white' : 'black';
return (

View File

@ -165,7 +165,7 @@ function VariablesSetting({
<Modal
title="Delete variable"
centered
visible={deleteVariableModal}
open={deleteVariableModal}
onOk={handleDeleteConfirm}
onCancel={handleDeleteCancel}
>

View File

@ -83,7 +83,7 @@ function ShareModal({
return (
<Modal
visible={isJSONModalVisible}
open={isJSONModalVisible}
onCancel={(): void => {
onToggleHandler();
setIsViewJSON(false);

View File

@ -1,12 +1,10 @@
import { CloseCircleFilled } from '@ant-design/icons';
import { useMachine } from '@xstate/react';
import { Button, Select, Spin } from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { map } from 'lodash-es';
import React, { useCallback, useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { IMetricsBuilderQuery } from 'types/api/dashboard/getAll';
import AppReducer from 'types/reducer/app';
import { v4 as uuid } from 'uuid';
import { ResourceAttributesFilterMachine } from './MetricTagKey.machine';
@ -32,7 +30,7 @@ function MetricTagKeyFilter({
onSetQuery,
selectedTagFilters: selectedTagQueries,
}: IMetricTagKeyFilterProps): JSX.Element | null {
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
const [loading, setLoading] = useState(true);
const [selectedValues, setSelectedValues] = useState<string[]>([]);
const [staging, setStaging] = useState<string[]>([]);

View File

@ -213,7 +213,7 @@ function NewWidget({
onClickSaveHandler();
}}
centered
visible={saveModal}
open={saveModal}
width={600}
>
{hasUnstagedChanges ? (

View File

@ -69,7 +69,7 @@ function AddDomain({ refetch }: Props): JSX.Element {
centered
title="Add Domain"
footer={null}
visible={isAddDomains}
open={isAddDomains}
destroyOnClose
onCancel={(): void => setIsDomain(false)}
>

View File

@ -256,7 +256,7 @@ function AuthDomains(): JSX.Element {
title="Configure Authentication Method"
onCancel={onCloseHandler(setIsSettingsOpen)}
destroyOnClose
visible={isSettingsOpen}
open={isSettingsOpen}
footer={null}
>
<Create
@ -285,7 +285,7 @@ function AuthDomains(): JSX.Element {
title="Configure Authentication Method"
onCancel={onCloseHandler(setIsSettingsOpen)}
destroyOnClose
visible={isSettingsOpen}
open={isSettingsOpen}
footer={null}
>
<Create
@ -297,7 +297,7 @@ function AuthDomains(): JSX.Element {
</Modal>
<Modal
visible={isEditModalOpen}
open={isEditModalOpen}
centered
title={EditModalTitleText(currentDomain?.ssoType)}
onCancel={onCloseHandler(setIsEditModalOpen)}

View File

@ -1,5 +1,5 @@
import { Button, Modal, notification, Space, Typography } from 'antd';
import Table, { ColumnsType } from 'antd/lib/table';
import { Button, Modal, notification, Space, Table, Typography } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import deleteUser from 'api/user/deleteUser';
import editUserApi from 'api/user/editUser';
import getOrgUser from 'api/user/getOrgUser';
@ -176,7 +176,7 @@ function UserFunction({
</Space>
<Modal
title="Edit member details"
visible={isModalVisible}
open={isModalVisible}
onOk={(): void => onModalToggleHandler(setIsModalVisible, false)}
onCancel={(): void => onModalToggleHandler(setIsModalVisible, false)}
centered
@ -214,7 +214,7 @@ function UserFunction({
</Modal>
<Modal
title="Edit member details"
visible={isDeleteModalVisible}
open={isDeleteModalVisible}
onOk={onDeleteHandler}
onCancel={(): void => onModalToggleHandler(setIsDeleteModalVisible, false)}
centered

View File

@ -1,6 +1,6 @@
import { PlusOutlined } from '@ant-design/icons';
import { Button, Modal, notification, Space, Typography } from 'antd';
import Table, { ColumnsType } from 'antd/lib/table';
import { Button, Modal, notification, Space, Table, Typography } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import deleteInvite from 'api/user/deleteInvite';
import getPendingInvites from 'api/user/getPendingInvites';
import sendInvite from 'api/user/sendInvite';
@ -222,7 +222,7 @@ function PendingInvitesContainer(): JSX.Element {
<div>
<Modal
title={t('invite_team_members')}
visible={isInviteTeamMemberModalOpen}
open={isInviteTeamMemberModalOpen}
onCancel={(): void => toggleModal(false)}
centered
destroyOnClose

View File

@ -0,0 +1 @@
export const styles = { background: '#1f1f1f' };

View File

@ -4,7 +4,7 @@ import getLocalStorageKey from 'api/browser/localstorage/get';
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
import ROUTES from 'constants/routes';
import history from 'lib/history';
import React, { useCallback, useLayoutEffect, useState } from 'react';
import React, { useCallback, useLayoutEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom';
@ -12,6 +12,7 @@ import { SideBarCollapse } from 'store/actions/app';
import { AppState } from 'store/reducers';
import AppReducer from 'types/reducer/app';
import { styles } from './config';
import menus from './menuItems';
import Slack from './Slack';
import {
@ -89,7 +90,10 @@ function SideNav(): JSX.Element {
},
];
const currentMenu = menus.find((menu) => pathname.startsWith(menu.to));
const currentMenu = useMemo(
() => menus.find((menu) => pathname.startsWith(menu.to)),
[pathname],
);
return (
<Sider collapsible collapsed={collapsed} onCollapse={onCollapse} width={200}>
@ -98,6 +102,7 @@ function SideNav(): JSX.Element {
defaultSelectedKeys={[ROUTES.APPLICATION]}
selectedKeys={currentMenu ? [currentMenu?.to] : []}
mode="inline"
style={styles}
>
{menus.map(({ to, Icon, name, tags }) => (
<Menu.Item

View File

@ -10,18 +10,19 @@ interface LogoProps {
}
export const Sider = styled(SiderComponent)`
z-index: 999;
.ant-typography {
color: white;
}
&&& {
background: #1f1f1f;
.ant-layout-sider-trigger {
background-color: #1f1f1f;
background: #1f1f1f;
}
}
`;
export const SlackButton = styled(Typography)`
&&& {
margin-left: 1rem;
color: white;
}
`;
@ -31,6 +32,7 @@ export const SlackMenuItemContainer = styled.div<LogoProps>`
background: #262626;
width: ${({ collapsed }): string => (!collapsed ? '200px' : '80px')};
transition: inherit;
background: #1f1f1f;
&&& {
li {

View File

@ -1,7 +1,7 @@
import { StyledDiv } from 'components/Styled';
import { ITraceMetaData } from 'container/GantChart';
import { IIntervalUnit, INTERVAL_UNITS } from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React, { useEffect, useState } from 'react';
import { useMeasure } from 'react-use';
@ -18,7 +18,7 @@ function Timeline({
setIntervalUnit,
}: TimelineProps): JSX.Element {
const [ref, { width }] = useMeasure<HTMLDivElement>();
const { isDarkMode } = useThemeMode();
const isDarkMode = useIsDarkMode();
const [intervals, setIntervals] = useState<Interval[] | null>(null);

View File

@ -1,6 +1,5 @@
/* eslint-disable react/jsx-no-bind */
import { Modal } from 'antd';
import DatePicker from 'components/DatePicker';
import { DatePicker, Modal } from 'antd';
import dayjs, { Dayjs } from 'dayjs';
import React, { useState } from 'react';
@ -13,22 +12,22 @@ function CustomDateTimeModal({
onCreate,
onCancel,
}: CustomDateTimeModalProps): JSX.Element {
const [
customDateTimeRange,
setCustomDateTimeRange,
] = useState<DateTimeRangeType>();
const [customDateTimeRange, setCustomDateTimeRange] = useState();
function handleRangePickerOk(date_time: DateTimeRangeType): void {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function handleRangePickerOk(date_time: any): void {
setCustomDateTimeRange(date_time);
}
function disabledDate(current: Dayjs): boolean {
return current > dayjs();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function disabledDate(current: any): boolean {
const currentDay = dayjs(current);
return currentDay.isAfter(dayjs());
}
return (
<Modal
visible={visible}
open={visible}
title="Chose date and time range"
okText="Apply"
cancelText="Cancel"

View File

@ -1,5 +1,5 @@
import { TableProps, Tag, Typography } from 'antd';
import Table, { ColumnsType } from 'antd/lib/table';
import { Table, TableProps, Tag, Typography } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import ROUTES from 'constants/routes';
import {
getSpanOrder,

View File

@ -1,5 +1,5 @@
import { Collapse } from 'antd';
import useThemeMode from 'hooks/useThemeMode';
import { useIsDarkMode } from 'hooks/useDarkMode';
import keys from 'lodash-es/keys';
import map from 'lodash-es/map';
import React from 'react';
@ -18,7 +18,7 @@ function ErrorTag({
setText,
firstSpanStartTime,
}: ErrorTagProps): JSX.Element {
const { isDarkMode } = useThemeMode();
const isDarkMode = useIsDarkMode();
return (
<>

View File

@ -1,12 +1,12 @@
import { Popover } from 'antd';
import dayjs from 'dayjs';
import useThemeMode from 'hooks/useThemeMode';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React from 'react';
import { CustomSubText, CustomSubTitle } from '../styles';
function EventStartTime({ timeUnixNano }: EventStartTimeProps): JSX.Element {
const { isDarkMode } = useThemeMode();
const isDarkMode = useIsDarkMode();
const humanReadableTimeInDayJs = dayjs(timeUnixNano / 1e6).format(
'YYYY-MM-DD hh:mm:ss.SSS A',

View File

@ -1,7 +1,7 @@
import { InfoCircleOutlined } from '@ant-design/icons';
import { Popover, Space } from 'antd';
import { convertTimeToRelevantUnit } from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React from 'react';
import { CustomSubText, CustomSubTitle } from '../styles';
@ -10,7 +10,7 @@ function StartTime({
firstSpanStartTime,
timeUnixNano,
}: StartTimeProps): JSX.Element {
const { isDarkMode } = useThemeMode();
const isDarkMode = useIsDarkMode();
const { time, timeUnitName } = convertTimeToRelevantUnit(
timeUnixNano / 1e6 - (firstSpanStartTime || 0),

View File

@ -1,9 +1,7 @@
import { Tooltip } from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { ITraceTag } from 'types/api/trace/getTraceItem';
import AppReducer from 'types/reducer/app';
import EllipsedButton from '../EllipsedButton';
import { CustomSubText, CustomSubTitle, SubTextContainer } from '../styles';
@ -11,7 +9,7 @@ import { CommonTagsProps } from '.';
import { Container } from './styles';
function Tag({ tags, onToggleHandler, setText }: TagProps): JSX.Element {
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
const { value, isEllipsed } = useMemo(() => {
const value = tags.key === 'error' ? 'true' : tags.value;

View File

@ -1,7 +1,7 @@
import { Modal, Tabs, Tooltip } from 'antd';
import Editor from 'components/Editor';
import { StyledSpace } from 'components/Styled';
import useThemeMode from 'hooks/useThemeMode';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React, { useMemo, useState } from 'react';
import { ITraceTree } from 'types/api/trace/getTraceItem';
@ -20,7 +20,7 @@ const { TabPane } = Tabs;
function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element {
const { tree, firstSpanStartTime } = props;
const { isDarkMode } = useThemeMode();
const isDarkMode = useIsDarkMode();
const OverLayComponentName = useMemo(() => tree?.name, [tree?.name]);
const OverLayComponentServiceName = useMemo(() => tree?.serviceName, [
@ -67,7 +67,7 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element {
<Modal
onCancel={(): void => onToggleHandler(false)}
title={text.text}
visible={isOpen}
open={isOpen}
destroyOnClose
footer={[]}
width="70vw"

View File

@ -1,7 +1,7 @@
/* eslint-disable react/no-unstable-nested-components */
import Color from 'color';
import { ITraceMetaData } from 'container/GantChart';
import useThemeMode from 'hooks/useThemeMode';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React, { useLayoutEffect, useMemo, useState } from 'react';
import { ITraceTree } from 'types/api/trace/getTraceItem';
@ -37,7 +37,7 @@ function SpanItem({
const { serviceColour } = spanData;
const [isSelected, setIsSelected] = useState<boolean>(false);
// const [isLocalHover, setIsLocalHover] = useState<boolean>(false);
const { isDarkMode } = useThemeMode();
const isDarkMode = useIsDarkMode();
useLayoutEffect(() => {
if (

View File

@ -0,0 +1,4 @@
export const THEME_MODE = {
LIGHT: 'light',
DARK: 'dark',
};

View File

@ -0,0 +1,74 @@
import { theme as antdTheme } from 'antd';
import { ThemeConfig } from 'antd/es/config-provider/context';
import get from 'api/browser/localstorage/get';
import set from 'api/browser/localstorage/set';
import { LOCALSTORAGE } from 'constants/localStorage';
import React, { createContext, useCallback, useMemo, useState } from 'react';
import { THEME_MODE } from './constant';
export const ThemeContext = createContext({
theme: THEME_MODE.DARK,
toggleTheme: () => {},
});
export function ThemeProvider({ children }: ThemeProviderProps): JSX.Element {
const [theme, setTheme] = useState(get(LOCALSTORAGE.THEME) || THEME_MODE.DARK);
const toggleTheme = useCallback(() => {
if (theme === THEME_MODE.LIGHT) {
setTheme(THEME_MODE.DARK);
set(LOCALSTORAGE.THEME, THEME_MODE.DARK);
} else {
setTheme(THEME_MODE.LIGHT);
set(LOCALSTORAGE.THEME, THEME_MODE.LIGHT);
}
}, [theme]);
const value = useMemo(
() => ({
theme,
toggleTheme,
}),
[theme, toggleTheme],
);
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
}
interface ThemeProviderProps {
children: React.ReactNode;
}
interface ThemeMode {
theme: string;
toggleTheme: () => void;
}
export const useThemeMode = (): ThemeMode => {
const { theme, toggleTheme } = React.useContext(ThemeContext);
return { theme, toggleTheme };
};
export const useIsDarkMode = (): boolean => {
const { theme } = React.useContext(ThemeContext);
return theme === THEME_MODE.DARK;
};
export const useThemeConfig = (): ThemeConfig => {
const isDarkMode = useIsDarkMode();
return {
algorithm: isDarkMode ? antdTheme.darkAlgorithm : antdTheme.defaultAlgorithm,
token: {
borderRadius: 2,
borderRadiusLG: 2,
borderRadiusSM: 2,
borderRadiusXS: 2,
},
};
};
export default useThemeMode;

View File

@ -1,15 +0,0 @@
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import AppReducer from 'types/reducer/app';
export interface IUseThemeModeReturn {
isDarkMode: boolean;
}
const useThemeMode = (): IUseThemeModeReturn => {
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
return { isDarkMode };
};
export default useThemeMode;

View File

@ -50,27 +50,9 @@
<meta data-react-helmet="true" name="docusaurus_locale" content="en" />
<meta data-react-helmet="true" name="docusaurus_tag" content="default" />
<link data-react-helmet="true" rel="shortcut icon" href="/favicon.ico" />
<link
id="appMode"
rel="stylesheet"
type="text/css"
rel="preload"
/>
</head>
<body>
<body style="margin: 0; padding: 0; box-sizing: border-box;">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script>
const themeNode = document.getElementById('appMode');
let userTheme = localStorage.getItem('theme') || "";
if (userTheme === 'lightMode') {
themeNode.setAttribute('href', '/css/antd.min.css');
} else {
themeNode.setAttribute('href', '/css/antd.dark.min.css');
}
</script>
</body>
</html>

View File

@ -2,6 +2,7 @@ import './wdyr';
import './ReactI18';
import AppRoutes from 'AppRoutes';
import { ThemeProvider } from 'hooks/useDarkMode';
import React from 'react';
import ReactDOM from 'react-dom';
import { QueryClient, QueryClientProvider } from 'react-query';
@ -23,6 +24,7 @@ const queryClient = new QueryClient({
});
ReactDOM.render(
<ThemeProvider>
<QueryClientProvider client={queryClient}>
<Provider store={store}>
<React.StrictMode>
@ -32,6 +34,7 @@ ReactDOM.render(
{process.env.NODE_ENV === 'development' && (
<ReactQueryDevtools initialIsOpen />
)}
</QueryClientProvider>,
</QueryClientProvider>
</ThemeProvider>,
document.querySelector('#root'),
);

View File

@ -1,14 +0,0 @@
import getLocalStorageKey from 'api/browser/localstorage/get';
import { AppMode } from './setTheme';
const getTheme = (): AppMode => {
const userTheme = getLocalStorageKey('theme');
if (userTheme === null || userTheme === 'darkMode') {
return 'darkMode';
}
return 'lightMode';
};
export default getTheme;

View File

@ -1,9 +0,0 @@
import setLocalStorageKey from 'api/browser/localstorage/set';
const setTheme = (value: AppMode): void => {
setLocalStorageKey('theme', value);
};
export type AppMode = 'darkMode' | 'lightMode';
export default setTheme;

View File

@ -1,84 +0,0 @@
/* eslint-disable */
//@ts-nocheck
import { InfoCircleOutlined } from '@ant-design/icons';
import { Select } from 'antd';
import { cloneDeep } from 'lodash-es';
import React, { useState } from 'react';
import { ServicesItem } from 'store/actions';
import styled from 'styled-components';
const { Option } = Select;
const Container = styled.div`
margin-top: 12px;
display: flex;
.info {
display: flex;
font-family: Roboto;
margin-left: auto;
margin-right: 12px;
color: #4f4f4f;
font-size: 14px;
.anticon-info-circle {
margin-top: 22px;
margin-right: 18px;
}
}
`;
interface SelectServiceProps {
services: ServicesItem[];
zoomToService: (arg0: string) => void;
zoomToDefault: () => void;
}
const defaultOption = {
serviceName: 'Default',
};
function SelectService(props: SelectServiceProps): JSX.Element {
const [selectedVal, setSelectedVal] = useState<string>(
defaultOption.serviceName,
);
const { zoomToService, zoomToDefault, services } = props;
const service = cloneDeep(services);
service.unshift(defaultOption);
const handleSelect = (value: string): void => {
if (value === defaultOption.serviceName) {
zoomToDefault();
} else {
zoomToService(value);
}
setSelectedVal(value);
};
return (
<Container>
<Select
style={{ width: 270, marginBottom: '56px' }}
placeholder="Select a service"
onChange={handleSelect}
value={selectedVal}
>
{service.map(({ serviceName }) => (
<Option key={serviceName} value={serviceName}>
{serviceName}
</Option>
))}
</Select>
<div className="info">
<InfoCircleOutlined />
<div>
<div>
&gt; Size of circles is proportial to the number of requests served by
each node
</div>
<div>&gt; Click on node name to reposition the node</div>
</div>
</div>
</Container>
);
}
export default SelectService;

View File

@ -3,17 +3,16 @@
import { Card } from 'antd';
import Spinner from 'components/Spinner';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React, { useEffect, useRef } from 'react';
import { ForceGraph2D } from 'react-force-graph';
import { connect, useSelector } from 'react-redux';
import { connect } from 'react-redux';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { getDetailedServiceMapItems, ServiceMapStore } from 'store/actions';
import { AppState } from 'store/reducers';
import styled from 'styled-components';
import { GlobalTime } from 'types/actions/globalTime';
import AppReducer from 'types/reducer/app';
import SelectService from './SelectService';
import { getGraphData, getTooltip, getZoomPx, transformLabel } from './utils';
const Container = styled.div`
@ -61,7 +60,7 @@ export interface graphDataType {
function ServiceMap(props: ServiceMapProps): JSX.Element {
const fgRef = useRef();
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
const { getDetailedServiceMapItems, globalTime, serviceMap } = props;
@ -89,25 +88,10 @@ function ServiceMap(props: ServiceMapProps): JSX.Element {
);
}
const zoomToService = (value: string): void => {
fgRef &&
fgRef.current &&
fgRef.current.zoomToFit(700, getZoomPx(), (e) => e.id === value);
};
const zoomToDefault = () => {
fgRef && fgRef.current && fgRef.current.zoomToFit(100, 120);
};
const { nodes, links } = getGraphData(serviceMap, isDarkMode);
const graphData = { nodes, links };
return (
<Container>
{/* <SelectService
services={serviceMap.items}
zoomToService={zoomToService}
zoomToDefault={zoomToDefault}
/> */}
<ForceGraph2D
ref={fgRef}
cooldownTicks={100}
@ -153,12 +137,10 @@ const mapStateToProps = (
): {
serviceMap: serviceMapStore;
globalTime: GlobalTime;
} => {
return {
} => ({
serviceMap: state.serviceMap,
globalTime: state.globalTime,
};
};
});
export default withRouter(
connect(mapStateToProps, {

View File

@ -1,9 +1,7 @@
import { Typography } from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React from 'react';
import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import { AppState } from 'store/reducers';
import AppReducer from 'types/reducer/app';
import { DocCardContainer } from './styles';
import { TGetStartedContentDoc } from './types';
@ -15,7 +13,7 @@ interface IDocCardProps {
url: TGetStartedContentDoc['url'];
}
function DocCard({ icon, text, url }: IDocCardProps): JSX.Element {
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const isDarkMode = useIsDarkMode();
return (
<Link to={{ pathname: `${url}${UTMParams}` }} target="_blank">

View File

@ -1,2 +1 @@
export * from './sideBarCollapse';
export * from './toggleDarkMode';

View File

@ -1,12 +0,0 @@
import { Dispatch } from 'redux';
import AppActions from 'types/actions';
export const ToggleDarkMode = (): ((
dispatch: Dispatch<AppActions>,
) => void) => {
return (dispatch: Dispatch<AppActions>): void => {
dispatch({
type: 'SWITCH_DARK_MODE',
});
};
};

View File

@ -1,13 +1,11 @@
import getLocalStorageKey from 'api/browser/localstorage/get';
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
import { LOCALSTORAGE } from 'constants/localStorage';
import getTheme from 'lib/theme/getTheme';
import { getInitialUserTokenRefreshToken } from 'store/utils';
import {
AppAction,
LOGGED_IN,
SIDEBAR_COLLAPSE,
SWITCH_DARK_MODE,
UPDATE_CONFIGS,
UPDATE_CURRENT_ERROR,
UPDATE_CURRENT_VERSION,
@ -45,7 +43,6 @@ const getInitialUser = (): User | null => {
};
const InitialValue: InitialValueTypes = {
isDarkMode: getTheme() === 'darkMode',
isLoggedIn: getLocalStorageKey(LOCALSTORAGE.IS_LOGGED_IN) === 'true',
isSideBarCollapsed: getLocalStorageKey(IS_SIDEBAR_COLLAPSED) === 'true',
currentVersion: '',
@ -67,13 +64,6 @@ const appReducer = (
action: AppAction,
): InitialValueTypes => {
switch (action.type) {
case SWITCH_DARK_MODE: {
return {
...state,
isDarkMode: !state.isDarkMode,
};
}
case LOGGED_IN: {
return {
...state,

View File

@ -7,7 +7,6 @@ import { UserFlags } from 'types/api/user/setFlags';
import AppReducer, { User } from 'types/reducer/app';
import { ROLES } from 'types/roles';
export const SWITCH_DARK_MODE = 'SWITCH_DARK_MODE';
export const LOGGED_IN = 'LOGGED_IN';
export const SIDEBAR_COLLAPSE = 'SIDEBAR_COLLAPSE';
@ -27,10 +26,6 @@ export const UPDATE_FEATURE_FLAGS = 'UPDATE_FEATURE_FLAGS';
export const UPDATE_CONFIGS = 'UPDATE_CONFIGS';
export const UPDATE_USER_FLAG = 'UPDATE_USER_FLAG';
export interface SwitchDarkMode {
type: typeof SWITCH_DARK_MODE;
}
export interface LoggedInUser {
type: typeof LOGGED_IN;
payload: {
@ -134,7 +129,6 @@ export interface UpdateConfigs {
}
export type AppAction =
| SwitchDarkMode
| LoggedInUser
| SideBarCollapse
| UpdateAppVersion

View File

@ -102,7 +102,7 @@ export interface SetLogsAggregateSeries {
}
export interface SetDetailedLogData {
type: typeof SET_DETAILED_LOG_DATA;
payload: ILog;
payload: ILog | null;
}
export interface ToggleLiveTail {

View File

@ -15,7 +15,6 @@ export interface User {
}
export default interface AppReducer {
isDarkMode: boolean;
isLoggedIn: boolean;
isSideBarCollapsed: boolean;
currentVersion: string;

File diff suppressed because it is too large Load Diff