Cb 3536 add settings panel (#1787)

* CB-3536 add settings panel

* CB-3536 filter settings by group

* CB-3536 PR fixes, add settings to panel

* CB-3536 export settings group

* CB-3536 add translations, fix indentation

* CB-3536 refactor translations

---------

Co-authored-by: dariamarutkina <125263541+dariamarutkina@users.noreply.github.com>
This commit is contained in:
Tatiana Fokina
2023-06-30 15:22:20 +04:00
committed by GitHub
co-authored by dariamarutkina
parent a8e8f7ef33
commit ba48b282fd
74 changed files with 901 additions and 40 deletions
@@ -19,7 +19,7 @@ export class AdministrationSettingsService {
readonly settings: PluginSettings<AdministrationSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getCoreSettings('administration', defaultSettings);
this.settings = this.pluginManagerService.createSettings('administration', 'core', defaultSettings);
}
isBase(feature: string): boolean {
@@ -0,0 +1,24 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { createSettingsGroup, FormFieldType, SettingsData } from '@cloudbeaver/core-settings';
export const AUTH_SETTINGS_GROUP = createSettingsGroup('settings_authentication');
export const settings: SettingsData = {
scopeType: 'core',
scope: 'authentication',
settingsData: [
{
key: 'disableAnonymousAccess',
type: FormFieldType.Checkbox,
name: 'settings_authentication_disable_anonymous_access_name',
description: 'settings_authentication_disable_anonymous_access_description',
groupId: AUTH_SETTINGS_GROUP.id,
},
],
};
@@ -7,6 +7,9 @@
*/
import { injectable } from '@cloudbeaver/core-di';
import { PluginManagerService, PluginSettings } from '@cloudbeaver/core-plugin';
import { SettingsManagerService } from '@cloudbeaver/core-settings';
import { AUTH_SETTINGS_GROUP, settings } from './AUTH_SETTINGS_GROUP';
const defaultSettings = {
baseAuthProvider: undefined as undefined | string,
@@ -20,7 +23,10 @@ export type AuthSettings = typeof defaultSettings;
export class AuthSettingsService {
readonly settings: PluginSettings<AuthSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getCoreSettings('authentication', defaultSettings);
constructor(private readonly pluginManagerService: PluginManagerService, settingsManagerService: SettingsManagerService) {
this.settings = this.pluginManagerService.createSettings('authentication', 'core', defaultSettings);
settingsManagerService.addGroup(AUTH_SETTINGS_GROUP);
settingsManagerService.addSettings(settings.scopeType, settings.scope, settings.settingsData);
}
}
@@ -0,0 +1,35 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { LocalizationService } from '@cloudbeaver/core-localization';
@injectable()
export class LocaleService extends Bootstrap {
constructor(private readonly localizationService: LocalizationService) {
super();
}
register(): void | Promise<void> {
this.localizationService.addProvider(this.provider.bind(this));
}
load(): void | Promise<void> {}
private async provider(locale: string) {
switch (locale) {
case 'ru':
return (await import('./locales/ru')).default;
case 'it':
return (await import('./locales/it')).default;
case 'zh':
return (await import('./locales/zh')).default;
default:
return (await import('./locales/en')).default;
}
}
}
@@ -19,3 +19,4 @@ export * from './UserMetaParametersResource';
export * from './UsersResource';
export * from './TeamMetaParametersResource';
export * from './EAdminPermission';
export * from './AUTH_SETTINGS_GROUP';
@@ -0,0 +1,5 @@
export default [
['settings_authentication', 'Authentication'],
['settings_authentication_disable_anonymous_access_name', 'Disable anonymous access'],
['settings_authentication_disable_anonymous_access_description', 'Disable anonymous access function'],
];
@@ -0,0 +1,5 @@
export default [
['settings_authentication', 'Authentication'],
['settings_authentication_disable_anonymous_access_name', 'Disable anonymous access'],
['settings_authentication_disable_anonymous_access_description', 'Disable anonymous access function'],
];
@@ -0,0 +1,5 @@
export default [
['settings_authentication', 'Аутентификация'],
['settings_authentication_disable_anonymous_access_name', 'Отключить анонимный доступ'],
['settings_authentication_disable_anonymous_access_description', 'Отключить функцию анонимного доступа'],
];
@@ -0,0 +1,5 @@
export default [
['settings_authentication', 'Authentication'],
['settings_authentication_disable_anonymous_access_name', 'Disable anonymous access'],
['settings_authentication_disable_anonymous_access_description', 'Disable anonymous access function'],
];
@@ -15,6 +15,7 @@ import { AuthProviderService } from './AuthProviderService';
import { AuthProvidersResource } from './AuthProvidersResource';
import { AuthRolesResource } from './AuthRolesResource';
import { AuthSettingsService } from './AuthSettingsService';
import { LocaleService } from './LocaleService';
import { TeamMetaParametersResource } from './TeamMetaParametersResource';
import { TeamsManagerService } from './TeamsManagerService';
import { TeamsResource } from './TeamsResource';
@@ -46,5 +47,6 @@ export const manifest: PluginManifest = {
UserConfigurationBootstrap,
AuthRolesResource,
TeamMetaParametersResource,
LocaleService,
],
};
@@ -29,7 +29,7 @@ export class BrowserSettingsService {
readonly deprecatedSettings: PluginSettings<DeprecatedCookiesSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getCoreSettings('browser', defaultSettings);
this.deprecatedSettings = this.pluginManagerService.getCoreSettings('cookies', deprecatedDefaultSettings);
this.settings = this.pluginManagerService.createSettings('browser', 'core', defaultSettings);
this.deprecatedSettings = this.pluginManagerService.createSettings('cookies', 'core', deprecatedDefaultSettings);
}
}
@@ -19,6 +19,6 @@ export class ConnectionsSettingsService {
readonly settings: PluginSettings<ConnectionsSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getCoreSettings('connections', defaultSettings);
this.settings = this.pluginManagerService.createSettings('connections', 'core', defaultSettings);
}
}
@@ -22,7 +22,7 @@ export class EventsSettingsService {
readonly deprecatedSettings: PluginSettings<EventsSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('notifications', defaultSettings);
this.settings = this.pluginManagerService.createSettings('notifications', 'plugin', defaultSettings);
this.deprecatedSettings = this.pluginManagerService.getDeprecatedPluginSettings('core_events', defaultSettings);
}
}
@@ -71,8 +71,8 @@ export class LocalizationService extends Bootstrap {
this.settings = getDefaultLocalizationSettings();
this.onChange = new SyncExecutor();
this.pluginSettings = this.pluginManagerService.getCoreSettings('localization', defaultThemeSettings);
this.deprecatedPluginSettings = this.pluginManagerService.getCoreSettings('user', defaultThemeSettings);
this.pluginSettings = this.pluginManagerService.createSettings('localization', 'core', defaultThemeSettings);
this.deprecatedPluginSettings = this.pluginManagerService.createSettings('user', 'core', defaultThemeSettings);
sessionResource.onDataUpdate.addHandler(this.syncLanguage.bind(this));
this.onChange.addHandler(key => {
@@ -22,6 +22,6 @@ export class NavTreeSettingsService {
readonly settings: PluginSettings<NavTreeSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getCoreSettings('navigation-tree', defaultSettings);
this.settings = this.pluginManagerService.createSettings('navigation-tree', 'core', defaultSettings);
}
}
@@ -7,24 +7,32 @@
*/
import { injectable } from '@cloudbeaver/core-di';
import { ProductManagerService } from '@cloudbeaver/core-product';
import type { SettingsScopeType } from '@cloudbeaver/core-settings';
import { PluginSettings } from './PluginSettings';
@injectable()
export class PluginManagerService {
constructor(private readonly productManagerService: ProductManagerService) {}
getCoreSettings<T>(scope: string, defaults: T) {
return new PluginSettings(this.productManagerService.settings, 'core.' + scope, defaults);
store: Map<string, PluginSettings<any>>;
constructor(private readonly productManagerService: ProductManagerService) {
this.store = new Map();
}
getPluginSettings<T>(scope: string, defaults: T) {
return new PluginSettings(this.productManagerService.settings, 'plugin.' + scope, defaults);
createSettings<T>(scope: string, scopeType: SettingsScopeType, defaults: T) {
const key = scopeType + '.' + scope;
const settings = new PluginSettings(this.productManagerService.settings, key, defaults);
this.store.set(key, settings);
return settings;
}
getSettings(scope: string, scopeType: SettingsScopeType): PluginSettings<any> | undefined {
return this.store.get(scopeType + '.' + scope);
}
/**
* Please use getPluginSettings instead
* @deprecated Please use getPluginSettings instead, will be removed in 23.0.0
* Please use createSettings instead
* @deprecated Please use createSettings instead, will be removed in 23.0.0
*/
getDeprecatedPluginSettings<T>(scope: string, defaults: T) {
return new PluginSettings(this.productManagerService.settings, scope, defaults);
+1 -1
View File
@@ -22,4 +22,4 @@
"peerDependencies": {
"mobx": "~6.x.x"
}
}
}
@@ -0,0 +1,73 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { injectable } from '@cloudbeaver/core-di';
export enum FormFieldType {
Checkbox,
Combobox,
Textarea,
Input,
}
export interface SettingsGroupType {
id: string;
name: string;
}
export interface SettingsOptions {
id: string | number;
name: string;
}
export type SettingsScopeType = 'plugin' | 'core';
export interface SettingsData {
scopeType: SettingsScopeType;
scope: string;
settingsData: ScopeSettingsItemOptions[];
}
export interface ScopeSettingsItem extends ScopeSettingsItemOptions {
scopeType: SettingsScopeType;
scope: string;
}
interface ScopeSettingsItemOptions {
key: string;
type: FormFieldType;
name: string;
groupId: string;
description?: string;
options?: SettingsOptions[];
}
@injectable()
export class SettingsManagerService {
settings: ScopeSettingsItem[];
groups: Map<string, SettingsGroupType>;
constructor() {
this.settings = [];
this.groups = new Map();
}
addSettings(scopeType: SettingsScopeType, scope: string, settings: ScopeSettingsItemOptions[]) {
this.settings.push(...settings.map(item => ({ ...item, scopeType, scope })));
}
addGroup(group: SettingsGroupType) {
this.groups.set(group.id, group);
}
deleteSettings(scope: string, scopeType: string, key: string) {
this.settings = this.settings.filter(
settingsItem => settingsItem.scope !== scope && settingsItem.scopeType !== scopeType && settingsItem.key !== key,
);
}
}
@@ -0,0 +1,14 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { uuid } from '@cloudbeaver/core-utils';
import type { SettingsGroupType } from './SettingsManagerService';
export function createSettingsGroup(name: string): SettingsGroupType {
return { name, id: uuid() };
}
@@ -1,6 +1,8 @@
export { manifest as coreSettingsManifest } from './manifest';
export * from './createSettingsGroup';
export * from './SettingsService';
export * from './LocalStorageSaveService';
export * from './SettingsManagerService';
export * from './SettingsSource';
export * from './SettingsResolverSource';
export * from './ISettingsResolverSource';
@@ -8,6 +8,7 @@
import type { PluginManifest } from '@cloudbeaver/core-di';
import { LocalStorageSaveService } from './LocalStorageSaveService';
import { SettingsManagerService } from './SettingsManagerService';
import { SettingsService } from './SettingsService';
export const manifest: PluginManifest = {
@@ -15,5 +16,5 @@ export const manifest: PluginManifest = {
name: 'Core Settings',
},
providers: [SettingsService, LocalStorageSaveService],
providers: [SettingsService, LocalStorageSaveService, SettingsManagerService],
};
@@ -0,0 +1,35 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { LocalizationService } from '@cloudbeaver/core-localization';
@injectable()
export class LocaleService extends Bootstrap {
constructor(private readonly localizationService: LocalizationService) {
super();
}
register(): void | Promise<void> {
this.localizationService.addProvider(this.provider.bind(this));
}
load(): void | Promise<void> {}
private async provider(locale: string) {
switch (locale) {
case 'ru':
return (await import('./locales/ru')).default;
case 'it':
return (await import('./locales/it')).default;
case 'zh':
return (await import('./locales/zh')).default;
default:
return (await import('./locales/en')).default;
}
}
}
@@ -0,0 +1,27 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { createSettingsGroup, FormFieldType, SettingsData } from '@cloudbeaver/core-settings';
import { themes } from './themes';
export const THEME_SETTINGS_GROUP = createSettingsGroup('settings_theming');
export const settings: SettingsData = {
scopeType: 'core',
scope: 'theming',
settingsData: [
{
key: 'defaultTheme',
type: FormFieldType.Combobox,
name: 'settings_theming_default_theme_name',
description: 'settings_theming_default_theme_description',
options: themes.map(theme => ({ id: theme.id, name: theme.name })),
groupId: THEME_SETTINGS_GROUP.id,
},
],
};
@@ -7,7 +7,9 @@
*/
import { injectable } from '@cloudbeaver/core-di';
import { PluginManagerService, PluginSettings } from '@cloudbeaver/core-plugin';
import { SettingsManagerService } from '@cloudbeaver/core-settings';
import { settings, THEME_SETTINGS_GROUP } from './THEME_SETTINGS_GROUP';
import { themes } from './themes';
export interface IThemeSettings {
@@ -24,8 +26,11 @@ export class ThemeSettingsService {
/** @deprecated Use settings instead, will be removed in 23.0.0 */
readonly deprecatedSettings: PluginSettings<IThemeSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getCoreSettings('theming', defaultThemeSettings);
this.deprecatedSettings = this.pluginManagerService.getCoreSettings('user', defaultThemeSettings);
constructor(private readonly pluginManagerService: PluginManagerService, settingsManagerService: SettingsManagerService) {
this.settings = this.pluginManagerService.createSettings('theming', 'core', defaultThemeSettings);
this.deprecatedSettings = this.pluginManagerService.createSettings('user', 'core', defaultThemeSettings);
settingsManagerService.addGroup(THEME_SETTINGS_GROUP);
settingsManagerService.addSettings(settings.scopeType, settings.scope, settings.settingsData);
}
}
@@ -3,3 +3,4 @@ export * from './ComponentStyle';
export * from './ThemeService';
export * from './themeUtils';
export * from './ThemeSettingsService';
export * from './THEME_SETTINGS_GROUP';
@@ -0,0 +1,5 @@
export default [
['settings_theming', 'Theme'],
['settings_theming_default_theme_name', 'Default Theme'],
['settings_theming_default_theme_description', 'Default Theme'],
];
@@ -0,0 +1,5 @@
export default [
['settings_theming', 'Theme'],
['settings_theming_default_theme_name', 'Default Theme'],
['settings_theming_default_theme_description', 'Default Theme'],
];
@@ -0,0 +1,5 @@
export default [
['settings_theming', 'Тема'],
['settings_theming_default_theme_name', 'Тема по умолчанию'],
['settings_theming_default_theme_description', 'Тема по умолчанию'],
];
@@ -0,0 +1,5 @@
export default [
['settings_theming', 'Theme'],
['settings_theming_default_theme_name', 'Default Theme'],
['settings_theming_default_theme_description', 'Default Theme'],
];
+2 -1
View File
@@ -7,6 +7,7 @@
*/
import type { PluginManifest } from '@cloudbeaver/core-di';
import { LocaleService } from './LocaleService';
import { ThemeService } from './ThemeService';
import { ThemeSettingsService } from './ThemeSettingsService';
@@ -15,5 +16,5 @@ export const manifest: PluginManifest = {
name: 'Core Theming',
},
providers: [ThemeService, ThemeSettingsService],
providers: [ThemeService, ThemeSettingsService, LocaleService],
};
@@ -21,6 +21,6 @@ export class CustomConnectionSettingsService {
readonly settings: PluginSettings<Settings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('connection-custom', settings);
this.settings = this.pluginManagerService.createSettings('connection-custom', 'plugin', settings);
}
}
@@ -21,6 +21,6 @@ export class ConnectionSearchSettingsService {
readonly settings: PluginSettings<Settings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('connection-search', settings);
this.settings = this.pluginManagerService.createSettings('connection-search', 'plugin', settings);
}
}
@@ -0,0 +1,24 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { createSettingsGroup, FormFieldType, type SettingsData } from '@cloudbeaver/core-settings';
export const CONNECTIONS_SETTINGS_GROUP = createSettingsGroup('settings_connections');
export const settings: SettingsData = {
scopeType: 'plugin',
scope: 'connections',
settingsData: [
{
key: 'hideConnectionViewForUsers',
type: FormFieldType.Checkbox,
name: 'settings_connections_hide_connections_view_name',
description: 'settings_connections_hide_connections_view_description',
groupId: CONNECTIONS_SETTINGS_GROUP.id,
},
],
};
@@ -7,6 +7,9 @@
*/
import { injectable } from '@cloudbeaver/core-di';
import { PluginManagerService, PluginSettings } from '@cloudbeaver/core-plugin';
import { SettingsManagerService } from '@cloudbeaver/core-settings';
import { CONNECTIONS_SETTINGS_GROUP, settings } from './CONNECTIONS_SETTINGS_GROUP';
const defaultSettings = {
hideConnectionViewForUsers: false,
@@ -18,7 +21,10 @@ export type PluginConnectionsSettings = typeof defaultSettings;
export class PluginConnectionsSettingsService {
readonly settings: PluginSettings<PluginConnectionsSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('connections', defaultSettings);
constructor(private readonly pluginManagerService: PluginManagerService, settingsManagerService: SettingsManagerService) {
this.settings = this.pluginManagerService.createSettings('connections', 'plugin', defaultSettings);
settingsManagerService.addGroup(CONNECTIONS_SETTINGS_GROUP);
settingsManagerService.addSettings(settings.scopeType, settings.scope, settings.settingsData);
}
}
@@ -21,5 +21,6 @@ export * from './ContextMenu/MENU_CONNECTIONS';
export * from './PublicConnectionForm/PublicConnectionFormService';
export * from './ConnectionAuthService';
export * from './PluginConnectionsSettingsService';
export * from './CONNECTIONS_SETTINGS_GROUP';
export default connectionPlugin;
@@ -15,4 +15,7 @@ export default [
['connections_public_connection_folder_delete_confirmation', 'You\'re going to delete "{arg:name}". Connections won\'t be deleted. Are you sure?'],
['plugin_connections_menu_connections_label', 'Connection'],
['plugin_connections_action_disconnect_all_label', 'Disconnect All'],
['settings_connections', 'Connections'],
['settings_connections_hide_connections_view_name', 'Show connections to admins only'],
['settings_connections_hide_connections_view_description', 'Show connections to admins only'],
];
@@ -17,4 +17,7 @@ export default [
['connections_public_connection_folder_delete_confirmation', 'You\'re going to delete "{arg:name}". Connections won\'t be deleted. Are you sure?'],
['plugin_connections_menu_connections_label', 'Connessione'],
['plugin_connections_action_disconnect_all_label', 'Scollegati da tutto'],
['settings_connections', 'Connections'],
['settings_connections_hide_connections_view_name', 'Show connections to admins only'],
['settings_connections_hide_connections_view_description', 'Show connections to admins only'],
];
@@ -14,4 +14,7 @@ export default [
['connections_public_connection_folder_delete_confirmation', 'Вы удаляете "{arg:name}". Подключения не будут удалены. Вы уверены?'],
['plugin_connections_menu_connections_label', 'Подключение'],
['plugin_connections_action_disconnect_all_label', 'Отключить все'],
['settings_connections', 'Подключения'],
['settings_connections_hide_connections_view_name', 'Показывать подключения только администраторам'],
['settings_connections_hide_connections_view_description', 'Показывать подключения только администраторам'],
];
@@ -14,4 +14,7 @@ export default [
['connections_public_connection_folder_delete_confirmation', 'You\'re going to delete "{arg:name}". Connections won\'t be deleted. Are you sure?'],
['plugin_connections_menu_connections_label', '连接'],
['plugin_connections_action_disconnect_all_label', '断开所有连接'],
['settings_connections', 'Connections'],
['settings_connections_hide_connections_view_name', 'Show connections to admins only'],
['settings_connections_hide_connections_view_description', 'Show connections to admins only'],
];
@@ -21,7 +21,7 @@ export class DataExportSettingsService {
readonly deprecatedSettings: PluginSettings<DataExportSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('data-export', defaultSettings);
this.settings = this.pluginManagerService.createSettings('data-export', 'plugin', defaultSettings);
this.deprecatedSettings = this.pluginManagerService.getDeprecatedPluginSettings('plugin_data_export', defaultSettings);
}
}
@@ -21,7 +21,7 @@ export class DataGridSettingsService {
readonly deprecatedSettings: PluginSettings<typeof defaultSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('data-spreadsheet', defaultSettings);
this.settings = this.pluginManagerService.createSettings('data-spreadsheet', 'plugin', defaultSettings);
this.deprecatedSettings = this.pluginManagerService.getDeprecatedPluginSettings('plugin_data_spreadsheet_new', defaultSettings);
}
}
@@ -46,4 +46,4 @@
"reshadow": "~0.x.x",
"@testing-library/jest-dom": "~5.x.x"
}
}
}
@@ -0,0 +1,45 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { createSettingsGroup, FormFieldType, SettingsData } from '@cloudbeaver/core-settings';
export const DATA_EDITOR_SETTINGS_GROUP = createSettingsGroup('settings_data_editor');
export const settings: SettingsData = {
scopeType: 'plugin',
scope: 'data-viewer',
settingsData: [
{
key: 'disableEdit',
type: FormFieldType.Checkbox,
name: 'settings_data_editor_disable_edit_name',
description: 'settings_data_editor_disable_edit_description',
groupId: DATA_EDITOR_SETTINGS_GROUP.id,
},
{
key: 'fetchMin',
type: FormFieldType.Input,
name: 'settings_data_editor_fetch_min_name',
description: 'settings_data_editor_fetch_min_description',
groupId: DATA_EDITOR_SETTINGS_GROUP.id,
},
{
key: 'fetchMax',
type: FormFieldType.Input,
name: 'settings_data_editor_fetch_max_name',
description: 'settings_data_editor_fetch_max_description',
groupId: DATA_EDITOR_SETTINGS_GROUP.id,
},
{
key: 'fetchDefault',
type: FormFieldType.Input,
name: 'settings_data_editor_fetch_default_name',
description: 'settings_data_editor_fetch_default_description',
groupId: DATA_EDITOR_SETTINGS_GROUP.id,
},
],
};
@@ -7,6 +7,9 @@
*/
import { injectable } from '@cloudbeaver/core-di';
import { PluginManagerService, PluginSettings } from '@cloudbeaver/core-plugin';
import { SettingsManagerService } from '@cloudbeaver/core-settings';
import { DATA_EDITOR_SETTINGS_GROUP, settings } from './DATA_EDITOR_SETTINGS_GROUP';
const defaultSettings = {
disableEdit: false,
@@ -23,9 +26,12 @@ export class DataViewerSettingsService {
/** @deprecated Use settings instead, will be removed in 23.0.0 */
readonly deprecatedSettings: PluginSettings<typeof defaultSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('data-viewer', defaultSettings);
constructor(private readonly pluginManagerService: PluginManagerService, private readonly settingsManagerService: SettingsManagerService) {
this.settings = this.pluginManagerService.createSettings('data-viewer', 'plugin', defaultSettings);
this.deprecatedSettings = this.pluginManagerService.getDeprecatedPluginSettings('core.app.dataViewer', defaultSettings);
settingsManagerService.addGroup(DATA_EDITOR_SETTINGS_GROUP);
settingsManagerService.addSettings(settings.scopeType, settings.scope, settings.settingsData);
}
getMaxFetchSize(): number {
@@ -60,3 +60,4 @@ export * from './DataViewerDataChangeConfirmationService';
export * from './useDataModel';
export * from './ValuePanelPresentation/BooleanValue/isBooleanValuePresentationAvailable';
export * from './DataViewerSettingsService';
export * from './DATA_EDITOR_SETTINGS_GROUP';
@@ -40,4 +40,13 @@ export default [
['data_viewer_script_preview_dialog_title', 'Preview changes'],
['data_viewer_script_preview_error_title', "Can't get the script"],
['data_viewer_refresh_result_set', 'Refresh result set'],
['settings_data_editor', 'Data Editor'],
['settings_data_editor_disable_edit_name', 'Disable Edit'],
['settings_data_editor_disable_edit_description', 'Disable Edit'],
['settings_data_editor_fetch_min_name', 'Minimum fetch size'],
['settings_data_editor_fetch_min_description', 'Minimum number of rows to fetch'],
['settings_data_editor_fetch_max_name', 'Maximum fetch size'],
['settings_data_editor_fetch_max_description', 'Maximum number of rows to fetch'],
['settings_data_editor_fetch_default_name', 'Default fetch size'],
['settings_data_editor_fetch_default_description', 'Default number of rows to fetch'],
];
@@ -33,4 +33,13 @@ export default [
['data_viewer_presentation_value_content_value_size', 'Value size'],
['data_viewer_presentation_value_content_download_error', 'Download failed'],
['data_viewer_refresh_result_set', 'Refresh result set'],
['settings_data_editor', 'Data Editor'],
['settings_data_editor_disable_edit_name', 'Disable Edit'],
['settings_data_editor_disable_edit_description', 'Disable Edit'],
['settings_data_editor_fetch_min_name', 'Minimum fetch size'],
['settings_data_editor_fetch_min_description', 'Minimum number of rows to fetch'],
['settings_data_editor_fetch_max_name', 'Maximum fetch size'],
['settings_data_editor_fetch_max_description', 'Maximum number of rows to fetch'],
['settings_data_editor_fetch_default_name', 'Default fetch size'],
['settings_data_editor_fetch_default_description', 'Default number of rows to fetch'],
];
@@ -36,4 +36,13 @@ export default [
['data_viewer_script_preview_dialog_title', 'Предпросмотр изменений'],
['data_viewer_script_preview_error_title', 'Не удалось получить скрипт'],
['data_viewer_refresh_result_set', 'Обновить резалт сет'],
['settings_data_editor', 'Редактор данных'],
['settings_data_editor_disable_edit_name', 'Отключить редактирование'],
['settings_data_editor_disable_edit_description', 'Отключить редактирование'],
['settings_data_editor_fetch_min_name', 'Минимальный размер выборки'],
['settings_data_editor_fetch_min_description', 'Минимальное количество строк для выборки'],
['settings_data_editor_fetch_max_name', 'Максимальный размер выборки'],
['settings_data_editor_fetch_max_description', 'Максимальное количество строк для выборки'],
['settings_data_editor_fetch_default_name', 'Размер выборки по умолчанию'],
['settings_data_editor_fetch_default_description', 'Количество строк для выборки по умолчанию'],
];
@@ -40,4 +40,13 @@ export default [
['data_viewer_script_preview_dialog_title', '预览更改'],
['data_viewer_script_preview_error_title', '无法获取脚本'],
['data_viewer_refresh_result_set', 'Refresh result set'],
['settings_data_editor', 'Data Editor'],
['settings_data_editor_disable_edit_name', 'Disable Edit'],
['settings_data_editor_disable_edit_description', 'Disable Edit'],
['settings_data_editor_fetch_min_name', 'Minimum fetch size'],
['settings_data_editor_fetch_min_description', 'Minimum number of rows to fetch'],
['settings_data_editor_fetch_max_name', 'Maximum fetch size'],
['settings_data_editor_fetch_max_description', 'Maximum number of rows to fetch'],
['settings_data_editor_fetch_default_name', 'Default fetch size'],
['settings_data_editor_fetch_default_description', 'Default number of rows to fetch'],
];
@@ -23,6 +23,6 @@ export class LogViewerSettingsService {
readonly settings: PluginSettings<LogViewerSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('log-viewer', defaultSettings);
this.settings = this.pluginManagerService.createSettings('log-viewer', 'plugin', defaultSettings);
}
}
@@ -25,7 +25,7 @@ export class NavigationTreeSettingsService {
readonly settings: PluginSettings<NavigationTreeSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('navigation-tree', defaultSettings);
this.settings = this.pluginManagerService.createSettings('navigation-tree', 'plugin', defaultSettings);
makeObservable(this, {
disabled: computed,
@@ -19,6 +19,6 @@ export class ResourceManagerScriptsSettingsService {
readonly settings: PluginSettings<Settings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('resource-manager-scripts', settings);
this.settings = this.pluginManagerService.createSettings('resource-manager-scripts', 'plugin', settings);
}
}
@@ -21,7 +21,7 @@ export class ResourceManagerSettingsService {
readonly deprecatedSettings: PluginSettings<ResourceManagerSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('resource-manager', defaultSettings);
this.settings = this.pluginManagerService.createSettings('resource-manager', 'plugin', defaultSettings);
this.deprecatedSettings = this.pluginManagerService.getDeprecatedPluginSettings('plugin_resource_manager', defaultSettings);
}
}
@@ -0,0 +1,17 @@
# dependencies
/node_modules
# testing
/coverage
# production
/lib
# misc
.DS_Store
.env*
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
@@ -0,0 +1,36 @@
{
"name": "@cloudbeaver/plugin-settings-panel",
"sideEffects": false,
"version": "0.1.0",
"description": "",
"license": "Apache-2.0",
"main": "lib/index.js",
"module": "lib/index.js",
"types": "src/index.ts",
"scripts": {
"prebuild": "rimraf --glob lib/*",
"build": "webpack --config ../../configs/webpack.plugin.config.js",
"postbuild": "tsc",
"lint": "eslint ./src/ --ext .ts,.tsx",
"lint-fix": "eslint ./src/ --ext .ts,.tsx --fix",
"test": "core-cli-test",
"validate-dependencies": "core-cli-validate-dependencies"
},
"dependencies": {
"@cloudbeaver/core-blocks": "~0.1.0",
"@cloudbeaver/core-utils": "~0.1.0",
"@cloudbeaver/core-di": "~0.1.0",
"@cloudbeaver/core-ui": "~0.1.0",
"@cloudbeaver/core-plugin": "~0.1.0",
"@cloudbeaver/core-settings": "~0.1.0",
"@cloudbeaver/core-localization": "~0.1.0",
"@cloudbeaver/core-authentication": "~0.1.0",
"@cloudbeaver/core-view": "~0.1.0",
"@cloudbeaver/plugin-settings-menu": "~0.1.0"
},
"peerDependencies": {
"mobx-react-lite": "~3.x.x",
"react": "~18.x.x",
"reshadow": "~0.x.x"
}
}
@@ -0,0 +1,35 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { LocalizationService } from '@cloudbeaver/core-localization';
@injectable()
export class LocaleService extends Bootstrap {
constructor(private readonly localizationService: LocalizationService) {
super();
}
register(): void | Promise<void> {
this.localizationService.addProvider(this.provider.bind(this));
}
load(): void | Promise<void> {}
private async provider(locale: string) {
switch (locale) {
case 'ru':
return (await import('./locales/ru')).default;
case 'it':
return (await import('./locales/it')).default;
case 'zh':
return (await import('./locales/zh')).default;
default:
return (await import('./locales/en')).default;
}
}
}
@@ -0,0 +1,51 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import React from 'react';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, Group, GroupTitle, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { PluginManagerService } from '@cloudbeaver/core-plugin';
import { SettingsGroupType, SettingsManagerService, SettingsScopeType } from '@cloudbeaver/core-settings';
import { SettingsInfoForm } from './SettingsInfoForm';
interface Props {
group: SettingsGroupType;
}
export const SettingsGroup = observer<Props>(function SettingsGroup({ group }) {
const settingsManagerService = useService(SettingsManagerService);
const pluginManagerService = useService(PluginManagerService);
const translate = useTranslate();
function getValue(scope: string, scopeType: SettingsScopeType, key: string) {
const settings = pluginManagerService.getSettings(scope, scopeType);
return settings?.getValue(key);
}
const settings = settingsManagerService.settings
.filter(settingsItem => settingsItem.groupId === group.id)
.map(settingsItem => ({
...settingsItem,
value: getValue(settingsItem.scope, settingsItem.scopeType, settingsItem.key),
name: translate(settingsItem.name),
description: translate(settingsItem.description),
options: settingsItem.options?.map(option => ({ ...option, name: translate(option.name) })),
}));
return styled(BASE_CONTAINERS_STYLES)(
<Group gap vertical>
<GroupTitle keepSize large>
{translate(group.name)}
</GroupTitle>
<SettingsInfoForm fields={settings} readOnly />
</Group>,
);
});
@@ -0,0 +1,60 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import { TextPlaceholder, useTranslate } from '@cloudbeaver/core-blocks';
import type { FormFieldType } from '@cloudbeaver/core-settings';
import { SettingsInfoFormField } from './SettingsInfoFormField';
interface SettingsProps {
key: string;
type: FormFieldType;
disabled?: boolean;
value?: any;
options?: any[];
description?: string;
name?: string;
}
interface SettingsInfoFormProps {
fields: SettingsProps[];
className?: string;
readOnly?: boolean;
onSelect?: (value: any) => void;
onChange?: (value: any) => void;
}
export const SettingsInfoForm = observer<SettingsInfoFormProps>(function SettingsInfoForm({ fields, className, readOnly, onChange, onSelect }) {
const translate = useTranslate();
if (fields.length === 0) {
return <TextPlaceholder>{translate('settings_panel_empty_fields')}</TextPlaceholder>;
}
return (
<>
{fields.map(field => (
<SettingsInfoFormField
key={field.key}
id={field.key}
type={field.type}
value={field.value}
options={field.options}
description={field.description}
name={field.name}
disabled={field.disabled}
readOnly={readOnly}
className={className}
onChange={onChange}
onSelect={onSelect}
/>
))}
</>
);
});
@@ -0,0 +1,102 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import { Combobox, FieldCheckbox, InputField, Textarea } from '@cloudbeaver/core-blocks';
import { FormFieldType } from '@cloudbeaver/core-settings';
export interface SettingsInfoFormFieldProps {
id: string;
type: FormFieldType;
disabled?: boolean;
value?: any;
options?: any[];
description?: string;
name?: string;
className?: string;
readOnly?: boolean;
onSelect?: (value: any) => void;
onChange?: (value: any) => void;
}
export const SettingsInfoFormField = observer<SettingsInfoFormFieldProps>(function SettingsInfoFormField({
id,
type,
value,
description,
disabled,
name,
className,
readOnly,
options,
onSelect,
onChange,
}) {
if (type === FormFieldType.Checkbox) {
return (
<FieldCheckbox id={id} checked={value} title={description} disabled={disabled || readOnly} className={className} onChange={onChange}>
{name ?? ''}
</FieldCheckbox>
);
}
if (type === FormFieldType.Combobox && options !== undefined) {
return (
<Combobox
id={id}
items={options}
keySelector={value => value.id}
valueSelector={value => value.name}
value={value}
title={description}
disabled={disabled}
readOnly={readOnly}
className={className}
onSelect={onSelect}
>
{name ?? ''}
</Combobox>
);
}
if (type === FormFieldType.Textarea) {
return (
<Textarea
id={id}
title={value}
labelTooltip={description || name}
value={value}
disabled={disabled}
readOnly={readOnly}
mod="surface"
className={className}
onChange={onChange}
>
{name ?? ''}
</Textarea>
);
}
return (
<InputField
id={id}
type="text"
title={value}
labelTooltip={description || name}
value={value}
description={description}
disabled={disabled}
readOnly={readOnly}
mod="surface"
className={className}
onChange={onChange}
>
{name ?? ''}
</InputField>
);
});
@@ -0,0 +1,44 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import React from 'react';
import styled, { css } from 'reshadow';
import { BASE_CONTAINERS_STYLES, ColoredContainer, Container, useStyles } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { SettingsManagerService } from '@cloudbeaver/core-settings';
import { SettingsGroup } from './SettingsGroup';
const styles = css`
content {
height: 100%;
display: flex;
flex-direction: column;
overflow: auto;
}
`;
export const SettingsPanelForm = observer(function SettingsPanelForm() {
const style = useStyles(BASE_CONTAINERS_STYLES, styles);
const settingsManagerService = useService(SettingsManagerService);
const groups = Array.from(settingsManagerService.groups);
return styled(style)(
<content>
<ColoredContainer gap overflow parent>
<Container medium gap vertical overflow>
{groups.map(([_, group]) => (
<SettingsGroup key={group.id} group={group} />
))}
</Container>
</ColoredContainer>
</content>,
);
});
@@ -0,0 +1,46 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { AuthInfoService } from '@cloudbeaver/core-authentication';
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { OptionsPanelService } from '@cloudbeaver/core-ui';
import { ActionService, DATA_CONTEXT_MENU, MenuService } from '@cloudbeaver/core-view';
import { TOP_NAV_BAR_SETTINGS_MENU } from '@cloudbeaver/plugin-settings-menu';
import { ACTION_OPEN_APP_SETTINGS } from './actions/ACTION_OPEN_APP_SETTINGS';
import { SettingsPanelForm } from './SettingsPanel/SettingsPanelForm';
@injectable()
export class SettingsPanelPluginBootstrap extends Bootstrap {
constructor(
private readonly menuService: MenuService,
private readonly optionsPanelService: OptionsPanelService,
private readonly authInfoService: AuthInfoService,
private readonly actionService: ActionService,
) {
super();
}
register(): void | Promise<void> {
this.addTopAppMenuItems();
}
load(): void | Promise<void> {}
private addTopAppMenuItems() {
this.actionService.addHandler({
id: 'open-app-settings',
isActionApplicable: (context, action) => ACTION_OPEN_APP_SETTINGS === action,
handler: () => this.optionsPanelService.open(() => SettingsPanelForm),
});
this.menuService.addCreator({
isApplicable: context => context.get(DATA_CONTEXT_MENU) === TOP_NAV_BAR_SETTINGS_MENU && !!this.authInfoService.userInfo,
getItems: (context, items) => [...items, ACTION_OPEN_APP_SETTINGS],
});
}
}
@@ -0,0 +1,13 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { createAction } from '@cloudbeaver/core-view';
export const ACTION_OPEN_APP_SETTINGS = createAction('open-app-settings', {
label: 'settings_panel',
tooltip: 'settings_panel',
});
@@ -0,0 +1,6 @@
import { settingsPanelPlugin } from './manifest';
export * from './SettingsPanel/SettingsInfoFormField';
export * from './SettingsPanel/SettingsInfoForm';
export default settingsPanelPlugin;
@@ -0,0 +1,4 @@
export default [
['settings_panel', 'Settings'],
['settings_panel_empty_fields', 'Fields are empty'],
];
@@ -0,0 +1,4 @@
export default [
['settings_panel', 'Settings'],
['settings_panel_empty_fields', 'Fields are empty'],
];
@@ -0,0 +1,4 @@
export default [
['settings_panel', 'Настройки'],
['settings_panel_empty_fields', 'Поля пустые'],
];
@@ -0,0 +1,4 @@
export default [
['settings_panel', 'Settings'],
['settings_panel_empty_fields', 'Fields are empty'],
];
@@ -0,0 +1,16 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import type { PluginManifest } from '@cloudbeaver/core-di';
import { LocaleService } from './LocaleService';
import { SettingsPanelPluginBootstrap } from './SettingsPanelPluginBootstrap';
export const settingsPanelPlugin: PluginManifest = {
info: { name: 'Settings panel plugin' },
providers: [SettingsPanelPluginBootstrap, LocaleService],
};
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "lib"
},
"include": ["src"],
"exclude": ["**/node_modules", "**/.*/"],
"references": [{ "path": "../*" }]
}
@@ -17,6 +17,6 @@ export class ResourceEditorSettingsService {
readonly settings: PluginSettings<ResourceEditorSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('sql-editor-navigation-tab-resource', defaultSettings);
this.settings = this.pluginManagerService.createSettings('sql-editor-navigation-tab-resource', 'plugin', defaultSettings);
}
}
@@ -22,7 +22,7 @@ export class SqlEditorSettingsService {
readonly deprecatedSettings: PluginSettings<SqlEditorSettings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('sql-editor', defaultSettings);
this.settings = this.pluginManagerService.createSettings('sql-editor', 'plugin', defaultSettings);
this.deprecatedSettings = this.pluginManagerService.getDeprecatedPluginSettings('core.app.sqlEditor', defaultSettings);
}
}
@@ -19,6 +19,6 @@ export class ToolsPanelSettingsService {
readonly settings: PluginSettings<Settings>;
constructor(private readonly pluginManagerService: PluginManagerService) {
this.settings = this.pluginManagerService.getPluginSettings('tools-panel', settings);
this.settings = this.pluginManagerService.createSettings('tools-panel', 'plugin', settings);
}
}
@@ -56,6 +56,7 @@
"@cloudbeaver/plugin-root": "~0.1.0",
"@cloudbeaver/plugin-settings-menu": "~0.1.0",
"@cloudbeaver/plugin-settings-menu-administration": "~0.1.0",
"@cloudbeaver/plugin-settings-panel": "~0.1.0",
"@cloudbeaver/plugin-sql-editor": "~0.1.0",
"@cloudbeaver/plugin-sql-editor-navigation-tab": "~0.1.0",
"@cloudbeaver/plugin-sql-editor-navigation-tab-script": "~0.1.0",
@@ -34,6 +34,7 @@ import resourceManagerScripts from '@cloudbeaver/plugin-resource-manager-scripts
import root from '@cloudbeaver/plugin-root';
import settingsMenu from '@cloudbeaver/plugin-settings-menu';
import settingsMenuAdministration from '@cloudbeaver/plugin-settings-menu-administration';
import settingsPanelPlugin from '@cloudbeaver/plugin-settings-panel';
import sqlEditor from '@cloudbeaver/plugin-sql-editor';
import sqlEditorTab from '@cloudbeaver/plugin-sql-editor-navigation-tab';
import sqlEditorResource from '@cloudbeaver/plugin-sql-editor-navigation-tab-script';
@@ -81,6 +82,7 @@ const PLUGINS: PluginManifest[] = [
productPlugin,
settingsMenu,
settingsMenuAdministration,
settingsPanelPlugin,
help,
resourceManager,
resourceManagerAdministration,