Skip to content

Commit

Permalink
fix: add simple UI
Browse files Browse the repository at this point in the history
  • Loading branch information
ivarconr committed Oct 19, 2022
1 parent e4958fc commit 5f8d822
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 3 deletions.
11 changes: 11 additions & 0 deletions frontend/src/component/admin/instance-admin/InstanceAdmin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import AdminMenu from '../menu/AdminMenu';
import { InstanceStats } from './InstanceStats/InstanceStats';

export const InstanceAdmin = () => {
return (
<div>
<AdminMenu />
<InstanceStats />
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Save } from '@mui/icons-material';
import { Button, IconButton, Link, Table, TableBody, TableCell, TableHead, TableRow } from '@mui/material';
import { Box } from '@mui/system';
import { VFC } from 'react';
import { useInstanceStats } from '../../../../hooks/api/getters/useInstanceStats/useInstanceStats';
import { formatApiPath } from '../../../../utils/formatPath';
import { PageContent } from '../../../common/PageContent/PageContent';
import { PageHeader } from '../../../common/PageHeader/PageHeader';

export const InstanceStats: VFC = () => {
const { stats, loading } = useInstanceStats();


let versionTitle;
let version;

if(stats?.versionEnterprise) {
versionTitle = 'Unleash Enterprise version';
version = stats.versionEnterprise;
} else {
versionTitle = 'Unleash OSS version';
version = stats?.versionOSS;
}



const rows = [
{title: 'Instance Id', value: stats?.instanceId},
{title: versionTitle, value: version},
{title: 'Users', value: stats?.users},
{title: 'Feature toggles', value: stats?.featureToggles},
{title: 'Projects', value: stats?.projects},
{title: 'Environments', value: stats?.environments},
{title: 'Roles', value: stats?.roles},
{title: 'Groups', value: stats?.groups},
{title: 'Context fields', value: stats?.contextFields},
{title: 'Strategies', value: stats?.strategies},
];

if(stats?.versionEnterprise) {
rows.push(
{title: 'SAML enabled', value: stats?.SAMLenabled ? 'Yes' : 'No'},
{title: 'OIDC enabled', value: stats?.OIDCenabled ? 'Yes' : 'No'},
);
}

return (
<PageContent header={<PageHeader title="Instance Statistics" />}>
<Box sx={{ display: 'grid', gap: 4 }}>
<Table aria-label="Instance statistics">
<TableHead>
<TableRow>
<TableCell>Item</TableCell>
<TableCell align="right">Value</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map(row => (
<TableRow >
<TableCell component="th" scope="row">{row.title}</TableCell>
<TableCell align="right">{row.value}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<span style={{ textAlign: 'center' }}>
<Button
startIcon={<Save />}
aria-label="Download instance statistics"
color="primary"
variant="contained"
target="_blank"
href={formatApiPath('/api/admin/instance-admin/statistics/csv')}
>
Download
</Button>
</span>
</Box>

</PageContent>
)
}
13 changes: 13 additions & 0 deletions frontend/src/component/admin/menu/AdminMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,19 @@ function AdminMenu() {
</NavLink>
}
/>
<Tab
value="/admin/instance"
label={
<NavLink
to="/admin/instance"
style={({ isActive }) =>
createNavLinkStyle({ isActive, theme })
}
>
Instance admin
</NavLink>
}
/>
{isBilling && (
<Tab
value="/admin/billing"
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/component/menu/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import { LazyPlayground } from 'component/playground/Playground/LazyPlayground';
import { CorsAdmin } from 'component/admin/cors';
import { InviteLink } from 'component/admin/users/InviteLink/InviteLink';
import { Profile } from 'component/user/Profile/Profile';
import { InstanceAdmin } from '../admin/instance-admin/InstanceAdmin';

export const routes: IRoute[] = [
// Splash
Expand Down Expand Up @@ -497,6 +498,14 @@ export const routes: IRoute[] = [
type: 'protected',
menu: { adminSettings: true },
},
{
path: '/admin/instance',
parent: '/admin',
title: 'Instance admin',
component: InstanceAdmin,
type: 'protected',
menu: { adminSettings: true },
},
{
path: '/admin/cors',
parent: '/admin',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import useSWR from 'swr';
import { useMemo } from 'react';
import { formatApiPath } from 'utils/formatPath';
import handleErrorResponses from '../httpErrorResponseHandler';

interface InstanceStats {
instanceId: string;
timestamp: Date;
versionOSS: string;
versionEnterprise?: string;
users: number;
featureToggles: number;
projects: number;
contextFields: number;
roles: number;
groups: number;
environments: number;
segments: number;
strategies: number;
SAMLenabled: boolean;
OIDCenabled: boolean;
}

export interface IInstanceStatsResponse {
stats?: InstanceStats;
refetchGroup: () => void;
loading: boolean;
error?: Error;
}

export const mapGroupUsers = (users: any[]) =>
users.map(user => ({
...user.user,
joinedAt: new Date(user.joinedAt),
}));

export const useInstanceStats = (): IInstanceStatsResponse => {
const { data, error, mutate } = useSWR(
formatApiPath(`api/admin/instance-admin/statistics`),
fetcher
);

return useMemo(
() => ({
stats: data,
loading: !error && !data,
refetchGroup: () => mutate(),
error,
}),
[data, error, mutate]
);
};

const fetcher = (path: string) => {
return fetch(path)
.then(handleErrorResponses('Instance Stats'))
.then(res => res.json());
};
15 changes: 13 additions & 2 deletions src/lib/routes/admin-api/instance-admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { IUnleashConfig } from '../../types/option';
import Controller from '../controller';
import { NONE } from '../../types/permissions';
import { UiConfigSchema } from '../../openapi/spec/ui-config-schema';
import { InstanceStatsService } from '../../services/instance-stats-service';
import {
InstanceStats,
InstanceStatsService,
} from '../../services/instance-stats-service';
import { OpenApiService } from '../../services/openapi-service';
import { createResponseSchema } from '../../openapi/util/create-response-schema';

Expand Down Expand Up @@ -37,7 +40,7 @@ class InstanceAdminController extends Controller {
this.route({
method: 'get',
path: '/statistics',
handler: this.getStatisticsCSV,
handler: this.getStatistics,
permission: NONE,
middleware: [
openApiService.validPath({
Expand All @@ -52,6 +55,14 @@ class InstanceAdminController extends Controller {
});
}

async getStatistics(
req: AuthedRequest,
res: Response<InstanceStats>,
): Promise<void> {
const instanceStats = await this.instanceStatsService.getStats();
res.json(instanceStats);
}

async getStatisticsCSV(
req: AuthedRequest,
res: Response<UiConfigSchema>,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/services/instance-stats-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import VersionService from './version-service';
import { ISettingStore } from '../types/stores/settings-store';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface InstanceStats {
export interface InstanceStats {
instanceId: string;
timestamp: Date;
versionOSS: string;
Expand Down

0 comments on commit 5f8d822

Please sign in to comment.