@coocoon/react-awesome-query-builder
Version:
User-friendly query builder for React. Demo: https://ukrbublik.github.io/react-awesome-query-builder
1,144 lines (1,023 loc) • 36.9 kB
TypeScript
/* eslint-disable no-extra-semi */
import {List as ImmutableList, Map as ImmutableMap, OrderedMap as ImmutableOMap} from "immutable";
import {ElementType, ReactElement, Factory} from "react";
////////////////
// common
/////////////////
type AnyObject = object;
type Empty = null | undefined;
type IdPath = Array<string> | ImmutableList<string>;
type Optional<T> = {
[P in keyof T]?: T[P];
}
type TypedMap<T> = {
[key: string]: T;
}
// You can not use a union for types on a key, but can define overloaded accessors of different types.
// Key can be a string OR number
type TypedKeyMap<K extends string|number, T> = {
[key: string]: T;
[key: number]: T;
}
// for export/import
type MongoValue = any;
type ElasticSearchQueryType = string;
type JsonLogicResult = {
logic?: JsonLogicTree,
data?: Object,
errors?: Array<string>
}
type JsonLogicTree = Object;
type JsonLogicValue = any;
type JsonLogicField = { "var": string };
////////////////
// query value
/////////////////
type RuleValue = boolean | number | string | Date | Array<string> | any;
type ValueSource = "value" | "field" | "func" | "const";
type RuleGroupMode = "struct" | "some" | "array";
type ItemType = "group" | "rule_group" | "rule";
type ItemProperties = RuleProperties | RuleGroupExtProperties | RuleGroupProperties | GroupProperties;
type TypedValueSourceMap<T> = {
[key in ValueSource]: T;
}
interface BasicItemProperties {
isLocked?: boolean,
}
interface RuleProperties extends BasicItemProperties {
field: string | Empty,
operator: string | Empty,
value: Array<RuleValue>,
valueSrc?: Array<ValueSource>,
valueType?: Array<string>,
valueError?: Array<string>,
operatorOptions?: AnyObject,
}
interface RuleGroupExtProperties extends RuleProperties {
mode: RuleGroupMode,
}
interface RuleGroupProperties extends BasicItemProperties {
field: string | Empty,
mode?: RuleGroupMode,
}
interface GroupProperties extends BasicItemProperties {
conjunction: string,
not?: boolean,
}
interface SwitchGroupProperties extends BasicItemProperties {
}
interface CaseGroupProperties extends BasicItemProperties {
}
type JsonAnyRule = JsonRule|JsonRuleGroup|JsonRuleGroupExt;
type JsonItem = JsonGroup|JsonAnyRule;
type JsonSwitchGroup = {
type: "switch_group",
id?: string,
children1?: {[id: string]: JsonCaseGroup} | [JsonCaseGroup],
properties?: SwitchGroupProperties
};
type JsonCaseGroup = {
type: "case_group",
id?: string,
children1?: {[id: string]: JsonGroup} | [JsonGroup],
properties?: CaseGroupProperties
};
type JsonGroup = {
type: "group",
id?: string,
// tip: if got array, it will be converted to immutable ordered map in `_addChildren1`
children1?: {[id: string]: JsonItem} | [JsonItem],
properties?: GroupProperties
}
type JsonRuleGroup = {
type: "rule_group",
id?: string,
children1?: {[id: string]: JsonRule} | [JsonRule],
properties?: RuleGroupProperties
}
type JsonRuleGroupExt = {
type: "rule_group",
id?: string,
children1?: {[id: string]: JsonRule} | [JsonRule],
properties?: RuleGroupExtProperties
}
type JsonRule = {
type: "rule",
properties: RuleProperties,
}
export type JsonTree = JsonGroup|JsonSwitchGroup;
export type ImmutableTree = ImmutableOMap<string, any>;
////////////////
// Query, Builder, Utils, Config
/////////////////
export interface SpelConcatPart {
value: string;
type: "property" | "variable" | "const";
}
type SpelConcatParts = SpelConcatPart[];
interface SpelConcatCaseValue {
valueType: "case_value";
value: SpelConcatNormalValue[];
}
interface SpelConcatNormalValue {
value: string;
valueType: string;
valueSrc: "value" | "field";
isVariable?: boolean;
}
type SpelConcatValue = SpelConcatNormalValue | SpelConcatCaseValue;
export interface Utils {
// export
jsonLogicFormat(tree: ImmutableTree, config: Config): JsonLogicResult;
queryBuilderFormat(tree: ImmutableTree, config: Config): Object | undefined;
queryString(tree: ImmutableTree, config: Config, isForDisplay?: boolean): string | undefined;
sqlFormat(tree: ImmutableTree, config: Config): string | undefined;
_sqlFormat(tree: ImmutableTree, config: Config): [string | undefined, Array<string>];
spelFormat(tree: ImmutableTree, config: Config): string | undefined;
_spelFormat(tree: ImmutableTree, config: Config): [string | undefined, Array<string>];
mongodbFormat(tree: ImmutableTree, config: Config): Object | undefined;
_mongodbFormat(tree: ImmutableTree, config: Config): [Object | undefined, Array<string>];
elasticSearchFormat(tree: ImmutableTree, config: Config): Object | undefined;
// load, save
getTree(tree: ImmutableTree, light?: boolean, children1AsArray?: boolean): JsonTree;
loadTree(jsonTree: JsonTree): ImmutableTree;
checkTree(tree: ImmutableTree, config: Config): ImmutableTree;
isValidTree(tree: ImmutableTree): boolean;
getSwitchValues(tree: ImmutableTree): Array<SpelConcatParts | null>;
// import
loadFromJsonLogic(logicTree: JsonLogicTree | undefined, config: Config): ImmutableTree | undefined;
_loadFromJsonLogic(logicTree: JsonLogicTree | undefined, config: Config): [ImmutableTree | undefined, Array<string>];
loadFromSpel(spelStr: string, config: Config): [ImmutableTree | undefined, Array<string>];
isJsonLogic(value: any): boolean;
// other
uuid(): string;
simulateAsyncFetch(all: AsyncFetchListValues, pageSize?: number, delay?: number): AsyncFetchListValuesFn;
// config utils
ConfigUtils: {
getFieldConfig(config: Config, field: string): Field | null;
getFuncConfig(config: Config, func: string): Func | null;
getFuncArgConfig(config: Config, func: string, arg: string): FuncArg | null;
getOperatorConfig(config: Config, operator: string, field?: string): Operator | null;
getFieldWidgetConfig(config: Config, field: string, operator: string, widget?: string, valueStr?: ValueSource): Widget | null;
};
ExportUtils: {
spelEscape(val: any): string;
spelFormatConcat(parts: SpelConcatParts): string;
spelImportConcat(val: SpelConcatValue): [SpelConcatParts | undefined, Array<string>],
}
}
export interface BuilderProps {
tree: ImmutableTree,
config: Config,
actions: Actions,
dispatch: Dispatch,
}
export interface QueryProps {
conjunctions: Conjunctions;
operators: Operators;
widgets: Widgets;
types: Types;
settings: Settings;
fields: Fields;
funcs?: Funcs;
value: ImmutableTree;
onChange(immutableTree: ImmutableTree, config: Config, actionMeta?: ActionMeta): void;
renderBuilder(props: BuilderProps): ReactElement;
}
export type Builder = ElementType<BuilderProps>;
export type Query = ElementType<QueryProps>;
export interface Config {
conjunctions: Conjunctions,
operators: Operators,
widgets: Widgets,
types: Types,
settings: Settings,
fields: Fields,
funcs?: Funcs,
}
/////////////////
// Actions
/////////////////
type Placement = "after" | "before" | "append" | "prepend";
type ActionType = string | "ADD_RULE" | "REMOVE_RULE" | "ADD_GROUP" | "ADD_CASE_GROUP" | "REMOVE_GROUP" | "SET_NOT" | "SET_LOCK" | "SET_CONJUNCTION" | "SET_FIELD" | "SET_OPERATOR" | "SET_VALUE" | "SET_VALUE_SRC" | "SET_OPERATOR_OPTION" | "MOVE_ITEM";
interface BaseAction {
type: ActionType,
id?: string, // for ADD_RULE, ADD_GROUP - id of new item
path?: IdPath, // for all except MOVE_ITEM (for ADD_RULE/ADD_GROUP it's parent path)
conjunction?: string,
not?: boolean,
lock?: boolean,
field?: string,
operator?: string,
delta?: number, // for SET_VALUE
value?: RuleValue,
valueType?: string,
srcKey?: ValueSource,
name?: string, // for SET_OPERATOR_OPTION
fromPath?: IdPath, // for MOVE_ITEM
toPath?: IdPath, // for MOVE_ITEM
placement?: Placement, // for MOVE_ITEM
properties?: TypedMap<any>, // for ADD_RULE, ADD_GROUP
}
export interface InputAction extends BaseAction {
config: Config,
}
export interface ActionMeta extends BaseAction {
affectedField?: string, // gets field name from `path` (or `field` for first SET_FIELD)
}
export type Dispatch = (action: InputAction) => void;
export interface Actions {
// tip: children will be converted to immutable ordered map in `_addChildren1`
addRule(path: IdPath, properties?: ItemProperties, type?: ItemType, children?: Array<JsonAnyRule>): undefined;
removeRule(path: IdPath): undefined;
addGroup(path: IdPath, properties?: ItemProperties, children?: Array<JsonItem>): undefined;
removeGroup(path: IdPath): undefined;
setNot(path: IdPath, not: boolean): undefined;
setLock(path: IdPath, lock: boolean): undefined;
setConjunction(path: IdPath, conjunction: string): undefined;
setField(path: IdPath, field: string): undefined;
setOperator(path: IdPath, operator: string): undefined;
setValue(path: IdPath, delta: number, value: RuleValue, valueType: string): undefined;
setValueSrc(path: IdPath, delta: number, valueSrc: ValueSource): undefined;
setOperatorOption(path: IdPath, name: string, value: RuleValue): undefined;
moveItem(fromPath: IdPath, toPath: IdPath, placement: Placement): undefined;
setTree(tree: ImmutableTree): undefined;
}
/////////////////
// Widgets, WidgetProps
/////////////////
type SpelImportValue = (val: any) => [any, string[]];
type FormatValue = (val: RuleValue, fieldDef: Field, wgtDef: Widget, isForDisplay: boolean, op: string, opDef: Operator, rightFieldDef?: Field) => string;
type SqlFormatValue = (val: RuleValue, fieldDef: Field, wgtDef: Widget, op: string, opDef: Operator, rightFieldDef?: Field) => string;
type SpelFormatValue = (val: RuleValue, fieldDef: Field, wgtDef: Widget, op: string, opDef: Operator, rightFieldDef?: Field) => string;
type MongoFormatValue = (val: RuleValue, fieldDef: Field, wgtDef: Widget, op: string, opDef: Operator) => MongoValue;
type JsonLogicFormatValue = (val: RuleValue, fieldDef: Field, wgtDef: Widget, op: string, opDef: Operator) => JsonLogicValue;
type ValidateValue = (val: RuleValue, fieldSettings: FieldSettings, op: string, opDef: Operator, rightFieldDef?: Field) => boolean | string | null;
type ElasticSearchFormatValue = (queryType: ElasticSearchQueryType, val: RuleValue, op: string, field: string, config: Config) => AnyObject | null;
interface BaseWidgetProps {
value: RuleValue,
setValue(val: RuleValue, asyncListValues?: Array<any>): void,
placeholder: string,
field: string,
parentField?: string,
operator: string,
fieldDefinition: Field,
config: Config,
delta?: number,
customProps?: AnyObject,
readonly?: boolean,
id?: string, // id of rule
groupId?: string, // id of parent group
}
interface RangeWidgetProps extends BaseWidgetProps {
placeholders: Array<string>,
textSeparators: Array<string>,
}
export type WidgetProps = (BaseWidgetProps | RangeWidgetProps) & FieldSettings;
export type TextWidgetProps = BaseWidgetProps & TextFieldSettings;
export type DateTimeWidgetProps = BaseWidgetProps & DateTimeFieldSettings;
export type BooleanWidgetProps = BaseWidgetProps & BooleanFieldSettings;
export type NumberWidgetProps = BaseWidgetProps & NumberFieldSettings;
export type SelectWidgetProps = BaseWidgetProps & SelectFieldSettings;
export type TreeSelectWidgetProps = BaseWidgetProps & TreeSelectFieldSettings;
export type RangeSliderWidgetProps = RangeWidgetProps & NumberFieldSettings;
export type CaseValueWidgetProps = BaseWidgetProps & CaseValueFieldSettings;
export interface BaseWidget {
customProps?: AnyObject;
type: string;
jsType?: string;
factory: Factory<WidgetProps>;
valueSrc?: ValueSource;
valuePlaceholder?: string;
valueLabel?: string;
fullWidth?: boolean;
formatValue?: FormatValue;
sqlFormatValue?: SqlFormatValue;
spelFormatValue?: SpelFormatValue;
spelImportValue?: SpelImportValue;
mongoFormatValue?: MongoFormatValue;
elasticSearchFormatValue?: ElasticSearchFormatValue;
hideOperator?: boolean;
jsonLogic?: JsonLogicFormatValue;
//obsolete:
validateValue?: ValidateValue;
}
export interface RangeableWidget extends BaseWidget {
singleWidget?: string,
valueLabels?: Array<string | {label: string, placeholder: string}>,
}
export interface FieldWidget {
customProps?: AnyObject,
valueSrc: "field",
valuePlaceholder?: string,
valueLabel?: string,
formatValue: FormatValue, // with rightFieldDef
sqlFormatValue?: SqlFormatValue, // with rightFieldDef
spelFormatValue?: SpelFormatValue, // with rightFieldDef
//obsolete:
validateValue?: ValidateValue,
}
export type TextWidget = BaseWidget & TextFieldSettings;
export type DateTimeWidget = RangeableWidget & DateTimeFieldSettings;
export type BooleanWidget = BaseWidget & BooleanFieldSettings;
export type NumberWidget = RangeableWidget & NumberFieldSettings;
export type SelectWidget = BaseWidget & SelectFieldSettings;
export type TreeSelectWidget = BaseWidget & TreeSelectFieldSettings;
export type CaseValueWidget = BaseWidget & CaseValueFieldSettings;
export type Widget = FieldWidget | TextWidget | DateTimeWidget | BooleanWidget | NumberWidget | SelectWidget | TreeSelectWidget | RangeableWidget | BaseWidget;
export type Widgets = TypedMap<Widget>;
/////////////////
// Conjunctions
/////////////////
type FormatConj = (children: ImmutableList<string>, conj: string, not: boolean, isForDisplay?: boolean) => string;
type SqlFormatConj = (children: ImmutableList<string>, conj: string, not: boolean) => string;
type SpelFormatConj = (children: ImmutableList<string>, conj: string, not: boolean, omitBrackets?: boolean) => string;
export interface Conjunction {
label: string,
formatConj: FormatConj,
sqlFormatConj: SqlFormatConj,
spelFormatConj: SpelFormatConj,
mongoConj: string,
jsonLogicConj?: string,
sqlConj?: string,
spelConj?: string,
spelConjs?: [string],
reversedConj?: string,
}
export type Conjunctions = TypedMap<Conjunction>;
export interface ConjunctionOption {
id: string,
key: string,
label: string,
checked: boolean,
}
export interface ConjsProps {
id: string,
readonly?: boolean,
disabled?: boolean,
selectedConjunction?: string,
setConjunction(conj: string): void,
conjunctionOptions?: TypedMap<ConjunctionOption>,
config?: Config,
not: boolean,
setNot(not: boolean): void,
showNot?: boolean,
notLabel?: string,
}
/////////////////
// Rule, Group
/////////////////
export interface ButtonProps {
type: "addRule" | "addGroup" | "delRule" | "delGroup" | "addRuleGroup" | "delRuleGroup",
onClick(): void,
label: string,
config?: Config,
readonly?: boolean,
}
export interface SwitchProps {
value: boolean,
setValue(newValue?: boolean): void,
label: string,
checkedLabel?: string,
hideLabel?: boolean,
config?: Config,
}
export interface ButtonGroupProps {
children: ReactElement,
config?: Config,
}
export interface ProviderProps {
children: ReactElement,
config?: Config,
}
export type ValueSourceItem = {
label: string,
}
type ValueSourcesItems = TypedValueSourceMap<ValueSourceItem>;
export interface ValueSourcesProps {
config?: Config,
valueSources: ValueSourcesItems,
valueSrc?: ValueSource,
setValueSrc(valueSrc: string): void,
readonly?: boolean,
title: string,
}
export interface ConfirmModalProps {
onOk(): void,
okText: string,
cancelText?: string,
title: string,
}
export interface RuleErrorProps {
error: string,
}
/////////////////
// Operators
/////////////////
type FormatOperator = (field: string, op: string, vals: string | ImmutableList<string>, valueSrc?: ValueSource, valueType?: string, opDef?: Operator, operatorOptions?: AnyObject, isForDisplay?: boolean, fieldDef?: Field) => string;
type MongoFormatOperator = (field: string, op: string, vals: MongoValue | Array<MongoValue>, useExpr?: boolean, valueSrc?: ValueSource, valueType?: string, opDef?: Operator, operatorOptions?: AnyObject, fieldDef?: Field) => Object;
type SqlFormatOperator = (field: string, op: string, vals: string | ImmutableList<string>, valueSrc?: ValueSource, valueType?: string, opDef?: Operator, operatorOptions?: AnyObject, fieldDef?: Field) => string;
type SpelFormatOperator = (field: string, op: string, vals: string | Array<string>, valueSrc?: ValueSource, valueType?: string, opDef?: Operator, operatorOptions?: AnyObject, fieldDef?: Field) => string;
type JsonLogicFormatOperator = (field: JsonLogicField, op: string, vals: JsonLogicValue | Array<JsonLogicValue>, opDef?: Operator, operatorOptions?: AnyObject, fieldDef?: Field) => JsonLogicTree;
type ElasticSearchFormatQueryType = (valueType: string) => ElasticSearchQueryType;
interface ProximityConfig {
optionLabel: string,
optionTextBefore: string,
optionPlaceholder: string,
minProximity: number,
maxProximity: number,
defaults: {
proximity: number,
},
customProps?: AnyObject,
}
export interface ProximityProps extends ProximityConfig {
options: ImmutableMap<string, any>,
setOption: (key: string, value: any) => void,
config: Config,
}
export interface ProximityOptions extends ProximityConfig {
factory: Factory<ProximityProps>,
}
interface BaseOperator {
label: string,
reversedOp?: string,
isNotOp?: boolean,
cardinality?: number,
formatOp?: FormatOperator,
labelForFormat?: string,
mongoFormatOp?: MongoFormatOperator,
sqlOp?: string,
sqlFormatOp?: SqlFormatOperator,
spelOp?: string,
spelOps?: [string],
spelFormatOp?: SpelFormatOperator,
jsonLogic?: string | JsonLogicFormatOperator,
_jsonLogicIsRevArgs?: boolean,
elasticSearchQueryType?: ElasticSearchQueryType | ElasticSearchFormatQueryType,
valueSources?: Array<ValueSource>,
}
interface UnaryOperator extends BaseOperator {
//cardinality: 0,
}
interface BinaryOperator extends BaseOperator {
//cardinality: 1,
}
interface Operator2 extends BaseOperator {
//cardinality: 2
textSeparators: Array<string>,
valueLabels: Array<string | {label: string, placeholder: string}>,
isSpecialRange?: boolean,
}
interface OperatorProximity extends Operator2 {
options: ProximityOptions,
}
export type Operator = UnaryOperator | BinaryOperator | Operator2 | OperatorProximity;
export type Operators = TypedMap<Operator>;
/////////////////
// Types
/////////////////
interface WidgetConfigForType {
widgetProps?: Optional<Widget>,
opProps?: Optional<Operator>,
operators?: Array<string>,
}
interface Type {
valueSources?: Array<ValueSource>,
defaultOperator?: string,
widgets: TypedMap<WidgetConfigForType>,
mainWidget?: string,
excludeOperators?: Array<string>,
}
export type Types = TypedMap<Type>;
/////////////////
// Fields
/////////////////
type FieldType = string | "!struct" | "!group";
interface ListItem {
value: any,
title?: string,
}
interface TreeItem extends ListItem {
children?: Array<TreeItem>,
parent?: any,
disabled?: boolean,
selectable?: boolean,
disableCheckbox?: boolean,
checkable?: boolean,
path?: Array<string>
}
type TreeData = Array<TreeItem>;
type ListValues = TypedMap<string> | TypedKeyMap<string | number, string> | Array<ListItem> | Array<string | number>;
type AsyncFetchListValues = ListValues;
interface AsyncFetchListValuesResult {
values: AsyncFetchListValues,
hasMore?: boolean,
}
type AsyncFetchListValuesFn = (search: string | null, offset: number) => Promise<AsyncFetchListValuesResult>;
export interface BasicFieldSettings {
validateValue?: ValidateValue,
}
export interface TextFieldSettings extends BasicFieldSettings {
maxLength?: number,
maxRows?: number,
}
export interface NumberFieldSettings extends BasicFieldSettings {
min?: number,
max?: number,
step?: number,
marks?: {[mark: number]: ReactElement | string}
}
export interface DateTimeFieldSettings extends BasicFieldSettings {
timeFormat?: string,
dateFormat?: string,
valueFormat?: string,
use12Hours?: boolean,
useKeyboard?: boolean,
}
export interface SelectFieldSettings extends BasicFieldSettings {
listValues?: ListValues,
allowCustomValues?: boolean,
showSearch?: boolean,
showCheckboxes?: boolean,
asyncFetch?: AsyncFetchListValuesFn,
useLoadMore?: boolean,
useAsyncSearch?: boolean,
forceAsyncSearch?: boolean,
}
export interface TreeSelectFieldSettings extends BasicFieldSettings {
listValues?: TreeData,
treeExpandAll?: boolean,
treeSelectOnlyLeafs?: boolean,
}
export interface BooleanFieldSettings extends BasicFieldSettings {
labelYes?: ReactElement | string,
labelNo?: ReactElement | string,
}
export interface CaseValueFieldSettings extends BasicFieldSettings {
}
export type FieldSettings = NumberFieldSettings | DateTimeFieldSettings | SelectFieldSettings | TreeSelectFieldSettings | BooleanFieldSettings | TextFieldSettings | BasicFieldSettings;
interface BaseField {
type: FieldType,
label?: string,
tooltip?: string,
}
interface ValueField extends BaseField {
type: string,
preferWidgets?: Array<string>,
valueSources?: Array<ValueSource>,
funcs?: Array<string>,
tableName?: string, // legacy: PR #18, PR #20
fieldName?: string,
jsonLogicVar?: string,
fieldSettings?: FieldSettings,
defaultValue?: RuleValue,
widgets?: TypedMap<WidgetConfigForType>,
mainWidgetProps?: Optional<Widget>,
hideForSelect?: boolean,
hideForCompare?: boolean,
//obsolete - moved to FieldSettings
listValues?: ListValues,
allowCustomValues?: boolean,
isSpelVariable?: boolean,
}
interface SimpleField extends ValueField {
label2?: string,
operators?: Array<string>,
defaultOperator?: string,
excludeOperators?: Array<string>,
}
interface FieldStruct extends BaseField {
type: "!struct",
subfields: Fields,
isSpelMap?: boolean,
}
interface FieldGroup extends BaseField {
type: "!group",
subfields: Fields,
mode: RuleGroupMode,
isSpelArray?: boolean,
isSpelItemMap?: boolean,
}
interface FieldGroupExt extends BaseField {
type: "!group",
subfields: Fields,
mode: "array",
operators?: Array<string>,
defaultOperator?: string,
initialEmptyWhere?: boolean,
showNot?: boolean,
conjunctions?: Array<string>,
isSpelArray?: boolean,
isSpelItemMap?: boolean,
}
export type Field = SimpleField;
type FieldOrGroup = FieldStruct | FieldGroup | FieldGroupExt | Field;
export type Fields = TypedMap<FieldOrGroup>;
/////////////////
// FieldProps
/////////////////
export type FieldItem = {
items?: FieldItems,
key: string,
path?: string, // field path with separator
label: string,
fullLabel?: string,
altLabel?: string,
tooltip?: string,
disabled?: boolean,
}
type FieldItems = FieldItem[];
export interface FieldProps {
items: FieldItems,
setField(fieldPath: string): void,
selectedKey: string | Empty,
selectedKeys?: Array<string> | Empty,
selectedPath?: Array<string> | Empty,
selectedLabel?: string | Empty,
selectedAltLabel?: string | Empty,
selectedFullLabel?: string | Empty,
config?: Config,
customProps?: AnyObject,
placeholder?: string,
selectedOpts?: {tooltip?: string},
readonly?: boolean,
id?: string, // id of rule
groupId?: string, // id of parent group
}
/////////////////
// Settings
/////////////////
type SpelFieldMeta = {
key: string,
parent: "map" | "class" | "[class]" | "[map]" | null,
isSpelVariable?: boolean,
};
type ValueSourcesInfo = {[vs in ValueSource]?: {label: string, widget?: string}}
type AntdPosition = "topLeft" | "topCenter" | "topRight" | "bottomLeft" | "bottomCenter" | "bottomRight";
type AntdSize = "small" | "large" | "medium";
type ChangeFieldStrategy = "default" | "keep" | "first" | "none";
type FormatReverse = (q: string, op: string, reversedOp: string, operatorDefinition: Operator, revOperatorDefinition: Operator, isForDisplay: boolean) => string;
type SqlFormatReverse = (q: string) => string;
type SpelFormatReverse = (q: string) => string;
type FormatField = (field: string, parts: Array<string>, label2: string, fieldDefinition: Field, config: Config, isForDisplay: boolean) => string;
type FormatSpelField = (field: string, parentField: string | null, parts: Array<string>, partsExt: Array<SpelFieldMeta>, fieldDefinition: Field, config: Config) => string;
type CanCompareFieldWithField = (leftField: string, leftFieldConfig: Field, rightField: string, rightFieldConfig: Field, op: string) => boolean;
type FormatAggr = (whereStr: string, aggrField: string, operator: string, value: string | ImmutableList<string>, valueSrc: ValueSource, valueType: string, opDef: Operator, operatorOptions: AnyObject, isForDisplay: boolean, aggrFieldDef: Field) => string;
export interface LocaleSettings {
locale?: {
moment?: string,
antd?: Object,
material?: Object,
mui?: Object,
},
theme?: {
material?: Object,
mui?: Object,
},
valueLabel?: string,
valuePlaceholder?: string,
fieldLabel?: string,
operatorLabel?: string,
fieldPlaceholder?: string,
funcPlaceholder?: string,
funcLabel?: string,
operatorPlaceholder?: string,
lockLabel?: string,
lockedLabel?: string,
deleteLabel?: string,
addGroupLabel?: string,
addCaseLabel?: string,
addDefaultCaseLabel?: string,
defaultCaseLabel?: string,
addRuleLabel?: string,
addSubRuleLabel?: string,
delGroupLabel?: string,
notLabel?: string,
valueSourcesPopupTitle?: string,
removeRuleConfirmOptions?: {
title?: string,
okText?: string,
okType?: string,
cancelText?: string,
},
removeGroupConfirmOptions?: {
title?: string,
okText?: string,
okType?: string,
cancelText?: string,
},
}
export interface RenderSettings {
renderField?: Factory<FieldProps>,
renderOperator?: Factory<FieldProps>,
renderFunc?: Factory<FieldProps>,
renderConjs?: Factory<ConjsProps>,
renderButton?: Factory<ButtonProps>,
renderButtonGroup?: Factory<ButtonGroupProps>,
renderSwitch?: Factory<SwitchProps>,
renderProvider?: Factory<ProviderProps>,
renderValueSources?: Factory<ValueSourcesProps>,
renderConfirm?: ConfirmFunc,
useConfirm?: () => Function,
renderSize?: AntdSize,
dropdownPlacement?: AntdPosition,
groupActionsPosition?: AntdPosition,
showLabels?: boolean,
maxLabelsLength?: number,
customFieldSelectProps?: AnyObject,
renderBeforeWidget?: Factory<FieldProps>,
renderAfterWidget?: Factory<FieldProps>,
renderBeforeActions?: Factory<FieldProps>,
renderAfterActions?: Factory<FieldProps>,
renderRuleError?: Factory<RuleErrorProps>,
renderSwitchPrefix?: Factory<AnyObject>,
defaultSliderWidth?: string,
defaultSelectWidth?: string,
defaultSearchWidth?: string,
defaultMaxRows?: number,
}
export interface BehaviourSettings {
valueSourcesInfo?: ValueSourcesInfo,
canCompareFieldWithField?: CanCompareFieldWithField,
canReorder?: boolean,
canRegroup?: boolean,
canRegroupCases?: boolean,
showNot?: boolean,
showLock?: boolean,
canDeleteLocked?: boolean,
maxNesting?: number,
setOpOnChangeField: Array<ChangeFieldStrategy>,
clearValueOnChangeField?: boolean,
clearValueOnChangeOp?: boolean,
canLeaveEmptyGroup?: boolean,
canLeaveEmptyCase?: boolean,
shouldCreateEmptyGroup?: boolean,
forceShowConj?: boolean,
immutableGroupsMode?: boolean,
immutableFieldsMode?: boolean,
immutableOpsMode?: boolean,
immutableValuesMode?: boolean,
maxNumberOfRules?: Number,
maxNumberOfCases?: Number,
showErrorMessage?: boolean,
canShortMongoQuery?: boolean,
convertableWidgets?: TypedMap<Array<string>>,
removeEmptyGroupsOnLoad?: boolean,
removeIncompleteRulesOnLoad?: boolean,
}
export interface OtherSettings {
fieldSeparator?: string,
fieldSeparatorDisplay?: string,
formatReverse?: FormatReverse,
sqlFormatReverse?: SqlFormatReverse,
spelFormatReverse?: SpelFormatReverse,
formatField?: FormatField,
formatSpelField?: FormatSpelField,
formarAggr?: FormatAggr,
}
export type Settings = LocaleSettings & RenderSettings & BehaviourSettings & OtherSettings;
/////////////////
// Funcs
/////////////////
type SqlFormatFunc = (formattedArgs: TypedMap<string>) => string;
type FormatFunc = (formattedArgs: TypedMap<string>, isForDisplay: boolean) => string;
type MongoFormatFunc = (formattedArgs: TypedMap<MongoValue>) => MongoValue;
type JsonLogicFormatFunc = (formattedArgs: TypedMap<JsonLogicValue>) => JsonLogicTree;
type JsonLogicImportFunc = (val: JsonLogicValue) => Array<RuleValue>;
type SpelFormatFunc = (formattedArgs: TypedMap<string>) => string;
interface FuncGroup {
type?: "!struct",
label?: string,
subfields: TypedMap<Func>,
}
export interface Func {
returnType: string,
args: TypedMap<FuncArg>,
label?: string,
sqlFunc?: string,
spelFunc?: string,
mongoFunc?: string,
mongoArgsAsObject?: boolean,
jsonLogic?: string | JsonLogicFormatFunc,
// Deprecated!
// Calling methods on objects was remvoed in JsonLogic 2.x
// https://github.com/jwadhams/json-logic-js/issues/86
jsonLogicIsMethod?: boolean,
jsonLogicImport?: JsonLogicImportFunc,
formatFunc?: FormatFunc,
sqlFormatFunc?: SqlFormatFunc,
mongoFormatFunc?: MongoFormatFunc,
renderBrackets?: Array<ReactElement | string>,
renderSeps?: Array<ReactElement | string>,
spelFormatFunc?: SpelFormatFunc,
}
export interface FuncArg extends ValueField {
isOptional?: boolean,
showPrefix?: boolean,
}
export type Funcs = TypedMap<Func | FuncGroup>;
/////////////////
// BasicConfig
/////////////////
export interface BasicConfig extends Config {
conjunctions: {
AND: Conjunction,
OR: Conjunction,
},
operators: {
equal: BinaryOperator,
not_equal: BinaryOperator,
less: BinaryOperator,
less_or_equal: BinaryOperator,
greater: BinaryOperator,
greater_or_equal: BinaryOperator,
like: BinaryOperator,
not_like: BinaryOperator,
starts_with: BinaryOperator,
ends_with: BinaryOperator,
between: Operator2,
not_between: Operator2,
is_null: UnaryOperator,
is_not_null: UnaryOperator,
is_empty: UnaryOperator,
is_not_empty: UnaryOperator,
select_equals: BinaryOperator,
select_not_equals: BinaryOperator,
select_any_in: BinaryOperator,
select_not_any_in: BinaryOperator,
multiselect_equals: BinaryOperator,
multiselect_not_equals: BinaryOperator,
proximity: OperatorProximity,
},
widgets: {
text: TextWidget,
textarea: TextWidget,
number: NumberWidget,
slider: NumberWidget,
rangeslider: NumberWidget,
select: SelectWidget,
multiselect: SelectWidget,
treeselect: TreeSelectWidget,
treemultiselect: TreeSelectWidget,
date: DateTimeWidget,
time: DateTimeWidget,
datetime: DateTimeWidget,
boolean: BooleanWidget,
field: FieldWidget,
func: FieldWidget,
case_value: CaseValueWidget,
},
types: {
text: Type,
number: Type,
date: Type,
time: Type,
datetime: Type,
select: Type,
multiselect: Type,
treeselect: Type,
treemultiselect: Type,
boolean: Type,
case_value: Type,
},
settings: Settings,
}
/////////////////
// ReadyWidgets
/////////////////
type ConfirmFunc = (opts: ConfirmModalProps) => void;
interface VanillaWidgets {
// vanilla core widgets
VanillaFieldSelect: ElementType<FieldProps>,
VanillaConjs: ElementType<ConjsProps>,
VanillaSwitch: ElementType<SwitchProps>,
VanillaButton: ElementType<ButtonProps>,
VanillaButtonGroup: ElementType<ButtonGroupProps>,
VanillaProvider: ElementType<ProviderProps>,
VanillaValueSources: ElementType<ValueSourcesProps>,
vanillaConfirm: ConfirmFunc,
// vanilla core widgets
VanillaBooleanWidget: ElementType<BooleanWidgetProps>,
VanillaTextWidget: ElementType<TextWidgetProps>,
VanillaTextAreaWidget: ElementType<TextWidgetProps>,
VanillaDateWidget: ElementType<DateTimeWidgetProps>,
VanillaTimeWidget: ElementType<DateTimeWidgetProps>,
VanillaDateTimeWidget: ElementType<DateTimeWidgetProps>,
VanillaMultiSelectWidget: ElementType<SelectWidgetProps>,
VanillaSelectWidget: ElementType<SelectWidgetProps>,
VanillaNumberWidget: ElementType<NumberWidgetProps>,
VanillaSliderWidget: ElementType<NumberWidgetProps>,
}
export interface AntdWidgets {
// antd core widgets
FieldSelect: ElementType<FieldProps>,
FieldDropdown: ElementType<FieldProps>,
FieldCascader: ElementType<FieldProps>,
FieldTreeSelect: ElementType<FieldProps>,
Button: ElementType<ButtonProps>,
ButtonGroup: ElementType<ButtonGroupProps>,
Conjs: ElementType<ConjsProps>,
Switch: ElementType<SwitchProps>,
Provider: ElementType<ProviderProps>,
ValueSources: ElementType<ValueSourcesProps>,
confirm: ConfirmFunc,
// antd value widgets
TextWidget: ElementType<TextWidgetProps>,
TextAreaWidget: ElementType<TextWidgetProps>,
NumberWidget: ElementType<NumberWidgetProps>,
SliderWidget: ElementType<NumberWidgetProps>,
RangeWidget: ElementType<RangeSliderWidgetProps>,
SelectWidget: ElementType<SelectWidgetProps>,
AutocompleteWidget: ElementType<SelectWidgetProps>,
MultiSelectWidget: ElementType<SelectWidgetProps>,
TreeSelectWidget: ElementType<TreeSelectWidgetProps>,
DateWidget: ElementType<DateTimeWidgetProps>,
TimeWidget: ElementType<DateTimeWidgetProps>,
DateTimeWidget: ElementType<DateTimeWidgetProps>,
BooleanWidget: ElementType<BooleanWidgetProps>,
}
interface ReadyWidgets extends VanillaWidgets {
ValueFieldWidget: ElementType<WidgetProps>,
FuncWidget: ElementType<WidgetProps>,
}
export interface MaterialWidgets {
// material core widgets
MaterialFieldSelect: ElementType<FieldProps>,
MaterialFieldAutocomplete: ElementType<FieldProps>,
MaterialConjs: ElementType<ConjsProps>,
MaterialSwitch: ElementType<SwitchProps>,
MaterialButton: ElementType<ButtonProps>,
MaterialButtonGroup: ElementType<ButtonGroupProps>,
MaterialProvider: ElementType<ProviderProps>,
MaterialValueSources: ElementType<ValueSourcesProps>,
MaterialConfirm: ConfirmFunc,
MaterialUseConfirm: () => Function,
// material core widgets
MaterialBooleanWidget: ElementType<BooleanWidgetProps>,
MaterialTextWidget: ElementType<TextWidgetProps>,
MaterialTextAreaWidget: ElementType<TextWidgetProps>,
MaterialDateWidget: ElementType<DateTimeWidgetProps>,
MaterialTimeWidget: ElementType<DateTimeWidgetProps>,
MaterialDateTimeWidget: ElementType<DateTimeWidgetProps>,
MaterialMultiSelectWidget: ElementType<SelectWidgetProps>,
MaterialSelectWidget: ElementType<SelectWidgetProps>,
MaterialNumberWidget: ElementType<NumberWidgetProps>,
MaterialSliderWidget: ElementType<NumberWidgetProps>,
MaterialRangeWidget: ElementType<RangeSliderWidgetProps>,
MaterialAutocompleteWidget: ElementType<SelectWidgetProps>,
}
export interface BootstrapWidgets {
// bootstrap core widgets
BootstrapFieldSelect: ElementType<FieldProps>,
BootstrapConjs: ElementType<ConjsProps>,
BootstrapButton: ElementType<ButtonProps>,
BootstrapButtonGroup: ElementType<ButtonGroupProps>,
BootstrapProvider: ElementType<ProviderProps>,
BootstrapValueSources: ElementType<ValueSourcesProps>,
BootstrapConfirm: ConfirmFunc,
// bootstrap value widgets
BootstrapBooleanWidget: ElementType<BooleanWidgetProps>,
BootstrapTextWidget: ElementType<TextWidgetProps>,
BootstrapTextAreaWidget: ElementType<TextWidgetProps>,
BootstrapDateWidget: ElementType<DateTimeWidgetProps>,
BootstrapTimeWidget: ElementType<DateTimeWidgetProps>,
BootstrapDateTimeWidget: ElementType<DateTimeWidgetProps>,
BootstrapMultiSelectWidget: ElementType<SelectWidgetProps>,
BootstrapSelectWidget: ElementType<SelectWidgetProps>,
BootstrapNumberWidget: ElementType<NumberWidgetProps>,
BootstrapSliderWidget: ElementType<NumberWidgetProps>,
}
export interface MuiWidgets {
// material core widgets
MuiFieldSelect: ElementType<FieldProps>,
MuiFieldAutocomplete: ElementType<FieldProps>,
MuiConjs: ElementType<ConjsProps>,
MuiSwitch: ElementType<SwitchProps>,
MuiButton: ElementType<ButtonProps>,
MuiButtonGroup: ElementType<ButtonGroupProps>,
MuiProvider: ElementType<ProviderProps>,
MuiValueSources: ElementType<ValueSourcesProps>,
MuiConfirm: ConfirmFunc,
MuiUseConfirm: () => Function,
// material core widgets
MuiBooleanWidget: ElementType<BooleanWidgetProps>,
MuiTextWidget: ElementType<TextWidgetProps>,
MuiTextAreaWidget: ElementType<TextWidgetProps>,
MuiDateWidget: ElementType<DateTimeWidgetProps>,
MuiTimeWidget: ElementType<DateTimeWidgetProps>,
MuiDateTimeWidget: ElementType<DateTimeWidgetProps>,
MuiMultiSelectWidget: ElementType<SelectWidgetProps>,
MuiSelectWidget: ElementType<SelectWidgetProps>,
MuiNumberWidget: ElementType<NumberWidgetProps>,
MuiSliderWidget: ElementType<NumberWidgetProps>,
MuiRangeWidget: ElementType<RangeSliderWidgetProps>,
MuiAutocompleteWidget: ElementType<SelectWidgetProps>,
}
/////////////////
export const Utils: Utils;
export const Query: Query;
export const Builder: Builder;
export const BasicConfig: BasicConfig;
export const BasicFuncs: Funcs;
export const Widgets: ReadyWidgets;