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:
Palash 2021-09-28 18:50:10 +05:30 committed by GitHub
parent ea5b40c7ea
commit 93b347d25e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 147 additions and 49932 deletions

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

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

View File

@ -1,5 +1,3 @@
@import '~antd/dist/antd.dark.css';
.ant-space-item {
margin-right: 0 !important;
}

View File

@ -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>();

View File

@ -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);

View File

@ -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;
}
`;

View File

@ -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>

View File

@ -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>
<AppRoutes />
</React.StrictMode>
</Provider>,
document.querySelector('#root'),

View File

@ -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;

View File

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

View 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',
});
};
};

View File

@ -1,3 +1,4 @@
export * from './app';
export * from './dashboard';
export * from './global';
export * from './MetricsActions';

View 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;

View File

@ -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:

View File

@ -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>;

View File

@ -1,6 +0,0 @@
const themes = {
dark: '/dark-theme.css',
light: '/light-theme.css',
};
export default themes;

View 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;

View File

@ -1,5 +1,6 @@
import { AppAction } from './app';
import { DashboardActions } from './dashboard';
type AppActions = DashboardActions;
type AppActions = DashboardActions | AppAction;
export default AppActions;

View File

@ -0,0 +1,3 @@
export default interface AppReducer {
isDarkMode: boolean;
}

View File

@ -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"