mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-31 00:16:47 +01:00
refactor: instance health cleanup (#4602)
## About the changes Cleanup after hackathon. Discovered project on: https://linear.app/unleash/project/active-users-and-instance-dashboard-67352abadf49
This commit is contained in:
parent
5ae86ef196
commit
8aace7f93f
@ -18,7 +18,6 @@ import UsersAdmin from './users/UsersAdmin';
|
||||
import NotFound from 'component/common/NotFound/NotFound';
|
||||
import { AdminIndex } from './AdminIndex';
|
||||
import { AdminTabsMenu } from './menu/AdminTabsMenu';
|
||||
import { InstanceHealth } from './instance-health/InstanceHealth';
|
||||
|
||||
export const Admin = () => {
|
||||
return (
|
||||
@ -35,7 +34,6 @@ export const Admin = () => {
|
||||
<Route path="groups/*" element={<GroupsAdmin />} />
|
||||
<Route path="roles/*" element={<Roles />} />
|
||||
<Route path="instance" element={<InstanceAdmin />} />
|
||||
<Route path="instance-health" element={<InstanceHealth />} />
|
||||
<Route path="network/*" element={<Network />} />
|
||||
<Route path="maintenance" element={<MaintenanceAdmin />} />
|
||||
<Route path="cors" element={<CorsAdmin />} />
|
||||
|
@ -80,13 +80,6 @@ export const adminRoutes: INavigationMenuItem[] = [
|
||||
menu: { adminSettings: true },
|
||||
group: 'instance',
|
||||
},
|
||||
{
|
||||
path: '/admin/instance-health',
|
||||
title: 'Instance health',
|
||||
menu: { adminSettings: true },
|
||||
group: 'instance',
|
||||
flag: 'instanceHealthDashboard',
|
||||
},
|
||||
{
|
||||
path: '/admin/instance-privacy',
|
||||
title: 'Instance privacy',
|
||||
|
@ -30,24 +30,9 @@ export const InstanceStats: VFC = () => {
|
||||
}
|
||||
|
||||
const rows = [
|
||||
{ title: 'Instance Id', value: stats?.instanceId },
|
||||
{ title: 'Instance Id', value: stats?.instanceId, offset: false },
|
||||
{ title: versionTitle, value: version },
|
||||
{ title: 'Users', value: stats?.users },
|
||||
{
|
||||
title: 'Active past 7 days',
|
||||
value: stats?.activeUsers?.last7,
|
||||
offset: true,
|
||||
},
|
||||
{
|
||||
title: 'Active past 30 days',
|
||||
value: stats?.activeUsers?.last30,
|
||||
offset: true,
|
||||
},
|
||||
{
|
||||
title: 'Active past 90 days',
|
||||
value: stats?.activeUsers?.last90,
|
||||
offset: true,
|
||||
},
|
||||
{ title: 'Feature toggles', value: stats?.featureToggles },
|
||||
{ title: 'Projects', value: stats?.projects },
|
||||
{ title: 'Environments', value: stats?.environments },
|
||||
@ -80,22 +65,16 @@ export const InstanceStats: VFC = () => {
|
||||
{rows.map(row => (
|
||||
<TableRow key={row.title}>
|
||||
<TableCell component="th" scope="row">
|
||||
<ConditionallyRender
|
||||
condition={Boolean(row.offset)}
|
||||
show={
|
||||
<Box
|
||||
component="span"
|
||||
sx={theme => ({
|
||||
marginLeft: row.offset
|
||||
? theme.spacing(2)
|
||||
: 0,
|
||||
})}
|
||||
>
|
||||
{row.title}
|
||||
</Box>
|
||||
}
|
||||
elseShow={row.title}
|
||||
/>
|
||||
<Box
|
||||
component="span"
|
||||
sx={theme => ({
|
||||
marginLeft: row.offset
|
||||
? theme.spacing(2)
|
||||
: 0,
|
||||
})}
|
||||
>
|
||||
{row.title}
|
||||
</Box>
|
||||
</TableCell>
|
||||
<TableCell align="right">{row.value}</TableCell>
|
||||
</TableRow>
|
||||
|
@ -1,220 +0,0 @@
|
||||
import { VFC, useMemo } from 'react';
|
||||
import { useSortBy, useTable } from 'react-table';
|
||||
import { styled, Typography, Box } from '@mui/material';
|
||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||
import { useInstanceStats } from 'hooks/api/getters/useInstanceStats/useInstanceStats';
|
||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||
import { sortTypes } from 'utils/sortTypes';
|
||||
import {
|
||||
SortableTableHeader,
|
||||
Table,
|
||||
TableBody,
|
||||
TableRow,
|
||||
TableCell,
|
||||
} from 'component/common/Table';
|
||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
||||
import { HelpPopper } from 'component/project/Project/ProjectStats/HelpPopper';
|
||||
import { StatusBox } from 'component/project/Project/ProjectStats/StatusBox';
|
||||
import { DateCell } from 'component/common/Table/cells/DateCell/DateCell';
|
||||
|
||||
interface IInstanceHealthProps {}
|
||||
|
||||
const CardsGrid = styled('div')(({ theme }) => ({
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
|
||||
gap: theme.spacing(2),
|
||||
paddingBottom: theme.spacing(2),
|
||||
}));
|
||||
|
||||
const Card = styled('div')(({ theme }) => ({
|
||||
padding: theme.spacing(2.5),
|
||||
borderRadius: `${theme.shape.borderRadiusLarge}px`,
|
||||
backgroundColor: `${theme.palette.background.paper}`,
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
// boxShadow: theme.boxShadows.card,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}));
|
||||
|
||||
/**
|
||||
* @deprecated unify with project widget
|
||||
*/
|
||||
const StyledWidget = styled(Box)(({ theme }) => ({
|
||||
position: 'relative',
|
||||
padding: theme.spacing(3),
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderRadius: `${theme.shape.borderRadiusLarge}px`,
|
||||
[theme.breakpoints.down('lg')]: {
|
||||
padding: theme.spacing(2),
|
||||
},
|
||||
}));
|
||||
|
||||
export const InstanceHealth: VFC<IInstanceHealthProps> = () => {
|
||||
const { stats } = useInstanceStats();
|
||||
const { projects } = useProjects();
|
||||
// FIXME: loading state
|
||||
|
||||
const initialState = useMemo(
|
||||
() => ({
|
||||
hiddenColumns: [],
|
||||
sortBy: [{ id: 'createdAt' }],
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
const data = useMemo(() => projects, [projects]);
|
||||
|
||||
const dormantUsersPercentage =
|
||||
(1 - stats?.activeUsers?.last90! / stats?.users!) * 100;
|
||||
|
||||
const dormantUsersColor =
|
||||
dormantUsersPercentage < 30
|
||||
? 'success.main'
|
||||
: dormantUsersPercentage < 50
|
||||
? 'warning.main'
|
||||
: 'error.main';
|
||||
|
||||
const COLUMNS = useMemo(
|
||||
() => [
|
||||
{
|
||||
accessor: 'name',
|
||||
Header: 'Project name',
|
||||
Cell: TextCell,
|
||||
width: '80%',
|
||||
},
|
||||
{
|
||||
Header: 'Feature toggles',
|
||||
accessor: 'featureCount',
|
||||
Cell: TextCell,
|
||||
},
|
||||
{
|
||||
Header: 'Created at',
|
||||
accessor: 'createdAt',
|
||||
Cell: DateCell,
|
||||
},
|
||||
{
|
||||
Header: 'Members',
|
||||
accessor: 'memberCount',
|
||||
Cell: TextCell,
|
||||
},
|
||||
{
|
||||
Header: 'Health',
|
||||
accessor: 'health',
|
||||
Cell: ({ value }: { value: number }) => {
|
||||
const healthRatingColor =
|
||||
value < 50
|
||||
? 'error.main'
|
||||
: value < 75
|
||||
? 'warning.main'
|
||||
: 'success.main';
|
||||
return (
|
||||
<TextCell>
|
||||
<Typography
|
||||
component="span"
|
||||
sx={{ color: healthRatingColor }}
|
||||
>
|
||||
{value}%
|
||||
</Typography>
|
||||
</TextCell>
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
const { headerGroups, rows, prepareRow, getTableProps, getTableBodyProps } =
|
||||
useTable(
|
||||
{
|
||||
columns: COLUMNS as any,
|
||||
data: data as any,
|
||||
initialState,
|
||||
sortTypes,
|
||||
autoResetGlobalFilter: false,
|
||||
autoResetHiddenColumns: false,
|
||||
autoResetSortBy: false,
|
||||
disableSortRemove: true,
|
||||
},
|
||||
useSortBy
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<CardsGrid>
|
||||
<Card>
|
||||
<StatusBox
|
||||
title="User accounts"
|
||||
boxText={String(stats?.users)}
|
||||
customChangeElement={<></>}
|
||||
>
|
||||
{/* <HelpPopper id="user-accounts">
|
||||
Sum of all configuration and state modifications in
|
||||
the project.
|
||||
</HelpPopper> */}
|
||||
{/* FIXME: tooltip */}
|
||||
</StatusBox>
|
||||
</Card>
|
||||
<Card>
|
||||
<StatusBox
|
||||
title="Dormant users"
|
||||
boxText={String(
|
||||
stats?.users! - stats?.activeUsers?.last90!
|
||||
)}
|
||||
customChangeElement={
|
||||
<Typography
|
||||
component="span"
|
||||
sx={{ color: dormantUsersColor }}
|
||||
>
|
||||
({dormantUsersPercentage.toFixed(1)}%)
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
{/* <HelpPopper id="dormant-users">
|
||||
Sum of all configuration and state modifications in
|
||||
the project.
|
||||
</HelpPopper> */}
|
||||
</StatusBox>
|
||||
</Card>
|
||||
<Card>
|
||||
<StatusBox
|
||||
title="Number of projects"
|
||||
boxText={String(projects?.length)}
|
||||
customChangeElement={<></>}
|
||||
></StatusBox>
|
||||
</Card>
|
||||
<Card>
|
||||
<StatusBox
|
||||
title="Number of feature toggles"
|
||||
boxText={String(stats?.featureToggles)}
|
||||
customChangeElement={<></>}
|
||||
></StatusBox>
|
||||
</Card>
|
||||
</CardsGrid>
|
||||
<PageContent header={<PageHeader title="Health per project" />}>
|
||||
<Table {...getTableProps()} rowHeight="standard">
|
||||
<SortableTableHeader headerGroups={headerGroups} />
|
||||
<TableBody {...getTableBodyProps()}>
|
||||
{rows.map(row => {
|
||||
prepareRow(row);
|
||||
return (
|
||||
<TableRow hover {...row.getRowProps()}>
|
||||
{row.cells.map(cell => (
|
||||
<TableCell {...cell.getCellProps()}>
|
||||
{cell.render('Cell')}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</PageContent>
|
||||
</>
|
||||
);
|
||||
};
|
@ -57,7 +57,6 @@ export interface IFlags {
|
||||
integrationsRework?: boolean;
|
||||
multipleRoles?: boolean;
|
||||
doraMetrics?: boolean;
|
||||
instanceHealthDashboard?: boolean;
|
||||
[key: string]: boolean | Variant | undefined;
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,7 @@ export type IFlagKey =
|
||||
| 'newApplicationList'
|
||||
| 'integrationsRework'
|
||||
| 'multipleRoles'
|
||||
| 'doraMetrics'
|
||||
| 'instanceHealthDashboard';
|
||||
| 'doraMetrics';
|
||||
|
||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
||||
|
||||
|
@ -42,7 +42,6 @@ process.nextTick(async () => {
|
||||
lastSeenByEnvironment: true,
|
||||
newApplicationList: true,
|
||||
doraMetrics: true,
|
||||
instanceHealthDashboard: true,
|
||||
},
|
||||
},
|
||||
authentication: {
|
||||
|
Loading…
Reference in New Issue
Block a user