feat(plugin-administration): CB-718 CB-719 blank license page

This commit is contained in:
Wroud
2021-02-17 13:37:11 +03:00
parent bd535c9945
commit 2c2a6e6ced
11 changed files with 346 additions and 5 deletions
@@ -43,7 +43,7 @@ export class ConfigurationWizardPagesBootstrapService extends Bootstrap {
type: AdministrationItemType.Default,
configurationWizardOptions: {
description: 'administration_configuration_wizard_configuration_step_description',
order: 1.1,
order: 1.5,
isDone: this.serverConfigurationService.isDone.bind(this.serverConfigurationService),
onFinish: this.serverConfigurationService.validate.bind(this.serverConfigurationService),
onConfigurationFinish: this.serverConfigurationService.handleConfigurationFinish.bind(
@@ -83,13 +83,13 @@ export class ServerConfigurationService {
};
};
async save(): Promise<boolean> {
async save(): Promise<void> {
if (!this.state) {
throw new Error('No state available');
}
if (!(await this.validate())) {
return false;
return;
}
try {
@@ -102,8 +102,6 @@ export class ServerConfigurationService {
});
await this.serverConfigResource.update();
this.usersResource.refreshAllLazy();
return true;
} catch (exception) {
this.notificationService.logException(exception, 'Can\'t save server configuration');
@@ -0,0 +1,43 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2021 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 { AdministrationItemService, AdministrationItemType } from '@cloudbeaver/core-administration';
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { AdministrationLicensePageService } from './AdministrationLicensePageService';
import { LicenseDrawerItem } from './LicenseDrawerItem';
import { LicensePage } from './LicensePage';
@injectable()
export class AdministrationLicensePageBootstrapService extends Bootstrap {
constructor(
private readonly administrationItemService: AdministrationItemService,
private readonly administrationLicensePageService: AdministrationLicensePageService
) {
super();
}
register(): void {
this.administrationItemService.create({
name: 'license',
type: AdministrationItemType.Default,
configurationWizardOptions: {
description: 'administration_configuration_wizard_license_step_description',
order: 1.2,
isDone: this.administrationLicensePageService.isDone.bind(this.administrationLicensePageService),
onFinish: this.administrationLicensePageService.save.bind(this.administrationLicensePageService),
},
order: 5,
onActivate: this.administrationLicensePageService.loadConfig.bind(this.administrationLicensePageService),
getContentComponent: () => LicensePage,
getDrawerComponent: () => LicenseDrawerItem,
});
}
load(): void { }
}
@@ -0,0 +1,118 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2021 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 { makeObservable, observable } from 'mobx';
import { AdministrationScreenService } from '@cloudbeaver/core-administration';
import { injectable } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';
import { Executor, IExecutor } from '@cloudbeaver/core-executor';
import { ServerConfigResource } from '@cloudbeaver/core-root';
import type { ILicensePageState } from './ILicensePageState';
export interface IValidationStatusContext {
getState: () => boolean;
invalidate: () => void;
}
@injectable()
export class AdministrationLicensePageService {
state: ILicensePageState;
loading: boolean;
readonly validationTask: IExecutor<boolean>;
constructor(
private readonly administrationScreenService: AdministrationScreenService,
private readonly serverConfigResource: ServerConfigResource,
private readonly notificationService: NotificationService,
) {
makeObservable(this, {
state: observable,
loading: observable,
});
this.loading = true;
this.state = this.getConfig();
this.validationTask = new Executor();
}
isDone(): boolean {
return this.isFormFilled();
}
validationStatusContext = (): IValidationStatusContext => {
let state = this.isFormFilled();
const invalidate = () => {
state = false;
};
const getState = () => state;
return {
getState,
invalidate,
};
};
async save(): Promise<boolean> {
if (!this.state) {
throw new Error('No state available');
}
if (!(await this.validate())) {
return false;
}
return true;
}
async validate(): Promise<boolean> {
const context = await this.validationTask.execute(true);
const state = await context.getContext(this.validationStatusContext);
return state.getState();
}
private isFormFilled() {
if ((this.state?.license.length || 0) < 6) {
return false;
}
return true;
}
async loadConfig(): Promise<void> {
this.loading = true;
try {
const config = await this.serverConfigResource.load();
this.state = this.administrationScreenService
.getItemState(
'license',
this.getConfig.bind(this),
!config?.configurationMode,
value => {
if (typeof value === 'object' && typeof value.license === 'string') {
return true;
}
return false;
}
);
} catch (exception) {
this.notificationService.logException(exception, 'Can\'t load server configuration');
} finally {
this.loading = false;
}
}
private getConfig(): ILicensePageState {
return {
license: '',
};
}
}
@@ -0,0 +1,11 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2021 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 interface ILicensePageState {
license: string;
}
@@ -0,0 +1,25 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2021 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 styled from 'reshadow';
import type { AdministrationItemDrawerProps } from '@cloudbeaver/core-administration';
import { Tab, TabTitle, TabIcon } from '@cloudbeaver/core-blocks';
import { Translate } from '@cloudbeaver/core-localization';
import { useStyles } from '@cloudbeaver/core-theming';
export const LicenseDrawerItem: React.FC<AdministrationItemDrawerProps> = function LicenseDrawerItem({
item, onSelect, style, disabled,
}) {
return styled(useStyles(...style))(
<Tab tabId={item.name} disabled={disabled} onOpen={() => onSelect(item.name)}>
<TabIcon icon='/icons/welcome_bold.svg' viewBox='0 0 16 16' />
<TabTitle><Translate token='administration_configuration_wizard_license' /></TabTitle>
</Tab>
);
};
@@ -0,0 +1,133 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2021 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 { useCallback } from 'react';
import styled, { use, css } from 'reshadow';
import { AdministrationItemContentComponent, ConfigurationWizardService } from '@cloudbeaver/core-administration';
import { FormBox, FormBoxElement, FormGroup, InputField, Loader, SubmittingForm, useFocus } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { useFormValidator } from '@cloudbeaver/core-executor';
import { Translate, useTranslate } from '@cloudbeaver/core-localization';
import { useStyles, composes } from '@cloudbeaver/core-theming';
import { AdministrationLicensePageService } from './AdministrationLicensePageService';
const styles = composes(
css`
layout-grid-cell {
composes: theme-background-surface theme-text-on-surface from global;
}
layout-grid-cell, message-box {
composes: theme-border-color-background from global;
}
`,
css`
layout-grid {
width: 100%;
flex: 1;
}
layout-grid-inner {
min-height: 100%;
}
layout-grid-cell {
position: relative;
border: solid 1px;
padding: 16px 24px
}
message-box {
border-bottom: solid 1px;
}
message-box, SubmittingForm {
padding: 16px 24px;
}
SubmittingForm {
flex: 1;
display: flex;
overflow: auto;
flex-direction: column;
}
FormBox {
flex: 0;
}
p {
line-height: 2;
}
`
);
export const LicensePage: AdministrationItemContentComponent = observer(function LicensePage({
configurationWizard,
}) {
const translate = useTranslate();
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
const licensePageService = useService(AdministrationLicensePageService);
const configurationWizardService = useService(ConfigurationWizardService);
const handleSave = useCallback(async () => {
if (configurationWizard) {
await configurationWizardService.next();
} else {
await licensePageService.save();
}
}, []);
useFormValidator(licensePageService.validationTask, focusedRef);
return styled(useStyles(styles))(
<layout-grid as="div">
<layout-grid-inner as="div">
<layout-grid-cell as='div' {...use({ span: 12 })}>
<message-box as='div'>
<h3><Translate token='administration_configuration_wizard_welcome_title' /></h3>
<p><Translate token='administration_configuration_wizard_welcome_message' /></p>
</message-box>
{configurationWizard && (
<SubmittingForm ref={focusedRef} name='license' onSubmit={handleSave}>
{licensePageService.loading ? (
<Loader />
) : (
<>
<FormBox>
<FormBoxElement>
<FormGroup>
<InputField
type="text"
name="license"
state={licensePageService.state}
mod='surface'
minLength={6}
required
long
>
{translate('administration_configuration_wizard_license_key')}
</InputField>
</FormGroup>
</FormBoxElement>
<FormBoxElement />
<FormBoxElement />
</FormBox>
</>
)}
</SubmittingForm>
)}
</layout-grid-cell>
</layout-grid-inner>
</layout-grid>
);
});
@@ -7,3 +7,4 @@ export * from './ConfigurationWizard/ServerConfiguration/Form/ServerConfiguratio
export * from './ConfigurationWizard/ServerConfiguration/Form/ServerConfigurationInfoForm';
export * from './ConfigurationWizard/ServerConfiguration/Form/ServerConfigurationNavigatorViewForm';
export * from './ConfigurationWizard/ServerConfiguration/Form/ServerConfigurationSecurityForm';
export * from './Pages/License/AdministrationLicensePageService';
@@ -6,6 +6,10 @@ export default [
['administration_configuration_wizard_welcome_title', 'Welcome to CloudBeaver, cloud database management system!'],
['administration_configuration_wizard_welcome_message', 'The easy configuration wizard will guide you through several simple steps to set up the CloudBeaver server. You will need to set server information and administrator credentials. You can also add first database connections here.'],
['administration_configuration_wizard_welcome_note', 'Note: you will be able to change these configuration parameters later on the administration panel.'],
['administration_configuration_wizard_license', 'License'],
['administration_configuration_wizard_license_step_description', 'License setup'],
['administration_configuration_wizard_license_title', 'Please enter you License Key..'],
['administration_configuration_wizard_license_key', 'License Key'],
['administration_configuration_wizard_configuration', 'Server configuration'],
['administration_configuration_wizard_configuration_step_description', 'Main server configuration'],
['administration_configuration_wizard_configuration_title', 'You can configure the main server parameters here.'],
@@ -1,4 +1,8 @@
export default [
['administration_configuration_wizard_license', 'Лицензия'],
['administration_configuration_wizard_license_step_description', 'Настройка лицензии'],
['administration_configuration_wizard_license_title', 'Пожалуйста укажите лицензию...'],
['administration_configuration_wizard_license_key', 'Ключ'],
['administration_configuration_wizard_configuration', 'Настройки сервера'],
['administration_configuration_wizard_configuration_server_session_lifetime', 'Время сессии'],
['administration_configuration_wizard_configuration_custom_connections', 'Разрешить пользовательские подключения'],
@@ -11,6 +11,8 @@ import type { PluginManifest } from '@cloudbeaver/core-di';
import { ConfigurationWizardPagesBootstrapService } from './ConfigurationWizard/ConfigurationWizardPagesBootstrapService';
import { ServerConfigurationService } from './ConfigurationWizard/ServerConfiguration/ServerConfigurationService';
import { LocaleService } from './LocaleService';
import { AdministrationLicensePageBootstrapService } from './Pages/License/AdministrationLicensePageBootstrapService';
import { AdministrationLicensePageService } from './Pages/License/AdministrationLicensePageService';
export const manifest: PluginManifest = {
info: {
@@ -20,6 +22,8 @@ export const manifest: PluginManifest = {
providers: [
ServerConfigurationService,
ConfigurationWizardPagesBootstrapService,
AdministrationLicensePageBootstrapService,
AdministrationLicensePageService,
LocaleService,
],
};