mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-11 21:09:09 +08:00
Fix(FE): dark mode (#301)
* fix: fav icon is fixed and bootstrap is removed * fix: return type is updated for the global time reducer * fix: theme.css is replaced with .min.css * update: useThemeSwitcher is removed from the graph component and value is grabed from the reducer * update: instrumentation page is updated * update: react-css-theme-switcher package is removed * update: darkMode is updated * fix: Sider component is updated
This commit is contained in:
parent
ea5b40c7ea
commit
93b347d25e
10
frontend/public/css/antd.dark.min.css
vendored
Normal file
10
frontend/public/css/antd.dark.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
10
frontend/public/css/antd.min.css
vendored
Normal file
10
frontend/public/css/antd.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.4 KiB |
@ -1,5 +1,3 @@
|
||||
@import '~antd/dist/antd.dark.css';
|
||||
|
||||
.ant-space-item {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
@ -24,7 +24,9 @@ import chartjsAdapter from 'chartjs-adapter-date-fns';
|
||||
// import { colors } from 'lib/getRandomColor';
|
||||
// import stringToHTML from 'lib/stringToHTML';
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import { useThemeSwitcher } from 'react-css-theme-switcher';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import AppReducer from 'types/reducer/app';
|
||||
|
||||
// import Legends from './Legend';
|
||||
// import { LegendsContainer } from './styles';
|
||||
@ -55,8 +57,9 @@ const Graph = ({
|
||||
xAxisType,
|
||||
onClickHandler,
|
||||
}: GraphProps): JSX.Element => {
|
||||
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||
const chartRef = useRef<HTMLCanvasElement>(null);
|
||||
const { currentTheme } = useThemeSwitcher();
|
||||
const currentTheme = isDarkMode ? 'dark' : 'light';
|
||||
|
||||
// const [tooltipVisible, setTooltipVisible] = useState<boolean>(false);
|
||||
const lineChartRef = useRef<Chart>();
|
||||
|
@ -1,28 +1,45 @@
|
||||
import { Layout, Menu, Switch as ToggleButton, Typography } from 'antd';
|
||||
import { Menu, Switch as ToggleButton, Typography } from 'antd';
|
||||
import ROUTES from 'constants/routes';
|
||||
import history from 'lib/history';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useThemeSwitcher } from 'react-css-theme-switcher';
|
||||
import { connect, useSelector } from 'react-redux';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { Logo, ThemeSwitcherWrapper } from './styles';
|
||||
const { Sider } = Layout;
|
||||
import history from 'lib/history';
|
||||
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 menus from './menuItems';
|
||||
import { Logo, Sider, ThemeSwitcherWrapper } from './styles';
|
||||
|
||||
const SideNav = (): JSX.Element => {
|
||||
const { switcher, currentTheme, themes } = useThemeSwitcher();
|
||||
|
||||
const SideNav = ({ toggleDarkMode }: Props): JSX.Element => {
|
||||
const [collapsed, setCollapsed] = useState<boolean>(false);
|
||||
const { pathname } = useLocation();
|
||||
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||
|
||||
const toggleTheme = useCallback(
|
||||
(isChecked: boolean) => {
|
||||
switcher({ theme: isChecked ? themes.dark : themes.light });
|
||||
},
|
||||
[switcher, themes],
|
||||
);
|
||||
const toggleTheme = useCallback(() => {
|
||||
const preMode: mode = isDarkMode ? 'lightMode' : 'darkMode';
|
||||
const postMode: mode = isDarkMode ? 'darkMode' : 'lightMode';
|
||||
|
||||
const id: mode = preMode;
|
||||
const head = document.head;
|
||||
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(postMode);
|
||||
prevNode?.remove();
|
||||
};
|
||||
}, [toggleDarkMode, isDarkMode]);
|
||||
|
||||
const onCollapse = useCallback(() => {
|
||||
setCollapsed((collapsed) => !collapsed);
|
||||
@ -33,12 +50,9 @@ const SideNav = (): JSX.Element => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Sider collapsible collapsed={collapsed} onCollapse={onCollapse} width={160}>
|
||||
<Sider collapsible collapsed={collapsed} onCollapse={onCollapse} width={200}>
|
||||
<ThemeSwitcherWrapper>
|
||||
<ToggleButton
|
||||
checked={currentTheme === themes.dark}
|
||||
onChange={toggleTheme}
|
||||
/>
|
||||
<ToggleButton checked={isDarkMode} onChange={toggleTheme} />
|
||||
</ThemeSwitcherWrapper>
|
||||
<NavLink to="/">
|
||||
<Logo src={'/signoz.svg'} alt="SigNoz" collapsed={collapsed} />
|
||||
@ -62,4 +76,18 @@ const SideNav = (): JSX.Element => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SideNav;
|
||||
type mode = 'darkMode' | 'lightMode';
|
||||
|
||||
interface DispatchProps {
|
||||
toggleDarkMode: () => void;
|
||||
}
|
||||
|
||||
const mapDispatchToProps = (
|
||||
dispatch: ThunkDispatch<unknown, unknown, AppActions>,
|
||||
): DispatchProps => ({
|
||||
toggleDarkMode: bindActionCreators(ToggleDarkMode, dispatch),
|
||||
});
|
||||
|
||||
type Props = DispatchProps;
|
||||
|
||||
export default connect(null, mapDispatchToProps)(SideNav);
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { Layout } from 'antd';
|
||||
import styled from 'styled-components';
|
||||
const { Sider: SiderComponent } = Layout;
|
||||
|
||||
export const ThemeSwitcherWrapper = styled.div`
|
||||
display: flex;
|
||||
@ -16,3 +18,9 @@ export const Logo = styled.img<LogoProps>`
|
||||
interface LogoProps {
|
||||
collapsed: boolean;
|
||||
}
|
||||
|
||||
export const Sider = styled(SiderComponent)`
|
||||
.ant-typography {
|
||||
color: white;
|
||||
}
|
||||
`;
|
||||
|
@ -13,6 +13,8 @@
|
||||
<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='darkMode' rel='stylesheet' type='text/css' href='./css/antd.dark.min.css' />
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
@ -2,18 +2,14 @@ import 'assets/index.css';
|
||||
|
||||
import AppRoutes from 'AppRoutes';
|
||||
import React from 'react';
|
||||
import { ThemeSwitcherProvider } from 'react-css-theme-switcher';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import store from 'store';
|
||||
import themes from 'themes';
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<React.StrictMode>
|
||||
<ThemeSwitcherProvider themeMap={themes} defaultTheme="dark">
|
||||
<AppRoutes />
|
||||
</ThemeSwitcherProvider>
|
||||
</React.StrictMode>
|
||||
</Provider>,
|
||||
document.querySelector('#root'),
|
||||
|
@ -1,25 +1,22 @@
|
||||
import { Space } from 'antd';
|
||||
import React from 'react';
|
||||
import { useThemeSwitcher } from 'react-css-theme-switcher';
|
||||
import { connect } from 'react-redux';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import styled from 'styled-components';
|
||||
import AppReducer from 'types/reducer/app';
|
||||
|
||||
const InstrumentCard = styled.div<{
|
||||
currentThemeStatus: string | undefined;
|
||||
isDarkMode: boolean;
|
||||
}>`
|
||||
border-radius: 4px;
|
||||
background: ${({ currentThemeStatus }): string =>
|
||||
currentThemeStatus === 'dark' ? '#313131' : '#ddd'};
|
||||
background: ${({ isDarkMode }): string => (isDarkMode ? '#313131' : '#ddd')};
|
||||
padding: 33px 23px;
|
||||
max-width: 800px;
|
||||
margin-top: 40px;
|
||||
`;
|
||||
|
||||
interface InstrumentationPageProps {}
|
||||
|
||||
const InstrumentationPage = (props: InstrumentationPageProps) => {
|
||||
const { currentTheme } = useThemeSwitcher();
|
||||
const InstrumentationPage = (): JSX.Element => {
|
||||
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
@ -27,7 +24,7 @@ const InstrumentationPage = (props: InstrumentationPageProps) => {
|
||||
<div>
|
||||
<h2>Instrument your application</h2>
|
||||
</div>
|
||||
<InstrumentCard currentThemeStatus={currentTheme}>
|
||||
<InstrumentCard isDarkMode={isDarkMode}>
|
||||
Congrats, you have successfully installed SigNoz!
|
||||
<br />
|
||||
To start seeing YOUR application data here, follow the instructions in the
|
||||
@ -61,8 +58,4 @@ const InstrumentationPage = (props: InstrumentationPageProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state: AppState): {} => {
|
||||
return {};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, {})(InstrumentationPage);
|
||||
export default InstrumentationPage;
|
||||
|
1
frontend/src/store/actions/app/index.ts
Normal file
1
frontend/src/store/actions/app/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './toggleDarkMode';
|
12
frontend/src/store/actions/app/toggleDarkMode.ts
Normal file
12
frontend/src/store/actions/app/toggleDarkMode.ts
Normal file
@ -0,0 +1,12 @@
|
||||
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',
|
||||
});
|
||||
};
|
||||
};
|
@ -1,3 +1,4 @@
|
||||
export * from './app';
|
||||
export * from './dashboard';
|
||||
export * from './global';
|
||||
export * from './MetricsActions';
|
||||
|
25
frontend/src/store/reducers/app.ts
Normal file
25
frontend/src/store/reducers/app.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { AppAction, SWITCH_DARK_MODE } from 'types/actions/app';
|
||||
import InitialValueTypes from 'types/reducer/app';
|
||||
|
||||
const InitialValue: InitialValueTypes = {
|
||||
isDarkMode: true,
|
||||
};
|
||||
|
||||
const appReducer = (
|
||||
state = InitialValue,
|
||||
action: AppAction,
|
||||
): InitialValueTypes => {
|
||||
switch (action.type) {
|
||||
case SWITCH_DARK_MODE: {
|
||||
return {
|
||||
...state,
|
||||
isDarkMode: !state.isDarkMode,
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default appReducer;
|
@ -6,7 +6,7 @@ export const updateGlobalTimeReducer = (
|
||||
minTime: (Date.now() - 15 * 60 * 1000) * 1000000,
|
||||
},
|
||||
action: Action,
|
||||
) => {
|
||||
): GlobalTime => {
|
||||
// Initial global state is time now and 15 minute interval
|
||||
switch (action.type) {
|
||||
case ActionTypes.updateTimeInterval:
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { combineReducers } from 'redux';
|
||||
|
||||
import appReducer from './app';
|
||||
import dashboardReducer from './dashboard';
|
||||
import { updateGlobalTimeReducer } from './global';
|
||||
import { metricsReducer } from './metrics';
|
||||
@ -17,6 +18,7 @@ const reducers = combineReducers({
|
||||
metricsData: metricsReducer,
|
||||
serviceMap: ServiceMapReducer,
|
||||
dashboards: dashboardReducer,
|
||||
app: appReducer,
|
||||
});
|
||||
|
||||
export type AppState = ReturnType<typeof reducers>;
|
||||
|
@ -1,6 +0,0 @@
|
||||
const themes = {
|
||||
dark: '/dark-theme.css',
|
||||
light: '/light-theme.css',
|
||||
};
|
||||
|
||||
export default themes;
|
7
frontend/src/types/actions/app.ts
Normal file
7
frontend/src/types/actions/app.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export const SWITCH_DARK_MODE = 'SWITCH_DARK_MODE';
|
||||
|
||||
export interface SwitchDarkMode {
|
||||
type: typeof SWITCH_DARK_MODE;
|
||||
}
|
||||
|
||||
export type AppAction = SwitchDarkMode;
|
@ -1,5 +1,6 @@
|
||||
import { AppAction } from './app';
|
||||
import { DashboardActions } from './dashboard';
|
||||
|
||||
type AppActions = DashboardActions;
|
||||
type AppActions = DashboardActions | AppAction;
|
||||
|
||||
export default AppActions;
|
||||
|
3
frontend/src/types/reducer/app.ts
Normal file
3
frontend/src/types/reducer/app.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default interface AppReducer {
|
||||
isDarkMode: boolean;
|
||||
}
|
@ -11891,11 +11891,6 @@ react-chips@^0.8.0:
|
||||
react-autosuggest "^9.0.1"
|
||||
react-themeable "^1.1.0"
|
||||
|
||||
react-css-theme-switcher@^0.1.6:
|
||||
version "0.1.6"
|
||||
resolved "https://registry.yarnpkg.com/react-css-theme-switcher/-/react-css-theme-switcher-0.1.6.tgz#9b765e4ffa7d1ce092ff11c5524b1466990e9eaf"
|
||||
integrity sha512-GG5OqeWTWJFH3Vbd42Tj0QVUwh/uBN/ki7EOTUL99wbzxulX8bof3NOdRHzY6j7746HNZ72s8Ko4TjO3GaWdxA==
|
||||
|
||||
react-dev-utils@^11.0.0:
|
||||
version "11.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a"
|
||||
|
Loading…
x
Reference in New Issue
Block a user