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 { .ant-space-item {
margin-right: 0 !important; margin-right: 0 !important;
} }

View File

@ -24,7 +24,9 @@ import chartjsAdapter from 'chartjs-adapter-date-fns';
// import { colors } from 'lib/getRandomColor'; // import { colors } from 'lib/getRandomColor';
// import stringToHTML from 'lib/stringToHTML'; // import stringToHTML from 'lib/stringToHTML';
import React, { useCallback, useEffect, useRef } from 'react'; 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 Legends from './Legend';
// import { LegendsContainer } from './styles'; // import { LegendsContainer } from './styles';
@ -55,8 +57,9 @@ const Graph = ({
xAxisType, xAxisType,
onClickHandler, onClickHandler,
}: GraphProps): JSX.Element => { }: GraphProps): JSX.Element => {
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const chartRef = useRef<HTMLCanvasElement>(null); const chartRef = useRef<HTMLCanvasElement>(null);
const { currentTheme } = useThemeSwitcher(); const currentTheme = isDarkMode ? 'dark' : 'light';
// const [tooltipVisible, setTooltipVisible] = useState<boolean>(false); // const [tooltipVisible, setTooltipVisible] = useState<boolean>(false);
const lineChartRef = useRef<Chart>(); 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 ROUTES from 'constants/routes';
import history from 'lib/history';
import React, { useCallback, useState } from 'react'; 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 { NavLink } from 'react-router-dom';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { bindActionCreators } from 'redux';
import { Logo, ThemeSwitcherWrapper } from './styles'; import { ThunkDispatch } from 'redux-thunk';
const { Sider } = Layout; import { ToggleDarkMode } from 'store/actions';
import history from 'lib/history'; import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import AppReducer from 'types/reducer/app';
import menus from './menuItems'; import menus from './menuItems';
import { Logo, Sider, ThemeSwitcherWrapper } from './styles';
const SideNav = (): JSX.Element => { const SideNav = ({ toggleDarkMode }: Props): JSX.Element => {
const { switcher, currentTheme, themes } = useThemeSwitcher();
const [collapsed, setCollapsed] = useState<boolean>(false); const [collapsed, setCollapsed] = useState<boolean>(false);
const { pathname } = useLocation(); const { pathname } = useLocation();
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const toggleTheme = useCallback( const toggleTheme = useCallback(() => {
(isChecked: boolean) => { const preMode: mode = isDarkMode ? 'lightMode' : 'darkMode';
switcher({ theme: isChecked ? themes.dark : themes.light }); const postMode: mode = isDarkMode ? 'darkMode' : 'lightMode';
},
[switcher, themes], 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(() => { const onCollapse = useCallback(() => {
setCollapsed((collapsed) => !collapsed); setCollapsed((collapsed) => !collapsed);
@ -33,12 +50,9 @@ const SideNav = (): JSX.Element => {
}, []); }, []);
return ( return (
<Sider collapsible collapsed={collapsed} onCollapse={onCollapse} width={160}> <Sider collapsible collapsed={collapsed} onCollapse={onCollapse} width={200}>
<ThemeSwitcherWrapper> <ThemeSwitcherWrapper>
<ToggleButton <ToggleButton checked={isDarkMode} onChange={toggleTheme} />
checked={currentTheme === themes.dark}
onChange={toggleTheme}
/>
</ThemeSwitcherWrapper> </ThemeSwitcherWrapper>
<NavLink to="/"> <NavLink to="/">
<Logo src={'/signoz.svg'} alt="SigNoz" collapsed={collapsed} /> <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'; import styled from 'styled-components';
const { Sider: SiderComponent } = Layout;
export const ThemeSwitcherWrapper = styled.div` export const ThemeSwitcherWrapper = styled.div`
display: flex; display: flex;
@ -16,3 +18,9 @@ export const Logo = styled.img<LogoProps>`
interface LogoProps { interface LogoProps {
collapsed: boolean; 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_locale" content="en">
<meta data-react-helmet="true" name="docusaurus_tag" content="default"> <meta data-react-helmet="true" name="docusaurus_tag" content="default">
<link data-react-helmet="true" rel="shortcut icon" href="/favicon.ico"> <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> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <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 AppRoutes from 'AppRoutes';
import React from 'react'; import React from 'react';
import { ThemeSwitcherProvider } from 'react-css-theme-switcher';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import store from 'store'; import store from 'store';
import themes from 'themes';
ReactDOM.render( ReactDOM.render(
<Provider store={store}> <Provider store={store}>
<React.StrictMode> <React.StrictMode>
<ThemeSwitcherProvider themeMap={themes} defaultTheme="dark">
<AppRoutes /> <AppRoutes />
</ThemeSwitcherProvider>
</React.StrictMode> </React.StrictMode>
</Provider>, </Provider>,
document.querySelector('#root'), document.querySelector('#root'),

View File

@ -1,25 +1,22 @@
import { Space } from 'antd'; import { Space } from 'antd';
import React from 'react'; import React from 'react';
import { useThemeSwitcher } from 'react-css-theme-switcher'; import { useSelector } from 'react-redux';
import { connect } from 'react-redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import styled from 'styled-components'; import styled from 'styled-components';
import AppReducer from 'types/reducer/app';
const InstrumentCard = styled.div<{ const InstrumentCard = styled.div<{
currentThemeStatus: string | undefined; isDarkMode: boolean;
}>` }>`
border-radius: 4px; border-radius: 4px;
background: ${({ currentThemeStatus }): string => background: ${({ isDarkMode }): string => (isDarkMode ? '#313131' : '#ddd')};
currentThemeStatus === 'dark' ? '#313131' : '#ddd'};
padding: 33px 23px; padding: 33px 23px;
max-width: 800px; max-width: 800px;
margin-top: 40px; margin-top: 40px;
`; `;
interface InstrumentationPageProps {} const InstrumentationPage = (): JSX.Element => {
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const InstrumentationPage = (props: InstrumentationPageProps) => {
const { currentTheme } = useThemeSwitcher();
return ( return (
<React.Fragment> <React.Fragment>
@ -27,7 +24,7 @@ const InstrumentationPage = (props: InstrumentationPageProps) => {
<div> <div>
<h2>Instrument your application</h2> <h2>Instrument your application</h2>
</div> </div>
<InstrumentCard currentThemeStatus={currentTheme}> <InstrumentCard isDarkMode={isDarkMode}>
Congrats, you have successfully installed SigNoz! Congrats, you have successfully installed SigNoz!
<br /> <br />
To start seeing YOUR application data here, follow the instructions in the To start seeing YOUR application data here, follow the instructions in the
@ -61,8 +58,4 @@ const InstrumentationPage = (props: InstrumentationPageProps) => {
); );
}; };
const mapStateToProps = (state: AppState): {} => { export default InstrumentationPage;
return {};
};
export default connect(mapStateToProps, {})(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 './dashboard';
export * from './global'; export * from './global';
export * from './MetricsActions'; 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, minTime: (Date.now() - 15 * 60 * 1000) * 1000000,
}, },
action: Action, action: Action,
) => { ): GlobalTime => {
// Initial global state is time now and 15 minute interval // Initial global state is time now and 15 minute interval
switch (action.type) { switch (action.type) {
case ActionTypes.updateTimeInterval: case ActionTypes.updateTimeInterval:

View File

@ -1,5 +1,6 @@
import { combineReducers } from 'redux'; import { combineReducers } from 'redux';
import appReducer from './app';
import dashboardReducer from './dashboard'; import dashboardReducer from './dashboard';
import { updateGlobalTimeReducer } from './global'; import { updateGlobalTimeReducer } from './global';
import { metricsReducer } from './metrics'; import { metricsReducer } from './metrics';
@ -17,6 +18,7 @@ const reducers = combineReducers({
metricsData: metricsReducer, metricsData: metricsReducer,
serviceMap: ServiceMapReducer, serviceMap: ServiceMapReducer,
dashboards: dashboardReducer, dashboards: dashboardReducer,
app: appReducer,
}); });
export type AppState = ReturnType<typeof reducers>; 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'; import { DashboardActions } from './dashboard';
type AppActions = DashboardActions; type AppActions = DashboardActions | AppAction;
export default AppActions; 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-autosuggest "^9.0.1"
react-themeable "^1.1.0" 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: react-dev-utils@^11.0.0:
version "11.0.4" version "11.0.4"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a"