diff --git a/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.styles.ts b/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.styles.ts
index 1f326346aa..7723163dcb 100644
--- a/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.styles.ts
+++ b/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.styles.ts
@@ -53,8 +53,8 @@ export const StyledWidgetTitle = styled('p')(({ theme }) => ({
export const StyledParagraphGridRow = styled('div')(({ theme }) => ({
display: 'grid',
- gridGap: theme.spacing(1),
- gridTemplateColumns: `${theme.spacing(1.25)} auto auto`,
+ gridGap: theme.spacing(1.5),
+ gridTemplateColumns: `${theme.spacing(1.25)} auto auto`, //20px auto auto
margin: theme.spacing(1, 0, 1, 0),
fontSize: theme.fontSizes.smallBody,
color: theme.palette.text.secondary,
diff --git a/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx b/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx
index ddbc3e349f..a905c5c297 100644
--- a/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx
+++ b/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx
@@ -7,6 +7,7 @@ import { ToggleTypesWidget } from './ToggleTypesWidget';
import { MetaWidget } from './MetaWidget';
import { ProjectMembersWidget } from './ProjectMembersWidget';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
+import { ProjectStatsSchema } from '@server/openapi';
import { ChangeRequestsWidget } from './ChangeRequestsWidget';
interface IProjectInfoProps {
@@ -15,6 +16,7 @@ interface IProjectInfoProps {
features: IFeatureToggleListItem[];
health: number;
description?: string;
+ stats: ProjectStatsSchema;
}
const ProjectInfo = ({
@@ -23,6 +25,7 @@ const ProjectInfo = ({
memberCount,
health,
features,
+ stats,
}: IProjectInfoProps) => {
const { uiConfig, isEnterprise } = useUiConfig();
@@ -52,6 +55,7 @@ const ProjectInfo = ({
}
/>
diff --git a/frontend/src/component/project/Project/ProjectInfo/ProjectMembersWidget.tsx b/frontend/src/component/project/Project/ProjectInfo/ProjectMembersWidget.tsx
index 3f7489ce28..89db931a6e 100644
--- a/frontend/src/component/project/Project/ProjectInfo/ProjectMembersWidget.tsx
+++ b/frontend/src/component/project/Project/ProjectInfo/ProjectMembersWidget.tsx
@@ -1,21 +1,21 @@
import {
- StyledArrowIcon,
- StyledProjectInfoWidgetContainer,
StyledLink,
- StyledParagraphEmphasizedText,
- StyledWidgetTitle,
+ StyledProjectInfoWidgetContainer,
StyledSpanLinkText,
} from './ProjectInfo.styles';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
+import { StatusBox } from '../ProjectStats/StatusBox';
interface IProjectMembersWidgetProps {
projectId: string;
memberCount: number;
+ change?: number;
}
export const ProjectMembersWidget = ({
projectId,
memberCount,
+ change = 0,
}: IProjectMembersWidgetProps) => {
const { uiConfig } = useUiConfig();
@@ -26,14 +26,19 @@ export const ProjectMembersWidget = ({
}
return (
-
- Project members
-
- {memberCount}
-
+ theme.spacing(0, 0, 3, 0) }}
+ >
+
- view more
-
+
+ View all members
+
);
diff --git a/frontend/src/component/project/Project/ProjectInfo/ToggleTypesWidget.tsx b/frontend/src/component/project/Project/ProjectInfo/ToggleTypesWidget.tsx
index 21ab49214b..c0955320a7 100644
--- a/frontend/src/component/project/Project/ProjectInfo/ToggleTypesWidget.tsx
+++ b/frontend/src/component/project/Project/ProjectInfo/ToggleTypesWidget.tsx
@@ -1,13 +1,14 @@
import { useMemo } from 'react';
-import { styled } from '@mui/material';
+import { styled, SvgIconTypeMap } from '@mui/material';
import type { IFeatureToggleListItem } from 'interfaces/featureToggle';
import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons';
import {
StyledCount,
- StyledProjectInfoWidgetContainer,
StyledParagraphGridRow,
+ StyledProjectInfoWidgetContainer,
StyledWidgetTitle,
} from './ProjectInfo.styles';
+import { OverridableComponent } from '@mui/material/OverridableComponent';
export interface IToggleTypesWidgetProps {
features: IFeatureToggleListItem[];
@@ -17,74 +18,66 @@ const StyledTypeCount = styled(StyledCount)(() => ({
marginLeft: 'auto',
}));
-const StyledDiv = styled('div')(({ theme }) => ({
- marginLeft: theme.spacing(1.5),
-}));
+interface IToggleTypeRowProps {
+ type: string;
+ Icon: OverridableComponent;
+ count: number;
+}
+const ToggleTypesRow = ({ type, Icon, count }: IToggleTypeRowProps) => {
+ const getTitleText = (str: string) => {
+ return str.charAt(0).toUpperCase() + str.slice(1).replace('-', ' ');
+ };
+ return (
+
+
+ {getTitleText(type)}
+ {count}
+
+ );
+};
export const ToggleTypesWidget = ({ features }: IToggleTypesWidgetProps) => {
- const { release, experiment, operational, kill, permission } =
- useMemo(() => {
- const release =
- features?.filter(feature => feature.type === 'release')
- .length || 0;
- const experiment =
- features?.filter(feature => feature.type === 'experiment')
- .length || 0;
- const operational =
- features?.filter(feature => feature.type === 'operational')
- .length || 0;
- const kill =
- features?.filter(feature => feature.type === 'kill-switch')
- .length || 0;
- const permission =
- features?.filter(feature => feature.type === 'permission')
- .length || 0;
+ const featureTypeStats = useMemo(() => {
+ const release =
+ features?.filter(feature => feature.type === 'release').length || 0;
+ const experiment =
+ features?.filter(feature => feature.type === 'experiment').length ||
+ 0;
+ const operational =
+ features?.filter(feature => feature.type === 'operational')
+ .length || 0;
+ const kill =
+ features?.filter(feature => feature.type === 'kill-switch')
+ .length || 0;
+ const permission =
+ features?.filter(feature => feature.type === 'permission').length ||
+ 0;
- return {
- release,
- experiment,
- operational,
- kill,
- permission,
- };
- }, [features]);
-
- const ReleaseToggleIcon = getFeatureTypeIcons('release');
- const ExperimentToggleIcon = getFeatureTypeIcons('experiment');
- const OperationalToggleIcon = getFeatureTypeIcons('operational');
- const KillToggleIcon = getFeatureTypeIcons('kill-switch');
- const PermissionToggleIcon = getFeatureTypeIcons('permission');
+ return {
+ release,
+ experiment,
+ operational,
+ 'kill-switch': kill,
+ permission,
+ };
+ }, [features]);
return (
-
+ theme.spacing(3) }}
+ >
Toggle types used
-
-
- Release
- {release}
-
-
-
- Experiment
- {experiment}
-
-
-
- Operational
- {operational}
-
-
-
- Kill switch
- {kill}
-
-
-
- Permission
- {permission}
-
+ {Object.keys(featureTypeStats).map(type => (
+
+ ))}
);
};
diff --git a/frontend/src/component/project/Project/ProjectOverview.tsx b/frontend/src/component/project/Project/ProjectOverview.tsx
index 143687e1b9..8a21f88fc8 100644
--- a/frontend/src/component/project/Project/ProjectOverview.tsx
+++ b/frontend/src/component/project/Project/ProjectOverview.tsx
@@ -39,7 +39,8 @@ const ProjectOverview = () => {
const { project, loading } = useProject(projectId, {
refreshInterval,
});
- const { members, features, health, description, environments } = project;
+ const { members, features, health, description, environments, stats } =
+ project;
usePageTitle(`Project overview – ${projectName}`);
const { setLastViewed } = useLastViewedProject();
const { uiConfig } = useUiConfig();
@@ -57,6 +58,7 @@ const ProjectOverview = () => {
memberCount={members}
health={health}
features={features}
+ stats={stats}
/>
{
@@ -81,17 +82,30 @@ export const StatusBox = ({
boxText,
change,
percentage,
+ fullWidthBodyText,
}: IStatusBoxProps) => {
return (
{title}
-
+
{boxText}
-
+
{resolveIcon(change)}