Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ export class PermissionControlledUiSettingsWrapper {
): Promise<SavedObjectsUpdateResponse<T>> => {
if (type === 'config' && id === DASHBOARD_ADMIN_SETTINGS_ID) {
try {
return ((await wrapperOptions.client.update<SavedObject<T>>(
return await wrapperOptions.client.update<T>(
type,
DASHBOARD_ADMIN_SETTINGS_ID,
attributes,
options
)) as unknown) as SavedObjectsUpdateResponse<T>;
);
} catch (error) {
if (SavedObjectsErrorHelpers.isNotFoundError(error)) {
return this.createPermissionUiSetting(attributes, options, wrapperOptions);
Expand Down
4 changes: 2 additions & 2 deletions src/core/server/ui_settings/ui_settings_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,10 @@ export class UiSettingsClient implements IUiSettingsClient {
this.log.warn(
`Deprecation warning: The setting "${key}" has multiple scopes. Please specify a scope when updating it.`
);
} else if (this.userLevelSettingsKeys.includes(key)) {
groupedChanges[UiSettingScope.USER][key] = val;
} else if (this.adminUiSettingsKeys.includes(key)) {
groupedChanges[UiSettingScope.DASHBOARD_ADMIN][key] = val;
} else if (this.userLevelSettingsKeys.includes(key)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the order matter? If yes, would be nice to add a comment or unit test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to maintain the existing logic hierarchy that the admin-level configurations should has higher privilege level as initiatively admin setting > user settings > workspace settings > global settings.

groupedChanges[UiSettingScope.USER][key] = val;
} else if (this.workspaceLevelSettingsKeys.includes(key)) {
groupedChanges[UiSettingScope.WORKSPACE][key] = val;
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/core/server/ui_settings/ui_settings_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ export class UiSettingsService
// Use uiSettings.defaults from the config file
this.validateAndUpdateConfiguredDefaults(config.uiSettingsConfig.defaults);

this.register(getAIFeaturesSetting());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, does the order matter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is just a minor improvement as for settings we should define what exists before we define how to control access to it


const permissionControlledUiSettingsWrapper = new PermissionControlledUiSettingsWrapper(
config.savedObjectsConfig.permission.enabled
);
Expand All @@ -111,8 +113,6 @@ export class UiSettingsService
permissionControlledUiSettingsWrapper.wrapperFactory
);

this.register(getAIFeaturesSetting());

return {
register: this.register.bind(this),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,16 @@ export class AdvancedSettingsComponent extends Component<
value: setting[1].userValue,
isCustom: config.isCustom(setting[0]),
isOverridden: config.isOverridden(setting[0]),
// Setting is permission controlled if:
// 1. It has DASHBOARD_ADMIN scope (string or array) AND
// 2. Current user is NOT a dashboard admin
// This prevents non-admin users from modifying admin-only settings
isPermissionControlled:
all[setting[0]].scope === UiSettingScope.DASHBOARD_ADMIN && !isDashboardAdmin,
((typeof all[setting[0]].scope === 'string' &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to add a comment to describe the logic, it's hard to read

all[setting[0]].scope === UiSettingScope.DASHBOARD_ADMIN) ||
(Array.isArray(all[setting[0]].scope) &&
(all[setting[0]].scope || []).includes(UiSettingScope.DASHBOARD_ADMIN))) &&
!isDashboardAdmin,
userSettingsEnabled,
});
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { i18n } from '@osd/i18n';
import { ENABLE_AI_FEATURES, HttpSetup } from 'opensearch-dashboards/public';
import React, { useCallback, useEffect, useState } from 'react';
import { BehaviorSubject, of } from 'rxjs';
import { BehaviorSubject, of, combineLatest } from 'rxjs';
import { useObservable } from 'react-use';
import { distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
import { DATA_STRUCTURE_META_TYPES, DEFAULT_DATA } from '../../../../data/common';
Expand Down Expand Up @@ -133,8 +133,8 @@ export const createQueryAssistExtension = (
}
},
isEnabled$: () =>
getAvailableLanguages$(http, data).pipe(
map((languages) => languages.length > 0 && assistantEnabled$.value)
combineLatest([getAvailableLanguages$(http, data), assistantEnabled$]).pipe(
map(([languages, assistantEnabled]) => languages.length > 0 && assistantEnabled)
),
getComponent: (dependencies) => {
// only show the component if user is on a supported language.
Expand Down