mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 10:59:02 +08:00
feat: data time, UI and graph label consistency across FE (#878)
* feat: data time and graph label consistency across FE * feat: saved state of sidebar and horizontal scroll fix for trace filter page * feat: add Y-Axis unit for missing metrics graphs * chore: update node version from 12.18 to 12.22 * fix: 24hr time unit on graph
This commit is contained in:
parent
f1f606844a
commit
3ab0e1395a
@ -1,5 +1,5 @@
|
|||||||
# stage1 as builder
|
# stage1 as builder
|
||||||
FROM node:12.18.0 as builder
|
FROM node:12.22.0 as builder
|
||||||
|
|
||||||
# Add Maintainer Info
|
# Add Maintainer Info
|
||||||
LABEL maintainer="signoz"
|
LABEL maintainer="signoz"
|
||||||
|
@ -51,6 +51,7 @@ Chart.register(
|
|||||||
);
|
);
|
||||||
|
|
||||||
function Graph({
|
function Graph({
|
||||||
|
animate = true,
|
||||||
data,
|
data,
|
||||||
type,
|
type,
|
||||||
title,
|
title,
|
||||||
@ -58,15 +59,14 @@ function Graph({
|
|||||||
onClickHandler,
|
onClickHandler,
|
||||||
name,
|
name,
|
||||||
yAxisUnit = 'short',
|
yAxisUnit = 'short',
|
||||||
|
forceReRender,
|
||||||
}: GraphProps): JSX.Element {
|
}: GraphProps): JSX.Element {
|
||||||
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||||
const chartRef = useRef<HTMLCanvasElement>(null);
|
const chartRef = useRef<HTMLCanvasElement>(null);
|
||||||
const currentTheme = isDarkMode ? 'dark' : 'light';
|
const currentTheme = isDarkMode ? 'dark' : 'light';
|
||||||
|
|
||||||
const xAxisTimeUnit = useXAxisTimeUnit(data); // Computes the relevant time unit for x axis by analyzing the time stamp data
|
const xAxisTimeUnit = useXAxisTimeUnit(data); // Computes the relevant time unit for x axis by analyzing the time stamp data
|
||||||
|
|
||||||
const lineChartRef = useRef<Chart>();
|
const lineChartRef = useRef<Chart>();
|
||||||
|
|
||||||
const getGridColor = useCallback(() => {
|
const getGridColor = useCallback(() => {
|
||||||
if (currentTheme === undefined) {
|
if (currentTheme === undefined) {
|
||||||
return 'rgba(231,233,237,0.1)';
|
return 'rgba(231,233,237,0.1)';
|
||||||
@ -86,6 +86,9 @@ function Graph({
|
|||||||
|
|
||||||
if (chartRef.current !== null) {
|
if (chartRef.current !== null) {
|
||||||
const options: ChartOptions = {
|
const options: ChartOptions = {
|
||||||
|
animation: {
|
||||||
|
duration: animate ? 200 : 0,
|
||||||
|
},
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
interaction: {
|
interaction: {
|
||||||
@ -117,8 +120,8 @@ function Graph({
|
|||||||
unit: xAxisTimeUnit?.unitName || 'minute',
|
unit: xAxisTimeUnit?.unitName || 'minute',
|
||||||
stepSize: xAxisTimeUnit?.stepSize || 1,
|
stepSize: xAxisTimeUnit?.stepSize || 1,
|
||||||
displayFormats: {
|
displayFormats: {
|
||||||
millisecond: 'hh:mm:ss',
|
millisecond: 'HH:mm:ss',
|
||||||
second: 'hh:mm:ss',
|
second: 'HH:mm:ss',
|
||||||
minute: 'HH:mm',
|
minute: 'HH:mm',
|
||||||
hour: 'MM/dd HH:mm',
|
hour: 'MM/dd HH:mm',
|
||||||
day: 'MM/dd',
|
day: 'MM/dd',
|
||||||
@ -166,11 +169,23 @@ function Graph({
|
|||||||
plugins: [legend(name, data.datasets.length > 3)],
|
plugins: [legend(name, data.datasets.length > 3)],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [chartRef, data, type, title, isStacked, getGridColor, onClickHandler]);
|
}, [
|
||||||
|
animate,
|
||||||
|
title,
|
||||||
|
getGridColor,
|
||||||
|
xAxisTimeUnit?.unitName,
|
||||||
|
xAxisTimeUnit?.stepSize,
|
||||||
|
isStacked,
|
||||||
|
type,
|
||||||
|
data,
|
||||||
|
name,
|
||||||
|
yAxisUnit,
|
||||||
|
onClickHandler,
|
||||||
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
buildChart();
|
buildChart();
|
||||||
}, [buildChart]);
|
}, [buildChart, forceReRender]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ height: '85%' }}>
|
<div style={{ height: '85%' }}>
|
||||||
@ -181,6 +196,7 @@ function Graph({
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface GraphProps {
|
interface GraphProps {
|
||||||
|
animate?: boolean;
|
||||||
type: ChartType;
|
type: ChartType;
|
||||||
data: Chart['data'];
|
data: Chart['data'];
|
||||||
title?: string;
|
title?: string;
|
||||||
@ -189,6 +205,7 @@ interface GraphProps {
|
|||||||
onClickHandler?: graphOnClickHandler;
|
onClickHandler?: graphOnClickHandler;
|
||||||
name: string;
|
name: string;
|
||||||
yAxisUnit?: string;
|
yAxisUnit?: string;
|
||||||
|
forceReRender?: boolean | null | number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type graphOnClickHandler = (
|
export type graphOnClickHandler = (
|
||||||
|
@ -5,3 +5,5 @@ export const WITHOUT_SESSION_PATH = ['/redirect'];
|
|||||||
export const AUTH0_REDIRECT_PATH = '/redirect';
|
export const AUTH0_REDIRECT_PATH = '/redirect';
|
||||||
|
|
||||||
export const DEFAULT_AUTH0_APP_REDIRECTION_PATH = ROUTES.APPLICATION;
|
export const DEFAULT_AUTH0_APP_REDIRECTION_PATH = ROUTES.APPLICATION;
|
||||||
|
|
||||||
|
export const IS_SIDEBAR_COLLAPSED = 'isSideBarCollapsed'
|
@ -107,7 +107,7 @@ function Application({ getWidget }: DashboardProps): JSX.Element {
|
|||||||
View Traces
|
View Traces
|
||||||
</Button>
|
</Button>
|
||||||
<Card>
|
<Card>
|
||||||
<GraphTitle>Application latency in ms</GraphTitle>
|
<GraphTitle>Application latency</GraphTitle>
|
||||||
<GraphContainer>
|
<GraphContainer>
|
||||||
<Graph
|
<Graph
|
||||||
onClickHandler={(ChartEvent, activeElements, chart, data): void => {
|
onClickHandler={(ChartEvent, activeElements, chart, data): void => {
|
||||||
@ -175,7 +175,7 @@ function Application({ getWidget }: DashboardProps): JSX.Element {
|
|||||||
View Traces
|
View Traces
|
||||||
</Button>
|
</Button>
|
||||||
<Card>
|
<Card>
|
||||||
<GraphTitle>Request per sec</GraphTitle>
|
<GraphTitle>Requests</GraphTitle>
|
||||||
<GraphContainer>
|
<GraphContainer>
|
||||||
<FullView
|
<FullView
|
||||||
name="request_per_sec"
|
name="request_per_sec"
|
||||||
@ -190,7 +190,7 @@ function Application({ getWidget }: DashboardProps): JSX.Element {
|
|||||||
legend: 'Request per second',
|
legend: 'Request per second',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
yAxisUnit="short"
|
yAxisUnit="reqps"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
@ -210,7 +210,7 @@ function Application({ getWidget }: DashboardProps): JSX.Element {
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
<GraphTitle>Error Percentage (%)</GraphTitle>
|
<GraphTitle>Error Percentage</GraphTitle>
|
||||||
<GraphContainer>
|
<GraphContainer>
|
||||||
<FullView
|
<FullView
|
||||||
name="error_percentage_%"
|
name="error_percentage_%"
|
||||||
|
@ -25,7 +25,7 @@ function DBCall({ getWidget }: DBCallProps): JSX.Element {
|
|||||||
legend: '{{db_system}}',
|
legend: '{{db_system}}',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
yAxisUnit="short"
|
yAxisUnit="reqps"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
@ -33,7 +33,7 @@ function DBCall({ getWidget }: DBCallProps): JSX.Element {
|
|||||||
|
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Card>
|
<Card>
|
||||||
<GraphTitle>Database Calls Avg Duration (in ms)</GraphTitle>
|
<GraphTitle>Database Calls Avg Duration</GraphTitle>
|
||||||
<GraphContainer>
|
<GraphContainer>
|
||||||
<FullView
|
<FullView
|
||||||
name="database_call_avg_duration"
|
name="database_call_avg_duration"
|
||||||
|
@ -14,7 +14,7 @@ function External({ getWidget }: ExternalProps): JSX.Element {
|
|||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Card>
|
<Card>
|
||||||
<GraphTitle>External Call Error Percentage (%)</GraphTitle>
|
<GraphTitle>External Call Error Percentage</GraphTitle>
|
||||||
<GraphContainer>
|
<GraphContainer>
|
||||||
<FullView
|
<FullView
|
||||||
name="external_call_error_percentage"
|
name="external_call_error_percentage"
|
||||||
@ -68,7 +68,7 @@ function External({ getWidget }: ExternalProps): JSX.Element {
|
|||||||
legend: '{{http_url}}',
|
legend: '{{http_url}}',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
yAxisUnit="short"
|
yAxisUnit="reqps"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import { Menu, Typography } from 'antd';
|
import { Menu, Typography } from 'antd';
|
||||||
|
import getLocalStorageKey from 'api/browser/localstorage/get';
|
||||||
|
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import setTheme from 'lib/theme/setTheme';
|
import setTheme from 'lib/theme/setTheme';
|
||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useLayoutEffect, useState } from 'react';
|
||||||
import { connect, useSelector } from 'react-redux';
|
import { connect, useDispatch, useSelector } from 'react-redux';
|
||||||
import { NavLink, useLocation } from 'react-router-dom';
|
import { NavLink, useLocation } from 'react-router-dom';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { ThunkDispatch } from 'redux-thunk';
|
import { ThunkDispatch } from 'redux-thunk';
|
||||||
import { ToggleDarkMode } from 'store/actions';
|
import { ToggleDarkMode } from 'store/actions';
|
||||||
|
import { SideBarCollapse } from 'store/actions/app';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import AppActions from 'types/actions';
|
import AppActions from 'types/actions';
|
||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
@ -24,7 +27,10 @@ import {
|
|||||||
} from './styles';
|
} from './styles';
|
||||||
|
|
||||||
function SideNav({ toggleDarkMode }: Props): JSX.Element {
|
function SideNav({ toggleDarkMode }: Props): JSX.Element {
|
||||||
const [collapsed, setCollapsed] = useState<boolean>(false);
|
const dispatch = useDispatch();
|
||||||
|
const [collapsed, setCollapsed] = useState<boolean>(
|
||||||
|
getLocalStorageKey(IS_SIDEBAR_COLLAPSED) === 'true',
|
||||||
|
);
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||||
|
|
||||||
@ -53,6 +59,10 @@ function SideNav({ toggleDarkMode }: Props): JSX.Element {
|
|||||||
setCollapsed((collapsed) => !collapsed);
|
setCollapsed((collapsed) => !collapsed);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
dispatch(SideBarCollapse(collapsed));
|
||||||
|
}, [collapsed]);
|
||||||
|
|
||||||
const onClickHandler = useCallback(
|
const onClickHandler = useCallback(
|
||||||
(to: string) => {
|
(to: string) => {
|
||||||
if (pathname !== to) {
|
if (pathname !== to) {
|
||||||
@ -62,7 +72,7 @@ function SideNav({ toggleDarkMode }: Props): JSX.Element {
|
|||||||
[pathname],
|
[pathname],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onClickSlackHandler = () => {
|
const onClickSlackHandler = (): void => {
|
||||||
window.open('https://signoz.io/slack', '_blank');
|
window.open('https://signoz.io/slack', '_blank');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import Graph from 'components/Graph';
|
|||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
|
import { useMeasure } from 'react-use';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { TraceReducer } from 'types/reducer/trace';
|
import { TraceReducer } from 'types/reducer/trace';
|
||||||
|
|
||||||
@ -10,6 +11,8 @@ import { getChartData, getChartDataforGroupBy } from './config';
|
|||||||
import { Container } from './styles';
|
import { Container } from './styles';
|
||||||
|
|
||||||
function TraceGraph(): JSX.Element {
|
function TraceGraph(): JSX.Element {
|
||||||
|
const [ref, { width }] = useMeasure();
|
||||||
|
|
||||||
const { spansGraph, selectedGroupBy, yAxisUnit } = useSelector<
|
const { spansGraph, selectedGroupBy, yAxisUnit } = useSelector<
|
||||||
AppState,
|
AppState,
|
||||||
TraceReducer
|
TraceReducer
|
||||||
@ -21,7 +24,7 @@ function TraceGraph(): JSX.Element {
|
|||||||
return selectedGroupBy.length === 0
|
return selectedGroupBy.length === 0
|
||||||
? getChartData(payload)
|
? getChartData(payload)
|
||||||
: getChartDataforGroupBy(payload);
|
: getChartDataforGroupBy(payload);
|
||||||
}, [payload]);
|
}, [payload, selectedGroupBy.length]);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
@ -40,12 +43,14 @@ function TraceGraph(): JSX.Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container ref={ref}>
|
||||||
<Graph
|
<Graph
|
||||||
|
animate={false}
|
||||||
data={ChartData}
|
data={ChartData}
|
||||||
name="traceGraph"
|
name="traceGraph"
|
||||||
type="line"
|
type="line"
|
||||||
yAxisUnit={yAxisUnit}
|
yAxisUnit={yAxisUnit}
|
||||||
|
forceReRender={width}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
|
import React from 'react';
|
||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
center?: boolean;
|
center?: boolean;
|
||||||
|
ref?: React.RefObject<HTMLDivElement> | null; // The ref type provided by react-use is incorrect -> https://github.com/streamich/react-use/issues/1264 Open Issue
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Container = styled.div<Props>`
|
export const Container = styled.div<Props>`
|
||||||
height: 25vh;
|
height: 25vh !important;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
|
overflow: auto;
|
||||||
|
width: 100% !important;
|
||||||
|
|
||||||
${({ center }) =>
|
${({ center }) =>
|
||||||
center &&
|
center &&
|
||||||
|
@ -67,35 +67,35 @@ export const functions: Dropdown[] = [
|
|||||||
key: 'ratePerSec',
|
key: 'ratePerSec',
|
||||||
yAxisUnit: 'reqps',
|
yAxisUnit: 'reqps',
|
||||||
},
|
},
|
||||||
{ displayValue: 'Sum(duration in ns)', key: 'sum', yAxisUnit: 'ns' },
|
{ displayValue: 'Sum (duration)', key: 'sum', yAxisUnit: 'ns' },
|
||||||
{ displayValue: 'Avg(duration in ns)', key: 'avg', yAxisUnit: 'ns' },
|
{ displayValue: 'Avg (duration)', key: 'avg', yAxisUnit: 'ns' },
|
||||||
{
|
{
|
||||||
displayValue: 'Max(duration in ns)',
|
displayValue: 'Max (duration)',
|
||||||
key: 'max',
|
key: 'max',
|
||||||
yAxisUnit: 'ns',
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayValue: 'Min(duration in ns)',
|
displayValue: 'Min (duration)',
|
||||||
key: 'min',
|
key: 'min',
|
||||||
yAxisUnit: 'ns',
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayValue: '50th percentile(duration in ns)',
|
displayValue: '50th percentile (duration)',
|
||||||
key: 'p50',
|
key: 'p50',
|
||||||
yAxisUnit: 'ns',
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayValue: '90th percentile(duration in ns)',
|
displayValue: '90th percentile (duration)',
|
||||||
key: 'p90',
|
key: 'p90',
|
||||||
yAxisUnit: 'ns',
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayValue: '95th percentile(duration in ns)',
|
displayValue: '95th percentile (duration)',
|
||||||
key: 'p95',
|
key: 'p95',
|
||||||
yAxisUnit: 'ns',
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayValue: '99th percentile(duration in ns)',
|
displayValue: '99th percentile (duration)',
|
||||||
key: 'p99',
|
key: 'p99',
|
||||||
yAxisUnit: 'ns',
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,6 @@ import styled from 'styled-components';
|
|||||||
|
|
||||||
export const SelectComponent = styled(Select)`
|
export const SelectComponent = styled(Select)`
|
||||||
&&& {
|
&&& {
|
||||||
min-width: 10rem;
|
min-width: 12rem;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -43,7 +43,7 @@ function TraceTable({ getSpansAggregate }: TraceProps): JSX.Element {
|
|||||||
sorter: true,
|
sorter: true,
|
||||||
render: (value: TableType['timestamp']): JSX.Element => {
|
render: (value: TableType['timestamp']): JSX.Element => {
|
||||||
const day = dayjs(value);
|
const day = dayjs(value);
|
||||||
return <div>{day.format('DD/MM/YYYY hh:mm:ss A')}</div>;
|
return <div>{day.format('YYYY/MM/DD HH:mm:ss')}</div>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
export * from './sideBarCollapse';
|
||||||
export * from './toggleDarkMode';
|
export * from './toggleDarkMode';
|
||||||
|
16
frontend/src/store/actions/app/sideBarCollapse.ts
Normal file
16
frontend/src/store/actions/app/sideBarCollapse.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import setLocalStorageKey from 'api/browser/localstorage/set';
|
||||||
|
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
|
||||||
|
import { Dispatch } from 'redux';
|
||||||
|
import AppActions from 'types/actions';
|
||||||
|
|
||||||
|
export const SideBarCollapse = (
|
||||||
|
collapseState: boolean,
|
||||||
|
): ((dispatch: Dispatch<AppActions>) => void) => {
|
||||||
|
setLocalStorageKey(IS_SIDEBAR_COLLAPSED, `${collapseState}`);
|
||||||
|
return (dispatch: Dispatch<AppActions>): void => {
|
||||||
|
dispatch({
|
||||||
|
type: 'SIDEBAR_COLLAPSE',
|
||||||
|
payload: collapseState,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
@ -1,12 +1,19 @@
|
|||||||
import getLocalStorageKey from 'api/browser/localstorage/get';
|
import getLocalStorageKey from 'api/browser/localstorage/get';
|
||||||
|
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
|
||||||
import { IS_LOGGED_IN } from 'constants/auth';
|
import { IS_LOGGED_IN } from 'constants/auth';
|
||||||
import getTheme from 'lib/theme/getTheme';
|
import getTheme from 'lib/theme/getTheme';
|
||||||
import { AppAction, LOGGED_IN, SWITCH_DARK_MODE } from 'types/actions/app';
|
import {
|
||||||
|
AppAction,
|
||||||
|
LOGGED_IN,
|
||||||
|
SIDEBAR_COLLAPSE,
|
||||||
|
SWITCH_DARK_MODE,
|
||||||
|
} from 'types/actions/app';
|
||||||
import InitialValueTypes from 'types/reducer/app';
|
import InitialValueTypes from 'types/reducer/app';
|
||||||
|
|
||||||
const InitialValue: InitialValueTypes = {
|
const InitialValue: InitialValueTypes = {
|
||||||
isDarkMode: getTheme() === 'darkMode',
|
isDarkMode: getTheme() === 'darkMode',
|
||||||
isLoggedIn: getLocalStorageKey(IS_LOGGED_IN) === 'yes',
|
isLoggedIn: getLocalStorageKey(IS_LOGGED_IN) === 'yes',
|
||||||
|
isSideBarCollapsed: getLocalStorageKey(IS_SIDEBAR_COLLAPSED) === 'true',
|
||||||
};
|
};
|
||||||
|
|
||||||
const appReducer = (
|
const appReducer = (
|
||||||
@ -28,6 +35,13 @@ const appReducer = (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SIDEBAR_COLLAPSE: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isSideBarCollapsed: action.payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
export const SWITCH_DARK_MODE = 'SWITCH_DARK_MODE';
|
export const SWITCH_DARK_MODE = 'SWITCH_DARK_MODE';
|
||||||
export const LOGGED_IN = 'LOGGED_IN';
|
export const LOGGED_IN = 'LOGGED_IN';
|
||||||
|
export const SIDEBAR_COLLAPSE = 'SIDEBAR_COLLAPSE';
|
||||||
|
|
||||||
export interface SwitchDarkMode {
|
export interface SwitchDarkMode {
|
||||||
type: typeof SWITCH_DARK_MODE;
|
type: typeof SWITCH_DARK_MODE;
|
||||||
@ -9,4 +10,9 @@ export interface LoggedInUser {
|
|||||||
type: typeof LOGGED_IN;
|
type: typeof LOGGED_IN;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AppAction = SwitchDarkMode | LoggedInUser;
|
export interface SideBarCollapse {
|
||||||
|
type: typeof SIDEBAR_COLLAPSE;
|
||||||
|
payload: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AppAction = SwitchDarkMode | LoggedInUser | SideBarCollapse;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export default interface AppReducer {
|
export default interface AppReducer {
|
||||||
isDarkMode: boolean;
|
isDarkMode: boolean;
|
||||||
isLoggedIn: boolean;
|
isLoggedIn: boolean;
|
||||||
|
isSideBarCollapsed: boolean;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user