mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-24 01:18:01 +02:00
feat: remove newApplicationsList feature flag (#4653)
This commit is contained in:
parent
a9ac81a089
commit
77fbac01e4
@ -1,99 +0,0 @@
|
|||||||
import { useEffect, useMemo, useState } from 'react';
|
|
||||||
import { CircularProgress, Link } from '@mui/material';
|
|
||||||
import { Warning } from '@mui/icons-material';
|
|
||||||
import { AppsLinkList, styles as themeStyles } from 'component/common';
|
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
|
||||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
|
||||||
import useApplications from 'hooks/api/getters/useApplications/useApplications';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { useSearchParams } from 'react-router-dom';
|
|
||||||
import { Search } from 'component/common/Search/Search';
|
|
||||||
import { safeRegExp } from '@server/util/escape-regex';
|
|
||||||
|
|
||||||
type PageQueryType = Partial<Record<'search', string>>;
|
|
||||||
|
|
||||||
export const OldApplicationList = () => {
|
|
||||||
const { applications, loading } = useApplications();
|
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
|
||||||
const [searchValue, setSearchValue] = useState(
|
|
||||||
searchParams.get('search') || ''
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const tableState: PageQueryType = {};
|
|
||||||
if (searchValue) {
|
|
||||||
tableState.search = searchValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
setSearchParams(tableState, {
|
|
||||||
replace: true,
|
|
||||||
});
|
|
||||||
}, [searchValue, setSearchParams]);
|
|
||||||
|
|
||||||
const filteredApplications = useMemo(() => {
|
|
||||||
const regExp = safeRegExp(searchValue, 'i');
|
|
||||||
return searchValue
|
|
||||||
? applications?.filter(a => regExp.test(a.appName))
|
|
||||||
: applications;
|
|
||||||
}, [applications, searchValue]);
|
|
||||||
|
|
||||||
const renderNoApplications = () => (
|
|
||||||
<>
|
|
||||||
<section style={{ textAlign: 'center' }}>
|
|
||||||
<Warning titleAccess="Warning" /> <br />
|
|
||||||
<br />
|
|
||||||
Oh snap, it does not seem like you have connected any
|
|
||||||
applications. To connect your application to Unleash you will
|
|
||||||
require a Client SDK.
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
You can read more about how to use Unleash in your application
|
|
||||||
in the{' '}
|
|
||||||
<Link href="https://docs.getunleash.io/docs/sdks/">
|
|
||||||
documentation.
|
|
||||||
</Link>
|
|
||||||
</section>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!filteredApplications) {
|
|
||||||
return <CircularProgress variant="indeterminate" />;
|
|
||||||
}
|
|
||||||
|
|
||||||
let applicationCount =
|
|
||||||
filteredApplications.length < applications.length
|
|
||||||
? `${filteredApplications.length} of ${applications.length}`
|
|
||||||
: applications.length;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<PageContent
|
|
||||||
header={
|
|
||||||
<PageHeader
|
|
||||||
title={`Applications (${applicationCount})`}
|
|
||||||
actions={
|
|
||||||
<Search
|
|
||||||
initialValue={searchValue}
|
|
||||||
onChange={setSearchValue}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className={themeStyles.fullwidth}>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={filteredApplications.length > 0}
|
|
||||||
show={<AppsLinkList apps={filteredApplications} />}
|
|
||||||
elseShow={
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={loading}
|
|
||||||
show={<div>...loading</div>}
|
|
||||||
elseShow={renderNoApplications()}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</PageContent>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,16 +0,0 @@
|
|||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import useUiConfig from '../../../hooks/api/getters/useUiConfig/useUiConfig';
|
|
||||||
import { ApplicationList } from './ApplicationList';
|
|
||||||
import { OldApplicationList } from './OldApplicationList';
|
|
||||||
|
|
||||||
export const TemporaryApplicationListWrapper = () => {
|
|
||||||
const { uiConfig } = useUiConfig();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={Boolean(uiConfig.flags.newApplicationList)}
|
|
||||||
show={<ApplicationList />}
|
|
||||||
elseShow={<OldApplicationList />}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
@ -44,8 +44,8 @@ import { LazyProject } from 'component/project/Project/LazyProject';
|
|||||||
import { LoginHistory } from 'component/loginHistory/LoginHistory';
|
import { LoginHistory } from 'component/loginHistory/LoginHistory';
|
||||||
import { FeatureTypesList } from 'component/featureTypes/FeatureTypesList';
|
import { FeatureTypesList } from 'component/featureTypes/FeatureTypesList';
|
||||||
import { AddonsList } from 'component/integrations/IntegrationList/AddonsList';
|
import { AddonsList } from 'component/integrations/IntegrationList/AddonsList';
|
||||||
import { TemporaryApplicationListWrapper } from 'component/application/ApplicationList/TemporaryApplicationListWrapper';
|
|
||||||
import { ViewIntegration } from 'component/integrations/ViewIntegration/ViewIntegration';
|
import { ViewIntegration } from 'component/integrations/ViewIntegration/ViewIntegration';
|
||||||
|
import { ApplicationList } from '../application/ApplicationList/ApplicationList';
|
||||||
|
|
||||||
export const routes: IRoute[] = [
|
export const routes: IRoute[] = [
|
||||||
// Splash
|
// Splash
|
||||||
@ -181,7 +181,7 @@ export const routes: IRoute[] = [
|
|||||||
{
|
{
|
||||||
path: '/applications',
|
path: '/applications',
|
||||||
title: 'Applications',
|
title: 'Applications',
|
||||||
component: TemporaryApplicationListWrapper,
|
component: ApplicationList,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
menu: { mobile: true, advanced: true },
|
menu: { mobile: true, advanced: true },
|
||||||
},
|
},
|
||||||
@ -502,14 +502,13 @@ const computeRoutes = () => {
|
|||||||
|
|
||||||
export const getCondensedRoutes = (routes: IRoute[]): INavigationMenuItem[] => {
|
export const getCondensedRoutes = (routes: IRoute[]): INavigationMenuItem[] => {
|
||||||
return routes.map(route => {
|
return routes.map(route => {
|
||||||
const condensedRoute = {
|
return {
|
||||||
path: route.path,
|
path: route.path,
|
||||||
flag: route.flag,
|
flag: route.flag,
|
||||||
title: route.title,
|
title: route.title,
|
||||||
menu: route.menu,
|
menu: route.menu,
|
||||||
configFlag: route.configFlag,
|
configFlag: route.configFlag,
|
||||||
};
|
};
|
||||||
return condensedRoute;
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,7 +60,6 @@ export type UiFlags = {
|
|||||||
customRootRolesKillSwitch?: boolean;
|
customRootRolesKillSwitch?: boolean;
|
||||||
strategyVariant?: boolean;
|
strategyVariant?: boolean;
|
||||||
lastSeenByEnvironment?: boolean;
|
lastSeenByEnvironment?: boolean;
|
||||||
newApplicationList?: boolean;
|
|
||||||
integrationsRework?: boolean;
|
integrationsRework?: boolean;
|
||||||
multipleRoles?: boolean;
|
multipleRoles?: boolean;
|
||||||
featureNamingPattern?: boolean;
|
featureNamingPattern?: boolean;
|
||||||
|
@ -94,7 +94,6 @@ exports[`should create default config 1`] = `
|
|||||||
},
|
},
|
||||||
"migrationLock": true,
|
"migrationLock": true,
|
||||||
"multipleRoles": false,
|
"multipleRoles": false,
|
||||||
"newApplicationList": false,
|
|
||||||
"personalAccessTokensKillSwitch": false,
|
"personalAccessTokensKillSwitch": false,
|
||||||
"proPlanAutoCharge": false,
|
"proPlanAutoCharge": false,
|
||||||
"responseTimeWithAppNameKillSwitch": false,
|
"responseTimeWithAppNameKillSwitch": false,
|
||||||
@ -130,7 +129,6 @@ exports[`should create default config 1`] = `
|
|||||||
},
|
},
|
||||||
"migrationLock": true,
|
"migrationLock": true,
|
||||||
"multipleRoles": false,
|
"multipleRoles": false,
|
||||||
"newApplicationList": false,
|
|
||||||
"personalAccessTokensKillSwitch": false,
|
"personalAccessTokensKillSwitch": false,
|
||||||
"proPlanAutoCharge": false,
|
"proPlanAutoCharge": false,
|
||||||
"responseTimeWithAppNameKillSwitch": false,
|
"responseTimeWithAppNameKillSwitch": false,
|
||||||
|
@ -7,7 +7,6 @@ import {
|
|||||||
import { Logger, LogProvider } from '../logger';
|
import { Logger, LogProvider } from '../logger';
|
||||||
import { IApplicationQuery } from '../types/query';
|
import { IApplicationQuery } from '../types/query';
|
||||||
import { Db } from './db';
|
import { Db } from './db';
|
||||||
import { IFlagResolver } from '../types';
|
|
||||||
|
|
||||||
const COLUMNS = [
|
const COLUMNS = [
|
||||||
'app_name',
|
'app_name',
|
||||||
@ -110,18 +109,10 @@ export default class ClientApplicationsStore
|
|||||||
{
|
{
|
||||||
private db: Db;
|
private db: Db;
|
||||||
|
|
||||||
private flagResolver: IFlagResolver;
|
|
||||||
|
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(
|
constructor(db: Db, eventBus: EventEmitter, getLogger: LogProvider) {
|
||||||
db: Db,
|
|
||||||
eventBus: EventEmitter,
|
|
||||||
getLogger: LogProvider,
|
|
||||||
flagResolver: IFlagResolver,
|
|
||||||
) {
|
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.flagResolver = flagResolver;
|
|
||||||
this.logger = getLogger('client-applications-store.ts');
|
this.logger = getLogger('client-applications-store.ts');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,38 +184,26 @@ export default class ClientApplicationsStore
|
|||||||
async getAppsForStrategy(
|
async getAppsForStrategy(
|
||||||
query: IApplicationQuery,
|
query: IApplicationQuery,
|
||||||
): Promise<IClientApplication[]> {
|
): Promise<IClientApplication[]> {
|
||||||
if (this.flagResolver.isEnabled('newApplicationList')) {
|
const rows = await this.db
|
||||||
const rows = await this.db
|
.select([
|
||||||
.select([
|
...COLUMNS.map((column) => `${TABLE}.${column}`),
|
||||||
...COLUMNS.map((column) => `${TABLE}.${column}`),
|
'project',
|
||||||
'project',
|
'environment',
|
||||||
'environment',
|
])
|
||||||
])
|
.from(TABLE)
|
||||||
.from(TABLE)
|
.leftJoin(
|
||||||
.leftJoin(
|
TABLE_USAGE,
|
||||||
TABLE_USAGE,
|
`${TABLE_USAGE}.app_name`,
|
||||||
`${TABLE_USAGE}.app_name`,
|
`${TABLE}.app_name`,
|
||||||
`${TABLE}.app_name`,
|
);
|
||||||
);
|
const apps = reduceRows(rows);
|
||||||
const apps = reduceRows(rows);
|
|
||||||
|
|
||||||
if (query.strategyName) {
|
if (query.strategyName) {
|
||||||
return apps.filter((app) =>
|
return apps.filter((app) =>
|
||||||
app.strategies.includes(query.strategyName),
|
app.strategies.includes(query.strategyName),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
return apps;
|
|
||||||
} else {
|
|
||||||
const rows = await this.db.select(COLUMNS).from(TABLE);
|
|
||||||
const apps = rows.map(mapRow);
|
|
||||||
|
|
||||||
if (query.strategyName) {
|
|
||||||
return apps.filter((app) =>
|
|
||||||
app.strategies.includes(query.strategyName),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return apps;
|
|
||||||
}
|
}
|
||||||
|
return apps;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUnannounced(): Promise<IClientApplication[]> {
|
async getUnannounced(): Promise<IClientApplication[]> {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { IUnleashConfig } from '../types/option';
|
import { IUnleashConfig, IUnleashStores } from '../types';
|
||||||
import { IUnleashStores } from '../types/stores';
|
|
||||||
|
|
||||||
import EventStore from './event-store';
|
import EventStore from './event-store';
|
||||||
import FeatureToggleStore from './feature-toggle-store';
|
import FeatureToggleStore from './feature-toggle-store';
|
||||||
@ -54,7 +53,6 @@ export const createStores = (
|
|||||||
db,
|
db,
|
||||||
eventBus,
|
eventBus,
|
||||||
getLogger,
|
getLogger,
|
||||||
config.flagResolver,
|
|
||||||
),
|
),
|
||||||
clientInstanceStore: new ClientInstanceStore(db, eventBus, getLogger),
|
clientInstanceStore: new ClientInstanceStore(db, eventBus, getLogger),
|
||||||
clientMetricsStoreV2: new ClientMetricsStoreV2(
|
clientMetricsStoreV2: new ClientMetricsStoreV2(
|
||||||
|
@ -24,7 +24,6 @@ export type IFlagKey =
|
|||||||
| 'filterInvalidClientMetrics'
|
| 'filterInvalidClientMetrics'
|
||||||
| 'lastSeenByEnvironment'
|
| 'lastSeenByEnvironment'
|
||||||
| 'customRootRolesKillSwitch'
|
| 'customRootRolesKillSwitch'
|
||||||
| 'newApplicationList'
|
|
||||||
| 'integrationsRework'
|
| 'integrationsRework'
|
||||||
| 'multipleRoles'
|
| 'multipleRoles'
|
||||||
| 'featureNamingPattern'
|
| 'featureNamingPattern'
|
||||||
@ -120,10 +119,6 @@ const flags: IFlags = {
|
|||||||
process.env.UNLEASH_EXPERIMENTAL_MULTIPLE_ROLES,
|
process.env.UNLEASH_EXPERIMENTAL_MULTIPLE_ROLES,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
newApplicationList: parseEnvVarBoolean(
|
|
||||||
process.env.UNLEASH_EXPERIMENTAL_NEW_APPLICATION_LIST,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
featureNamingPattern: parseEnvVarBoolean(
|
featureNamingPattern: parseEnvVarBoolean(
|
||||||
process.env.UNLEASH_EXPERIMENTAL_FEATURE_NAMING_PATTERN,
|
process.env.UNLEASH_EXPERIMENTAL_FEATURE_NAMING_PATTERN,
|
||||||
false,
|
false,
|
||||||
|
@ -40,7 +40,6 @@ process.nextTick(async () => {
|
|||||||
slackAppAddon: true,
|
slackAppAddon: true,
|
||||||
lastSeenByEnvironment: true,
|
lastSeenByEnvironment: true,
|
||||||
integrationsRework: true,
|
integrationsRework: true,
|
||||||
newApplicationList: true,
|
|
||||||
featureNamingPattern: true,
|
featureNamingPattern: true,
|
||||||
doraMetrics: true,
|
doraMetrics: true,
|
||||||
},
|
},
|
||||||
|
@ -9,16 +9,8 @@ let app: IUnleashTest;
|
|||||||
let db: ITestDb;
|
let db: ITestDb;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
db = await dbInit('metrics_serial', getLogger, {
|
db = await dbInit('metrics_serial', getLogger, {});
|
||||||
experimental: { flags: { newApplicationList: true } },
|
app = await setupAppWithCustomConfig(db.stores, {});
|
||||||
});
|
|
||||||
app = await setupAppWithCustomConfig(db.stores, {
|
|
||||||
experimental: {
|
|
||||||
flags: {
|
|
||||||
newApplicationList: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user