Skip to content

Commit

Permalink
CB-4652 migrate server configuration form (#2916)
Browse files Browse the repository at this point in the history
* CB-4652 migrate server configuration form

* CB-4652 review fixes

---------

Co-authored-by: Alexey <[email protected]>
Co-authored-by: mr-anton-t <[email protected]>
Co-authored-by: Evgenia Bezborodova <[email protected]>
  • Loading branch information
4 people authored Sep 25, 2024
1 parent 4b9e1c8 commit fe020f8
Show file tree
Hide file tree
Showing 27 changed files with 533 additions and 701 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/

export const ADMIN_USERNAME_MIN_LENGTH = 6;
1 change: 1 addition & 0 deletions webapp/packages/core-authentication/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ export * from './AUTH_SETTINGS_GROUP.js';
export * from './PasswordPolicyService.js';
export * from './TeamRolesResource.js';
export * from './TeamInfoMetaParametersResource.js';
export * from './ADMIN_USERNAME_MIN_LENGTH.js';
76 changes: 6 additions & 70 deletions webapp/packages/core-root/src/DefaultNavigatorSettingsResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { action, makeObservable, observable } from 'mobx';

import { injectable } from '@cloudbeaver/core-di';
import { CachedDataResource } from '@cloudbeaver/core-resource';
import { type DefaultNavigatorSettingsFragment, GraphQLService, type NavigatorSettingsInput } from '@cloudbeaver/core-sdk';
Expand All @@ -18,86 +16,24 @@ export type DefaultNavigatorSettings = DefaultNavigatorSettingsFragment['default

@injectable()
export class DefaultNavigatorSettingsResource extends CachedDataResource<DefaultNavigatorSettings | null> {
update: NavigatorSettingsInput;

constructor(
private readonly graphQLService: GraphQLService,
serverConfigResource: ServerConfigResource,
) {
super(() => null, undefined, []);
this.sync(serverConfigResource);

this.update = getDefaultNavigatorSettings();

makeObservable<this, 'syncUpdateData'>(this, {
update: observable,
unlinkUpdate: action,
syncUpdateData: action,
});
}

isChanged(): boolean {
if (!this.data) {
return false;
}

return !isNavigatorViewSettingsEqual(this.data, this.update);
}

setDataUpdate(update: NavigatorSettingsInput): void {
this.update = update;
}

resetUpdate(): void {
if (this.data) {
this.syncUpdateData(this.data);
}
}

unlinkUpdate(): void {
if (this.data) {
Object.assign(this.update, this.data);
} else {
this.update = getDefaultNavigatorSettings();
}
}

async save(): Promise<void> {
await this.performUpdate(
undefined,
undefined,
async () => {
await this.graphQLService.sdk.setDefaultNavigatorSettings({ settings: this.update });

this.setData(await this.loader());

this.onDataOutdated.execute();
},
() => !this.isChanged(),
);
async save(settings: NavigatorSettingsInput): Promise<void> {
await this.performUpdate(undefined, undefined, async () => {
await this.graphQLService.sdk.setDefaultNavigatorSettings({ settings });
this.setData(await this.loader());
this.onDataOutdated.execute();
});
}

protected async loader(): Promise<DefaultNavigatorSettings> {
const { defaultNavigatorSettings } = await this.graphQLService.sdk.getDefaultNavigatorSettings();

this.syncUpdateData(defaultNavigatorSettings.defaultNavigatorSettings);

return defaultNavigatorSettings.defaultNavigatorSettings;
}

private syncUpdateData(defaultNavigatorSettings: DefaultNavigatorSettings) {
Object.assign(this.update, defaultNavigatorSettings);
}
}

function getDefaultNavigatorSettings(): NavigatorSettingsInput {
return {
hideFolders: false,
hideSchemas: false,
hideVirtualModel: false,
mergeEntities: false,
showOnlyEntities: false,
showSystemObjects: false,
showUtilityObjects: false,
};
}
125 changes: 14 additions & 111 deletions webapp/packages/core-root/src/ServerConfigResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { action, makeObservable, observable } from 'mobx';

import { injectable } from '@cloudbeaver/core-di';
import { CachedDataResource } from '@cloudbeaver/core-resource';
import { GraphQLService, type ServerConfigFragment, type ServerConfigInput } from '@cloudbeaver/core-sdk';
Expand All @@ -22,8 +20,6 @@ export type ServerConfig = ServerConfigFragment;

@injectable()
export class ServerConfigResource extends CachedDataResource<ServerConfig | null> {
update: ServerConfigInput;

private readonly syncQueue: DataSynchronizationQueue;

constructor(
Expand All @@ -38,13 +34,6 @@ export class ServerConfigResource extends CachedDataResource<ServerConfig | null
this.markOutdated();
}
});
this.update = {};

makeObservable<this, 'syncUpdateData'>(this, {
update: observable,
unlinkUpdate: action,
syncUpdateData: action,
});

serverConfigEventHandler.on(
() => {
Expand Down Expand Up @@ -89,27 +78,27 @@ export class ServerConfigResource extends CachedDataResource<ServerConfig | null
}

get enabledFeatures(): string[] {
return this.update.enabledFeatures || this.data?.enabledFeatures || [];
return this.data?.enabledFeatures || [];
}

get enabledAuthProviders(): string[] {
return this.update.enabledAuthProviders || this.data?.enabledAuthProviders || [];
return this.data?.enabledAuthProviders || [];
}

get disabledDrivers(): string[] {
return this.update.disabledDrivers || this.data?.disabledDrivers || [];
return this.data?.disabledDrivers || [];
}

get credentialsSaveEnabled(): boolean {
return this.update.adminCredentialsSaveEnabled ?? this.data?.adminCredentialsSaveEnabled ?? false;
return this.data?.adminCredentialsSaveEnabled ?? false;
}

get userCredentialsSaveEnabled(): boolean {
return this.update.publicCredentialsSaveEnabled ?? this.data?.publicCredentialsSaveEnabled ?? false;
return this.data?.publicCredentialsSaveEnabled ?? false;
}

get resourceManagerEnabled() {
return this.update.resourceManagerEnabled ?? this.data?.resourceManagerEnabled ?? false;
return this.data?.resourceManagerEnabled ?? false;
}

isBetaFeatureDisabled(feature: string): boolean {
Expand All @@ -123,44 +112,6 @@ export class ServerConfigResource extends CachedDataResource<ServerConfig | null
return this.enabledFeatures.includes(feature);
}

isChanged(): boolean {
if (!this.data || Object.keys(this.update).length === 0) {
return false;
}

if (this.update.adminName || this.update.adminPassword) {
return true;
}

return (
this.update.serverName !== this.data.name ||
this.update.serverURL !== this.data.serverURL ||
this.update.sessionExpireTime !== this.data.sessionExpireTime ||
this.update.anonymousAccessEnabled !== this.data.anonymousAccessEnabled ||
this.update.resourceManagerEnabled !== this.data.resourceManagerEnabled ||
this.update.adminCredentialsSaveEnabled !== this.data.adminCredentialsSaveEnabled ||
this.update.publicCredentialsSaveEnabled !== this.data.publicCredentialsSaveEnabled ||
this.update.customConnectionsEnabled !== this.data.supportsCustomConnections ||
!isArraysEqual(this.update.enabledAuthProviders || [], this.data.enabledAuthProviders) ||
!isArraysEqual(this.update.enabledFeatures || [], this.data.enabledFeatures) ||
!isArraysEqual(this.update.disabledDrivers || [], this.data.disabledDrivers)
);
}

setDataUpdate(update: ServerConfigInput): void {
this.update = update;
}

resetUpdate(): void {
if (this.data) {
this.syncUpdateData(this.data);
}
}

unlinkUpdate(): void {
this.update = {};
}

async updateProductConfiguration(configuration: any) {
await this.performUpdate(undefined, undefined, async () => {
await this.graphQLService.sdk.updateProductConfiguration({ configuration });
Expand All @@ -169,67 +120,19 @@ export class ServerConfigResource extends CachedDataResource<ServerConfig | null
});
}

async save(): Promise<void> {
await this.performUpdate(
undefined,
undefined,
async () => {
await this.graphQLService.sdk.configureServer({
configuration: this.update,
});
this.setData(await this.loader());
this.onDataOutdated.execute();
},
() => !this.isChanged(),
);
}

async finishConfiguration(onlyRestart = false): Promise<void> {
await this.performUpdate(
undefined,
undefined,
async () => {
await this.graphQLService.sdk.configureServer({
configuration: !this.isChanged() && onlyRestart ? {} : this.update,
});
async save(configuration: ServerConfigInput): Promise<void> {
await this.performUpdate(undefined, undefined, async () => {
await this.graphQLService.sdk.configureServer({
configuration,
});

this.setData(await this.loader());
this.onDataOutdated.execute();
},
() => !this.isChanged() && !onlyRestart,
);
this.setData(await this.loader());
this.onDataOutdated.execute();
});
}

protected async loader(): Promise<ServerConfig> {
const { serverConfig } = await this.graphQLService.sdk.serverConfig();

this.syncUpdateData(serverConfig);

return serverConfig;
}

private syncUpdateData(serverConfig: ServerConfig) {
if (serverConfig.configurationMode) {
return;
}

this.update.serverName = serverConfig.name;
this.update.serverURL = serverConfig.serverURL;
this.update.sessionExpireTime = serverConfig.sessionExpireTime;

this.update.adminName = undefined;
this.update.adminPassword = undefined;

this.update.anonymousAccessEnabled = serverConfig.anonymousAccessEnabled;

this.update.adminCredentialsSaveEnabled = serverConfig.adminCredentialsSaveEnabled;
this.update.publicCredentialsSaveEnabled = serverConfig.publicCredentialsSaveEnabled;

this.update.resourceManagerEnabled = serverConfig.resourceManagerEnabled;

this.update.customConnectionsEnabled = serverConfig.supportsCustomConnections;
this.update.enabledAuthProviders = [...serverConfig.enabledAuthProviders];
this.update.enabledFeatures = [...serverConfig.enabledFeatures];
this.update.disabledDrivers = [...serverConfig.disabledDrivers];
}
}
1 change: 1 addition & 0 deletions webapp/packages/plugin-administration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@cloudbeaver/core-authentication": "^0",
"@cloudbeaver/core-blocks": "^0",
"@cloudbeaver/core-connections": "^0",
"@cloudbeaver/core-data-context": "^0",
"@cloudbeaver/core-di": "^0",
"@cloudbeaver/core-dialogs": "^0",
"@cloudbeaver/core-events": "^0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@
* you may not use this file except in compliance with the License.
*/
import { AdministrationItemService, AdministrationItemType, ConfigurationWizardService } from '@cloudbeaver/core-administration';
import { importLazyComponent } from '@cloudbeaver/core-blocks';
import { ConfirmationDialog, importLazyComponent } from '@cloudbeaver/core-blocks';
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { CommonDialogService, DialogueStateResult } from '@cloudbeaver/core-dialogs';
import { SessionDataResource } from '@cloudbeaver/core-root';
import { formValidationContext } from '@cloudbeaver/core-ui';

import { ADMINISTRATION_SERVER_CONFIGURATION_ITEM } from './ServerConfiguration/ADMINISTRATION_SERVER_CONFIGURATION_ITEM.js';
import { ServerConfigurationFormStateManager } from './ServerConfiguration/ServerConfigurationFormStateManager.js';
import { ServerConfigurationService } from './ServerConfiguration/ServerConfigurationService.js';

const FinishPage = importLazyComponent(() => import('./Finish/FinishPage.js').then(m => m.FinishPage));
Expand All @@ -28,7 +32,10 @@ export class ConfigurationWizardPagesBootstrapService extends Bootstrap {
constructor(
private readonly administrationItemService: AdministrationItemService,
private readonly configurationWizardService: ConfigurationWizardService,
private readonly serverConfigurationFormStateManager: ServerConfigurationFormStateManager,
private readonly commonDialogService: CommonDialogService,
private readonly serverConfigurationService: ServerConfigurationService,
private readonly sessionDataResource: SessionDataResource,
) {
super();
}
Expand All @@ -50,15 +57,51 @@ export class ConfigurationWizardPagesBootstrapService extends Bootstrap {
configurationWizardOptions: {
description: 'administration_configuration_wizard_configuration_step_description',
order: 1.5,
onLoad: this.serverConfigurationService.loadConfig.bind(this.serverConfigurationService),
isDone: this.serverConfigurationService.isDone.bind(this.serverConfigurationService),
onFinish: this.serverConfigurationService.saveConfiguration.bind(this.serverConfigurationService, false),
onConfigurationFinish: this.serverConfigurationService.saveConfiguration.bind(this.serverConfigurationService, true),
isDone: () => this.serverConfigurationService.isDone,
onFinish: async () => {
const state = this.serverConfigurationFormStateManager.formState;

if (state) {
const contexts = await state.validationTask.execute(state);
const validation = contexts.getContext(formValidationContext);

return validation.valid;
}

return true;
},
onConfigurationFinish: async () => {
await this.serverConfigurationFormStateManager.formState?.save();
await this.sessionDataResource.refresh();
},
onLoad: () => {
this.serverConfigurationFormStateManager.create();
},
},
order: 2,
onActivate: () => this.serverConfigurationService.activate(),
onDeActivate: this.serverConfigurationService.deactivate.bind(this.serverConfigurationService),
onLoad: this.serverConfigurationService.loadConfig.bind(this.serverConfigurationService, false),
onLoad: () => {
this.serverConfigurationFormStateManager.create();
},
canDeActivate: async configurationWizard => {
const state = this.serverConfigurationFormStateManager.formState;

if (state?.isSaving) {
return false;
}

if (!configurationWizard && state?.isChanged) {
const result = await this.commonDialogService.open(ConfirmationDialog, {
title: 'ui_save_reminder',
message: 'ui_are_you_sure',
});

if (result === DialogueStateResult.Rejected) {
return false;
}
}

return true;
},
getContentComponent: () => ServerConfigurationPage,
getDrawerComponent: () => ServerConfigurationDrawerItem,
});
Expand Down
Loading

0 comments on commit fe020f8

Please sign in to comment.