From 2e3f333f6843d0b3067c277bc33f5f6b18ba589c Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 22 Mar 2021 10:31:52 -0700 Subject: [PATCH] [uiSettings/theme] restrict theme options based on KBN_OPTIMIZER_THEMES (#94834) Co-authored-by: spalger Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- src/core/server/ui_settings/settings/index.ts | 10 +++- .../server/ui_settings/settings/theme.test.ts | 54 +++++++++++++++++++ src/core/server/ui_settings/settings/theme.ts | 49 ++++++++++++++--- .../server/ui_settings/ui_settings_service.ts | 8 ++- 4 files changed, 112 insertions(+), 9 deletions(-) diff --git a/src/core/server/ui_settings/settings/index.ts b/src/core/server/ui_settings/settings/index.ts index 494ab2e01e7c7..944ada3a63e4f 100644 --- a/src/core/server/ui_settings/settings/index.ts +++ b/src/core/server/ui_settings/settings/index.ts @@ -15,14 +15,20 @@ import { getNotificationsSettings } from './notifications'; import { getThemeSettings } from './theme'; import { getStateSettings } from './state'; -export const getCoreSettings = (): Record => { +interface GetCoreSettingsOptions { + isDist?: boolean; +} + +export const getCoreSettings = ( + options?: GetCoreSettingsOptions +): Record => { return { ...getAccessibilitySettings(), ...getDateFormatSettings(), ...getMiscUiSettings(), ...getNavigationSettings(), ...getNotificationsSettings(), - ...getThemeSettings(), + ...getThemeSettings(options), ...getStateSettings(), }; }; diff --git a/src/core/server/ui_settings/settings/theme.test.ts b/src/core/server/ui_settings/settings/theme.test.ts index f0ca4f1eff4cd..58cbffb255b53 100644 --- a/src/core/server/ui_settings/settings/theme.test.ts +++ b/src/core/server/ui_settings/settings/theme.test.ts @@ -44,3 +44,57 @@ describe('theme settings', () => { }); }); }); + +describe('process.env.KBN_OPTIMIZER_THEMES handling', () => { + it('provides valid options based on tags', () => { + process.env.KBN_OPTIMIZER_THEMES = 'v7light,v8dark'; + let settings = getThemeSettings({ isDist: false }); + expect(settings['theme:version'].options).toEqual(['v7', 'v8']); + + process.env.KBN_OPTIMIZER_THEMES = 'v8dark,v7light'; + settings = getThemeSettings({ isDist: false }); + expect(settings['theme:version'].options).toEqual(['v7', 'v8']); + + process.env.KBN_OPTIMIZER_THEMES = 'v8dark,v7light,v7dark,v8light'; + settings = getThemeSettings({ isDist: false }); + expect(settings['theme:version'].options).toEqual(['v7', 'v8']); + + process.env.KBN_OPTIMIZER_THEMES = '*'; + settings = getThemeSettings({ isDist: false }); + expect(settings['theme:version'].options).toEqual(['v7', 'v8']); + + process.env.KBN_OPTIMIZER_THEMES = 'v7light'; + settings = getThemeSettings({ isDist: false }); + expect(settings['theme:version'].options).toEqual(['v7']); + + process.env.KBN_OPTIMIZER_THEMES = 'v8light'; + settings = getThemeSettings({ isDist: false }); + expect(settings['theme:version'].options).toEqual(['v8']); + }); + + it('defaults to properties of first tag', () => { + process.env.KBN_OPTIMIZER_THEMES = 'v8dark,v7light'; + let settings = getThemeSettings({ isDist: false }); + expect(settings['theme:darkMode'].value).toBe(true); + expect(settings['theme:version'].value).toBe('v8'); + + process.env.KBN_OPTIMIZER_THEMES = 'v7light,v8dark'; + settings = getThemeSettings({ isDist: false }); + expect(settings['theme:darkMode'].value).toBe(false); + expect(settings['theme:version'].value).toBe('v7'); + }); + + it('ignores the value when isDist is undefined', () => { + process.env.KBN_OPTIMIZER_THEMES = 'v7light'; + const settings = getThemeSettings({ isDist: undefined }); + expect(settings['theme:darkMode'].value).toBe(false); + expect(settings['theme:version'].options).toEqual(['v7', 'v8']); + }); + + it('ignores the value when isDist is true', () => { + process.env.KBN_OPTIMIZER_THEMES = 'v7light'; + const settings = getThemeSettings({ isDist: true }); + expect(settings['theme:darkMode'].value).toBe(false); + expect(settings['theme:version'].options).toEqual(['v7', 'v8']); + }); +}); diff --git a/src/core/server/ui_settings/settings/theme.ts b/src/core/server/ui_settings/settings/theme.ts index 35b8f0217c114..cc2919f7555c2 100644 --- a/src/core/server/ui_settings/settings/theme.ts +++ b/src/core/server/ui_settings/settings/theme.ts @@ -6,17 +6,54 @@ * Side Public License, v 1. */ -import { schema } from '@kbn/config-schema'; +import { schema, Type } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; import { UiSettingsParams } from '../../../types'; -export const getThemeSettings = (): Record => { +function parseThemeTags() { + if (!process.env.KBN_OPTIMIZER_THEMES) { + return ['v8light', 'v8dark']; + } + + if (process.env.KBN_OPTIMIZER_THEMES === '*') { + return ['v8light', 'v8dark', 'v7light', 'v7dark']; + } + + return process.env.KBN_OPTIMIZER_THEMES.split(',').map((t) => t.trim()); +} + +function getThemeInfo(options: GetThemeSettingsOptions) { + if (options?.isDist ?? true) { + return { + defaultDarkMode: false, + defaultVersion: 'v8', + availableVersions: ['v7', 'v8'], + }; + } + + const themeTags = parseThemeTags(); + return { + defaultDarkMode: themeTags[0].endsWith('dark'), + defaultVersion: themeTags[0].slice(0, 2), + availableVersions: ['v7', 'v8'].filter((v) => themeTags.some((t) => t.startsWith(v))), + }; +} + +interface GetThemeSettingsOptions { + isDist?: boolean; +} + +export const getThemeSettings = ( + options: GetThemeSettingsOptions = {} +): Record => { + const { availableVersions, defaultDarkMode, defaultVersion } = getThemeInfo(options); + return { 'theme:darkMode': { name: i18n.translate('core.ui_settings.params.darkModeTitle', { defaultMessage: 'Dark mode', }), - value: false, + value: defaultDarkMode, description: i18n.translate('core.ui_settings.params.darkModeText', { defaultMessage: `Enable a dark mode for the Kibana UI. A page refresh is required for the setting to be applied.`, }), @@ -27,14 +64,14 @@ export const getThemeSettings = (): Record => { name: i18n.translate('core.ui_settings.params.themeVersionTitle', { defaultMessage: 'Theme version', }), - value: 'v8', + value: defaultVersion, type: 'select', - options: ['v7', 'v8'], + options: availableVersions, description: i18n.translate('core.ui_settings.params.themeVersionText', { defaultMessage: `Switch between the theme used for the current and next version of Kibana. A page refresh is required for the setting to be applied.`, }), requiresPageReload: true, - schema: schema.oneOf([schema.literal('v7'), schema.literal('v8')]), + schema: schema.oneOf(availableVersions.map((v) => schema.literal(v)) as [Type]), }, }; }; diff --git a/src/core/server/ui_settings/ui_settings_service.ts b/src/core/server/ui_settings/ui_settings_service.ts index efa024e096599..93878d264541c 100644 --- a/src/core/server/ui_settings/ui_settings_service.ts +++ b/src/core/server/ui_settings/ui_settings_service.ts @@ -37,11 +37,13 @@ export class UiSettingsService implements CoreService { private readonly log: Logger; private readonly config$: Observable; + private readonly isDist: boolean; private readonly uiSettingsDefaults = new Map(); private overrides: Record = {}; constructor(private readonly coreContext: CoreContext) { this.log = coreContext.logger.get('ui-settings-service'); + this.isDist = coreContext.env.packageInfo.dist; this.config$ = coreContext.configService.atPath(uiConfigDefinition.path); } @@ -50,7 +52,11 @@ export class UiSettingsService savedObjects.registerType(uiSettingsType); registerRoutes(http.createRouter('')); - this.register(getCoreSettings()); + this.register( + getCoreSettings({ + isDist: this.isDist, + }) + ); const config = await this.config$.pipe(first()).toPromise(); this.overrides = config.overrides;