mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Enterprise Search] Replace Engines UI Settings feature flag (#149996)
## Summary Replaced the Engines UI Settings feature flag with product access field from the client config. Then removed the Engines UI Setting. We opted for a backend feature flag instead of the UI setting so that a single feature flag could be used to gate both the UI and the API for engines for the 8.7 release, since this work will not be completed until 8.8.
This commit is contained in:
parent
f002889cca
commit
e8eb04420e
16 changed files with 38 additions and 43 deletions
|
@ -570,8 +570,4 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
|
|||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
'enterpriseSearch:enableEnginesSection': {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
};
|
||||
|
|
|
@ -152,5 +152,4 @@ export interface UsageStats {
|
|||
'securitySolution:enableGroupedNav': boolean;
|
||||
'securitySolution:showRelatedIntegrations': boolean;
|
||||
'visualization:visualize:legacyGaugeChartsLibrary': boolean;
|
||||
'enterpriseSearch:enableEnginesSection': boolean;
|
||||
}
|
||||
|
|
|
@ -9113,12 +9113,6 @@
|
|||
"_meta": {
|
||||
"description": "Non-default value of setting."
|
||||
}
|
||||
},
|
||||
"enterpriseSearch:enableEnginesSection": {
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
"description": "Non-default value of setting."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -29,6 +29,7 @@ export const DEFAULT_INITIAL_APP_DATA = {
|
|||
},
|
||||
access: {
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
},
|
||||
appSearch: {
|
||||
|
|
|
@ -32,6 +32,7 @@ export interface ConfiguredLimits {
|
|||
|
||||
export interface ProductAccess {
|
||||
hasAppSearchAccess: boolean;
|
||||
hasSearchEnginesAccess: boolean;
|
||||
hasWorkplaceSearchAccess: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,4 +6,3 @@
|
|||
*/
|
||||
|
||||
export const enterpriseSearchFeatureId = 'enterpriseSearch';
|
||||
export const enableEnginesSection = 'enterpriseSearch:enableEnginesSection';
|
||||
|
|
|
@ -29,6 +29,7 @@ export const mockKibanaValues = {
|
|||
navigateToUrl: jest.fn(),
|
||||
productAccess: {
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
},
|
||||
uiSettings: uiSettingsServiceMock.createStartContract(),
|
||||
|
|
|
@ -10,7 +10,6 @@ import { Route, Switch } from 'react-router-dom';
|
|||
|
||||
import { useValues } from 'kea';
|
||||
|
||||
import { enableEnginesSection } from '../../../../../common/ui_settings_keys';
|
||||
import { KibanaLogic } from '../../../shared/kibana';
|
||||
import { ENGINES_PATH, ENGINE_PATH } from '../../routes';
|
||||
|
||||
|
@ -20,8 +19,8 @@ import { NotFound } from '../not_found';
|
|||
import { EnginesList } from './engines_list';
|
||||
|
||||
export const EnginesRouter: React.FC = () => {
|
||||
const { uiSettings } = useValues(KibanaLogic);
|
||||
const enginesSectionEnabled = uiSettings?.get<boolean>(enableEnginesSection, false);
|
||||
const { productAccess } = useValues(KibanaLogic);
|
||||
const enginesSectionEnabled = productAccess.hasSearchEnginesAccess;
|
||||
if (!enginesSectionEnabled) {
|
||||
return (
|
||||
<Switch>
|
||||
|
|
|
@ -45,6 +45,7 @@ export const renderApp = (
|
|||
|
||||
const noProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
};
|
||||
const productAccess = data.access || noProductAccess;
|
||||
|
|
|
@ -15,8 +15,6 @@ import { EuiSideNavItemType } from '@elastic/eui';
|
|||
|
||||
import { ProductAccess } from '../../../../common/types';
|
||||
|
||||
import { enableEnginesSection } from '../../../../common/ui_settings_keys';
|
||||
|
||||
import { useEnterpriseSearchNav, useEnterpriseSearchEngineNav } from './nav';
|
||||
|
||||
describe('useEnterpriseSearchContentNav', () => {
|
||||
|
@ -28,6 +26,7 @@ describe('useEnterpriseSearchContentNav', () => {
|
|||
it('returns an array of top-level Enterprise Search nav items', () => {
|
||||
const fullProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
};
|
||||
setMockValues({ productAccess: fullProductAccess });
|
||||
|
@ -93,12 +92,12 @@ describe('useEnterpriseSearchContentNav', () => {
|
|||
name: 'Search',
|
||||
},
|
||||
]);
|
||||
expect(mockKibanaValues.uiSettings.get).toHaveBeenCalledWith(enableEnginesSection, false);
|
||||
});
|
||||
|
||||
it('excludes legacy products when the user has no access to them', () => {
|
||||
const noProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
};
|
||||
|
||||
|
@ -129,6 +128,7 @@ describe('useEnterpriseSearchContentNav', () => {
|
|||
it('excludes App Search when the user has no access to it', () => {
|
||||
const workplaceSearchProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
};
|
||||
|
||||
|
@ -163,6 +163,7 @@ describe('useEnterpriseSearchContentNav', () => {
|
|||
it('excludes Workplace Search when the user has no access to it', () => {
|
||||
const appSearchProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
};
|
||||
|
||||
|
@ -197,6 +198,7 @@ describe('useEnterpriseSearchContentNav', () => {
|
|||
it('excludes engines when feature flag is off', () => {
|
||||
const fullProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
};
|
||||
setMockValues({ productAccess: fullProductAccess });
|
||||
|
@ -209,12 +211,12 @@ describe('useEnterpriseSearchContentNav', () => {
|
|||
describe('useEnterpriseSearchContentNav Engines feature flag', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockKibanaValues.uiSettings.get.mockReturnValue(true);
|
||||
});
|
||||
|
||||
it('returns an array of top-level Enterprise Search nav items', () => {
|
||||
const fullProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: true,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
};
|
||||
setMockValues({ productAccess: fullProductAccess });
|
||||
|
@ -286,12 +288,12 @@ describe('useEnterpriseSearchContentNav Engines feature flag', () => {
|
|||
name: 'Standalone Experiences',
|
||||
},
|
||||
]);
|
||||
expect(mockKibanaValues.uiSettings.get).toHaveBeenCalledWith(enableEnginesSection, false);
|
||||
});
|
||||
|
||||
it('excludes standalone experiences when the user has no access to them', () => {
|
||||
const fullProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: true,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
};
|
||||
setMockValues({ productAccess: fullProductAccess });
|
||||
|
@ -302,6 +304,7 @@ describe('useEnterpriseSearchContentNav Engines feature flag', () => {
|
|||
it('excludes App Search when the user has no access to it', () => {
|
||||
const fullProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: true,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
};
|
||||
setMockValues({ productAccess: fullProductAccess });
|
||||
|
@ -324,6 +327,7 @@ describe('useEnterpriseSearchContentNav Engines feature flag', () => {
|
|||
it('excludes Workplace Search when the user has no access to it', () => {
|
||||
const fullProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: true,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
};
|
||||
setMockValues({ productAccess: fullProductAccess });
|
||||
|
@ -351,6 +355,7 @@ describe('useEnterpriseSearchEngineNav', () => {
|
|||
mockKibanaValues.uiSettings.get.mockReturnValue(true);
|
||||
const fullProductAccess: ProductAccess = {
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: true,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
};
|
||||
setMockValues({ productAccess: fullProductAccess });
|
||||
|
@ -424,7 +429,6 @@ describe('useEnterpriseSearchEngineNav', () => {
|
|||
name: 'Standalone Experiences',
|
||||
},
|
||||
]);
|
||||
expect(mockKibanaValues.uiSettings.get).toHaveBeenCalledWith(enableEnginesSection, false);
|
||||
});
|
||||
|
||||
it('returns selected engine sub nav items', () => {
|
||||
|
|
|
@ -19,7 +19,6 @@ import {
|
|||
SEARCH_EXPERIENCES_PLUGIN,
|
||||
WORKPLACE_SEARCH_PLUGIN,
|
||||
} from '../../../../common/constants';
|
||||
import { enableEnginesSection } from '../../../../common/ui_settings_keys';
|
||||
import {
|
||||
ENGINES_PATH,
|
||||
SEARCH_INDICES_PATH,
|
||||
|
@ -31,9 +30,9 @@ import { KibanaLogic } from '../kibana';
|
|||
import { generateNavLink } from './nav_link_helpers';
|
||||
|
||||
export const useEnterpriseSearchNav = () => {
|
||||
const { productAccess, uiSettings } = useValues(KibanaLogic);
|
||||
const { productAccess } = useValues(KibanaLogic);
|
||||
|
||||
const enginesSectionEnabled = uiSettings?.get<boolean>(enableEnginesSection, false);
|
||||
const enginesSectionEnabled = productAccess.hasSearchEnginesAccess;
|
||||
|
||||
const navItems: Array<EuiSideNavItemType<unknown>> = [
|
||||
{
|
||||
|
|
|
@ -59,6 +59,7 @@ describe('checkAccess', () => {
|
|||
};
|
||||
expect(await checkAccess({ ...mockDependencies, security })).toEqual({
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
});
|
||||
});
|
||||
|
@ -71,6 +72,7 @@ describe('checkAccess', () => {
|
|||
};
|
||||
expect(await checkAccess({ ...mockDependencies, request })).toEqual({
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
});
|
||||
});
|
||||
|
@ -81,6 +83,7 @@ describe('checkAccess', () => {
|
|||
mockSpaces.spacesService.getActiveSpace.mockResolvedValueOnce(disabledSpace);
|
||||
expect(await checkAccess({ ...mockDependencies })).toEqual({
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
});
|
||||
});
|
||||
|
@ -94,6 +97,7 @@ describe('checkAccess', () => {
|
|||
);
|
||||
expect(await checkAccess({ ...mockDependencies })).toEqual({
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
});
|
||||
});
|
||||
|
@ -134,6 +138,7 @@ describe('checkAccess', () => {
|
|||
};
|
||||
expect(await checkAccess({ ...mockDependencies, security })).toEqual({
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
});
|
||||
});
|
||||
|
@ -149,6 +154,7 @@ describe('checkAccess', () => {
|
|||
};
|
||||
expect(await checkAccess({ ...mockDependencies, security })).toEqual({
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
});
|
||||
});
|
||||
|
@ -170,6 +176,7 @@ describe('checkAccess', () => {
|
|||
const config = { host: undefined };
|
||||
expect(await checkAccess({ ...mockDependencies, config })).toEqual({
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
});
|
||||
});
|
||||
|
@ -180,11 +187,13 @@ describe('checkAccess', () => {
|
|||
(callEnterpriseSearchConfigAPI as jest.Mock).mockImplementationOnce(() => ({
|
||||
access: {
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
},
|
||||
}));
|
||||
expect(await checkAccess(mockDependencies)).toEqual({
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: true,
|
||||
});
|
||||
});
|
||||
|
@ -193,6 +202,7 @@ describe('checkAccess', () => {
|
|||
(callEnterpriseSearchConfigAPI as jest.Mock).mockImplementationOnce(() => ({}));
|
||||
expect(await checkAccess(mockDependencies)).toEqual({
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
});
|
||||
});
|
||||
|
@ -204,6 +214,7 @@ describe('checkAccess', () => {
|
|||
}));
|
||||
expect(await checkAccess(mockDependencies)).toEqual({
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,12 +23,14 @@ interface CheckAccess {
|
|||
log: Logger;
|
||||
}
|
||||
|
||||
const ALLOW_ALL_PLUGINS = {
|
||||
const ALLOW_ALL_PLUGINS: ProductAccess = {
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: false, // still false unless Feature Flag explicitly enabled on backend
|
||||
hasWorkplaceSearchAccess: true,
|
||||
};
|
||||
const DENY_ALL_PLUGINS = {
|
||||
const DENY_ALL_PLUGINS: ProductAccess = {
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
};
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ describe('callEnterpriseSearchConfigAPI', () => {
|
|||
name: 'someuser',
|
||||
access: {
|
||||
app_search: true,
|
||||
search_engines: true,
|
||||
workplace_search: false,
|
||||
},
|
||||
app_search: {
|
||||
|
@ -123,6 +124,7 @@ describe('callEnterpriseSearchConfigAPI', () => {
|
|||
kibanaVersion: '1.0.0',
|
||||
access: {
|
||||
hasAppSearchAccess: true,
|
||||
hasSearchEnginesAccess: true,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
},
|
||||
publicUrl: 'http://some.vanity.url',
|
||||
|
@ -136,6 +138,7 @@ describe('callEnterpriseSearchConfigAPI', () => {
|
|||
kibanaVersion: '1.0.0',
|
||||
access: {
|
||||
hasAppSearchAccess: false,
|
||||
hasSearchEnginesAccess: false,
|
||||
hasWorkplaceSearchAccess: false,
|
||||
},
|
||||
publicUrl: undefined,
|
||||
|
|
|
@ -87,6 +87,7 @@ export const callEnterpriseSearchConfigAPI = async ({
|
|||
kibanaVersion: kibanaPackageJson.version,
|
||||
access: {
|
||||
hasAppSearchAccess: !!data?.current_user?.access?.app_search,
|
||||
hasSearchEnginesAccess: !!data?.current_user?.access?.search_engines,
|
||||
hasWorkplaceSearchAccess: !!data?.current_user?.access?.workplace_search,
|
||||
},
|
||||
publicUrl: stripTrailingSlash(data?.settings?.external_url),
|
||||
|
|
|
@ -5,25 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { UiSettingsParams } from '@kbn/core/types';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { enterpriseSearchFeatureId, enableEnginesSection } from '../common/ui_settings_keys';
|
||||
/**
|
||||
* uiSettings definitions for Enterprise Search
|
||||
*/
|
||||
export const uiSettings: Record<string, UiSettingsParams<boolean>> = {
|
||||
[enableEnginesSection]: {
|
||||
category: [enterpriseSearchFeatureId],
|
||||
description: i18n.translate('xpack.enterpriseSearch.uiSettings.engines.description', {
|
||||
defaultMessage: 'Enable the new Engines section in Enterprise Search.',
|
||||
}),
|
||||
name: i18n.translate('xpack.enterpriseSearch.uiSettings.engines.name', {
|
||||
defaultMessage: 'Enable Engines',
|
||||
}),
|
||||
requiresPageReload: false,
|
||||
schema: schema.boolean(),
|
||||
value: false,
|
||||
},
|
||||
};
|
||||
export const uiSettings: Record<string, UiSettingsParams<boolean>> = {};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue