半成品

This commit is contained in:
2betop 2020-08-13 20:05:28 +08:00
parent e27c38ed00
commit 93297e8c5c
10 changed files with 192 additions and 14 deletions

View File

@ -1,3 +1,26 @@
import React from 'react';
import ConditionBuilder from '../../../src/components/condition-builder/ConditionBuilder';
const fields = [
{
label: '姓名',
name: 'name',
type: 'text'
},
{
label: '年龄',
name: 'age',
type: 'number'
},
{
label: '入职时间',
name: 'ruzhi',
type: 'datetime'
}
];
export default { export default {
type: 'page', type: 'page',
title: '表单页面', title: '表单页面',
@ -17,6 +40,10 @@ export default {
label: 'Email', label: 'Email',
type: 'email', type: 'email',
name: 'email' name: 'email'
},
{
children: () => <ConditionBuilder fields={fields} />
} }
] ]
} }

View File

@ -0,0 +1,7 @@
.#{$ns}CBCGroup {
&-toolbar {
display: flex;
flex-direction: row;
justify-content: space-between;
}
}

View File

@ -505,6 +505,7 @@ $Satus-icon-width: px2rem(14px);
@import '../components/dropdown'; @import '../components/dropdown';
@import '../components/collapse'; @import '../components/collapse';
@import '../components/color'; @import '../components/color';
@import '../components/condition-builder';
@import '../components/context-menu'; @import '../components/context-menu';
@import '../components/wizard'; @import '../components/wizard';
@import '../components/crud'; @import '../components/crud';

View File

