mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: extended metrics options ui (#5786)
This commit is contained in:
parent
c6f1f44e64
commit
8955a9906d
@ -2,7 +2,7 @@ import { useFeatureMetricsRaw } from 'hooks/api/getters/useFeatureMetricsRaw/use
|
|||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
FEATURE_METRIC_HOURS_BACK_MAX,
|
FEATURE_METRIC_HOURS_BACK_DEFAULT,
|
||||||
FeatureMetricsHours,
|
FeatureMetricsHours,
|
||||||
} from './FeatureMetricsHours/FeatureMetricsHours';
|
} from './FeatureMetricsHours/FeatureMetricsHours';
|
||||||
import { IFeatureMetricsRaw } from 'interfaces/featureToggle';
|
import { IFeatureMetricsRaw } from 'interfaces/featureToggle';
|
||||||
@ -23,7 +23,7 @@ export const FeatureMetrics = () => {
|
|||||||
const applications = useFeatureMetricsApplications(featureId);
|
const applications = useFeatureMetricsApplications(featureId);
|
||||||
usePageTitle('Metrics');
|
usePageTitle('Metrics');
|
||||||
|
|
||||||
const [hoursBack = FEATURE_METRIC_HOURS_BACK_MAX, setHoursBack] =
|
const [hoursBack = FEATURE_METRIC_HOURS_BACK_DEFAULT, setHoursBack] =
|
||||||
useQueryStringNumberState('hoursBack');
|
useQueryStringNumberState('hoursBack');
|
||||||
const { featureMetrics } = useFeatureMetricsRaw(featureId, hoursBack);
|
const { featureMetrics } = useFeatureMetricsRaw(featureId, hoursBack);
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ const useFeatureMetricsEnvironments = (
|
|||||||
const useFeatureMetricsApplications = (featureId: string): Set<string> => {
|
const useFeatureMetricsApplications = (featureId: string): Set<string> => {
|
||||||
const { featureMetrics = [] } = useFeatureMetricsRaw(
|
const { featureMetrics = [] } = useFeatureMetricsRaw(
|
||||||
featureId,
|
featureId,
|
||||||
FEATURE_METRIC_HOURS_BACK_MAX,
|
FEATURE_METRIC_HOURS_BACK_DEFAULT,
|
||||||
);
|
);
|
||||||
|
|
||||||
const applications = featureMetrics.map((metric) => {
|
const applications = featureMetrics.map((metric) => {
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
import { screen, waitFor } from '@testing-library/react';
|
||||||
|
import { render } from 'utils/testRenderer';
|
||||||
|
import { testServerRoute, testServerSetup } from 'utils/testServer';
|
||||||
|
import { FeatureMetricsHours } from './FeatureMetricsHours';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
|
const server = testServerSetup();
|
||||||
|
|
||||||
|
test('Display extended daily metrics', async () => {
|
||||||
|
testServerRoute(server, '/api/admin/ui-config', {
|
||||||
|
flags: {
|
||||||
|
extendedUsageMetrics: true,
|
||||||
|
},
|
||||||
|
versionInfo: {
|
||||||
|
current: { oss: 'irrelevant', enterprise: 'some value' },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
let recordedHoursBack: number | null = null;
|
||||||
|
render(
|
||||||
|
<FeatureMetricsHours
|
||||||
|
hoursBack={48}
|
||||||
|
setHoursBack={(hoursBack) => {
|
||||||
|
recordedHoursBack = hoursBack;
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
const intialSelectedValue = await screen.findByText('Last 48 hours');
|
||||||
|
|
||||||
|
userEvent.click(intialSelectedValue);
|
||||||
|
|
||||||
|
const newSelectedValue = await screen.findByText('Last week');
|
||||||
|
|
||||||
|
userEvent.click(newSelectedValue);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(recordedHoursBack).toBe(7 * 24);
|
||||||
|
});
|
||||||
|
});
|
@ -2,6 +2,9 @@ import { styled } from '@mui/material';
|
|||||||
import GeneralSelect, {
|
import GeneralSelect, {
|
||||||
IGeneralSelectProps,
|
IGeneralSelectProps,
|
||||||
} from 'component/common/GeneralSelect/GeneralSelect';
|
} from 'component/common/GeneralSelect/GeneralSelect';
|
||||||
|
import { subWeeks, subMonths, differenceInHours } from 'date-fns';
|
||||||
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
|
||||||
const StyledTitle = styled('h2')(({ theme }) => ({
|
const StyledTitle = styled('h2')(({ theme }) => ({
|
||||||
margin: 0,
|
margin: 0,
|
||||||
@ -16,15 +19,21 @@ interface IFeatureMetricsHoursProps {
|
|||||||
setHoursBack: (value: number) => void;
|
setHoursBack: (value: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FEATURE_METRIC_HOURS_BACK_MAX = 48;
|
export const FEATURE_METRIC_HOURS_BACK_DEFAULT = 48;
|
||||||
|
|
||||||
export const FeatureMetricsHours = ({
|
export const FeatureMetricsHours = ({
|
||||||
hoursBack,
|
hoursBack,
|
||||||
setHoursBack,
|
setHoursBack,
|
||||||
}: IFeatureMetricsHoursProps) => {
|
}: IFeatureMetricsHoursProps) => {
|
||||||
const onChange: IGeneralSelectProps['onChange'] = (key) => {
|
const onChange: IGeneralSelectProps['onChange'] = (key) => {
|
||||||
setHoursBack(parseFeatureMetricsHour(key));
|
setHoursBack(parseInt(key));
|
||||||
};
|
};
|
||||||
|
const { isEnterprise } = useUiConfig();
|
||||||
|
const extendedUsageMetrics = useUiFlag('extendedUsageMetrics');
|
||||||
|
const extendedOptions = isEnterprise() && extendedUsageMetrics;
|
||||||
|
const options = extendedOptions
|
||||||
|
? [...hourOptions, ...daysOptions]
|
||||||
|
: hourOptions;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -32,7 +41,7 @@ export const FeatureMetricsHours = ({
|
|||||||
<GeneralSelect
|
<GeneralSelect
|
||||||
name='feature-metrics-period'
|
name='feature-metrics-period'
|
||||||
id='feature-metrics-period'
|
id='feature-metrics-period'
|
||||||
options={hourOptions}
|
options={options}
|
||||||
value={String(hoursBack)}
|
value={String(hoursBack)}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
fullWidth
|
fullWidth
|
||||||
@ -41,17 +50,6 @@ export const FeatureMetricsHours = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseFeatureMetricsHour = (value: unknown) => {
|
|
||||||
switch (value) {
|
|
||||||
case '1':
|
|
||||||
return 1;
|
|
||||||
case '24':
|
|
||||||
return 24;
|
|
||||||
default:
|
|
||||||
return FEATURE_METRIC_HOURS_BACK_MAX;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const hourOptions: { key: `${number}`; label: string }[] = [
|
const hourOptions: { key: `${number}`; label: string }[] = [
|
||||||
{
|
{
|
||||||
key: '1',
|
key: '1',
|
||||||
@ -62,7 +60,24 @@ const hourOptions: { key: `${number}`; label: string }[] = [
|
|||||||
label: 'Last 24 hours',
|
label: 'Last 24 hours',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: `${FEATURE_METRIC_HOURS_BACK_MAX}`,
|
key: '48',
|
||||||
label: `Last ${FEATURE_METRIC_HOURS_BACK_MAX} hours`,
|
label: 'Last 48 hours',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
const daysOptions: { key: `${number}`; label: string }[] = [
|
||||||
|
{
|
||||||
|
key: `${differenceInHours(now, subWeeks(now, 1))}`,
|
||||||
|
label: 'Last week',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${differenceInHours(now, subMonths(now, 1))}`,
|
||||||
|
label: 'Last month',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${differenceInHours(now, subMonths(now, 3))}`,
|
||||||
|
label: 'Last 3 months',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -73,6 +73,7 @@ export type UiFlags = {
|
|||||||
featureSearchFeedback?: boolean;
|
featureSearchFeedback?: boolean;
|
||||||
enableLicense?: boolean;
|
enableLicense?: boolean;
|
||||||
newStrategyConfigurationFeedback?: boolean;
|
newStrategyConfigurationFeedback?: boolean;
|
||||||
|
extendedUsageMetrics?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IVersionInfo {
|
export interface IVersionInfo {
|
||||||
|
@ -86,6 +86,7 @@ exports[`should create default config 1`] = `
|
|||||||
"embedProxyFrontend": true,
|
"embedProxyFrontend": true,
|
||||||
"enableLicense": false,
|
"enableLicense": false,
|
||||||
"encryptEmails": false,
|
"encryptEmails": false,
|
||||||
|
"extendedUsageMetrics": false,
|
||||||
"featureSearchAPI": false,
|
"featureSearchAPI": false,
|
||||||
"featureSearchFeedback": false,
|
"featureSearchFeedback": false,
|
||||||
"featureSearchFeedbackPosting": false,
|
"featureSearchFeedbackPosting": false,
|
||||||
|
@ -39,7 +39,8 @@ export type IFlagKey =
|
|||||||
| 'featureSearchFeedback'
|
| 'featureSearchFeedback'
|
||||||
| 'featureSearchFeedbackPosting'
|
| 'featureSearchFeedbackPosting'
|
||||||
| 'newStrategyConfigurationFeedback'
|
| 'newStrategyConfigurationFeedback'
|
||||||
| 'edgeBulkMetricsKillSwitch';
|
| 'edgeBulkMetricsKillSwitch'
|
||||||
|
| 'extendedUsageMetrics';
|
||||||
|
|
||||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
||||||
|
|
||||||
@ -178,6 +179,10 @@ const flags: IFlags = {
|
|||||||
process.env.UNLEASH_EXPERIMENTAL_EDGE_BULK_METRICS_KILL_SWITCH,
|
process.env.UNLEASH_EXPERIMENTAL_EDGE_BULK_METRICS_KILL_SWITCH,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
extendedUsageMetrics: parseEnvVarBoolean(
|
||||||
|
process.env.UNLEASH_EXPERIMENTAL_EXTENDED_USAGE_METRICS,
|
||||||
|
false,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultExperimentalOptions: IExperimentalOptions = {
|
export const defaultExperimentalOptions: IExperimentalOptions = {
|
||||||
|
Loading…
Reference in New Issue
Block a user