123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- import React from 'react';
- import { Dialog, ReactWidget } from '@jupyterlab/apputils';
- import { IDatasourceForm, textDatasource } from './api/datasource';
- import { Widget } from '@lumino/widgets';
- import { Input, message, Select } from 'antd';
- interface IProps {
- value: Partial<IDatasourceForm>;
- error: keyof IDatasourceForm | null;
- onChange: (v: Partial<IDatasourceForm>) => void;
- onConnection: (v: Partial<IDatasourceForm>) => void;
- }
- const DatasourceForm: React.FunctionComponent<IProps> = ({
- value,
- error,
- onChange,
- onConnection
- }) => {
- return (
- <form className="jldbq-form">
- <label className={error === 'datasource' ? 'jldbq-form-error' : ''}>
- <span className="jldbq-form-label">数据源类型:</span>
- <Select
- className="jldbq-form-select"
- placeholder="请选择数据源类型"
- onChange={(val: any) => onChange({ datasource: val })}
- >
- <Select.Option value="mysql">MySQL</Select.Option>
- <Select.Option value="hive">Hive</Select.Option>
- </Select>
- </label>
- <label className={error === 'datasource_name' ? 'jldbq-form-error' : ''}>
- <span className="jldbq-form-label">数据源名称:</span>
- <Input
- className="jldbq-form-input"
- placeholder="请输入数据源名称"
- value={value.datasource_name || ''}
- onChange={evt => onChange({ datasource_name: evt.target.value })}
- />
- </label>
- <label className={error === 'jdbc_url' ? 'jldbq-form-error' : ''}>
- <span className="jldbq-form-label">数据库地址:</span>
- <Input
- className="jldbq-form-input"
- placeholder="示例:host:port"
- value={value.jdbc_url || ''}
- onChange={evt => onChange({ jdbc_url: evt.target.value })}
- />
- </label>
- <label className={error === 'database_name' ? 'jldbq-form-error' : ''}>
- <span className="jldbq-form-label">数据库名称:</span>
- <Input
- className="jldbq-form-input"
- placeholder={
- value.datasource === 'hive' ? '选填' : '请输入数据库名称'
- }
- value={value.database_name || ''}
- onChange={evt => onChange({ database_name: evt.target.value })}
- />
- </label>
- <label className={error === 'jdbc_username' ? 'jldbq-form-error' : ''}>
- <span className="jldbq-form-label">用户名:</span>
- <Input
- className="jldbq-form-input"
- placeholder="请输入用户名"
- value={value.jdbc_username || ''}
- onChange={evt => onChange({ jdbc_username: evt.target.value })}
- />
- </label>
- <label className={error === 'jdbc_password' ? 'jldbq-form-error' : ''}>
- <span className="jldbq-form-label">密码:</span>
- <Input.Password
- className="jldbq-form-input"
- placeholder="请输入密码"
- value={value.jdbc_password || ''}
- onChange={evt => onChange({ jdbc_password: evt.target.value })}
- />
- </label>
- <span className="jldbq-form-link" onClick={() => onConnection(value)}>
- 测试连接
- </span>
- </form>
- );
- };
- export class DatasourceFormDialogBody
- extends ReactWidget
- implements Dialog.IBodyWidget<IDatasourceForm> {
- constructor(manager: string, options?: Widget.IOptions) {
- super(options);
- // this._manager = manager;
- }
- render(): JSX.Element {
- return (
- <DatasourceForm
- value={this._datasourceItem}
- error={this._error}
- onChange={v => {
- this._datasourceItem = { ...this._datasourceItem, ...v };
- this._error = null;
- this.update();
- }}
- onConnection={async v => {
- const res = await textDatasource({ ...v } as IDatasourceForm);
- if (res && res !== 'error') {
- void message.success('测试成功');
- } else {
- void message.error('测试失败');
- }
- }}
- />
- );
- }
- getValue(): IDatasourceForm {
- const {
- jdbc_url,
- jdbc_username,
- jdbc_password,
- database_name,
- datasource_name,
- datasource
- } = this._datasourceItem;
- if (!datasource) {
- this._setError('datasource');
- }
- if (!jdbc_url || !validateIpAndPort(jdbc_url)) {
- this._setError('jdbc_url');
- }
- if (!jdbc_username) {
- this._setError('jdbc_username');
- }
- if (!jdbc_password) {
- this._setError('jdbc_password');
- }
- if (!database_name && datasource === 'mysql') {
- this._setError('database_name');
- }
- if (!datasource_name) {
- this._setError('datasource_name');
- }
- return {
- jdbc_url,
- jdbc_username,
- jdbc_password,
- database_name: database_name as any,
- datasource_name,
- datasource
- // manager: this._manager
- };
- }
- private _setError(error: keyof IDatasourceForm): never {
- this._error = error;
- this.update();
- throw new Error(error);
- }
- private _datasourceItem: Partial<IDatasourceForm> = {};
- private _error: IProps['error'] = null;
- // private _manager: string;
- }
- function validateIpAndPort(input: string): boolean {
- const parts = input.split(':');
- if (parts.length > 2) {
- return false;
- }
- const ip = parts[0].split('.');
- if (
- ip.length !== 4 ||
- !ip.every(function (segment) {
- return validateNum(segment, 0, 255);
- })
- ) {
- return false;
- }
- const port = parts[1];
- if (port && !validateNum(port, 1, 65535)) {
- return false;
- }
- return true;
- }
- function validateNum(input: string, min: number, max: number): boolean {
- const num = +input;
- return num >= min && num <= max && input === num.toString();
- }
|