1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-03-23 00:16:25 +01:00

feat: show outdated sdks banner (#6541)

This commit is contained in:
Mateusz Kwasniewski 2024-03-14 10:15:33 +01:00 committed by GitHub
parent d5a084256e
commit c6fd558da4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 156 additions and 4 deletions

View File

@ -0,0 +1,36 @@
import { screen } from '@testing-library/react';
import { render } from 'utils/testRenderer';
import { testServerRoute, testServerSetup } from 'utils/testServer';
import { OutdatedSdksSchema } from 'openapi';
import { OutdatedSdksBanner } from './OutdatedSdksBanner';
const server = testServerSetup();
const setupApi = (outdatedSdks: OutdatedSdksSchema) => {
testServerRoute(server, '/api/admin/metrics/sdks/outdated', outdatedSdks);
testServerRoute(server, '/api/admin/ui-config', {
flags: {
outdatedSdksBanner: true,
},
});
};
test('Show outdated SDKs and apps using them', async () => {
setupApi({
sdks: [
{
sdkVersion: 'unleash-node-client:3.2.1',
applications: ['application1', 'application2'],
},
],
});
render(<OutdatedSdksBanner />);
const link = await screen.findByText('Please update those versions');
link.click();
await screen.findByText('unleash-node-client:3.2.1');
await screen.findByText('application1');
await screen.findByText('application2');
});

View File

@ -1,21 +1,48 @@
import { ConditionallyRender } from '../../common/ConditionallyRender/ConditionallyRender';
import { Banner } from '../Banner/Banner';
import { IBanner } from '../../../interfaces/banner';
import { IBanner } from 'interfaces/banner';
import { useOutdatedSdks } from 'hooks/api/getters/useOutdatedSdks/useOutdatedSdks';
import { useUiFlag } from 'hooks/useUiFlag';
import { Link } from 'react-router-dom';
import { styled } from '@mui/material';
const StyledList = styled('ul')({ margin: 0 });
export const OutdatedSdksBanner = () => {
const displayOutdatedSdksBanner = false;
const {
data: { sdks },
} = useOutdatedSdks();
const flagEnabled = useUiFlag('outdatedSdksBanner');
const outdatedSdksBanner: IBanner = {
message: `We noticed that you're using outdated SDKs. `,
variant: 'warning',
link: 'dialog',
linkText: 'Please update those versions',
dialogTitle: 'Outdated SDKs',
dialog: <h1>Outdated SDKs</h1>,
dialog: (
<>
{sdks.map((item) => (
<div key={item.sdkVersion}>
<span>{item.sdkVersion}</span>
<StyledList>
{item.applications.map((application) => (
<li key={application}>
<Link to={`/applications/${application}`}>
{application}
</Link>
</li>
))}
</StyledList>
</div>
))}
</>
),
};
return (
<>
<ConditionallyRender
condition={displayOutdatedSdksBanner}
condition={flagEnabled && sdks.length > 0}
show={<Banner banner={outdatedSdksBanner} />}
/>
</>

View File

@ -1,5 +1,6 @@
import useSWR, { SWRConfiguration, Key } from 'swr';
import { useCallback } from 'react';
import handleErrorResponses from '../httpErrorResponseHandler';
interface IUseApiGetterOutput<T> {
data?: T;
@ -26,3 +27,9 @@ export const useApiGetter = <T>(
loading: !error && !data,
};
};
export const fetcher = (path: string, errorTarget: string) => {
return fetch(path)
.then(handleErrorResponses(errorTarget))
.then((res) => res.json());
};

View File

@ -0,0 +1,14 @@
import { fetcher, useApiGetter } from '../useApiGetter/useApiGetter';
import { OutdatedSdksSchema } from '../../../../openapi';
const PATH = 'api/admin/metrics/sdks/outdated';
export const useOutdatedSdks = () => {
const { data, refetch, loading, error } = useApiGetter<OutdatedSdksSchema>(
PATH,
() => fetcher(PATH, 'Outdated SDKs'),
{ refreshInterval: 60 * 1000 },
);
return { data: data || { sdks: [] }, refetch, error };
};

View File

@ -79,6 +79,7 @@ export type UiFlags = {
featureSearchFeedbackPosting?: boolean;
userAccessUIEnabled?: boolean;
sdkReporting?: boolean;
outdatedSdksBanner?: boolean;
};
export interface IVersionInfo {

View File

@ -0,0 +1,14 @@
/**
* Generated by Orval
* Do not edit manually.
* See `gen:api` script in package.json
*/
export type GetOutdatedSdks404 = {
/** The ID of the error instance */
id?: string;
/** A description of what went wrong. */
message?: string;
/** The name of the error kind */
name?: string;
};

View File

@ -648,6 +648,7 @@ export * from './getMe401';
export * from './getOidcSettings400';
export * from './getOidcSettings401';
export * from './getOidcSettings403';
export * from './getOutdatedSdks404';
export * from './getPats401';
export * from './getPats403';
export * from './getPats404';
@ -789,6 +790,8 @@ export * from './notificationsSchemaItemNotificationType';
export * from './oidcSettingsSchema';
export * from './oidcSettingsSchemaDefaultRootRole';
export * from './oidcSettingsSchemaIdTokenSigningAlgorithm';
export * from './outdatedSdksSchema';
export * from './outdatedSdksSchemaSdksItem';
export * from './overrideSchema';
export * from './overwriteEnvironmentFeatureVariants400';
export * from './overwriteEnvironmentFeatureVariants401';
@ -1044,6 +1047,7 @@ export * from './toggleEnvironmentOff404';
export * from './toggleEnvironmentOn401';
export * from './toggleEnvironmentOn403';
export * from './toggleEnvironmentOn404';
export * from './toggleFeatureActionSchema';
export * from './toggleFeatureEnvironmentOff400';
export * from './toggleFeatureEnvironmentOff401';
export * from './toggleFeatureEnvironmentOff403';

View File

@ -0,0 +1,14 @@
/**
* Generated by Orval
* Do not edit manually.
* See `gen:api` script in package.json
*/
import type { OutdatedSdksSchemaSdksItem } from './outdatedSdksSchemaSdksItem';
/**
* Data about outdated SDKs that should be upgraded.
*/
export interface OutdatedSdksSchema {
/** A list of SDKs */
sdks: OutdatedSdksSchemaSdksItem[];
}

View File

@ -0,0 +1,12 @@
/**
* Generated by Orval
* Do not edit manually.
* See `gen:api` script in package.json
*/
export type OutdatedSdksSchemaSdksItem = {
/** A list of applications using the SDK version */
applications: string[];
/** An outdated SDK version identifier. Usually formatted as "unleash-client-<language>:<version>" */
sdkVersion: string;
};

View File

@ -0,0 +1,17 @@
/**
* Generated by Orval
* Do not edit manually.
* See `gen:api` script in package.json
*/
/**
* Input data required for the action
*/
export interface ToggleFeatureActionSchema {
/** The environment we want to target */
environment: string;
/** The name of the feature we want to target */
featureName: string;
/** The project where the feature is located */
project: string;
}

View File

@ -130,6 +130,7 @@ exports[`should create default config 1`] = `
},
"migrationLock": true,
"newStrategyConfigurationFeedback": false,
"outdatedSdksBanner": false,
"personalAccessTokensKillSwitch": false,
"proPlanAutoCharge": false,
"queryMissingTokens": false,

View File

@ -51,6 +51,7 @@ export type IFlagKey =
| 'disableUpdateMaxRevisionId'
| 'disablePublishUnannouncedEvents'
| 'sdkReporting'
| 'outdatedSdksBanner'
| 'responseTimeMetricsFix'
| 'scimApi'
| 'displayEdgeBanner'
@ -203,6 +204,10 @@ const flags: IFlags = {
process.env.UNLEASH_EXPERIMENTAL_SDK_REPORTING,
false,
),
outdatedSdksBanner: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_OUTDATED_SDKS_BANNER,
false,
),
feedbackComments: {
name: 'feedbackComments',
enabled: parseEnvVarBoolean(