mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
feat(core-administration): configuration forms validation handling
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
"@cloudbeaver/core-root": "^0.1.0",
|
||||
"@cloudbeaver/core-routing": "^0.1.0",
|
||||
"@cloudbeaver/core-theming": "^0.1.0",
|
||||
"@cloudbeaver/core-executor": "^0.1.0",
|
||||
"react": "^16.x.x",
|
||||
"mobx": "^5.x.x",
|
||||
"mobx-react": "^6.x.x",
|
||||
|
||||
@@ -54,7 +54,7 @@ export interface IAdministrationItemSubItem {
|
||||
|
||||
export interface IConfigurationWizardItemOptions {
|
||||
description: string;
|
||||
onValidate?: () => boolean;
|
||||
onValidate?: () => Promise<boolean> | boolean;
|
||||
isDisabled?: () => boolean;
|
||||
isHidden?: () => boolean;
|
||||
isDone?: () => boolean;
|
||||
|
||||
+15
-14
@@ -55,15 +55,6 @@ export class ConfigurationWizardService {
|
||||
});
|
||||
}
|
||||
|
||||
@computed get canNext() {
|
||||
if (this.currentStep?.configurationWizardOptions?.isDone
|
||||
&& !this.currentStep?.configurationWizardOptions?.isDone()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@computed get nextStep() {
|
||||
return this.steps.find((item, index) => {
|
||||
if (index <= this.currentStepIndex) {
|
||||
@@ -112,27 +103,37 @@ export class ConfigurationWizardService {
|
||||
const step = this.getStep(name);
|
||||
|
||||
if (!step) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (step.configurationWizardOptions?.onValidate) {
|
||||
const isValid = await step.configurationWizardOptions.onValidate();
|
||||
if (!isValid) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (step.configurationWizardOptions?.onFinish) {
|
||||
await step.configurationWizardOptions.onFinish();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
next() {
|
||||
if (!this.currentStep || !this.canNext) {
|
||||
async next() {
|
||||
if (!this.currentStep) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.finishStep(this.currentStep.name);
|
||||
if (!await this.finishStep(this.currentStep.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.currentStepIndex + 1 < this.steps.length) {
|
||||
if (this.nextStep) {
|
||||
this.administrationScreenService.navigateToItem(this.nextStep.name);
|
||||
}
|
||||
} else {
|
||||
this.finish();
|
||||
await this.finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
@@ -7,15 +7,19 @@
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import { useEffect } from 'react';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import {
|
||||
SubmittingForm, InputGroup, InputField, useFocus, Switch
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { ServerConfigInput } from '@cloudbeaver/core-sdk';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { ServerConfigurationService } from './ServerConfigurationService';
|
||||
|
||||
export const formStyles = css`
|
||||
SubmittingForm {
|
||||
flex: 1;
|
||||
@@ -51,9 +55,20 @@ export const ServerConfigurationForm = observer(function ServerConfigurationForm
|
||||
onChange,
|
||||
onSave,
|
||||
}: Props) {
|
||||
const service = useService(ServerConfigurationService);
|
||||
const translate = useTranslate();
|
||||
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
|
||||
|
||||
useEffect(() => {
|
||||
const validate = () => {
|
||||
focusedRef.current?.checkValidity();
|
||||
focusedRef.current?.reportValidity();
|
||||
};
|
||||
service.validationTask.addHandler(validate);
|
||||
|
||||
return () => service.validationTask.removeHandler(validate);
|
||||
}, [service]);
|
||||
|
||||
return styled(useStyles(formStyles, boxStyles))(
|
||||
<SubmittingForm onSubmit={onSave} name='server_config' ref={focusedRef}>
|
||||
<box as="div">
|
||||
|
||||
+22
-3
@@ -8,6 +8,7 @@
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { IExecutor, Executor, IContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { GraphQLService } from '@cloudbeaver/core-sdk';
|
||||
|
||||
import { AdministrationScreenService } from '../../../AdministrationScreenService';
|
||||
@@ -17,6 +18,7 @@ import { IServerConfigurationPageState } from './IServerConfigurationPageState';
|
||||
export class ServerConfigurationService {
|
||||
|
||||
readonly state: IServerConfigurationPageState;
|
||||
readonly validationTask: IExecutor<boolean>;
|
||||
|
||||
constructor(
|
||||
private administrationScreenService: AdministrationScreenService,
|
||||
@@ -42,18 +44,35 @@ export class ServerConfigurationService {
|
||||
showUtilityObjects: false,
|
||||
},
|
||||
}));
|
||||
this.validationTask = new Executor();
|
||||
}
|
||||
|
||||
isDone() {
|
||||
return this.isFormFilled();
|
||||
}
|
||||
|
||||
validate() {
|
||||
return this.isFormFilled();
|
||||
async validate() {
|
||||
const context = await this.validationTask.execute(true);
|
||||
const state = await context.getContext(this.validationStatusContext);
|
||||
|
||||
return state.getState();
|
||||
}
|
||||
|
||||
validationStatusContext = (context: IContextProvider<boolean>) => {
|
||||
let state = this.isFormFilled();
|
||||
|
||||
const invalidate = () => {
|
||||
state = false;
|
||||
};
|
||||
const getState = () => state;
|
||||
|
||||
return {
|
||||
getState,
|
||||
invalidate,
|
||||
};
|
||||
}
|
||||
|
||||
private isFormFilled() {
|
||||
|
||||
return !!(
|
||||
this.state?.serverConfig.serverName
|
||||
&& this.state.serverConfig.adminName
|
||||
|
||||
-1
@@ -79,7 +79,6 @@ export const WizardStepper = observer(function WizardStepper() {
|
||||
type="button"
|
||||
mod={['unelevated']}
|
||||
onClick={() => service.next()}
|
||||
disabled={!service.canNext}
|
||||
>
|
||||
{translate(service.currentStepIndex === service.steps.length - 1 ? 'ui_stepper_finish' : 'ui_stepper_next')}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user