@ -188,6 +188,7 @@ pre {
@import '../components/dropdown'; @import '../components/dropdown';
@import '../components/collapse'; @import '../components/collapse';
@import '../components/color'; @import '../components/color';
@import '../components/condition-builder';
@import '../components/context-menu'; @import '../components/context-menu';
@import '../components/wizard'; @import '../components/wizard';
@import '../components/crud'; @import '../components/crud';

View File

@ -51,6 +51,7 @@ $Form-input-borderColor: #cfdadd;
@import '../components/dropdown'; @import '../components/dropdown';
@import '../components/collapse'; @import '../components/collapse';
@import '../components/color'; @import '../components/color';
@import '../components/condition-builder';
@import '../components/context-menu'; @import '../components/context-menu';
@import '../components/wizard'; @import '../components/wizard';
@import '../components/crud'; @import '../components/crud';

View File

@ -2,15 +2,18 @@ import React from 'react';
import {ThemeProps, themeable} from '../../theme'; import {ThemeProps, themeable} from '../../theme';
import {LocaleProps, localeable} from '../../locale'; import {LocaleProps, localeable} from '../../locale';
import {uncontrollable} from 'uncontrollable'; import {uncontrollable} from 'uncontrollable';
import {FieldTypes, FieldItem} from './types'; import {FieldTypes, FieldItem, Fields} from './types';
import {ConditionGroup} from './ConditionGroup';
export interface QueryBuilderProps extends ThemeProps, LocaleProps { export interface QueryBuilderProps extends ThemeProps, LocaleProps {
fields: Array<FieldItem>; fields: Fields;
} }
export class QueryBuilder extends React.Component<QueryBuilderProps> { export class QueryBuilder extends React.Component<QueryBuilderProps> {
render() { render() {
return <p>this is querybuilder component</p>; const {classnames: cx, fields} = this.props;
return <ConditionGroup fields={fields} value={undefined} classnames={cx} />;
} }
} }

View File

@ -0,0 +1,48 @@
import React from 'react';
import {Fields, ConditionGroupValue} from './types';
import {ClassNamesFn} from '../../theme';
import Button from '../Button';
import {ConditionItem} from './ConditionItem';
import {autobind} from '../../utils/helper';
export interface ConditionGroupProps {
value?: ConditionGroupValue;
fields: Fields;
onChange: (value: ConditionGroupValue) => void;
classnames: ClassNamesFn;
}
export class ConditionGroup extends React.Component<ConditionGroupProps> {
@autobind
handleNotClick() {}
render() {
const {classnames: cx, value, fields} = this.props;
return (
<div className={cx('CBCGroup')}>
<div className={cx('CBCGroup-toolbar')}>
<div className={cx('CBCGroup-toolbarLeft')}>
<Button onClick={this.handleNotClick} size="sm" active={value?.not}>
</Button>
<Button size="sm" active={value?.conjunction !== 'or'}>
</Button>
<Button size="sm" active={value?.conjunction === 'or'}>
</Button>
</div>
<div className={cx('CBCGroup-toolbarRight')}>
<Button size="sm"></Button>
<Button size="sm"></Button>
</div>
</div>
{Array.isArray(value)
? value.map(item => <ConditionItem fields={fields} value={item} />)
: null}
</div>
);
}
}

View File

@ -0,0 +1,13 @@
import React from 'react';
import {Fields, ConditionRule, ConditionGroupValue} from './types';
export interface ConditionItemProps {
fields: Fields;
value: ConditionRule | ConditionGroupValue;
}
export class ConditionItem extends React.Component<ConditionItemProps> {
render() {
return <p>233</p>;
}
}

View File

@ -1,16 +1,28 @@
import {FieldTypes, OperatorType, Funcs} from './types'; import {FieldTypes, OperatorType, Funcs, Fields} from './types';
export interface BaseFieldConfig { export interface BaseFieldConfig {
operations: Array<OperatorType>; operations: Array<OperatorType>;
} }
export interface Config { export interface Config {
fields: Fields;
funcs?: Funcs; funcs?: Funcs;
maxLevel?: number; maxLevel?: number;
} }
const defaultConfig: Config = { const defaultConfig: Config = {
// fields: [], fields: [
// {
// type: 'text',
// name: 'test',
// label: 'Text'
// },
// {
// label: 'Group',
// children: [
// ]
// }
],
// 函数配置示例 // 函数配置示例
funcs: [ funcs: [

View File

@ -1,8 +1,11 @@
type TypedMap<T> = { export type FieldTypes =
[key: string]: T; | 'text'
}; | 'number'
| 'boolean'
export type FieldTypes = 'text' | 'number' | 'boolean' | 'date' | 'datetime'; | 'date'
| 'time'
| 'datetime'
| 'select';
export type OperatorType = export type OperatorType =
| 'equals' | 'equals'
@ -42,13 +45,13 @@ export interface ConditionRule {
right: ConditionRightValue | Array<ConditionRightValue>; right: ConditionRightValue | Array<ConditionRightValue>;
} }
export interface ConditionGroup { export interface ConditionGroupValue {
conjunction: 'and' | 'or'; conjunction: 'and' | 'or';
not?: boolean; not?: boolean;
children?: Array<ConditionRule | ConditionGroup>; children?: Array<ConditionRule | ConditionGroupValue>;
} }
export interface ConditionValue extends ConditionGroup {} export interface ConditionValue extends ConditionGroupValue {}
interface BaseField { interface BaseField {
type: FieldTypes; type: FieldTypes;
@ -61,11 +64,73 @@ interface BaseField {
defaultValue?: any; defaultValue?: any;
} }
type FieldGroup = {
label: string;
children: Array<FieldSimple>;
};
interface TextField extends BaseField { interface TextField extends BaseField {
name: string;
type: 'text'; type: 'text';
minLength?: number;
maxLength?: number;
} }
type Field = TextField; interface NumberField extends BaseField {
name: string;
type: 'number';
maximum?: number;
minimum?: number;
}
interface DateField extends BaseField {
name: string;
type: 'date';
minDate?: any;
maxDate?: any;
}
interface TimeField extends BaseField {
name: string;
type: 'time';
minTime?: any;
maxTime?: any;
}
interface DatetimeField extends BaseField {
type: 'datetime';
name: string;
}
interface SelectField extends BaseField {
type: 'select';
name: string;
multiple?: boolean;
options?: Array<any>;
}
interface BooleanField extends BaseField {
type: 'boolean';
name: string;
}
interface GroupField {
type: 'group';
label: string;
name: string;
children: Array<FieldSimple>;
}
type FieldSimple =
| TextField
| NumberField
| DateField
| TimeField
| DatetimeField
| SelectField
| BooleanField;
type Field = FieldSimple | FieldGroup | GroupField;
interface FuncGroup { interface FuncGroup {
label: string; label: string;