Skip to content

Commit

Permalink
LHS by rhallerman1 #896 deformatted (#900)
Browse files Browse the repository at this point in the history
* LHS rhallerman1 #896 deformatted

* fix lint & test

* .

* fix

* fix sh

* renderFieldSources for all ui

* remove valueSources from func root

* restore

* wip

* seamless change func to compatible one

* fix

* highlight fields/funcs matching fieldType

* fieldSourcesPopupTitle

* fix #929

* mui vs

* wip import from jl/spel

* ref

* support now()

* .

* ctor args

* spelImport, spelFunc

* spelImportFuncs, spelImportValue for func -> value

* datetime spel works perfectly

* getFieldParts, getFieldPath

* ' actionmate

* support funcs for mongo, sql, es, string

* fix tests

* lint fix

* chlog, readme

* test #923

* fix #929

* nit

* freeze config, isFieldDescendantOfField

* lint and test fix

* fix for #949

* fix fieldNane #609

* isOptional, defaultValue

* .

* optimize render;   todo:  filter edge cases?

* remove fieldSrc from funcs

* fix logs

* test "change field source to func, and vice versa"

* css fixes

* nit

* fix del group ext

* lint-fix
  • Loading branch information
ukrbublik committed Jul 21, 2023
1 parent a04dcbd commit c14f0ae
Show file tree
Hide file tree
Showing 106 changed files with 4,020 additions and 1,385 deletions.
4 changes: 2 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ module.exports = {
"@typescript-eslint/prefer-regexp-exec": 0,
"@typescript-eslint/no-empty-function": 0,
"@typescript-eslint/ban-ts-comment": 0,
"@typescript-eslint/no-floating-promises": 0

"@typescript-eslint/no-floating-promises": 0,
"@typescript-eslint/no-non-null-assertion": 0,
}
},
],
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Changelog
- 6.4.0
- Functions can be used in LHS with `fieldSources: ["field", "func"]` in `settings`
Thanks @rhallerman1 (PR #900, #896) (issues #287, #250, #344, #336)
- Support import/export of functions for SpEL (PR #900) (issue #754)
- Fix issue with `fieldName` (PR #900) (issues #929, #609)
- 6.3.0
- Allow saving and loading config from server (PR #866) (issue #817)
- New utils: `compressConfig()`, `decompressConfig()`
Expand Down
7 changes: 6 additions & 1 deletion CONFIG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ const { FieldCascader, FieldDropdown, FieldTreeSelect } = AntdWidgets;
widget: "func",
}
},
fieldSources: ["field", "func"],
locale: {
moment: 'ru',
antd: ru_RU,
Expand Down Expand Up @@ -304,6 +305,8 @@ Behaviour settings:
|valueSourcesInfo |`{value: {}}` |By default fields can be compared with values. +
If you want to enable comparing with another fields, add `field` like in example above. +
If you want to enable comparing with result of function, add `func` like in example above.
|fieldSources |`["field"]` |To enable functions in LHS, set to `["field", "func"]`
|keepInputOnChangeFieldSrc |true |Keep value entered in RHS after changing source of LHS?
|showErrorMessage |false |Show error message in QueryBuilder if validateValue() in field config returns false
|canReorder |true |Activate reordering support for rules and groups of rules?
|canRegroup |true |Allow move rules (or groups) in/out groups during reorder? +
Expand Down Expand Up @@ -431,6 +434,7 @@ Localization:
|addRuleLabel |Add rule
|addSubRuleLabel |Add sub rule
|notLabel |Not
|fieldSourcesPopupTitle |Select source
|valueSourcesPopupTitle |Select value source
|removeRuleConfirmOptions |If you want to ask confirmation of removing non-empty rule/group, add these options. +
List of all valid properties is https://ant.design/components/modal/#API[here]
Expand Down Expand Up @@ -745,6 +749,7 @@ To enable this feature set `valueSources` of type to `['value', 'func']` (see be
|mongoFormatFunc |- for MongoDB format | |Can be used instead of `mongoFunc`. Function with 1 param - args object `{<arg name> : <arg value>}`, should return formatted function expression object.
|jsonLogic |+ for http://jsonlogic.com[JsonLogic] | |String (function name) or function with 1 param - args object `{<arg name> : <arg value>}`, should return formatted function expression for JsonLogic.
|jsonLogicImport | | |Function to convert given JsonLogic expression to array of arguments of current function. If given expression can't be parsed into current function, throw an error.
|spelImport | | |Function to convert given raw SpEL value to array of arguments of current function. If given value can't be parsed into current function, throw an error.
|args.* | | |Arguments of function. Config is almost same as for simple link:#configfields[fields]
|args.<arg>.label | |arg's key |Label to be displayed in arg's label or placeholder (if `config.settings.showLabels` is false)
|args.<arg>.type |+ | |One of types described in link:#configtypes[config.types]
Expand Down Expand Up @@ -854,7 +859,7 @@ const ctx = {
return (val.length < 10);
},
myRenderField: (props: FieldProps, _ctx: ConfigContext) => {
if (props?.customProps["showSearch"]) {
if (props.customProps?.["showSearch"]) {
return <MuiFieldAutocomplete {...props}/>;
} else {
return <MuiFieldSelect {...props}/>;
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ See [live demo](https://ukrbublik.github.io/react-awesome-query-builder)
* [ctx](#ctx)
* [Versions](#versions)
* [Changelog](#changelog)
* [Migration to 6.4.0](#migration-to-640)
* [Migration to 6.3.0](#migration-to-630)
* [Migration to 6.2.0](#migration-to-620)
* [Migration to 6.0.0](#migration-to-600)
Expand All @@ -68,10 +69,11 @@ See [live demo](https://ukrbublik.github.io/react-awesome-query-builder)
- unary (is empty, is null)
- 'between' (for numbers, dates, times)
- complex operators like 'proximity'
- Values of fields can be compared with:
- RHS can be:
- values
- another fields (of same type)
- function (arguments also can be values/fields/funcs)
- functions (arguments also can be values/fields/funcs)
- LHS can be field or function
- Reordering (drag-n-drop) support for rules and groups of rules
- Themes:
- [Ant Design](https://ant.design/)
Expand Down Expand Up @@ -507,6 +509,13 @@ It's recommended to update your version to 6.x. You just need to change your imp
### Changelog
See [`CHANGELOG`](/CHANGELOG.md)

### Migration to 6.4.0

If you want to enable functions in LHS, please add to `config.settings`:
```js
fieldSources: ["field", "func"],
```

### Migration to 6.3.0

Now config has new [`ctx`](#ctx) property. Make sure you add it to your config.
Expand Down
7 changes: 4 additions & 3 deletions packages/antd/modules/config/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ const settings = {
...BasicConfig.settings,

renderField: (props, {RCE, W: {FieldSelect}}) => RCE(FieldSelect, props),
// renderField: (props, {RCE, W: {FieldDropdown}}) => RCE(FieldSelect, props),
// renderField: (props, {RCE, W: {FieldCascader}}) => RCE(FieldSelect, props),
// renderField: (props, {RCE, W: {FieldTreeSelect}}) => RCE(FieldSelect, props),
// renderField: (props, {RCE, W: {FieldDropdown}}) => RCE(FieldDropdown, props),
// renderField: (props, {RCE, W: {FieldCascader}}) => RCE(FieldCascader, props),
// renderField: (props, {RCE, W: {FieldTreeSelect}}) => RCE(FieldTreeSelect, props),

renderOperator: (props, {RCE, W: {FieldSelect}}) => RCE(FieldSelect, props),
// renderOperator: (props, {RCE, W: {FieldDropdown}}) => RCE(FieldDropdown, props),
Expand All @@ -23,6 +23,7 @@ const settings = {
renderButton: (props, {RCE, W: {Button}}) => RCE(Button, props),
renderButtonGroup: (props, {RCE, W: {ButtonGroup}}) => RCE(ButtonGroup, props),
renderValueSources: (props, {RCE, W: {ValueSources}}) => RCE(ValueSources, props),
renderFieldSources: (props, {RCE, W: {ValueSources}}) => RCE(ValueSources, props),
renderProvider: (props, {RCE, W: {Provider}}) => RCE(Provider, props),
renderConfirm: (props, {W: {confirm}}) => confirm(props),

Expand Down
45 changes: 40 additions & 5 deletions packages/antd/modules/widgets/core/FieldCascader.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import React, { PureComponent } from "react";
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Cascader, Tooltip } from "antd";
import {removePrefixPath} from "../../utils/stuff";
import { Utils } from "@react-awesome-query-builder/ui";
const { useOnPropsChanged } = Utils.ReactUtils;
const { getFieldParts } = Utils.ConfigUtils;


export default class FieldCascader extends PureComponent {
export default class FieldCascader extends Component {
static propTypes = {
config: PropTypes.object.isRequired,
customProps: PropTypes.object,
errorText: PropTypes.string,
items: PropTypes.array.isRequired,
placeholder: PropTypes.string,
selectedKey: PropTypes.string,
Expand All @@ -22,6 +26,36 @@ export default class FieldCascader extends PureComponent {
setField: PropTypes.func.isRequired,
};

constructor(props) {
super(props);
useOnPropsChanged(this);
this.onPropsChanged(props);
}

onPropsChanged(nextProps) {
const { items } = nextProps;
this.items = this.getItems(items);
}

getItems(items) {
return items.map(item => {
const {items, matchesType, label} = item;

if (items) {
return {
...item,
items: this.getItems(items),
label: matchesType ? <b>{label}</b> : label,
};
} else {
return {
...item,
label: matchesType ? <b>{label}</b> : label,
};
}
});
}

onChange = (keys) => {
const { parentField } = this.props;
const dotNotationToPath = str => str.split(".");
Expand All @@ -38,7 +72,7 @@ export default class FieldCascader extends PureComponent {

render() {
const {
config, customProps, items, placeholder,
config, customProps, items, placeholder, errorText,
selectedPath, selectedLabel, selectedOpts, selectedAltLabel, selectedFullLabel, readonly, selectedField, parentField,
} = this.props;
let customProps2 = {...customProps};
Expand All @@ -49,12 +83,13 @@ export default class FieldCascader extends PureComponent {
}

const {fieldSeparator} = config.settings;
const parentFieldPath = parentField ? parentField.split(fieldSeparator) : [];
const parentFieldPath = getFieldParts(parentField, config);
const value = removePrefixPath(selectedPath, parentFieldPath);
let res = (
<Cascader
status={errorText && "error"}
fieldNames={{ label: "label", value: "key", children: "items" }}
options={items}
options={this.items}
value={value}
onChange={this.onChange}
allowClear={false}
Expand Down
16 changes: 10 additions & 6 deletions packages/antd/modules/widgets/core/FieldDropdown.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import omit from "lodash/omit";
import { Menu, Dropdown, Tooltip, Button } from "antd";
const SubMenu = Menu.SubMenu;
const MenuItem = Menu.Item;
Expand All @@ -10,6 +11,7 @@ export default class FieldDropdown extends PureComponent {
static propTypes = {
config: PropTypes.object.isRequired,
customProps: PropTypes.object,
errorText: PropTypes.string,
items: PropTypes.array.isRequired,
placeholder: PropTypes.string,
selectedKey: PropTypes.string,
Expand All @@ -30,9 +32,10 @@ export default class FieldDropdown extends PureComponent {

renderMenuItems(fields) {
return fields.map(field => {
const {items, key, path, label, fullLabel, altLabel, tooltip, disabled} = field;
const {items, key, path, label, fullLabel, altLabel, tooltip, disabled, matchesType} = field;
const pathKey = path || key;
const option = tooltip ? <Tooltip title={tooltip}>{label}</Tooltip> : label;
const optionText = matchesType ? <b>{label}</b> : label;
const option = tooltip ? <Tooltip title={tooltip}>{optionText}</Tooltip> : optionText;

if (items) {
return <SubMenu
Expand All @@ -52,11 +55,12 @@ export default class FieldDropdown extends PureComponent {
});
}

renderMenuToggler(togglerLabel, tooltipText, config, readonly) {
renderMenuToggler(togglerLabel, tooltipText, config, readonly, errorText) {
let toggler
= <Button
size={config.settings.renderSize}
disabled={readonly}
danger={!!errorText}
>
{togglerLabel} <DownOutlined />
</Button>;
Expand All @@ -76,7 +80,7 @@ export default class FieldDropdown extends PureComponent {

render() {
const {
config, customProps, items, placeholder,
config, customProps, items, placeholder, errorText,
selectedKeys, selectedLabel, selectedOpts, readonly, selectedAltLabel, selectedFullLabel,
} = this.props;

Expand All @@ -87,14 +91,14 @@ export default class FieldDropdown extends PureComponent {
//size={config.settings.renderSize}
selectedKeys={selectedKeys}
onClick={this.onChange}
{...customProps}
{...omit(customProps, ["showSearch"])}
>{fieldMenuItems}</Menu>
);
const togglerLabel = selectedAltLabel || selectedLabel || placeholder;
let tooltipText = selectedFullLabel;
if (tooltipText == selectedLabel)
tooltipText = null;
const fieldToggler = this.renderMenuToggler(togglerLabel, tooltipText, config, readonly);
const fieldToggler = this.renderMenuToggler(togglerLabel, tooltipText, config, readonly, errorText);

return readonly ? fieldToggler : (
<Dropdown
Expand Down
10 changes: 7 additions & 3 deletions packages/antd/modules/widgets/core/FieldSelect.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default class FieldSelect extends PureComponent {
static propTypes = {
config: PropTypes.object.isRequired,
customProps: PropTypes.object,
errorText: PropTypes.string,
items: PropTypes.array.isRequired,
placeholder: PropTypes.string,
selectedKey: PropTypes.string,
Expand Down Expand Up @@ -39,7 +40,7 @@ export default class FieldSelect extends PureComponent {
render() {
const {
config, customProps, items, placeholder,
selectedKey, selectedLabel, selectedOpts, selectedAltLabel, selectedFullLabel, readonly,
selectedKey, selectedLabel, selectedOpts, selectedAltLabel, selectedFullLabel, readonly, errorText,
} = this.props;
const {showSearch} = customProps || {};

Expand Down Expand Up @@ -67,6 +68,7 @@ export default class FieldSelect extends PureComponent {
optionLabelProp={"label"}
filterOption={this.filterOption}
disabled={readonly}
status={errorText && "error"}
{...customProps}
>{fieldSelectItems}</Select>
);
Expand All @@ -80,7 +82,7 @@ export default class FieldSelect extends PureComponent {

renderSelectItems(fields, level = 0) {
return fields.map(field => {
const {items, key, path, label, fullLabel, altLabel, tooltip, grouplabel, disabled} = field;
const {items, key, path, label, fullLabel, altLabel, tooltip, grouplabel, disabled, matchesType} = field;
const groupPrefix = level > 0 ? "\u00A0\u00A0".repeat(level) : "";
const prefix = level > 1 ? "\u00A0\u00A0".repeat(level-1) : "";
const pathKey = path || key;
Expand All @@ -96,7 +98,9 @@ export default class FieldSelect extends PureComponent {
const list = complexItems.length ? this.renderSelectItems(complexItems, level+1) : [];
return [...gr, ...list];
} else {
const option = tooltip ? <Tooltip title={tooltip}>{prefix+label}</Tooltip> : prefix+label;
const optionText = matchesType ? <b>{prefix+label}</b> : prefix+label;
const option = tooltip ? <Tooltip title={tooltip}>{optionText}</Tooltip> : optionText;

return <Option
key={pathKey}
value={pathKey}
Expand Down
11 changes: 7 additions & 4 deletions packages/antd/modules/widgets/core/FieldTreeSelect.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default class FieldTreeSelect extends Component {
static propTypes = {
config: PropTypes.object.isRequired,
customProps: PropTypes.object,
errorText: PropTypes.string,
items: PropTypes.array.isRequired,
placeholder: PropTypes.string,
selectedKey: PropTypes.string,
Expand All @@ -26,7 +27,7 @@ export default class FieldTreeSelect extends Component {
constructor(props) {
super(props);
useOnPropsChanged(this);
this.onPropsChanged(props);
this.onPropsChanged(props);
}

onPropsChanged(nextProps) {
Expand All @@ -48,11 +49,12 @@ export default class FieldTreeSelect extends Component {

getTreeData(fields, fn = null) {
return fields.map(field => {
const {items, key, path, label, fullLabel, altLabel, tooltip, disabled} = field;
const {items, key, path, label, fullLabel, altLabel, tooltip, disabled, matchesType} = field;
if (fn)
fn(field);
const pathKey = path || key;
const option = tooltip ? <Tooltip title={tooltip}>{label}</Tooltip> : label;
const optionText = matchesType ? <b>{label}</b> : label;
const option = tooltip ? <Tooltip title={tooltip}>{optionText}</Tooltip> : optionText;

if (items) {
return {
Expand Down Expand Up @@ -94,7 +96,7 @@ export default class FieldTreeSelect extends Component {

render() {
const {
config, customProps = {}, placeholder,
config, customProps = {}, placeholder, errorText,
selectedKey, selectedLabel, selectedOpts, selectedAltLabel, selectedFullLabel, readonly,
} = this.props;
const { renderSize, fieldSeparator } = config.settings;
Expand All @@ -118,6 +120,7 @@ export default class FieldTreeSelect extends Component {

let res = (
<TreeSelect
status={errorText && "error"}
onChange={this.onChange}
value={selectedKey || undefined}
style={{
Expand Down
2 changes: 1 addition & 1 deletion packages/antd/modules/widgets/value/Boolean.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default class BooleanWidget extends PureComponent {
setValue: PropTypes.func.isRequired,
value: PropTypes.bool,
config: PropTypes.object.isRequired,
field: PropTypes.string.isRequired,
field: PropTypes.any,
customProps: PropTypes.object,
readonly: PropTypes.bool,
// from fieldSettings:
Expand Down
2 changes: 1 addition & 1 deletion packages/antd/modules/widgets/value/Date.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default class DateWidget extends PureComponent {
static propTypes = {
setValue: PropTypes.func.isRequired,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]) , //in valueFormat
field: PropTypes.string.isRequired,
field: PropTypes.any,
config: PropTypes.object.isRequired,
placeholder: PropTypes.string,
placeholders: PropTypes.arrayOf(PropTypes.string),
Expand Down
2 changes: 1 addition & 1 deletion packages/antd/modules/widgets/value/DateTime.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default class DateTimeWidget extends PureComponent {
setValue: PropTypes.func.isRequired,
value: PropTypes.string, //in valueFormat
config: PropTypes.object.isRequired,
field: PropTypes.string.isRequired,
field: PropTypes.any,
placeholder: PropTypes.string,
customProps: PropTypes.object,
readonly: PropTypes.bool,
Expand Down
2 changes: 1 addition & 1 deletion packages/antd/modules/widgets/value/MultiSelect.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class MultiSelectWidget extends Component {
setValue: PropTypes.func.isRequired,
config: PropTypes.object.isRequired,
value: PropTypes.array,
field: PropTypes.string.isRequired,
field: PropTypes.any,
placeholder: PropTypes.string,
customProps: PropTypes.object,
fieldDefinition: PropTypes.object,
Expand Down

3 comments on commit c14f0ae

@vercel
Copy link

@vercel vercel bot commented on c14f0ae Jul 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on c14f0ae Jul 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on c14f0ae Jul 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.