mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-04 00:18:01 +01:00
Cleaning up stale flag: insightsV2 with value true (#7896)
Co-authored-by: Gitar <noreply@gitar.co> Co-authored-by: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com>
This commit is contained in:
parent
ee1d8ee8cd
commit
43100f9561
@ -1,6 +1,6 @@
|
||||
import { render } from '../../utils/testRenderer';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { NewInsights } from './Insights';
|
||||
import { Insights } from './Insights';
|
||||
import { testServerRoute, testServerSetup } from '../../utils/testServer';
|
||||
import { vi } from 'vitest';
|
||||
|
||||
@ -30,7 +30,7 @@ const currentTime = '2024-04-25T08:05:00.000Z';
|
||||
test('Filter insights by project and date', async () => {
|
||||
vi.setSystemTime(currentTime);
|
||||
setupApi();
|
||||
render(<NewInsights ChartComponent={undefined} />);
|
||||
render(<Insights withCharts={false} />);
|
||||
const addFilter = await screen.findByText('Add Filter');
|
||||
fireEvent.click(addFilter);
|
||||
|
||||
|
@ -1,17 +1,11 @@
|
||||
import { useState, type FC } from 'react';
|
||||
import { Box, styled } from '@mui/material';
|
||||
import { ArrayParam, withDefault } from 'use-query-params';
|
||||
import { styled } from '@mui/material';
|
||||
import { usePersistentTableState } from 'hooks/usePersistentTableState';
|
||||
import {
|
||||
allOption,
|
||||
ProjectSelect,
|
||||
} from 'component/common/ProjectSelect/ProjectSelect';
|
||||
import { allOption } from 'component/common/ProjectSelect/ProjectSelect';
|
||||
import { useInsights } from 'hooks/api/getters/useInsights/useInsights';
|
||||
import { InsightsHeader } from './components/InsightsHeader/InsightsHeader';
|
||||
import { useInsightsData } from './hooks/useInsightsData';
|
||||
import { type IChartsProps, InsightsCharts } from './InsightsCharts';
|
||||
import { LegacyInsightsCharts } from './LegacyInsightsCharts';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
import { InsightsCharts } from './InsightsCharts';
|
||||
import { Sticky } from 'component/common/Sticky/Sticky';
|
||||
import { InsightsFilters } from './InsightsFilters';
|
||||
import { FilterItemParam } from '../../utils/serializeQueryParams';
|
||||
@ -29,87 +23,11 @@ const StickyContainer = styled(Sticky)(({ theme }) => ({
|
||||
transition: 'padding 0.3s ease',
|
||||
}));
|
||||
|
||||
/**
|
||||
* @deprecated remove with insightsV2 flag
|
||||
*/
|
||||
const StickyWrapper = styled(Box, {
|
||||
shouldForwardProp: (prop) => prop !== 'scrolled',
|
||||
})<{ scrolled?: boolean }>(({ theme, scrolled }) => ({
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
zIndex: theme.zIndex.sticky,
|
||||
padding: scrolled ? theme.spacing(2, 0) : theme.spacing(2, 0, 2),
|
||||
background: theme.palette.background.application,
|
||||
transition: 'padding 0.3s ease',
|
||||
}));
|
||||
|
||||
const StyledProjectSelect = styled(ProjectSelect)(({ theme }) => ({
|
||||
flex: 1,
|
||||
width: '300px',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
width: '100%',
|
||||
},
|
||||
}));
|
||||
|
||||
/**
|
||||
* @deprecated remove with insightsV2 flag
|
||||
*/
|
||||
const LegacyInsights: FC = () => {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const { insights, loading, error } = useInsights();
|
||||
const stateConfig = {
|
||||
projects: withDefault(ArrayParam, [allOption.id]),
|
||||
};
|
||||
const [state, setState] = usePersistentTableState('insights', stateConfig);
|
||||
const setProjects = (projects: string[]) => {
|
||||
setState({ projects });
|
||||
};
|
||||
const projects = state.projects
|
||||
? (state.projects.filter(Boolean) as string[])
|
||||
: [];
|
||||
|
||||
const insightsData = useInsightsData(insights, projects);
|
||||
|
||||
const handleScroll = () => {
|
||||
if (!scrolled && window.scrollY > 0) {
|
||||
setScrolled(true);
|
||||
} else if (scrolled && window.scrollY === 0) {
|
||||
setScrolled(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<StickyWrapper>
|
||||
<InsightsHeader
|
||||
actions={
|
||||
<StyledProjectSelect
|
||||
selectedProjects={projects}
|
||||
onChange={setProjects}
|
||||
dataTestId={'DASHBOARD_PROJECT_SELECT'}
|
||||
limitTags={1}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</StickyWrapper>
|
||||
<LegacyInsightsCharts
|
||||
loading={loading}
|
||||
projects={projects}
|
||||
{...insightsData}
|
||||
/>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
interface InsightsProps {
|
||||
ChartComponent?: FC<IChartsProps>;
|
||||
withCharts?: boolean;
|
||||
}
|
||||
|
||||
export const NewInsights: FC<InsightsProps> = ({ ChartComponent }) => {
|
||||
export const Insights: FC<InsightsProps> = ({ withCharts = true }) => {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
|
||||
const stateConfig = {
|
||||
@ -118,7 +36,7 @@ export const NewInsights: FC<InsightsProps> = ({ ChartComponent }) => {
|
||||
to: FilterItemParam,
|
||||
};
|
||||
const [state, setState] = usePersistentTableState('insights', stateConfig);
|
||||
const { insights, loading, error } = useInsights(
|
||||
const { insights, loading } = useInsights(
|
||||
state.from?.values[0],
|
||||
state.to?.values[0],
|
||||
);
|
||||
@ -148,8 +66,8 @@ export const NewInsights: FC<InsightsProps> = ({ ChartComponent }) => {
|
||||
}
|
||||
/>
|
||||
</StickyContainer>
|
||||
{ChartComponent && (
|
||||
<ChartComponent
|
||||
{withCharts && (
|
||||
<InsightsCharts
|
||||
loading={loading}
|
||||
projects={projects}
|
||||
{...insightsData}
|
||||
@ -158,12 +76,3 @@ export const NewInsights: FC<InsightsProps> = ({ ChartComponent }) => {
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export const Insights: FC = () => {
|
||||
const isInsightsV2Enabled = useUiFlag('insightsV2');
|
||||
|
||||
if (isInsightsV2Enabled)
|
||||
return <NewInsights ChartComponent={InsightsCharts} />;
|
||||
|
||||
return <LegacyInsights />;
|
||||
};
|
||||
|
@ -1,254 +0,0 @@
|
||||
import type { VFC } from 'react';
|
||||
import { Box, styled } from '@mui/material';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { Widget } from './components/Widget/Widget';
|
||||
import { UserStats } from './componentsStat/UserStats/UserStats';
|
||||
import { UsersChart } from './componentsChart/UsersChart/UsersChart';
|
||||
import { UsersPerProjectChart } from './componentsChart/UsersPerProjectChart/UsersPerProjectChart';
|
||||
import { FlagStats } from './componentsStat/FlagStats/FlagStats';
|
||||
import { FlagsChart } from './componentsChart/FlagsChart/FlagsChart';
|
||||
import { FlagsProjectChart } from './componentsChart/FlagsProjectChart/FlagsProjectChart';
|
||||
import { LegacyHealthStats } from './componentsStat/HealthStats/LegacyHealthStats';
|
||||
import { ProjectHealthChart } from './componentsChart/ProjectHealthChart/ProjectHealthChart';
|
||||
import { TimeToProduction } from './componentsStat/TimeToProduction/TimeToProduction';
|
||||
import { TimeToProductionChart } from './componentsChart/TimeToProductionChart/TimeToProductionChart';
|
||||
import { MetricsSummaryChart } from './componentsChart/MetricsSummaryChart/MetricsSummaryChart';
|
||||
import { UpdatesPerEnvironmentTypeChart } from './componentsChart/UpdatesPerEnvironmentTypeChart/UpdatesPerEnvironmentTypeChart';
|
||||
import type {
|
||||
InstanceInsightsSchema,
|
||||
InstanceInsightsSchemaFlags,
|
||||
InstanceInsightsSchemaUsers,
|
||||
} from 'openapi';
|
||||
import type { GroupedDataByProject } from './hooks/useGroupedProjectTrends';
|
||||
import { allOption } from 'component/common/ProjectSelect/ProjectSelect';
|
||||
import { chartInfo } from './chart-info';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
|
||||
interface IChartsProps {
|
||||
flags: InstanceInsightsSchema['flags'];
|
||||
flagTrends: InstanceInsightsSchema['flagTrends'];
|
||||
projectsData: InstanceInsightsSchema['projectFlagTrends'];
|
||||
groupedProjectsData: GroupedDataByProject<
|
||||
InstanceInsightsSchema['projectFlagTrends']
|
||||
>;
|
||||
metricsData: InstanceInsightsSchema['metricsSummaryTrends'];
|
||||
groupedMetricsData: GroupedDataByProject<
|
||||
InstanceInsightsSchema['metricsSummaryTrends']
|
||||
>;
|
||||
users: InstanceInsightsSchema['users'];
|
||||
userTrends: InstanceInsightsSchema['userTrends'];
|
||||
environmentTypeTrends: InstanceInsightsSchema['environmentTypeTrends'];
|
||||
summary: {
|
||||
total: number;
|
||||
active: number;
|
||||
stale: number;
|
||||
potentiallyStale: number;
|
||||
averageUsers: number;
|
||||
averageHealth?: string;
|
||||
flagsPerUser?: string;
|
||||
medianTimeToProduction?: number;
|
||||
};
|
||||
loading: boolean;
|
||||
projects: string[];
|
||||
allMetricsDatapoints: string[];
|
||||
}
|
||||
|
||||
const StyledGrid = styled(Box)(({ theme }) => ({
|
||||
display: 'grid',
|
||||
gridTemplateColumns: `repeat(2, 1fr)`,
|
||||
gridAutoRows: 'auto',
|
||||
gap: theme.spacing(2),
|
||||
paddingBottom: theme.spacing(2),
|
||||
[theme.breakpoints.up('md')]: {
|
||||
gridTemplateColumns: `300px 1fr`,
|
||||
},
|
||||
}));
|
||||
|
||||
const ChartWidget = styled(Widget)(({ theme }) => ({
|
||||
[theme.breakpoints.down('md')]: {
|
||||
gridColumnStart: 'span 2',
|
||||
order: 2,
|
||||
},
|
||||
}));
|
||||
|
||||
/**
|
||||
* @deprecated remove with insightsV2 flag
|
||||
*/
|
||||
export const LegacyInsightsCharts: VFC<IChartsProps> = ({
|
||||
projects,
|
||||
flags,
|
||||
users,
|
||||
summary,
|
||||
userTrends,
|
||||
groupedProjectsData,
|
||||
flagTrends,
|
||||
groupedMetricsData,
|
||||
environmentTypeTrends,
|
||||
allMetricsDatapoints,
|
||||
loading,
|
||||
}) => {
|
||||
const { isEnterprise } = useUiConfig();
|
||||
const showAllProjects = projects[0] === allOption.id;
|
||||
const isOneProjectSelected = projects.length === 1;
|
||||
|
||||
function getFlagsPerUser(
|
||||
flags: InstanceInsightsSchemaFlags,
|
||||
users: InstanceInsightsSchemaUsers,
|
||||
) {
|
||||
const flagsPerUserCalculation = flags.total / users.total;
|
||||
return Number.isNaN(flagsPerUserCalculation)
|
||||
? 'N/A'
|
||||
: flagsPerUserCalculation.toFixed(2);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledGrid>
|
||||
<ConditionallyRender
|
||||
condition={showAllProjects}
|
||||
show={
|
||||
<Widget {...chartInfo.totalUsers}>
|
||||
<UserStats
|
||||
count={users.total}
|
||||
active={users.active}
|
||||
inactive={users.inactive}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</Widget>
|
||||
}
|
||||
elseShow={
|
||||
<Widget
|
||||
{...(isOneProjectSelected
|
||||
? chartInfo.usersInProject
|
||||
: chartInfo.avgUsersPerProject)}
|
||||
>
|
||||
<UserStats
|
||||
count={summary.averageUsers}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</Widget>
|
||||
}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={showAllProjects}
|
||||
show={
|
||||
<ChartWidget {...chartInfo.users}>
|
||||
<UsersChart
|
||||
userTrends={userTrends}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</ChartWidget>
|
||||
}
|
||||
elseShow={
|
||||
<ChartWidget {...chartInfo.usersPerProject}>
|
||||
<UsersPerProjectChart
|
||||
projectFlagTrends={groupedProjectsData}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</ChartWidget>
|
||||
}
|
||||
/>
|
||||
<Widget {...chartInfo.totalFlags}>
|
||||
<FlagStats
|
||||
count={showAllProjects ? flags.total : summary.total}
|
||||
flagsPerUser={
|
||||
showAllProjects ? getFlagsPerUser(flags, users) : ''
|
||||
}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</Widget>
|
||||
<ConditionallyRender
|
||||
condition={showAllProjects}
|
||||
show={
|
||||
<ChartWidget {...chartInfo.flags}>
|
||||
<FlagsChart
|
||||
flagTrends={flagTrends}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</ChartWidget>
|
||||
}
|
||||
elseShow={
|
||||
<ChartWidget {...chartInfo.flagsPerProject}>
|
||||
<FlagsProjectChart
|
||||
projectFlagTrends={groupedProjectsData}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</ChartWidget>
|
||||
}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={isEnterprise()}
|
||||
show={
|
||||
<>
|
||||
<Widget {...chartInfo.averageHealth}>
|
||||
<LegacyHealthStats
|
||||
value={summary.averageHealth}
|
||||
healthy={summary.active}
|
||||
stale={summary.stale}
|
||||
potentiallyStale={summary.potentiallyStale}
|
||||
/>
|
||||
</Widget>
|
||||
<ChartWidget
|
||||
{...(showAllProjects
|
||||
? chartInfo.overallHealth
|
||||
: chartInfo.healthPerProject)}
|
||||
>
|
||||
<ProjectHealthChart
|
||||
projectFlagTrends={groupedProjectsData}
|
||||
isAggregate={showAllProjects}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</ChartWidget>
|
||||
<Widget {...chartInfo.medianTimeToProduction}>
|
||||
<TimeToProduction
|
||||
daysToProduction={
|
||||
summary.medianTimeToProduction
|
||||
}
|
||||
/>
|
||||
</Widget>
|
||||
<ChartWidget
|
||||
{...(showAllProjects
|
||||
? chartInfo.timeToProduction
|
||||
: chartInfo.timeToProductionPerProject)}
|
||||
>
|
||||
<TimeToProductionChart
|
||||
projectFlagTrends={groupedProjectsData}
|
||||
isAggregate={showAllProjects}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</ChartWidget>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</StyledGrid>
|
||||
<ConditionallyRender
|
||||
condition={isEnterprise()}
|
||||
show={
|
||||
<>
|
||||
<Widget
|
||||
{...(showAllProjects
|
||||
? chartInfo.metrics
|
||||
: chartInfo.metricsPerProject)}
|
||||
>
|
||||
<MetricsSummaryChart
|
||||
metricsSummaryTrends={groupedMetricsData}
|
||||
allDatapointsSorted={allMetricsDatapoints}
|
||||
isAggregate={showAllProjects}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</Widget>
|
||||
<Widget
|
||||
{...chartInfo.updates}
|
||||
sx={{ mt: (theme) => theme.spacing(2) }}
|
||||
>
|
||||
<UpdatesPerEnvironmentTypeChart
|
||||
environmentTypeTrends={environmentTypeTrends}
|
||||
isLoading={loading}
|
||||
/>
|
||||
</Widget>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
@ -1,85 +0,0 @@
|
||||
/**
|
||||
* @deprecated remove with insightsV2 flag
|
||||
*/
|
||||
export const chartInfo = {
|
||||
totalUsers: {
|
||||
title: 'Total users',
|
||||
tooltip: 'Total number of current users.',
|
||||
},
|
||||
usersInProject: {
|
||||
title: 'Users in project',
|
||||
tooltip: 'Average number of users for selected projects.',
|
||||
},
|
||||
avgUsersPerProject: {
|
||||
title: 'Users per project on average',
|
||||
tooltip: 'Number of users in selected projects.',
|
||||
},
|
||||
users: {
|
||||
title: 'Users',
|
||||
tooltip: 'How the number of users changes over time.',
|
||||
},
|
||||
usersPerProject: {
|
||||
title: 'Users per project',
|
||||
tooltip:
|
||||
'How the number of users changes over time for the selected projects.',
|
||||
},
|
||||
totalFlags: {
|
||||
title: 'Total flags',
|
||||
tooltip:
|
||||
'Active flags (not archived) that currently exist across the selected projects.',
|
||||
},
|
||||
flags: {
|
||||
title: 'Number of flags',
|
||||
tooltip:
|
||||
'How the number of flags has changed over time across all projects.',
|
||||
},
|
||||
flagsPerProject: {
|
||||
title: 'Flags per project',
|
||||
tooltip:
|
||||
'How the number of flags changes over time for the selected projects.',
|
||||
},
|
||||
averageHealth: {
|
||||
title: 'Average health',
|
||||
tooltip:
|
||||
'Average health is the current percentage of flags in the selected projects that are not stale or potentially stale.',
|
||||
},
|
||||
overallHealth: {
|
||||
title: 'Overall Health',
|
||||
tooltip:
|
||||
'How the overall health changes over time across all projects.',
|
||||
},
|
||||
healthPerProject: {
|
||||
title: 'Health per project',
|
||||
tooltip:
|
||||
'How the overall health changes over time for the selected projects.',
|
||||
},
|
||||
medianTimeToProduction: {
|
||||
title: 'Median time to production',
|
||||
tooltip:
|
||||
'How long does it currently take on average from when a feature flag was created until it was enabled in a "production" type environment. This is calculated only from feature flags of the type "release" and is the median across the selected projects.',
|
||||
},
|
||||
timeToProduction: {
|
||||
title: 'Time to production',
|
||||
tooltip:
|
||||
'How the median time to production changes over time across all projects.',
|
||||
},
|
||||
timeToProductionPerProject: {
|
||||
title: 'Time to production per project',
|
||||
tooltip:
|
||||
'How the average time to production changes over time for the selected projects.',
|
||||
},
|
||||
metrics: {
|
||||
title: 'Flag evaluation metrics',
|
||||
tooltip:
|
||||
'Summary of all flag evaluations reported by SDKs across all projects.',
|
||||
},
|
||||
metricsPerProject: {
|
||||
title: 'Flag evaluation metrics per project',
|
||||
tooltip:
|
||||
'Summary of all flag evaluations reported by SDKs for the selected projects.',
|
||||
},
|
||||
updates: {
|
||||
title: 'Updates per environment type',
|
||||
tooltip: 'Summary of all configuration updates per environment type.',
|
||||
},
|
||||
};
|
@ -1,47 +0,0 @@
|
||||
import type React from 'react';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import { Paper, Typography, styled, type SxProps } from '@mui/material';
|
||||
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import type { Theme } from '@mui/material/styles/createTheme';
|
||||
import InfoOutlined from '@mui/icons-material/InfoOutlined';
|
||||
|
||||
const StyledPaper = styled(Paper)(({ theme }) => ({
|
||||
padding: theme.spacing(3),
|
||||
borderRadius: `${theme.shape.borderRadiusLarge}px`,
|
||||
minWidth: 0, // bugfix, see: https://github.com/chartjs/Chart.js/issues/4156#issuecomment-295180128
|
||||
position: 'relative',
|
||||
}));
|
||||
|
||||
/**
|
||||
* @deprecated remove with insightsV2 flag
|
||||
*/
|
||||
export const Widget: FC<{
|
||||
title: ReactNode;
|
||||
tooltip?: ReactNode;
|
||||
sx?: SxProps<Theme>;
|
||||
children?: React.ReactNode;
|
||||
}> = ({ title, children, tooltip, ...rest }) => (
|
||||
<StyledPaper elevation={0} {...rest}>
|
||||
<Typography
|
||||
variant='h3'
|
||||
sx={(theme) => ({
|
||||
marginBottom: theme.spacing(3),
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: theme.spacing(0.5),
|
||||
})}
|
||||
>
|
||||
{title}
|
||||
<ConditionallyRender
|
||||
condition={Boolean(tooltip)}
|
||||
show={
|
||||
<HelpIcon htmlTooltip tooltip={tooltip}>
|
||||
<InfoOutlined />
|
||||
</HelpIcon>
|
||||
}
|
||||
/>
|
||||
</Typography>
|
||||
{children}
|
||||
</StyledPaper>
|
||||
);
|
@ -1,320 +0,0 @@
|
||||
import type { FC } from 'react';
|
||||
import { useThemeMode } from 'hooks/useThemeMode';
|
||||
import { styled, useTheme } from '@mui/material';
|
||||
|
||||
interface IHealthStatsProps {
|
||||
value?: string | number;
|
||||
healthy: number;
|
||||
stale: number;
|
||||
potentiallyStale: number;
|
||||
}
|
||||
|
||||
const StyledSvg = styled('svg')(() => ({
|
||||
maxWidth: '250px',
|
||||
margin: '0 auto',
|
||||
}));
|
||||
|
||||
/**
|
||||
* @deprecated remove with insightsV2 flag
|
||||
*/
|
||||
export const LegacyHealthStats: FC<IHealthStatsProps> = ({
|
||||
value,
|
||||
healthy,
|
||||
stale,
|
||||
potentiallyStale,
|
||||
}) => {
|
||||
const { themeMode } = useThemeMode();
|
||||
const isDark = themeMode === 'dark';
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<StyledSvg
|
||||
viewBox='0 0 268 281'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<title>Health Stats</title>
|
||||
<g filter={!isDark ? 'url(#filter0_d_22043_268578)' : undefined}>
|
||||
<circle
|
||||
cx='134'
|
||||
cy='129'
|
||||
r='97'
|
||||
fill={theme.palette.charts.health.mainCircleBackground}
|
||||
/>
|
||||
</g>
|
||||
<circle
|
||||
cx='134'
|
||||
cy='129'
|
||||
r='121'
|
||||
stroke={theme.palette.charts.health.orbit}
|
||||
strokeWidth='3'
|
||||
/>
|
||||
<text
|
||||
x={134}
|
||||
y={149}
|
||||
textAnchor='middle'
|
||||
fontSize={48}
|
||||
fill={theme.palette.charts.health.title}
|
||||
fontWeight={700}
|
||||
>
|
||||
{value !== undefined ? `${value}%` : 'N/A'}
|
||||
</text>
|
||||
<g filter={!isDark ? 'url(#filter1_d_22043_268578)' : undefined}>
|
||||
<circle
|
||||
cx='206'
|
||||
cy='58'
|
||||
r='50'
|
||||
fill={theme.palette.charts.health.circles}
|
||||
/>
|
||||
</g>
|
||||
<text
|
||||
x={206}
|
||||
y={56}
|
||||
fill={theme.palette.charts.health.healthy}
|
||||
fontWeight={700}
|
||||
fontSize={20}
|
||||
textAnchor='middle'
|
||||
>
|
||||
{healthy || 0}
|
||||
</text>
|
||||
<text
|
||||
x={206}
|
||||
y={72}
|
||||
fill={theme.palette.charts.health.text}
|
||||
fontSize={13}
|
||||
textAnchor='middle'
|
||||
>
|
||||
Healthy
|
||||
</text>
|
||||
<g filter={!isDark ? 'url(#filter2_d_22043_268578)' : undefined}>
|
||||
<circle
|
||||
cx='53'
|
||||
cy='66'
|
||||
r='41'
|
||||
fill={theme.palette.charts.health.circles}
|
||||
/>
|
||||
</g>
|
||||
<text
|
||||
x={53}
|
||||
y={65}
|
||||
fill={theme.palette.charts.health.stale}
|
||||
fontWeight={700}
|
||||
fontSize={20}
|
||||
textAnchor='middle'
|
||||
>
|
||||
{stale || 0}
|
||||
</text>
|
||||
<text
|
||||
x={53}
|
||||
y={81}
|
||||
fill={theme.palette.charts.health.text}
|
||||
fontSize={13}
|
||||
textAnchor='middle'
|
||||
>
|
||||
Stale
|
||||
</text>
|
||||
<g filter={!isDark ? 'url(#filter3_d_22043_268578)' : undefined}>
|
||||
<circle
|
||||
cx='144'
|
||||
cy='224'
|
||||
r='41'
|
||||
fill={theme.palette.charts.health.circles}
|
||||
/>
|
||||
</g>
|
||||
<text
|
||||
x={144}
|
||||
y={216}
|
||||
fill={theme.palette.charts.health.potentiallyStale}
|
||||
fontWeight={700}
|
||||
fontSize={20}
|
||||
textAnchor='middle'
|
||||
>
|
||||
{potentiallyStale || 0}
|
||||
</text>
|
||||
<text
|
||||
x={144}
|
||||
y={232}
|
||||
fill={theme.palette.charts.health.text}
|
||||
fontSize={13}
|
||||
textAnchor='middle'
|
||||
>
|
||||
<tspan x={144} dy='0'>
|
||||
Potentially
|
||||
</tspan>
|
||||
<tspan x={144} dy='1.2em'>
|
||||
stale
|
||||
</tspan>
|
||||
</text>
|
||||
<path
|
||||
d='M99.5 247.275C99.5 251.693 103.082 255.275 107.5 255.275C111.918 255.275 115.5 251.693 115.5 247.275C115.5 242.857 111.918 239.275 107.5 239.275C103.082 239.275 99.5 242.857 99.5 247.275ZM10.8811 92C10.8811 96.4183 14.4629 100 18.8811 100C23.2994 100 26.8811 96.4183 26.8811 92C26.8811 87.5817 23.2994 84 18.8811 84C14.4629 84 10.8811 87.5817 10.8811 92ZM107.827 245.811C54.4151 233.886 14.5 186.258 14.5 129.325H11.5C11.5 187.696 52.4223 236.515 107.173 248.739L107.827 245.811ZM14.5 129.325C14.5 116.458 16.5379 104.07 20.3078 92.4634L17.4545 91.5366C13.5886 103.439 11.5 116.14 11.5 129.325H14.5Z'
|
||||
fill='url(#paint0_linear_22043_268578)'
|
||||
/>
|
||||
<defs>
|
||||
<filter
|
||||
id='filter0_d_22043_268578'
|
||||
x='15'
|
||||
y='13'
|
||||
width='238'
|
||||
height='238'
|
||||
filterUnits='userSpaceOnUse'
|
||||
colorInterpolationFilters='sRGB'
|
||||
>
|
||||
<feFlood floodOpacity='0' result='BackgroundImageFix' />
|
||||
<feColorMatrix
|
||||
in='SourceAlpha'
|
||||
type='matrix'
|
||||
values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'
|
||||
result='hardAlpha'
|
||||
/>
|
||||
<feMorphology
|
||||
radius='2'
|
||||
operator='dilate'
|
||||
in='SourceAlpha'
|
||||
result='effect1_dropShadow_22043_268578'
|
||||
/>
|
||||
<feOffset dy='3' />
|
||||
<feGaussianBlur stdDeviation='10' />
|
||||
<feComposite in2='hardAlpha' operator='out' />
|
||||
<feColorMatrix
|
||||
type='matrix'
|
||||
values='0 0 0 0 0.505882 0 0 0 0 0.478431 0 0 0 0 0.996078 0 0 0 0.36 0'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in2='BackgroundImageFix'
|
||||
result='effect1_dropShadow_22043_268578'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in='SourceGraphic'
|
||||
in2='effect1_dropShadow_22043_268578'
|
||||
result='shape'
|
||||
/>
|
||||
</filter>
|
||||
<filter
|
||||
id='filter1_d_22043_268578'
|
||||
x='144'
|
||||
y='0'
|
||||
width='124'
|
||||
height='124'
|
||||
filterUnits='userSpaceOnUse'
|
||||
colorInterpolationFilters='sRGB'
|
||||
>
|
||||
<feFlood floodOpacity='0' result='BackgroundImageFix' />
|
||||
<feColorMatrix
|
||||
in='SourceAlpha'
|
||||
type='matrix'
|
||||
values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'
|
||||
result='hardAlpha'
|
||||
/>
|
||||
<feOffset dy='4' />
|
||||
<feGaussianBlur stdDeviation='6' />
|
||||
<feComposite in2='hardAlpha' operator='out' />
|
||||
<feColorMatrix
|
||||
type='matrix'
|
||||
values='0 0 0 0 0.380392 0 0 0 0 0.356863 0 0 0 0 0.760784 0 0 0 0.16 0'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in2='BackgroundImageFix'
|
||||
result='effect1_dropShadow_22043_268578'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in='SourceGraphic'
|
||||
in2='effect1_dropShadow_22043_268578'
|
||||
result='shape'
|
||||
/>
|
||||
</filter>
|
||||
<filter
|
||||
id='filter2_d_22043_268578'
|
||||
x='0'
|
||||
y='17'
|
||||
width='106'
|
||||
height='106'
|
||||
filterUnits='userSpaceOnUse'
|
||||
colorInterpolationFilters='sRGB'
|
||||
>
|
||||
<feFlood floodOpacity='0' result='BackgroundImageFix' />
|
||||
<feColorMatrix
|
||||
in='SourceAlpha'
|
||||
type='matrix'
|
||||
values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'
|
||||
result='hardAlpha'
|
||||
/>
|
||||
<feOffset dy='4' />
|
||||
<feGaussianBlur stdDeviation='6' />
|
||||
<feComposite in2='hardAlpha' operator='out' />
|
||||
<feColorMatrix
|
||||
type='matrix'
|
||||
values='0 0 0 0 0.380392 0 0 0 0 0.356863 0 0 0 0 0.760784 0 0 0 0.16 0'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in2='BackgroundImageFix'
|
||||
result='effect1_dropShadow_22043_268578'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in='SourceGraphic'
|
||||
in2='effect1_dropShadow_22043_268578'
|
||||
result='shape'
|
||||
/>
|
||||
</filter>
|
||||
<filter
|
||||
id='filter3_d_22043_268578'
|
||||
x='91'
|
||||
y='175'
|
||||
width='106'
|
||||
height='106'
|
||||
filterUnits='userSpaceOnUse'
|
||||
colorInterpolationFilters='sRGB'
|
||||
>
|
||||
<feFlood floodOpacity='0' result='BackgroundImageFix' />
|
||||
<feColorMatrix
|
||||
in='SourceAlpha'
|
||||
type='matrix'
|
||||
values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'
|
||||
result='hardAlpha'
|
||||
/>
|
||||
<feOffset dy='4' />
|
||||
<feGaussianBlur stdDeviation='6' />
|
||||
<feComposite in2='hardAlpha' operator='out' />
|
||||
<feColorMatrix
|
||||
type='matrix'
|
||||
values='0 0 0 0 0.380392 0 0 0 0 0.356863 0 0 0 0 0.760784 0 0 0 0.16 0'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in2='BackgroundImageFix'
|
||||
result='effect1_dropShadow_22043_268578'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in='SourceGraphic'
|
||||
in2='effect1_dropShadow_22043_268578'
|
||||
result='shape'
|
||||
/>
|
||||
</filter>
|
||||
<linearGradient
|
||||
id='paint0_linear_22043_268578'
|
||||
x1='64.2447'
|
||||
y1='87'
|
||||
x2='64.2447'
|
||||
y2='249'
|
||||
gradientUnits='userSpaceOnUse'
|
||||
>
|
||||
<stop
|
||||
stopColor={theme.palette.charts.health.gradientStale}
|
||||
/>
|
||||
<stop
|
||||
offset='1'
|
||||
stopColor={
|
||||
theme.palette.charts.health.gradientPotentiallyStale
|
||||
}
|
||||
/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</StyledSvg>
|
||||
);
|
||||
};
|
@ -89,7 +89,6 @@ export type UiFlags = {
|
||||
navigationSidebar?: boolean;
|
||||
flagCreator?: boolean;
|
||||
resourceLimits?: boolean;
|
||||
insightsV2?: boolean;
|
||||
integrationEvents?: boolean;
|
||||
newEventSearch?: boolean;
|
||||
archiveProjects?: boolean;
|
||||
|
@ -120,7 +120,6 @@ exports[`should create default config 1`] = `
|
||||
},
|
||||
"filterInvalidClientMetrics": false,
|
||||
"googleAuthEnabled": false,
|
||||
"insightsV2": false,
|
||||
"integrationEvents": false,
|
||||
"killInsightsUI": false,
|
||||
"killScheduledChangeRequestCache": false,
|
||||
|
@ -59,7 +59,6 @@ export type IFlagKey =
|
||||
| 'resourceLimits'
|
||||
| 'extendedMetrics'
|
||||
| 'removeUnsafeInlineStyleSrc'
|
||||
| 'insightsV2'
|
||||
| 'integrationEvents'
|
||||
| 'originMiddleware'
|
||||
| 'newEventSearch'
|
||||
@ -292,10 +291,6 @@ const flags: IFlags = {
|
||||
process.env.UNLEASH_EXPERIMENTAL_REMOVE_UNSAFE_INLINE_STYLE_SRC,
|
||||
false,
|
||||
),
|
||||
insightsV2: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_EXPERIMENTAL_INSIGHTS_V2,
|
||||
false,
|
||||
),
|
||||
integrationEvents: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_EXPERIMENTAL_INTEGRATION_EVENTS,
|
||||
false,
|
||||
|
@ -52,7 +52,6 @@ process.nextTick(async () => {
|
||||
enableLegacyVariants: false,
|
||||
resourceLimits: true,
|
||||
extendedMetrics: true,
|
||||
insightsV2: true,
|
||||
integrationEvents: true,
|
||||
originMiddleware: true,
|
||||
newEventSearch: true,
|
||||
|
Loading…
Reference in New Issue
Block a user