mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: dark theme UI fixes (#3423)
https://linear.app/unleash/issue/2-849/dark-mode-ui-fixes    Also includes misc UI fixes and improvements we identified along the way. Co-authored by @NicolaeUnleash --------- Co-authored-by: NicolaeUnleash <103567375+NicolaeUnleash@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									9db40f50cf
								
							
						
					
					
						commit
						2e6b6cd354
					
				| @ -1 +1 @@ | ||||
| <svg id="bg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 251.43 251.03"><defs><style>.cls-1{fill:#1a4049;}.cls-2{fill:#fff;}.cls-3{fill:#817afe;}</style></defs><circle class="cls-1" cx="125.71" cy="125.31" r="80"/><polygon class="cls-2" points="137.14 91.03 137.14 113.88 137.14 136.74 160 136.74 160 113.88 160 91.03 137.14 91.03"/><polygon class="cls-2" points="114.29 113.88 114.29 91.03 91.43 91.03 91.43 113.88 91.43 136.74 91.43 159.6 114.29 159.6 137.14 159.6 137.14 136.74 114.29 136.74 114.29 113.88"/><rect class="cls-3" x="137.14" y="136.74" width="22.86" height="22.86"/></svg> | ||||
| <svg width="35" height="35" viewBox="0 0 35 35" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.5 35C27.165 35 35 27.165 35 17.5S27.165 0 17.5 0 0 7.835 0 17.5 7.835 35 17.5 35Z" fill="#1A4049"/><path d="M15 10h-5v15h15V10h-5v10h-5V10Z" fill="#fff"/><path d="M20 20h5v5h-5v-5Z" fill="#817AFE"/></svg> | ||||
| Before Width: | Height: | Size: 593 B After Width: | Height: | Size: 312 B | 
| @ -1,7 +1 @@ | ||||
| <svg width="334" height="334" viewBox="0 0 334 334" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <circle cx="167" cy="167" r="167" fill="white"/> | ||||
| <rect x="96.3462" y="96.3457" width="44.9615" height="141.308" fill="#1A4049"/> | ||||
| <rect x="192.692" y="96.3457" width="44.9615" height="141.308" fill="#1A4049"/> | ||||
| <path d="M237.654 192.693L237.654 237.655L96.3461 237.655L96.3461 192.693L237.654 192.693Z" fill="#1A4049"/> | ||||
| <rect x="192.692" y="192.693" width="44.9615" height="44.9615" fill="#817AFE"/> | ||||
| </svg> | ||||
| <svg width="35" height="35" viewBox="0 0 35 35" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.5 35C27.165 35 35 27.165 35 17.5S27.165 0 17.5 0 0 7.835 0 17.5 7.835 35 17.5 35Z" fill="#fff"/><path d="M15 10h-5v15h15V10h-5v10h-5V10Z" fill="#1A4049"/><path d="M20 20h5v5h-5v-5Z" fill="#817AFE"/></svg> | ||||
| Before Width: | Height: | Size: 505 B After Width: | Height: | Size: 312 B | 
| @ -10,13 +10,18 @@ import { | ||||
|     RequestsPerSecondSchemaDataResultItem, | ||||
| } from 'openapi'; | ||||
| import logoIcon from 'assets/icons/logoBg.svg'; | ||||
| import logoWhiteIcon from 'assets/icons/logoWhiteBg.svg'; | ||||
| import { formatAssetPath } from 'utils/formatPath'; | ||||
| import { useThemeMode } from 'hooks/useThemeMode'; | ||||
| 
 | ||||
| const StyledMermaid = styled(Mermaid)(({ theme }) => ({ | ||||
|     '#mermaid .node rect': { | ||||
|         fill: theme.palette.secondary.light, | ||||
|         stroke: theme.palette.secondary.border, | ||||
|     }, | ||||
|     '#mermaid .unleash-logo': { | ||||
|         padding: theme.spacing(1), | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| const isRecent = (value: ResultValue) => { | ||||
| @ -79,6 +84,7 @@ const toGraphData = (metrics?: RequestsPerSecondSchema) => { | ||||
| 
 | ||||
| export const NetworkOverview = () => { | ||||
|     usePageTitle('Network - Overview'); | ||||
|     const { themeMode } = useThemeMode(); | ||||
|     const { metrics } = useInstanceMetrics(); | ||||
|     const apps = useMemo(() => { | ||||
|         return toGraphData(metrics); | ||||
| @ -89,8 +95,8 @@ export const NetworkOverview = () => { | ||||
|         subgraph _[ ] | ||||
|         direction BT | ||||
|             Unleash(<img src='${formatAssetPath( | ||||
|                 logoIcon | ||||
|             )}' width='60' height='60' /><br/>Unleash) | ||||
|                 themeMode === 'dark' ? logoWhiteIcon : logoIcon | ||||
|             )}' width='72' height='72' class='unleash-logo'/><br/>Unleash) | ||||
|             ${apps | ||||
|                 .map( | ||||
|                     ({ label, reqs, type }, i) => | ||||
|  | ||||
| @ -18,16 +18,18 @@ import { | ||||
|     ILocationSettings, | ||||
|     useLocationSettings, | ||||
| } from 'hooks/useLocationSettings'; | ||||
| import theme from 'themes/theme'; | ||||
| import { formatDateHM } from 'utils/formatDate'; | ||||
| import { RequestsPerSecondSchema } from 'openapi'; | ||||
| import 'chartjs-adapter-date-fns'; | ||||
| import { Alert } from '@mui/material'; | ||||
| import { Alert, useTheme } from '@mui/material'; | ||||
| import { Box } from '@mui/system'; | ||||
| import { CyclicIterator } from 'utils/cyclicIterator'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { usePageTitle } from 'hooks/usePageTitle'; | ||||
| import { unknownify } from 'utils/unknownify'; | ||||
| import { Theme } from '@mui/material/styles/createTheme'; | ||||
| 
 | ||||
| const pointStyles = ['circle', 'rect', 'rectRounded', 'rectRot', 'triangle']; | ||||
| 
 | ||||
| interface IPoint { | ||||
|     x: number; | ||||
| @ -49,6 +51,7 @@ const createChartPoints = ( | ||||
| }; | ||||
| 
 | ||||
| const createInstanceChartOptions = ( | ||||
|     theme: Theme, | ||||
|     locationSettings: ILocationSettings | ||||
| ): ChartOptions<'line'> => ({ | ||||
|     locale: locationSettings.locale, | ||||
| @ -58,6 +61,7 @@ const createInstanceChartOptions = ( | ||||
|         mode: 'index', | ||||
|         intersect: false, | ||||
|     }, | ||||
|     color: theme.palette.text.secondary, | ||||
|     plugins: { | ||||
|         tooltip: { | ||||
|             backgroundColor: theme.palette.background.paper, | ||||
| @ -78,12 +82,13 @@ const createInstanceChartOptions = ( | ||||
|             itemSort: (a, b) => b.parsed.y - a.parsed.y, | ||||
|         }, | ||||
|         legend: { | ||||
|             position: 'top', | ||||
|             align: 'end', | ||||
|             position: 'bottom', | ||||
|             align: 'start', | ||||
|             labels: { | ||||
|                 boxWidth: 10, | ||||
|                 boxHeight: 10, | ||||
|                 usePointStyle: true, | ||||
|                 padding: 24, | ||||
|             }, | ||||
|         }, | ||||
|         title: { | ||||
| @ -95,6 +100,10 @@ const createInstanceChartOptions = ( | ||||
|                 size: 16, | ||||
|                 weight: '400', | ||||
|             }, | ||||
|             color: theme.palette.text.primary, | ||||
|             padding: { | ||||
|                 bottom: 32, | ||||
|             }, | ||||
|         }, | ||||
|     }, | ||||
|     scales: { | ||||
| @ -103,15 +112,24 @@ const createInstanceChartOptions = ( | ||||
|             title: { | ||||
|                 display: true, | ||||
|                 text: 'Requests per second', | ||||
|                 color: theme.palette.text.secondary, | ||||
|             }, | ||||
|             // min: 0,
 | ||||
|             suggestedMin: 0, | ||||
|             ticks: { precision: 0 }, | ||||
|             ticks: { precision: 0, color: theme.palette.text.secondary }, | ||||
|             grid: { | ||||
|                 color: theme.palette.divider, | ||||
|                 borderColor: theme.palette.divider, | ||||
|             }, | ||||
|         }, | ||||
|         x: { | ||||
|             type: 'time', | ||||
|             time: { unit: 'minute' }, | ||||
|             grid: { display: true }, | ||||
|             grid: { | ||||
|                 display: true, | ||||
|                 color: theme.palette.divider, | ||||
|                 borderColor: theme.palette.divider, | ||||
|             }, | ||||
|             ticks: { | ||||
|                 callback: (_, i, data) => | ||||
|                     formatDateHM(data[i].value * 1000, locationSettings.locale), | ||||
| @ -135,7 +153,10 @@ class ItemPicker<T> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const toChartData = (rps?: RequestsPerSecondSchema): ChartDatasetType[] => { | ||||
| const toChartData = ( | ||||
|     theme: Theme, | ||||
|     rps?: RequestsPerSecondSchema | ||||
| ): ChartDatasetType[] => { | ||||
|     if (rps?.data?.result) { | ||||
|         const colorPicker = new ItemPicker([ | ||||
|             theme.palette.success, | ||||
| @ -143,7 +164,7 @@ const toChartData = (rps?: RequestsPerSecondSchema): ChartDatasetType[] => { | ||||
|             theme.palette.primary, | ||||
|             theme.palette.warning, | ||||
|         ]); | ||||
|         return rps.data.result.map(dataset => { | ||||
|         return rps.data.result.map((dataset, i) => { | ||||
|             const endpoint = unknownify(dataset.metric?.endpoint); | ||||
|             const appName = unknownify(dataset.metric?.appName); | ||||
|             const color = colorPicker.pick(endpoint); | ||||
| @ -156,7 +177,7 @@ const toChartData = (rps?: RequestsPerSecondSchema): ChartDatasetType[] => { | ||||
|                 elements: { | ||||
|                     point: { | ||||
|                         radius: 4, | ||||
|                         pointStyle: 'circle', | ||||
|                         pointStyle: pointStyles[i % pointStyles.length], | ||||
|                     }, | ||||
|                     line: { | ||||
|                         borderDash: [8, 4], | ||||
| @ -171,15 +192,16 @@ const toChartData = (rps?: RequestsPerSecondSchema): ChartDatasetType[] => { | ||||
| export const NetworkTraffic: VFC = () => { | ||||
|     const { locationSettings } = useLocationSettings(); | ||||
|     const { metrics } = useInstanceMetrics(); | ||||
|     const theme = useTheme(); | ||||
|     const options = useMemo(() => { | ||||
|         return createInstanceChartOptions(locationSettings); | ||||
|     }, [locationSettings]); | ||||
|         return createInstanceChartOptions(theme, locationSettings); | ||||
|     }, [theme, locationSettings]); | ||||
| 
 | ||||
|     usePageTitle('Network - Traffic'); | ||||
| 
 | ||||
|     const data = useMemo(() => { | ||||
|         return { datasets: toChartData(metrics) }; | ||||
|     }, [metrics, locationSettings]); | ||||
|         return { datasets: toChartData(theme, metrics) }; | ||||
|     }, [theme, metrics, locationSettings]); | ||||
| 
 | ||||
|     return ( | ||||
|         <ConditionallyRender | ||||
|  | ||||
| @ -30,14 +30,14 @@ const StyledBar = styled(Paper)(({ theme }) => ({ | ||||
|     marginRight: 'auto', | ||||
|     padding: theme.spacing(2, 3), | ||||
|     backgroundColor: theme.palette.background.paper, | ||||
|     border: `1px solid ${theme.palette.secondary.main}`, | ||||
|     border: `1px solid ${theme.palette.background.alternative}`, | ||||
|     borderRadius: theme.shape.borderRadiusLarge, | ||||
|     gap: theme.spacing(1), | ||||
|     flexWrap: 'wrap', | ||||
| })); | ||||
| 
 | ||||
| const StyledCount = styled('span')(({ theme }) => ({ | ||||
|     background: theme.palette.secondary.main, | ||||
|     background: theme.palette.background.alternative, | ||||
|     color: theme.palette.common.white, | ||||
|     padding: theme.spacing(0.5, 1), | ||||
|     borderRadius: theme.shape.borderRadius, | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| import { Box, Tooltip, useTheme } from '@mui/material'; | ||||
| import { Box, Tooltip } from '@mui/material'; | ||||
| import { ReactComponent as NegatedIcon } from 'assets/icons/24_Negator.svg'; | ||||
| import { ReactComponent as NegatedIconOff } from 'assets/icons/24_Negator off.svg'; | ||||
| import { IConstraint } from 'interfaces/strategy'; | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| import { styled, Tooltip, TooltipProps } from '@mui/material'; | ||||
| import { HelpOutline } from '@mui/icons-material'; | ||||
| import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip'; | ||||
| 
 | ||||
| const StyledContainer = styled('span')(({ theme }) => ({ | ||||
|     display: 'inline-grid', | ||||
| @ -22,12 +23,28 @@ const StyledContainer = styled('span')(({ theme }) => ({ | ||||
| })); | ||||
| 
 | ||||
| interface IHelpIconProps { | ||||
|     tooltip: string; | ||||
|     tooltip: React.ReactNode; | ||||
|     htmlTooltip?: boolean; | ||||
|     placement?: TooltipProps['placement']; | ||||
|     children?: React.ReactNode; | ||||
| } | ||||
| 
 | ||||
| export const HelpIcon = ({ tooltip, placement, children }: IHelpIconProps) => { | ||||
| export const HelpIcon = ({ | ||||
|     tooltip, | ||||
|     htmlTooltip, | ||||
|     placement, | ||||
|     children, | ||||
| }: IHelpIconProps) => { | ||||
|     if (htmlTooltip) { | ||||
|         return ( | ||||
|             <HtmlTooltip title={tooltip} placement={placement} arrow> | ||||
|                 <StyledContainer tabIndex={0} aria-label="Help"> | ||||
|                     {children ?? <HelpOutline />} | ||||
|                 </StyledContainer> | ||||
|             </HtmlTooltip> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|         <Tooltip title={tooltip} placement={placement} arrow> | ||||
|             <StyledContainer tabIndex={0} aria-label="Help"> | ||||
|  | ||||
| @ -5,8 +5,25 @@ import { useRef, useEffect } from 'react'; | ||||
| const StyledMermaid = styled('div')(({ theme }) => ({ | ||||
|     display: 'flex', | ||||
|     justifyContent: 'center', | ||||
|     '#mermaid .edgeLabel': { | ||||
|         backgroundColor: theme.palette.background.paper, | ||||
|     '#mermaid': { | ||||
|         '.edgeLabel': { | ||||
|             backgroundColor: theme.palette.background.paper, | ||||
|             color: theme.palette.text.primary, | ||||
|         }, | ||||
|         '.nodeLabel': { | ||||
|             color: theme.palette.secondary.dark, | ||||
|         }, | ||||
|         '.edgePaths > path': { | ||||
|             stroke: theme.palette.secondary.dark, | ||||
|         }, | ||||
|         '.arrowMarkerPath': { | ||||
|             fill: theme.palette.secondary.dark, | ||||
|             stroke: 'transparent', | ||||
|         }, | ||||
|     }, | ||||
|     '&&& #mermaid .node rect': { | ||||
|         stroke: theme.palette.secondary.border, | ||||
|         fill: theme.palette.secondary.light, | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
|  | ||||
| @ -56,7 +56,7 @@ const Toast = ({ title, text, type, confetti }: IToast) => { | ||||
|     }; | ||||
| 
 | ||||
|     return ( | ||||
|         <div className={styles.container}> | ||||
|         <div className={classnames(styles.container, 'dropdown-outline')}> | ||||
|             <div className={styles.innerContainer}> | ||||
|                 <div className={styles.confettiContainer}> | ||||
|                     {confetti && renderConfetti()} | ||||
|  | ||||
| @ -6,7 +6,7 @@ import { | ||||
|     FeatureMetricsHours, | ||||
| } from './FeatureMetricsHours/FeatureMetricsHours'; | ||||
| import { IFeatureMetricsRaw } from 'interfaces/featureToggle'; | ||||
| import { Grid, styled } from '@mui/material'; | ||||
| import { Grid } from '@mui/material'; | ||||
| import { FeatureMetricsContent } from './FeatureMetricsContent/FeatureMetricsContent'; | ||||
| import { useQueryStringNumberState } from 'hooks/useQueryStringNumberState'; | ||||
| import { useQueryStringState } from 'hooks/useQueryStringState'; | ||||
| @ -16,12 +16,6 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit | ||||
| import { usePageTitle } from 'hooks/usePageTitle'; | ||||
| import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; | ||||
| 
 | ||||
| const StyledContainer = styled('div')(({ theme }) => ({ | ||||
|     [theme.breakpoints.down('md')]: { | ||||
|         marginTop: theme.spacing(2), | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| export const FeatureMetrics = () => { | ||||
|     const projectId = useRequiredPathParam('projectId'); | ||||
|     const featureId = useRequiredPathParam('featureId'); | ||||
| @ -62,12 +56,7 @@ export const FeatureMetrics = () => { | ||||
| 
 | ||||
|     return ( | ||||
|         <PageContent> | ||||
|             <Grid | ||||
|                 container | ||||
|                 component="header" | ||||
|                 spacing={2} | ||||
|                 alignItems="flex-end" | ||||
|             > | ||||
|             <Grid container component="header" spacing={2}> | ||||
|                 <Grid item xs={12} md={5}> | ||||
|                     <ConditionallyRender | ||||
|                         condition={environments.size > 0} | ||||
| @ -95,12 +84,10 @@ export const FeatureMetrics = () => { | ||||
|                     /> | ||||
|                 </Grid> | ||||
|                 <Grid item xs={12} md={2}> | ||||
|                     <StyledContainer> | ||||
|                         <FeatureMetricsHours | ||||
|                             hoursBack={hoursBack} | ||||
|                             setHoursBack={setHoursBack} | ||||
|                         /> | ||||
|                     </StyledContainer> | ||||
|                     <FeatureMetricsHours | ||||
|                         hoursBack={hoursBack} | ||||
|                         setHoursBack={setHoursBack} | ||||
|                     /> | ||||
|                 </Grid> | ||||
|             </Grid> | ||||
|             <FeatureMetricsContent | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { IFeatureMetricsRaw } from 'interfaces/featureToggle'; | ||||
| import React, { useMemo } from 'react'; | ||||
| import { useMemo } from 'react'; | ||||
| import { Line } from 'react-chartjs-2'; | ||||
| import { | ||||
|     CategoryScale, | ||||
| @ -16,6 +16,7 @@ import { useLocationSettings } from 'hooks/useLocationSettings'; | ||||
| import 'chartjs-adapter-date-fns'; | ||||
| import { createChartData } from './createChartData'; | ||||
| import { createChartOptions } from './createChartOptions'; | ||||
| import { useTheme } from '@mui/material'; | ||||
| 
 | ||||
| interface IFeatureMetricsChartProps { | ||||
|     metrics: IFeatureMetricsRaw[]; | ||||
| @ -28,6 +29,7 @@ export const FeatureMetricsChart = ({ | ||||
|     hoursBack, | ||||
|     statsSectionId, | ||||
| }: IFeatureMetricsChartProps) => { | ||||
|     const theme = useTheme(); | ||||
|     const { locationSettings } = useLocationSettings(); | ||||
| 
 | ||||
|     const sortedMetrics = useMemo(() => { | ||||
| @ -37,12 +39,17 @@ export const FeatureMetricsChart = ({ | ||||
|     }, [metrics]); | ||||
| 
 | ||||
|     const options = useMemo(() => { | ||||
|         return createChartOptions(sortedMetrics, hoursBack, locationSettings); | ||||
|     }, [sortedMetrics, hoursBack, locationSettings]); | ||||
|         return createChartOptions( | ||||
|             theme, | ||||
|             sortedMetrics, | ||||
|             hoursBack, | ||||
|             locationSettings | ||||
|         ); | ||||
|     }, [theme, sortedMetrics, hoursBack, locationSettings]); | ||||
| 
 | ||||
|     const data = useMemo(() => { | ||||
|         return createChartData(sortedMetrics, locationSettings); | ||||
|     }, [sortedMetrics, locationSettings]); | ||||
|         return createChartData(theme, sortedMetrics, locationSettings); | ||||
|     }, [theme, sortedMetrics, locationSettings]); | ||||
| 
 | ||||
|     return ( | ||||
|         <div style={{ height: 400 }}> | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| import { IFeatureMetricsRaw } from 'interfaces/featureToggle'; | ||||
| import { ChartData } from 'chart.js'; | ||||
| import { ILocationSettings } from 'hooks/useLocationSettings'; | ||||
| import theme from 'themes/theme'; | ||||
| import 'chartjs-adapter-date-fns'; | ||||
| import { Theme } from '@mui/material/styles/createTheme'; | ||||
| 
 | ||||
| interface IPoint { | ||||
|     x: string; | ||||
| @ -10,6 +10,7 @@ interface IPoint { | ||||
| } | ||||
| 
 | ||||
| export const createChartData = ( | ||||
|     theme: Theme, | ||||
|     metrics: IFeatureMetricsRaw[], | ||||
|     locationSettings: ILocationSettings | ||||
| ): ChartData<'line', IPoint[], string> => { | ||||
|  | ||||
| @ -2,10 +2,11 @@ import { ILocationSettings } from 'hooks/useLocationSettings'; | ||||
| import 'chartjs-adapter-date-fns'; | ||||
| import { ChartOptions, defaults } from 'chart.js'; | ||||
| import { IFeatureMetricsRaw } from 'interfaces/featureToggle'; | ||||
| import theme from 'themes/theme'; | ||||
| import { formatDateHM } from 'utils/formatDate'; | ||||
| import { Theme } from '@mui/material/styles/createTheme'; | ||||
| 
 | ||||
| export const createChartOptions = ( | ||||
|     theme: Theme, | ||||
|     metrics: IFeatureMetricsRaw[], | ||||
|     hoursBack: number, | ||||
|     locationSettings: ILocationSettings | ||||
| @ -18,6 +19,7 @@ export const createChartOptions = ( | ||||
|             mode: 'index', | ||||
|             intersect: false, | ||||
|         }, | ||||
|         color: theme.palette.text.secondary, | ||||
|         plugins: { | ||||
|             tooltip: { | ||||
|                 backgroundColor: theme.palette.background.paper, | ||||
| @ -56,6 +58,7 @@ export const createChartOptions = ( | ||||
|                     size: 16, | ||||
|                     weight: '400', | ||||
|                 }, | ||||
|                 color: theme.palette.text.primary, | ||||
|             }, | ||||
|         }, | ||||
|         scales: { | ||||
| @ -64,10 +67,15 @@ export const createChartOptions = ( | ||||
|                 title: { | ||||
|                     display: true, | ||||
|                     text: 'Number of requests', | ||||
|                     color: theme.palette.text.secondary, | ||||
|                 }, | ||||
|                 // min: 0,
 | ||||
|                 suggestedMin: 0, | ||||
|                 ticks: { precision: 0 }, | ||||
|                 ticks: { precision: 0, color: theme.palette.text.secondary }, | ||||
|                 grid: { | ||||
|                     color: theme.palette.divider, | ||||
|                     borderColor: theme.palette.divider, | ||||
|                 }, | ||||
|             }, | ||||
|             x: { | ||||
|                 type: 'time', | ||||
| @ -76,6 +84,7 @@ export const createChartOptions = ( | ||||
|                 ticks: { | ||||
|                     callback: (_, i, data) => | ||||
|                         formatDateHM(data[i].value, locationSettings.locale), | ||||
|                     color: theme.palette.text.secondary, | ||||
|                 }, | ||||
|             }, | ||||
|         }, | ||||
|  | ||||
| @ -11,7 +11,7 @@ interface IFeatureMetricsChipsProps { | ||||
| 
 | ||||
| const StyledTitle = styled('h2')(({ theme }) => ({ | ||||
|     margin: 0, | ||||
|     marginBottom: theme.spacing(1), | ||||
|     marginBottom: theme.spacing(1.5), | ||||
|     fontSize: theme.fontSizes.smallBody, | ||||
|     fontWeight: theme.fontWeight.thin, | ||||
|     color: theme.palette.text.secondary, | ||||
|  | ||||
| @ -2,7 +2,6 @@ import { FeatureMetricsTable } from '../FeatureMetricsTable/FeatureMetricsTable' | ||||
| import { IFeatureMetricsRaw } from 'interfaces/featureToggle'; | ||||
| import { FeatureMetricsStatsRaw } from '../FeatureMetricsStats/FeatureMetricsStatsRaw'; | ||||
| import { Box, Typography } from '@mui/material'; | ||||
| import theme from 'themes/theme'; | ||||
| import { useId } from 'hooks/useId'; | ||||
| import React, { Suspense } from 'react'; | ||||
| 
 | ||||
| @ -35,12 +34,7 @@ export const FeatureMetricsContent = ({ | ||||
| 
 | ||||
|     return ( | ||||
|         <Suspense fallback={null}> | ||||
|             <Box | ||||
|                 borderTop={1} | ||||
|                 pt={2} | ||||
|                 mt={3} | ||||
|                 borderColor={theme.palette.divider} | ||||
|             > | ||||
|             <Box borderTop={1} pt={2} mt={3} borderColor="divider"> | ||||
|                 <LazyFeatureMetricsChart | ||||
|                     metrics={metrics} | ||||
|                     hoursBack={hoursBack} | ||||
|  | ||||
| @ -1,7 +1,16 @@ | ||||
| import { styled } from '@mui/material'; | ||||
| import GeneralSelect, { | ||||
|     IGeneralSelectProps, | ||||
| } from 'component/common/GeneralSelect/GeneralSelect'; | ||||
| 
 | ||||
| const StyledTitle = styled('h2')(({ theme }) => ({ | ||||
|     margin: 0, | ||||
|     marginBottom: theme.spacing(1), | ||||
|     fontSize: theme.fontSizes.smallBody, | ||||
|     fontWeight: theme.fontWeight.thin, | ||||
|     color: theme.palette.text.secondary, | ||||
| })); | ||||
| 
 | ||||
| interface IFeatureMetricsHoursProps { | ||||
|     hoursBack: number; | ||||
|     setHoursBack: (value: number) => void; | ||||
| @ -18,15 +27,17 @@ export const FeatureMetricsHours = ({ | ||||
|     }; | ||||
| 
 | ||||
|     return ( | ||||
|         <GeneralSelect | ||||
|             label="Period" | ||||
|             name="feature-metrics-period" | ||||
|             id="feature-metrics-period" | ||||
|             options={hourOptions} | ||||
|             value={String(hoursBack)} | ||||
|             onChange={onChange} | ||||
|             fullWidth | ||||
|         /> | ||||
|         <div> | ||||
|             <StyledTitle>Period</StyledTitle> | ||||
|             <GeneralSelect | ||||
|                 name="feature-metrics-period" | ||||
|                 id="feature-metrics-period" | ||||
|                 options={hourOptions} | ||||
|                 value={String(hoursBack)} | ||||
|                 onChange={onChange} | ||||
|                 fullWidth | ||||
|             /> | ||||
|         </div> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -1,11 +1,18 @@ | ||||
| import { useContext, useMemo, useState } from 'react'; | ||||
| import { Box, Button, IconButton, Tooltip, useTheme } from '@mui/material'; | ||||
| import { | ||||
|     Box, | ||||
|     Button, | ||||
|     IconButton, | ||||
|     Tooltip, | ||||
|     useTheme, | ||||
|     styled, | ||||
| } from '@mui/material'; | ||||
| import CloseIcon from '@mui/icons-material/Close'; | ||||
| import { ReactComponent as Logo } from 'assets/icons/logoPlain.svg'; | ||||
| import { ReactComponent as UnleashLogo } from 'assets/icons/logoBg.svg'; | ||||
| import { ReactComponent as UnleashLogoWhite } from 'assets/icons/logoWhiteBg.svg'; | ||||
| import AnimateOnMount from 'component/common/AnimateOnMount/AnimateOnMount'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { | ||||
|     contentSpacingY, | ||||
|     fadeInTopEnter, | ||||
|     fadeInTopLeave, | ||||
|     fadeInTopStart, | ||||
| @ -17,6 +24,13 @@ import { | ||||
| } from 'component/feedback/FeedbackNPS/showNPSFeedback'; | ||||
| import { useAuthFeedback } from 'hooks/api/getters/useAuth/useAuthFeedback'; | ||||
| import { useAuthFeedbackApi } from 'hooks/api/actions/useAuthFeedbackApi/useAuthFeedbackApi'; | ||||
| import { ThemeMode } from 'component/common/ThemeMode/ThemeMode'; | ||||
| 
 | ||||
| const StyledHeader = styled('h3')(({ theme }) => ({ | ||||
|     margin: 0, | ||||
|     color: theme.palette.text.primary, | ||||
|     marginLeft: theme.spacing(1), | ||||
| })); | ||||
| 
 | ||||
| interface IFeedbackNPSProps { | ||||
|     openUrl: string; | ||||
| @ -77,12 +91,13 @@ export const FeedbackNPS = ({ openUrl }: IFeedbackNPSProps) => { | ||||
|             leave={animations.leave} | ||||
|         > | ||||
|             <Box | ||||
|                 className="dropdown-outline" | ||||
|                 sx={{ | ||||
|                     borderRadius: `${theme.shape.borderRadiusLarge}px`, | ||||
|                     backgroundColor: theme.palette.background.paper, | ||||
|                     zIndex: 9999, | ||||
|                     boxShadow: theme.boxShadows.elevated, | ||||
|                     padding: theme.spacing(3), | ||||
|                     padding: theme.spacing(4), | ||||
|                     maxWidth: '400px', | ||||
|                 }} | ||||
|             > | ||||
| @ -90,35 +105,37 @@ export const FeedbackNPS = ({ openUrl }: IFeedbackNPSProps) => { | ||||
|                     sx={{ | ||||
|                         display: 'flex', | ||||
|                         flexDirection: 'column', | ||||
|                         rowGap: theme.spacing(1.5), | ||||
|                         position: 'relative', | ||||
|                         ...contentSpacingY(theme), | ||||
|                     }} | ||||
|                 > | ||||
|                     <Tooltip title="Close" arrow> | ||||
|                         <IconButton | ||||
|                             sx={{ | ||||
|                             sx={theme => ({ | ||||
|                                 position: 'absolute', | ||||
|                                 right: '-38px', | ||||
|                                 top: '-47px', | ||||
|                                 backgroundColor: theme.palette.background.paper, | ||||
|                                 boxShadow: theme.boxShadows.elevated, | ||||
|                                 '&:hover': { | ||||
|                                     backgroundColor: | ||||
|                                         theme.palette.background.paper, | ||||
|                                 }, | ||||
|                             }} | ||||
|                                 right: theme.spacing(-4), | ||||
|                                 top: theme.spacing(-4), | ||||
|                             })} | ||||
|                             onClick={() => setShowFeedback(false)} | ||||
|                             size="large" | ||||
|                         > | ||||
|                             <CloseIcon /> | ||||
|                         </IconButton> | ||||
|                     </Tooltip> | ||||
|                     <Logo | ||||
|                         style={{ | ||||
|                             width: '25px', | ||||
|                             height: '25px', | ||||
|                     <Box | ||||
|                         sx={{ | ||||
|                             display: 'flex', | ||||
|                             flexDirection: 'row', | ||||
|                             alignItems: 'center', | ||||
|                         }} | ||||
|                     /> | ||||
|                     > | ||||
|                         <ThemeMode | ||||
|                             darkmode={<UnleashLogoWhite />} | ||||
|                             lightmode={<UnleashLogo />} | ||||
|                         /> | ||||
|                         <StyledHeader>Unleash feedback</StyledHeader> | ||||
|                     </Box> | ||||
| 
 | ||||
|                     <ConditionallyRender | ||||
|                         condition={answeredNotNow} | ||||
|                         show={ | ||||
| @ -135,7 +152,12 @@ export const FeedbackNPS = ({ openUrl }: IFeedbackNPSProps) => { | ||||
|                         } | ||||
|                     /> | ||||
| 
 | ||||
|                     <Box> | ||||
|                     <Box | ||||
|                         sx={{ | ||||
|                             textAlign: 'right', | ||||
|                             marginTop: theme.spacing(2.5), | ||||
|                         }} | ||||
|                     > | ||||
|                         <ConditionallyRender | ||||
|                             condition={answeredNotNow} | ||||
|                             show={ | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| import { Box, styled, Typography } from '@mui/material'; | ||||
| import { HelpOutline } from '@mui/icons-material'; | ||||
| import { HtmlTooltip } from '../../../common/HtmlTooltip/HtmlTooltip'; | ||||
| import React, { FC } from 'react'; | ||||
| import { FC } from 'react'; | ||||
| import { HelpIcon } from 'component/common/HelpIcon/HelpIcon'; | ||||
| 
 | ||||
| const StyledTitle = styled(Typography)(({ theme }) => ({ | ||||
|     fontWeight: theme.fontWeight.bold, | ||||
| @ -13,8 +12,9 @@ const StyledDescription = styled(Typography)(({ theme }) => ({ | ||||
| })); | ||||
| 
 | ||||
| export const CollaborationModeTooltip: FC = () => ( | ||||
|     <HtmlTooltip | ||||
|         title={ | ||||
|     <HelpIcon | ||||
|         htmlTooltip | ||||
|         tooltip={ | ||||
|             <> | ||||
|                 <Box> | ||||
|                     <StyledTitle>open: </StyledTitle> | ||||
| @ -31,9 +31,5 @@ export const CollaborationModeTooltip: FC = () => ( | ||||
|                 </Box> | ||||
|             </> | ||||
|         } | ||||
|         arrow | ||||
|         describeChild | ||||
|     > | ||||
|         <HelpOutline /> | ||||
|     </HtmlTooltip> | ||||
|     /> | ||||
| ); | ||||
|  | ||||
| @ -140,10 +140,15 @@ const ProjectForm: React.FC<IProjectForm> = ({ | ||||
|                     condition={Boolean(projectModeFlag)} | ||||
|                     show={ | ||||
|                         <> | ||||
|                             <Box sx={{ display: 'flex' }}> | ||||
|                                 <StyledDescription> | ||||
|                                     What is your project collaboration mode? | ||||
|                                 </StyledDescription> | ||||
|                             <Box | ||||
|                                 sx={{ | ||||
|                                     display: 'flex', | ||||
|                                     alignItems: 'center', | ||||
|                                     marginBottom: 1, | ||||
|                                     gap: 1, | ||||
|                                 }} | ||||
|                             > | ||||
|                                 <p>What is your project collaboration mode?</p> | ||||
|                                 <CollaborationModeTooltip /> | ||||
|                             </Box> | ||||
|                             <Select | ||||
|  | ||||
| @ -3,7 +3,7 @@ import { useContext } from 'react'; | ||||
| import { setLocalStorageItem } from 'utils/storage'; | ||||
| import mainTheme from 'themes/theme'; | ||||
| import darkTheme from 'themes/dark-theme'; | ||||
| import { Theme } from '@emotion/react'; | ||||
| import { Theme } from '@mui/material/styles/createTheme'; | ||||
| 
 | ||||
| interface IUseThemeModeOutput { | ||||
|     resolveTheme: () => Theme; | ||||
|  | ||||
| @ -9,9 +9,6 @@ const actionColors = { | ||||
|     0.08: 'rgba(223, 222, 255, 0.08)', | ||||
|     0.05: 'rgba(223, 222, 255, 0.05)', | ||||
| }; | ||||
| const purpleColor = { | ||||
|     0.5: 'rgba(151, 146, 237, 0.5))', | ||||
| }; | ||||
| 
 | ||||
| const theme = { | ||||
|     breakpoints: { | ||||
| @ -95,7 +92,7 @@ const theme = { | ||||
|         }, | ||||
|         secondary: { | ||||
|             // Used for purple badges and puple light elements
 | ||||
|             main: '#57549C', // used on icons on these elements
 | ||||
|             main: '#9792ED', // used on icons on these elements
 | ||||
|             light: '#34325E', // used as a bakground on these elements
 | ||||
|             dark: '#EEEEFC', // used for text on these elements
 | ||||
|             border: '#4C4992', | ||||
| @ -543,7 +540,7 @@ export default createTheme({ | ||||
|                     '&:not(.Mui-disabled).MuiButton-containedPrimary': { | ||||
|                         backgroundColor: theme.palette.background.alternative, | ||||
|                         '&:hover': { | ||||
|                             backgroundColor: theme.palette.secondary.main, | ||||
|                             backgroundColor: theme.palette.secondary.light, | ||||
|                         }, | ||||
|                     }, | ||||
|                 }), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user