mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-31 13:47:02 +02:00
Insights UI improvements (#6433)
- improved page header - added help text to health and metrics - updated style for flag stats widget - fixed users widget shadow
This commit is contained in:
parent
2185742b1d
commit
85e9c934a9
@ -49,7 +49,7 @@ export const ExecutiveDashboard: VFC = () => {
|
|||||||
const stateConfig = {
|
const stateConfig = {
|
||||||
projects: withDefault(ArrayParam, [allOption.id]),
|
projects: withDefault(ArrayParam, [allOption.id]),
|
||||||
};
|
};
|
||||||
const [state, setState] = usePersistentTableState(`insights`, stateConfig);
|
const [state, setState] = usePersistentTableState('insights', stateConfig);
|
||||||
const setProjects = (projects: string[]) => {
|
const setProjects = (projects: string[]) => {
|
||||||
setState({ projects });
|
setState({ projects });
|
||||||
};
|
};
|
||||||
@ -79,7 +79,7 @@ export const ExecutiveDashboard: VFC = () => {
|
|||||||
selectedProjects={projects}
|
selectedProjects={projects}
|
||||||
onChange={setProjects}
|
onChange={setProjects}
|
||||||
dataTestId={'DASHBOARD_PROJECT_SELECT'}
|
dataTestId={'DASHBOARD_PROJECT_SELECT'}
|
||||||
sx={{ flex: 1, maxWidth: '360px' }}
|
sx={{ flex: 1, maxWidth: '360px', width: '100%' }}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -157,7 +157,10 @@ export const ExecutiveDashboard: VFC = () => {
|
|||||||
</ChartWidget>
|
</ChartWidget>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Widget title='Average health'>
|
<Widget
|
||||||
|
title='Average health'
|
||||||
|
tooltip='Average health is a percentage of flags that are not stale nor potencially stale.'
|
||||||
|
>
|
||||||
<HealthStats
|
<HealthStats
|
||||||
value={summary.averageHealth}
|
value={summary.averageHealth}
|
||||||
healthy={summary.active}
|
healthy={summary.active}
|
||||||
@ -185,7 +188,10 @@ export const ExecutiveDashboard: VFC = () => {
|
|||||||
<TimeToProductionChart projectFlagTrends={projectsData} />
|
<TimeToProductionChart projectFlagTrends={projectsData} />
|
||||||
</ChartWidget> */}
|
</ChartWidget> */}
|
||||||
</StyledGrid>
|
</StyledGrid>
|
||||||
<Widget title='Metrics'>
|
<Widget
|
||||||
|
title='Metrics'
|
||||||
|
tooltip='Summary of all flag evaluations reported by SDKs.'
|
||||||
|
>
|
||||||
<MetricsSummaryChart metricsSummaryTrends={metricsData} />
|
<MetricsSummaryChart metricsSummaryTrends={metricsData} />
|
||||||
</Widget>
|
</Widget>
|
||||||
</>
|
</>
|
||||||
|
@ -2,17 +2,57 @@ import { ReactNode, VFC } from 'react';
|
|||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
import { useFeedback } from 'component/feedbackNew/useFeedback';
|
import { useFeedback } from 'component/feedbackNew/useFeedback';
|
||||||
import { ReviewsOutlined } from '@mui/icons-material';
|
import { ReviewsOutlined } from '@mui/icons-material';
|
||||||
import { Button, Typography } from '@mui/material';
|
import {
|
||||||
|
Button,
|
||||||
|
Typography,
|
||||||
|
styled,
|
||||||
|
useMediaQuery,
|
||||||
|
useTheme,
|
||||||
|
} from '@mui/material';
|
||||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||||
import { Badge } from 'component/common/Badge/Badge';
|
import { Badge } from 'component/common/Badge/Badge';
|
||||||
import { ShareLink } from './ShareLink/ShareLink';
|
import { ShareLink } from './ShareLink/ShareLink';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
|
||||||
type DashboardHeaderProps = {
|
type DashboardHeaderProps = {
|
||||||
actions?: ReactNode;
|
actions?: ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const StyledActionsContainer = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
gap: theme.spacing(1),
|
||||||
|
[theme.breakpoints.down('md')]: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: theme.spacing(1),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledActionButtons = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
gap: theme.spacing(1),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledExternalActionsContainer = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
gap: theme.spacing(1),
|
||||||
|
width: 300,
|
||||||
|
[theme.breakpoints.down('md')]: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledActionsSmallScreen = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'flex-end',
|
||||||
|
gap: theme.spacing(1),
|
||||||
|
marginTop: theme.spacing(2),
|
||||||
|
}));
|
||||||
|
|
||||||
export const DashboardHeader: VFC<DashboardHeaderProps> = ({ actions }) => {
|
export const DashboardHeader: VFC<DashboardHeaderProps> = ({ actions }) => {
|
||||||
const showInactiveUsers = useUiFlag('showInactiveUsers');
|
const showInactiveUsers = useUiFlag('showInactiveUsers');
|
||||||
|
const theme = useTheme();
|
||||||
|
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
|
|
||||||
const { openFeedback } = useFeedback(
|
const { openFeedback } = useFeedback(
|
||||||
'insights',
|
'insights',
|
||||||
@ -29,6 +69,7 @@ export const DashboardHeader: VFC<DashboardHeaderProps> = ({ actions }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
titleElement={
|
titleElement={
|
||||||
<Typography
|
<Typography
|
||||||
@ -40,12 +81,21 @@ export const DashboardHeader: VFC<DashboardHeaderProps> = ({ actions }) => {
|
|||||||
gap: theme.spacing(1),
|
gap: theme.spacing(1),
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<span>Insights</span> <Badge color='success'>Beta</Badge>
|
<span>Insights</span>{' '}
|
||||||
|
<Badge color='success'>Beta</Badge>
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
actions={
|
actions={
|
||||||
<>
|
<StyledActionsContainer>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={!isSmallScreen}
|
||||||
|
show={
|
||||||
|
<StyledExternalActionsContainer>
|
||||||
{actions}
|
{actions}
|
||||||
|
</StyledExternalActionsContainer>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<StyledActionButtons>
|
||||||
<ShareLink />
|
<ShareLink />
|
||||||
<Button
|
<Button
|
||||||
startIcon={<ReviewsOutlined />}
|
startIcon={<ReviewsOutlined />}
|
||||||
@ -54,8 +104,18 @@ export const DashboardHeader: VFC<DashboardHeaderProps> = ({ actions }) => {
|
|||||||
>
|
>
|
||||||
Provide feedback
|
Provide feedback
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</StyledActionButtons>
|
||||||
|
</StyledActionsContainer>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={isSmallScreen}
|
||||||
|
show={
|
||||||
|
<StyledActionsSmallScreen>
|
||||||
|
{actions}
|
||||||
|
</StyledActionsSmallScreen>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -33,9 +33,9 @@ const StyledRingContent = styled(Box)(({ theme }) => ({
|
|||||||
|
|
||||||
const StyledInsightsContainer = styled(Box)(({ theme }) => ({
|
const StyledInsightsContainer = styled(Box)(({ theme }) => ({
|
||||||
marginTop: theme.spacing(4),
|
marginTop: theme.spacing(4),
|
||||||
padding: theme.spacing(1.5),
|
padding: theme.spacing(1.5, 2),
|
||||||
background: theme.palette.background.elevation2,
|
background: theme.palette.background.elevation2,
|
||||||
borderRadius: `${theme.shape.borderRadius}px`,
|
borderRadius: `${theme.shape.borderRadiusMedium}px`,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
}));
|
}));
|
||||||
@ -43,6 +43,7 @@ const StyledInsightsContainer = styled(Box)(({ theme }) => ({
|
|||||||
const StyledHeaderContainer = styled(Box)(({ theme }) => ({
|
const StyledHeaderContainer = styled(Box)(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
marginBottom: theme.spacing(0.5),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledTextContainer = styled(Box)(({ theme }) => ({
|
const StyledTextContainer = styled(Box)(({ theme }) => ({
|
||||||
|
@ -13,22 +13,23 @@ const StyledUserContainer = styled(Box)(({ theme }) => ({
|
|||||||
|
|
||||||
const StyledUserBox = styled(Box)(({ theme }) => ({
|
const StyledUserBox = styled(Box)(({ theme }) => ({
|
||||||
borderRadius: `${theme.shape.borderRadiusExtraLarge}px`,
|
borderRadius: `${theme.shape.borderRadiusExtraLarge}px`,
|
||||||
backgroundColor: theme.palette.primary.main,
|
backgroundColor: theme.palette.background.alternative,
|
||||||
maxWidth: 300,
|
maxWidth: 300,
|
||||||
padding: theme.spacing(2),
|
padding: theme.spacing(2),
|
||||||
marginBottom: theme.spacing(3),
|
margin: `0 auto ${theme.spacing(3)}`,
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
zIndex: 2,
|
zIndex: 2,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledCustomShadow = styled(Box)(({ theme }) => ({
|
const StyledCustomShadow = styled(Box)(({ theme }) => ({
|
||||||
width: '220px',
|
maxWidth: 270,
|
||||||
height: '54px',
|
height: '54px',
|
||||||
backgroundColor: 'rgba(108, 101, 229, 0.30)',
|
backgroundColor: 'rgba(108, 101, 229, 0.30)',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
margin: '0 auto',
|
margin: '0 auto',
|
||||||
top: '45px',
|
top: '45px',
|
||||||
left: '15px',
|
left: '15px',
|
||||||
|
right: '15px',
|
||||||
borderRadius: `${theme.shape.borderRadiusExtraLarge}px`,
|
borderRadius: `${theme.shape.borderRadiusExtraLarge}px`,
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
}));
|
}));
|
||||||
|
Loading…
Reference in New Issue
Block a user