mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
# Backport This will backport the following commits from `main` to `8.8`: - [Fixing User Profiles/Kibana.yml config light mode precedence logic (#158177)](https://github.com/elastic/kibana/pull/158177) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Kurt","email":"kc13greiner@users.noreply.github.com"},"sourceCommit":{"committedDate":"2023-05-22T17:48:22Z","message":"Fixing User Profiles/Kibana.yml config light mode precedence logic (#158177)\n\n## Summary\r\n\r\nAfter changing the UserSettingService to calculate darkmode and return\r\n`boolean | undefined` , the Rendering service `darkMode` logic needed to\r\nbe updated to work when a User chooses 'Light' which provides a 'false'\r\nvalue to the Rendering service.\r\n\r\n## Testing\r\n\r\nFor Space Setting:\r\n\r\n1. Set Space Adv. Setting to darkMode: true\r\n2. Set User Profile Setting to 'Light'\r\n3. Observe that Light mode takes precedence\r\n\r\nFor Config setting:\r\n\r\n1. Set User Profile Setting to 'Dark'\r\n2. In `kibana.yml` set `uiSettings.overrides.theme:darkMode: false`\r\n3. Observe that Light mode takes precedence","sha":"613b2d5034fc703e1fb3c596e4ca2a648566b4c6","branchLabelMapping":{"^v8.9.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Security","v8.9.0","v8.8.1"],"number":158177,"url":"https://github.com/elastic/kibana/pull/158177","mergeCommit":{"message":"Fixing User Profiles/Kibana.yml config light mode precedence logic (#158177)\n\n## Summary\r\n\r\nAfter changing the UserSettingService to calculate darkmode and return\r\n`boolean | undefined` , the Rendering service `darkMode` logic needed to\r\nbe updated to work when a User chooses 'Light' which provides a 'false'\r\nvalue to the Rendering service.\r\n\r\n## Testing\r\n\r\nFor Space Setting:\r\n\r\n1. Set Space Adv. Setting to darkMode: true\r\n2. Set User Profile Setting to 'Light'\r\n3. Observe that Light mode takes precedence\r\n\r\nFor Config setting:\r\n\r\n1. Set User Profile Setting to 'Dark'\r\n2. In `kibana.yml` set `uiSettings.overrides.theme:darkMode: false`\r\n3. Observe that Light mode takes precedence","sha":"613b2d5034fc703e1fb3c596e4ca2a648566b4c6"}},"sourceBranch":"main","suggestedTargetBranches":["8.8"],"targetPullRequestStates":[{"branch":"main","label":"v8.9.0","labelRegex":"^v8.9.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/158177","number":158177,"mergeCommit":{"message":"Fixing User Profiles/Kibana.yml config light mode precedence logic (#158177)\n\n## Summary\r\n\r\nAfter changing the UserSettingService to calculate darkmode and return\r\n`boolean | undefined` , the Rendering service `darkMode` logic needed to\r\nbe updated to work when a User chooses 'Light' which provides a 'false'\r\nvalue to the Rendering service.\r\n\r\n## Testing\r\n\r\nFor Space Setting:\r\n\r\n1. Set Space Adv. Setting to darkMode: true\r\n2. Set User Profile Setting to 'Light'\r\n3. Observe that Light mode takes precedence\r\n\r\nFor Config setting:\r\n\r\n1. Set User Profile Setting to 'Dark'\r\n2. In `kibana.yml` set `uiSettings.overrides.theme:darkMode: false`\r\n3. Observe that Light mode takes precedence","sha":"613b2d5034fc703e1fb3c596e4ca2a648566b4c6"}},{"branch":"8.8","label":"v8.8.1","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Kurt <kc13greiner@users.noreply.github.com>
This commit is contained in:
parent
cfef093567
commit
670772197d
4 changed files with 182 additions and 16 deletions
|
@ -209,7 +209,7 @@ function renderDarkModeTestCases(
|
|||
});
|
||||
|
||||
describe('Dark Mode', () => {
|
||||
it('UserSettings value should override the space setting', async () => {
|
||||
it('UserSettings darkMode === true should override the space setting', async () => {
|
||||
mockRenderingSetupDeps.userSettings.getUserSettingDarkMode.mockReturnValueOnce(
|
||||
Promise.resolve(true)
|
||||
);
|
||||
|
@ -235,6 +235,32 @@ function renderDarkModeTestCases(
|
|||
});
|
||||
});
|
||||
|
||||
it('UserSettings darkMode === false should override the space setting', async () => {
|
||||
mockRenderingSetupDeps.userSettings.getUserSettingDarkMode.mockReturnValueOnce(
|
||||
Promise.resolve(false)
|
||||
);
|
||||
|
||||
getSettingValueMock.mockImplementation((settingName: string) => {
|
||||
if (settingName === 'theme:darkMode') {
|
||||
return true;
|
||||
}
|
||||
return settingName;
|
||||
});
|
||||
|
||||
const settings = { 'theme:darkMode': { userValue: false } };
|
||||
uiSettings.client.getUserProvided.mockResolvedValue(settings);
|
||||
|
||||
const [render] = await getRender();
|
||||
await render(createKibanaRequest(), uiSettings);
|
||||
|
||||
expect(getStylesheetPathsMock).toHaveBeenCalledWith({
|
||||
darkMode: false,
|
||||
themeVersion: 'v8',
|
||||
basePath: '/mock-server-basepath',
|
||||
buildNum: expect.any(Number),
|
||||
});
|
||||
});
|
||||
|
||||
it('Space setting value should be used if UsersSettings value is undefined', async () => {
|
||||
mockRenderingSetupDeps.userSettings.getUserSettingDarkMode.mockReturnValueOnce(
|
||||
Promise.resolve(undefined)
|
||||
|
@ -258,6 +284,102 @@ function renderDarkModeTestCases(
|
|||
buildNum: expect.any(Number),
|
||||
});
|
||||
});
|
||||
|
||||
it('config `theme:darkMode: true` setting should override User Settings theme `darkMode === false', async () => {
|
||||
mockRenderingSetupDeps.userSettings.getUserSettingDarkMode.mockReturnValueOnce(
|
||||
Promise.resolve(false)
|
||||
);
|
||||
getSettingValueMock.mockImplementation((settingName: string) => {
|
||||
if (settingName === 'theme:darkMode') {
|
||||
return true;
|
||||
}
|
||||
return settingName;
|
||||
});
|
||||
|
||||
const settings = { 'theme:darkMode': { userValue: true, isOverridden: true } };
|
||||
uiSettings.client.getUserProvided.mockResolvedValue(settings);
|
||||
const [render] = await getRender();
|
||||
await render(createKibanaRequest(), uiSettings);
|
||||
|
||||
expect(getStylesheetPathsMock).toHaveBeenCalledWith({
|
||||
darkMode: true,
|
||||
themeVersion: 'v8',
|
||||
basePath: '/mock-server-basepath',
|
||||
buildNum: expect.any(Number),
|
||||
});
|
||||
});
|
||||
|
||||
it('config `theme:darkMode: false` setting should override User Settings theme `darkMode === true', async () => {
|
||||
mockRenderingSetupDeps.userSettings.getUserSettingDarkMode.mockReturnValueOnce(
|
||||
Promise.resolve(true)
|
||||
);
|
||||
getSettingValueMock.mockImplementation((settingName: string) => {
|
||||
if (settingName === 'theme:darkMode') {
|
||||
return false;
|
||||
}
|
||||
return settingName;
|
||||
});
|
||||
|
||||
const settings = { 'theme:darkMode': { userValue: false, isOverridden: true } };
|
||||
uiSettings.client.getUserProvided.mockResolvedValue(settings);
|
||||
const [render] = await getRender();
|
||||
await render(createKibanaRequest(), uiSettings);
|
||||
|
||||
expect(getStylesheetPathsMock).toHaveBeenCalledWith({
|
||||
darkMode: false,
|
||||
themeVersion: 'v8',
|
||||
basePath: '/mock-server-basepath',
|
||||
buildNum: expect.any(Number),
|
||||
});
|
||||
});
|
||||
|
||||
it('config `theme:darkMode: false` setting should override User Settings theme `darkMode === undefined', async () => {
|
||||
mockRenderingSetupDeps.userSettings.getUserSettingDarkMode.mockReturnValueOnce(
|
||||
Promise.resolve(undefined)
|
||||
);
|
||||
getSettingValueMock.mockImplementation((settingName: string) => {
|
||||
if (settingName === 'theme:darkMode') {
|
||||
return false;
|
||||
}
|
||||
return settingName;
|
||||
});
|
||||
|
||||
const settings = { 'theme:darkMode': { userValue: false, isOverridden: true } };
|
||||
uiSettings.client.getUserProvided.mockResolvedValue(settings);
|
||||
const [render] = await getRender();
|
||||
await render(createKibanaRequest(), uiSettings);
|
||||
|
||||
expect(getStylesheetPathsMock).toHaveBeenCalledWith({
|
||||
darkMode: false,
|
||||
themeVersion: 'v8',
|
||||
basePath: '/mock-server-basepath',
|
||||
buildNum: expect.any(Number),
|
||||
});
|
||||
});
|
||||
|
||||
it('config `theme:darkMode: true` setting should override User Settings theme `darkMode === undefined', async () => {
|
||||
mockRenderingSetupDeps.userSettings.getUserSettingDarkMode.mockReturnValueOnce(
|
||||
Promise.resolve(undefined)
|
||||
);
|
||||
getSettingValueMock.mockImplementation((settingName: string) => {
|
||||
if (settingName === 'theme:darkMode') {
|
||||
return true;
|
||||
}
|
||||
return settingName;
|
||||
});
|
||||
|
||||
const settings = { 'theme:darkMode': { userValue: true, isOverridden: true } };
|
||||
uiSettings.client.getUserProvided.mockResolvedValue(settings);
|
||||
const [render] = await getRender();
|
||||
await render(createKibanaRequest(), uiSettings);
|
||||
|
||||
expect(getStylesheetPathsMock).toHaveBeenCalledWith({
|
||||
darkMode: true,
|
||||
themeVersion: 'v8',
|
||||
basePath: '/mock-server-basepath',
|
||||
buildNum: expect.any(Number),
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -167,7 +167,9 @@ export class RenderingService {
|
|||
|
||||
let darkMode: boolean;
|
||||
|
||||
if (userSettingDarkMode) {
|
||||
const isThemeOverridden = settings.user['theme:darkMode']?.isOverridden ?? false;
|
||||
|
||||
if (userSettingDarkMode !== undefined && !isThemeOverridden) {
|
||||
darkMode = userSettingDarkMode;
|
||||
} else {
|
||||
darkMode = getSettingValue('theme:darkMode', settings, Boolean);
|
||||
|
|
|
@ -310,7 +310,7 @@ describe('useUserProfileForm', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should be disabled if the theme has been set in the config', () => {
|
||||
it('should be disabled if the theme has been set to `darkMode: true` in the config', () => {
|
||||
const data: UserProfileData = {};
|
||||
|
||||
const nonCloudUser = mockAuthenticatedUser({ elastic_cloud_user: false });
|
||||
|
@ -336,5 +336,32 @@ describe('useUserProfileForm', () => {
|
|||
expect(darkModeButton).toBeTruthy();
|
||||
expect(darkModeButton.getDOMNode()).toHaveProperty('disabled');
|
||||
});
|
||||
|
||||
it('should be disabled if the theme has been set to `darkMode: false` in the config', () => {
|
||||
const data: UserProfileData = {};
|
||||
|
||||
const nonCloudUser = mockAuthenticatedUser({ elastic_cloud_user: false });
|
||||
coreStart.settings.client.get.mockReturnValueOnce(false);
|
||||
coreStart.settings.client.isOverridden.mockReturnValueOnce(true);
|
||||
|
||||
const testWrapper = mount(
|
||||
<Providers
|
||||
services={coreStart}
|
||||
theme$={theme$}
|
||||
history={history}
|
||||
authc={authc}
|
||||
securityApiClients={{
|
||||
userProfiles: new UserProfileAPIClient(coreStart.http),
|
||||
users: new UserAPIClient(coreStart.http),
|
||||
}}
|
||||
>
|
||||
<UserProfile user={nonCloudUser} data={data} />
|
||||
</Providers>
|
||||
);
|
||||
|
||||
const darkModeButton = testWrapper.find('EuiButtonGroup[data-test-subj="darkModeButton"]');
|
||||
expect(darkModeButton).toBeTruthy();
|
||||
expect(darkModeButton.getDOMNode()).toHaveProperty('disabled');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -144,10 +144,12 @@ function UserDetailsEditor({ user }: { user: AuthenticatedUser }) {
|
|||
|
||||
function UserSettingsEditor({
|
||||
formik,
|
||||
isDarkModeOverride,
|
||||
isThemeOverridden,
|
||||
isOverriddenThemeDarkMode,
|
||||
}: {
|
||||
formik: ReturnType<typeof useUserProfileForm>;
|
||||
isDarkModeOverride: boolean;
|
||||
isThemeOverridden: boolean;
|
||||
isOverriddenThemeDarkMode: boolean;
|
||||
}) {
|
||||
if (!formik.values.data) {
|
||||
return null;
|
||||
|
@ -155,8 +157,12 @@ function UserSettingsEditor({
|
|||
|
||||
let idSelected = formik.values.data.userSettings.darkMode;
|
||||
|
||||
if (isDarkModeOverride) {
|
||||
idSelected = 'dark';
|
||||
if (isThemeOverridden) {
|
||||
if (isOverriddenThemeDarkMode) {
|
||||
idSelected = 'dark';
|
||||
} else {
|
||||
idSelected = 'light';
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -180,7 +186,7 @@ function UserSettingsEditor({
|
|||
>
|
||||
<FormRow
|
||||
name="data.userSettings.darkMode"
|
||||
helpText={renderHelpText(isDarkModeOverride)}
|
||||
helpText={renderHelpText(isThemeOverridden)}
|
||||
label={
|
||||
<FormLabel for="data.userSettings.darkMode">
|
||||
<FormattedMessage
|
||||
|
@ -201,7 +207,7 @@ function UserSettingsEditor({
|
|||
buttonSize="m"
|
||||
data-test-subj="darkModeButton"
|
||||
idSelected={idSelected}
|
||||
isDisabled={isDarkModeOverride}
|
||||
isDisabled={isThemeOverridden}
|
||||
options={[
|
||||
{
|
||||
id: '',
|
||||
|
@ -546,7 +552,9 @@ export const UserProfile: FunctionComponent<UserProfileProps> = ({ user, data })
|
|||
|
||||
const isCloudUser = user.elastic_cloud_user;
|
||||
|
||||
const isDarkModeOverride = determineIfDarkModeOverride(services.settings.client);
|
||||
const { isThemeOverridden, isOverriddenThemeDarkMode } = determineIfThemeOverridden(
|
||||
services.settings.client
|
||||
);
|
||||
|
||||
const rightSideItems = [
|
||||
{
|
||||
|
@ -675,7 +683,11 @@ export const UserProfile: FunctionComponent<UserProfileProps> = ({ user, data })
|
|||
onShowPasswordForm={() => setShowChangePasswordForm(true)}
|
||||
/>
|
||||
{isCloudUser ? null : (
|
||||
<UserSettingsEditor formik={formik} isDarkModeOverride={isDarkModeOverride} />
|
||||
<UserSettingsEditor
|
||||
formik={formik}
|
||||
isThemeOverridden={isThemeOverridden}
|
||||
isOverriddenThemeDarkMode={isOverriddenThemeDarkMode}
|
||||
/>
|
||||
)}
|
||||
</Form>
|
||||
</EuiPageTemplate>
|
||||
|
@ -910,9 +922,12 @@ function renderHelpText(isOverridden: boolean) {
|
|||
}
|
||||
}
|
||||
|
||||
function determineIfDarkModeOverride(settingsClient: IUiSettingsClient) {
|
||||
const isThemeOverridden = settingsClient.isOverridden('theme:darkMode');
|
||||
const isOverriddenThemeDarkMode = settingsClient.get<boolean>('theme:darkMode');
|
||||
|
||||
return isThemeOverridden && isOverriddenThemeDarkMode;
|
||||
function determineIfThemeOverridden(settingsClient: IUiSettingsClient): {
|
||||
isThemeOverridden: boolean;
|
||||
isOverriddenThemeDarkMode: boolean;
|
||||
} {
|
||||
return {
|
||||
isThemeOverridden: settingsClient.isOverridden('theme:darkMode'),
|
||||
isOverriddenThemeDarkMode: settingsClient.get<boolean>('theme:darkMode'),
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue