Skip to content

Commit

Permalink
Merge branch 'main' into melinda/upgrade-open-api-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
alvinometric committed Oct 18, 2024
2 parents a7e5b3c + 1c29f70 commit 74b1337
Show file tree
Hide file tree
Showing 30 changed files with 1,696 additions and 1,205 deletions.
2 changes: 2 additions & 0 deletions frontend/src/component/admin/auth/AuthSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ADMIN } from '@server/types/permissions';
import { PremiumFeature } from 'component/common/PremiumFeature/PremiumFeature';
import { useState } from 'react';
import { TabPanel } from 'component/common/TabNav/TabPanel/TabPanel';
import { usePageTitle } from 'hooks/usePageTitle';

export const AuthSettings = () => {
const { authenticationType } = useUiConfig().uiConfig;
Expand Down Expand Up @@ -46,6 +47,7 @@ export const AuthSettings = () => {
}

const [activeTab, setActiveTab] = useState(0);
usePageTitle(`Single sign-on: ${tabs[activeTab].label}`);

return (
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ describe('trim names and description', () => {
expect(result.current.name).toBe('my role');
});

test('description is trimmed before being set', () => {
test('description is not trimmed before being set', () => {
const { result } = renderHook(() => useRoleForm());

act(() => {
result.current.setDescription(' my description ');
});

expect(result.current.description).toBe('my description');
expect(result.current.description).toBe(' my description ');
});

test('name that is just whitespace triggers an error', () => {
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/component/admin/roles/RoleForm/useRoleForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ export const useRoleForm = (
const [name, setName] = useState(initialName);
const setTrimmedName = (newName: string) => setName(newName.trim());
const [description, setDescription] = useState(initialDescription);
const setTrimmedDescription = (newDescription: string) =>
setDescription(newDescription.trim());
const [checkedPermissions, setCheckedPermissions] =
useState<ICheckedPermissions>({});
const [errors, setErrors] = useState<IRoleFormErrors>(DEFAULT_ERRORS);
Expand Down Expand Up @@ -147,7 +145,7 @@ export const useRoleForm = (
setName: setTrimmedName,
validateName,
description,
setDescription: setTrimmedDescription,
setDescription,
validateDescription,
checkedPermissions,
setCheckedPermissions,
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/component/admin/roles/RolesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Add from '@mui/icons-material/Add';
import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton';
import type { IRole } from 'interfaces/role';
import { TabLink } from 'component/common/TabNav/TabLink';
import { usePageTitle } from 'hooks/usePageTitle';

const StyledHeader = styled('div')(() => ({
display: 'flex',
Expand All @@ -31,6 +32,7 @@ const StyledActions = styled('div')({
});

export const RolesPage = () => {
usePageTitle('Roles');
const { pathname } = useLocation();

const { roles, projectRoles, loading } = useRoles();
Expand Down
15 changes: 2 additions & 13 deletions frontend/src/component/featureTypes/FeatureTypesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { sortTypes } from 'utils/sortTypes';
import { PageContent } from 'component/common/PageContent/PageContent';
import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes';
import { PageHeader } from 'component/common/PageHeader/PageHeader';
import { Box, Typography } from '@mui/material';
import { Box } from '@mui/material';
import {
Table,
TableBody,
Expand Down Expand Up @@ -150,18 +150,7 @@ export const FeatureTypesList = () => {
return (
<PageContent
isLoading={loading}
header={
<PageHeader>
<Typography
component='h2'
sx={(theme) => ({
fontSize: theme.fontSizes.mainHeader,
})}
>
Feature flag types
</Typography>
</PageHeader>
}
header={<PageHeader title='Feature flag types' />}
>
<Table {...getTableProps()}>
<SortableTableHeader headerGroups={headerGroups} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const InsightsHeader: VFC<DashboardHeaderProps> = ({ actions }) => {
return (
<>
<PageHeader
title='Insights'
titleElement={
<Typography
variant='h1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import BillingIcon from '@mui/icons-material/CreditCardOutlined';
import EventLogIcon from '@mui/icons-material/EventNoteOutlined';
import GitHubIcon from '@mui/icons-material/GitHub';
import LibraryBooksIcon from '@mui/icons-material/LibraryBooks';
import LaunchIcon from '@mui/icons-material/Launch';
import PersonalDashboardIcon from '@mui/icons-material/DashboardOutlined';
import type { FC } from 'react';

// TODO: move to routes
Expand Down Expand Up @@ -56,6 +58,8 @@ const icons: Record<string, typeof SvgIcon> = {
'/admin/cors': CorsIcon,
'/admin/billing': BillingIcon,
'/history': EventLogIcon,
'/releases-management': LaunchIcon,
'/personal': PersonalDashboardIcon,
GitHub: GitHubIcon,
Documentation: LibraryBooksIcon,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,20 @@ exports[`returns all baseRoutes 1`] = `
"title": "Strategy types",
"type": "protected",
},
{
"component": [Function],
"enterprise": true,
"flag": "releasePlans",
"menu": {
"advanced": true,
"mode": [
"enterprise",
],
},
"path": "/releases-management",
"title": "Release management",
"type": "protected",
},
{
"component": [Function],
"menu": {},
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/component/menu/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { Application } from 'component/application/Application';
import { Signals } from 'component/signals/Signals';
import { LazyCreateProject } from '../project/Project/CreateProject/LazyCreateProject';
import { PersonalDashboard } from '../personalDashboard/PersonalDashboard';
import { ReleaseManagement } from 'component/releases/ReleaseManagement';

export const routes: IRoute[] = [
// Splash
Expand Down Expand Up @@ -246,6 +247,15 @@ export const routes: IRoute[] = [
type: 'protected',
menu: { mobile: true, advanced: true },
},
{
path: '/releases-management',
title: 'Release management',
component: ReleaseManagement,
type: 'protected',
menu: { advanced: true, mode: ['enterprise'] },
flag: 'releasePlans',
enterprise: true,
},
{
path: '/environments/create',
title: 'Environments',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import useSplashApi from 'hooks/api/actions/useSplashApi/useSplashApi';
import { useAuthSplash } from 'hooks/api/getters/useAuth/useAuthSplash';
import { useDashboardState } from './useDashboardState';
import { MyFlags } from './MyFlags';
import { usePageTitle } from 'hooks/usePageTitle';

const WelcomeSection = styled('div')(({ theme }) => ({
display: 'flex',
Expand Down Expand Up @@ -103,9 +104,10 @@ export const PersonalDashboard = () => {
const { trackEvent } = usePlausibleTracker();
const { setSplashSeen } = useSplashApi();
const { splash } = useAuthSplash();

const name = user?.name;

usePageTitle(`Dashboard: ${name}`);

const { personalDashboard, refetch: refetchDashboard } =
usePersonalDashboard();

Expand Down
3 changes: 3 additions & 0 deletions frontend/src/component/releases/ReleaseManagement.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const ReleaseManagement = () => {
return null;
};
Original file line number Diff line number Diff line change
Expand Up @@ -397,9 +397,10 @@ export const StrategiesList = () => {
<PageContent
isLoading={loading}
header={
<PageHeader>
<PredefinedStrategyTitle />
</PageHeader>
<PageHeader
titleElement={<PredefinedStrategyTitle />}
title='Strategy types'
/>
}
>
<Box>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/interfaces/uiConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export type UiFlags = {
personalDashboardUI?: boolean;
purchaseAdditionalEnvironments?: boolean;
unleashAI?: boolean;
releasePlans?: boolean;
};

export interface IVersionInfo {
Expand Down
12 changes: 6 additions & 6 deletions frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2743,20 +2743,20 @@ __metadata:
linkType: hard

"@types/node@npm:*":
version: 22.5.5
resolution: "@types/node@npm:22.5.5"
version: 22.7.6
resolution: "@types/node@npm:22.7.6"
dependencies:
undici-types: "npm:~6.19.2"
checksum: 10c0/ead9495cfc6b1da5e7025856dcce2591e9bae635357410c0d2dd619fce797d2a1d402887580ca4b336cb78168b195224869967de370a23f61663cf1e4836121c
checksum: 10c0/d4406a63afce981c363fb1d1954aaf1759ad2d487c0833ebf667565ea4e45ff217d6fab4b5343badbdeccdf9d2e4a0841d633e0c929ceabcb33c288663dd0c73
languageName: node
linkType: hard

"@types/node@npm:^20.12.12, @types/node@npm:^20.12.13":
version: 20.16.5
resolution: "@types/node@npm:20.16.5"
version: 20.16.12
resolution: "@types/node@npm:20.16.12"
dependencies:
undici-types: "npm:~6.19.2"
checksum: 10c0/6af7994129815010bcbc4cf8221865559c8116ff43e74a6549525c2108267596fc2d18aff5d5ecfe089fb60a119f975631343e2c65c52bfa0955ed9dc56733d6
checksum: 10c0/f6a3c90c6745881d47f8dae7eb39d0dd6df9a4060c8f1ab7004690f60b9b183d862c9c6b380b9e8d5a17dd670ac7b19d6318f24c170897c85a9729f9804f47cf
languageName: node
linkType: hard

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@
},
"devDependencies": {
"@apidevtools/swagger-parser": "10.1.0",
"@babel/core": "7.25.2",
"@babel/core": "7.25.8",
"@biomejs/biome": "^1.8.3",
"@cyclonedx/yarn-plugin-cyclonedx": "^1.0.0-rc.7",
"@swc/core": "1.7.26",
"@swc/core": "1.7.35",
"@swc/jest": "0.2.36",
"@types/bcryptjs": "2.4.6",
"@types/cors": "2.8.17",
Expand Down
42 changes: 27 additions & 15 deletions src/lib/features/instance-stats/instance-stats-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ import createStores from '../../../test/fixtures/store';
import VersionService from '../../services/version-service';
import { createFakeGetActiveUsers } from './getActiveUsers';
import { createFakeGetProductionChanges } from './getProductionChanges';

import { registerPrometheusMetrics } from '../../metrics';
import { register } from 'prom-client';
import type { IClientInstanceStore } from '../../types';
let instanceStatsService: InstanceStatsService;
let versionService: VersionService;

let clientInstanceStore: IClientInstanceStore;
let updateMetrics: () => Promise<void>;
beforeEach(() => {
jest.clearAllMocks();

register.clear();

const config = createTestConfig();
const stores = createStores();
versionService = new VersionService(
Expand All @@ -17,6 +24,7 @@ beforeEach(() => {
createFakeGetActiveUsers(),
createFakeGetProductionChanges(),
);
clientInstanceStore = stores.clientInstanceStore;
instanceStatsService = new InstanceStatsService(
stores,
config,
Expand All @@ -25,23 +33,28 @@ beforeEach(() => {
createFakeGetProductionChanges(),
);

jest.spyOn(instanceStatsService, 'refreshAppCountSnapshot');
jest.spyOn(instanceStatsService, 'getLabeledAppCounts');
const { collectDbMetrics } = registerPrometheusMetrics(
config,
stores,
undefined as unknown as string,
config.eventBus,
instanceStatsService,
);
updateMetrics = collectDbMetrics;

jest.spyOn(clientInstanceStore, 'getDistinctApplicationsCount');
jest.spyOn(instanceStatsService, 'getStats');

// validate initial state without calls to these methods
expect(instanceStatsService.refreshAppCountSnapshot).toHaveBeenCalledTimes(
0,
);
expect(instanceStatsService.getStats).toHaveBeenCalledTimes(0);
});

test('get snapshot should not call getStats', async () => {
await instanceStatsService.refreshAppCountSnapshot();
expect(instanceStatsService.getLabeledAppCounts).toHaveBeenCalledTimes(1);
await updateMetrics();
expect(
clientInstanceStore.getDistinctApplicationsCount,
).toHaveBeenCalledTimes(3);
expect(instanceStatsService.getStats).toHaveBeenCalledTimes(0);

// subsequent calls to getStatsSnapshot don't call getStats
for (let i = 0; i < 3; i++) {
const { clientApps } = await instanceStatsService.getStats();
expect(clientApps).toStrictEqual([
Expand All @@ -51,12 +64,11 @@ test('get snapshot should not call getStats', async () => {
]);
}
// after querying the stats snapshot no call to getStats should be issued
expect(instanceStatsService.getLabeledAppCounts).toHaveBeenCalledTimes(1);
expect(
clientInstanceStore.getDistinctApplicationsCount,
).toHaveBeenCalledTimes(3);
});

test('before the snapshot is refreshed we can still get the appCount', async () => {
expect(instanceStatsService.refreshAppCountSnapshot).toHaveBeenCalledTimes(
0,
);
expect(instanceStatsService.getAppCountSnapshot('7d')).toBeUndefined();
});
Loading

0 comments on commit 74b1337

Please sign in to comment.