@truedat/dq 4.28.5 → 4.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,12 @@
1
1
  import _ from "lodash/fp";
2
2
  import React from "react";
3
- import { Form } from "semantic-ui-react";
3
+ import { Form, Dropdown } from "semantic-ui-react";
4
4
  import PropTypes from "prop-types";
5
5
  import { useIntl } from "react-intl";
6
6
  import { getStructureFields } from "../../selectors/getStructureFields";
7
7
  import FiltersField from "./FiltersField";
8
+ import FieldModifier from "./FieldModifier";
9
+ import operatorFunctions from "./operators";
8
10
 
9
11
  const OptionGroup = React.lazy(() =>
10
12
  import("@truedat/core/components/OptionGroup")
@@ -20,47 +22,102 @@ const ValueConditionStructure = React.lazy(() =>
20
22
 
21
23
  export const FiltersFormGroup = ({
22
24
  clause = {},
23
- getOperators,
24
- getOperatorValue,
25
25
  index,
26
26
  onOperatorChange,
27
27
  onStructureChange,
28
28
  onValueChange,
29
+ onModifierChange,
29
30
  parentStructures,
30
31
  siblings,
31
32
  scope,
33
+ operators,
32
34
  }) => {
33
35
  const { formatMessage } = useIntl();
34
- const fieldType = clause?.structure?.field_type;
36
+ const structureFieldType = clause?.structure?.field_type;
37
+ const modifiers = _.path(`${structureFieldType}.modifiers`)(operators);
38
+ const modifierValue = clause?.modifier;
39
+ const modifier = _.find({ name: modifierValue?.name })(modifiers);
40
+
41
+ const fieldType = modifier?.cast_as || structureFieldType;
35
42
  const nestedCondition = !_.isEmpty(siblings);
36
- const operators = getOperators(fieldType, scope, nestedCondition);
37
43
  const structureFields = getStructureFields(parentStructures);
44
+
45
+ const { operatorsOptions, getOperatorValue, typeCastModifiers } =
46
+ operatorFunctions(
47
+ operators,
48
+ fieldType,
49
+ nestedCondition,
50
+ scope,
51
+ formatMessage
52
+ );
53
+
38
54
  return (
39
55
  <Form.Group className={"force-margin-bottom"}>
40
- <Form.Field width={4}>
41
- {nestedCondition ? (
42
- <ValueConditionStructure
43
- siblings={siblings}
44
- value={clause?.structure?.id}
45
- onChange={(value) => onStructureChange(index, value)}
46
- />
47
- ) : (
48
- <StructureFieldsDropdown
49
- label={formatMessage({ id: "filtersGrid.field.label" })}
50
- inline={false}
51
- parentStructures={parentStructures}
52
- structureFields={structureFields}
53
- onSelectField={(value) => onStructureChange(index, value)}
54
- value={clause?.structure?.id}
56
+ <div>
57
+ <div className={"flex-row-align-end"}>
58
+ <Form.Field>
59
+ {nestedCondition ? (
60
+ <ValueConditionStructure
61
+ siblings={siblings}
62
+ value={clause?.structure?.id}
63
+ onChange={(value) => onStructureChange(index, value)}
64
+ />
65
+ ) : (
66
+ <StructureFieldsDropdown
67
+ label={formatMessage({ id: "filtersGrid.field.label" })}
68
+ inline={false}
69
+ parentStructures={parentStructures}
70
+ structureFields={structureFields}
71
+ onSelectField={(value) => onStructureChange(index, value)}
72
+ value={clause?.structure?.id}
73
+ />
74
+ )}
75
+ </Form.Field>
76
+ {clause?.structure && !_.isEmpty(modifiers) && (
77
+ <Dropdown
78
+ className={"icon-dropdown-margin"}
79
+ size="mini"
80
+ icon="ellipsis vertical"
81
+ >
82
+ <Dropdown.Menu>
83
+ {modifiers.map((modifier, key) => (
84
+ <Dropdown.Item
85
+ key={key}
86
+ icon={
87
+ modifier.cast_as
88
+ ? formatMessage({
89
+ id: `field_type.icon.${modifier.cast_as}`,
90
+ defaultMessage: "hashtag",
91
+ })
92
+ : null
93
+ }
94
+ text={formatMessage({
95
+ id: `filtersGrid.field.modifier.${modifier.name}`,
96
+ })}
97
+ onClick={() =>
98
+ onModifierChange(index, { name: modifier.name })
99
+ }
100
+ />
101
+ ))}
102
+ </Dropdown.Menu>
103
+ </Dropdown>
104
+ )}
105
+ </div>
106
+ {modifier && (
107
+ <FieldModifier
108
+ modifier={modifier}
109
+ value={modifierValue}
110
+ onChange={(value) => onModifierChange(index, value)}
111
+ removable
55
112
  />
56
113
  )}
57
- </Form.Field>
114
+ </div>
58
115
  <Form.Field>
59
116
  <OptionGroup
60
117
  label={formatMessage({
61
118
  id: "filtersGrid.field.operator",
62
119
  })}
63
- options={operators}
120
+ options={operatorsOptions}
64
121
  value={getOperatorValue(clause)}
65
122
  onClick={({ id }) => onOperatorChange(index, id)}
66
123
  placeholder={formatMessage({
@@ -77,12 +134,14 @@ export const FiltersFormGroup = ({
77
134
  <FiltersField
78
135
  parentStructures={parentStructures}
79
136
  fieldType={fieldType}
137
+ typeCastModifiers={typeCastModifiers}
80
138
  operator={clause?.operator}
81
139
  value={_.nth(nth_value)(clause?.value)}
140
+ modifier={_.nth(nth_value)(clause?.value_modifier)}
82
141
  label={formatMessage({ id: "filtersGrid.field.value" })}
83
- onChange={(e, value) => {
84
- onValueChange(index, value, nth_value);
85
- }}
142
+ onChange={(_e, value, modifier) =>
143
+ onValueChange(index, value, modifier, nth_value)
144
+ }
86
145
  />
87
146
  </Form.Field>
88
147
  ))}
@@ -92,15 +151,15 @@ export const FiltersFormGroup = ({
92
151
 
93
152
  FiltersFormGroup.propTypes = {
94
153
  clause: PropTypes.object,
95
- getOperators: PropTypes.func,
96
- getOperatorValue: PropTypes.func,
97
154
  index: PropTypes.number,
98
155
  onOperatorChange: PropTypes.func,
99
156
  onStructureChange: PropTypes.func,
100
157
  onValueChange: PropTypes.func,
158
+ onModifierChange: PropTypes.func,
101
159
  parentStructures: PropTypes.array,
102
160
  siblings: PropTypes.array,
103
161
  scope: PropTypes.string,
162
+ operators: PropTypes.array,
104
163
  };
105
164
 
106
165
  export default FiltersFormGroup;
@@ -1,7 +1,6 @@
1
1
  import _ from "lodash/fp";
2
2
  import React, { useState } from "react";
3
3
  import PropTypes from "prop-types";
4
- import { useIntl } from "react-intl";
5
4
  import { Button, Grid } from "semantic-ui-react";
6
5
  import FiltersGroup from "./FiltersGroup";
7
6
 
@@ -13,7 +12,6 @@ export const FiltersGrid = ({
13
12
  scope,
14
13
  }) => {
15
14
  const [activeConditionIndex, setActiveConditionIndex] = useState();
16
- const { formatMessage } = useIntl();
17
15
  const parentStructures = _.map("structure")(structures);
18
16
  const allOperators = _.flow(
19
17
  _.values,
@@ -21,80 +19,6 @@ export const FiltersGrid = ({
21
19
  _.flatten
22
20
  )(typeOperators);
23
21
 
24
- const inScope = (operator, scope) => {
25
- const op_scope = _.prop("scope")(operator);
26
- return (
27
- _.isNull(op_scope) || _.isEmpty(op_scope) || _.isEqual(scope)(op_scope)
28
- );
29
- };
30
-
31
- const getOptions = (field_type, operators) =>
32
- _.flow(
33
- _.groupBy("group"),
34
- _.reduce.convert({ cap: false })(
35
- (acc, v, k) =>
36
- _.isNil(k) || k === "undefined" || _.size(v) <= 1
37
- ? [...acc, ...v]
38
- : [...acc, { label: k, options: v }],
39
- []
40
- ),
41
- _.sortBy(["label"]),
42
- _.map((o) => operatorOptions(field_type, o))
43
- )(operators);
44
-
45
- const operatorOptions = (field_type, operator) =>
46
- _.has("options")(operator)
47
- ? {
48
- icon: "random",
49
- label: formatMessage({
50
- id: `ruleImplementation.operator.group.${operator.label}`,
51
- }),
52
- options: _.map((o) => toOperatorOption(field_type, o))(
53
- operator.options
54
- ),
55
- }
56
- : toOperatorOption(field_type, operator);
57
-
58
- const toOperatorOption = (field_type, operator) => ({
59
- text: formatMessage({
60
- id: withValueType(
61
- `ruleImplementation.operator.${operator.name}`,
62
- operator.value_type
63
- ),
64
- }),
65
- id: operator.id,
66
- value: withValueType(`${field_type}.${operator.name}`, operator.value_type),
67
- });
68
-
69
- const getOperatorValue = (row) =>
70
- _.has("operator")(row) && !_.isEmpty(row.operator)
71
- ? withValueType(
72
- `${_.path("structure.field_type")(row)}.${_.path("operator.name")(
73
- row
74
- )}`,
75
- _.path("operator.value_type")(row)
76
- )
77
- : null;
78
-
79
- const withValueType = (value, valueType) =>
80
- valueType ? `${value}.${valueType}` : value;
81
-
82
- const filterFieldType = (operators, nested) =>
83
- nested ? _.filter((o) => o?.value_type !== "field")(operators) : operators;
84
-
85
- const getOperators = (type, scope, nested) =>
86
- !type
87
- ? []
88
- : _.flow(
89
- _.pick([type, "any"]),
90
- _.values,
91
- _.map(_.prop("operators")),
92
- _.flatten,
93
- _.filter((operator) => inScope(operator, scope)),
94
- (operators) => filterFieldType(operators, nested),
95
- (operators) => getOptions(type, operators)
96
- )(typeOperators);
97
-
98
22
  const onStructureChange = (index, value) => {
99
23
  const structure = {
100
24
  ..._.pick(["field_type", "name"])(value),
@@ -102,14 +26,36 @@ export const FiltersGrid = ({
102
26
  };
103
27
  setRowValue({
104
28
  index,
105
- value: { structure: structure, operator: {}, value: {} },
29
+ value: {
30
+ structure,
31
+ modifier: null,
32
+ operator: {},
33
+ value: null,
34
+ value_modifier: null,
35
+ },
36
+ });
37
+ };
38
+
39
+ const onModifierChange = (index, modifier) => {
40
+ const rowValue = _.nth(index)(rows);
41
+
42
+ setRowValue({
43
+ index,
44
+ value: {
45
+ ...rowValue,
46
+ modifier,
47
+ operator: {},
48
+ value: null,
49
+ value_modifier: null,
50
+ population: null,
51
+ },
106
52
  });
107
53
  };
108
54
 
109
55
  const composeValue = (value_type, value) => {
110
56
  if (value_type == "field") {
111
57
  return {
112
- id: value.data_structure_id,
58
+ id: value.data_structure_id || value.id,
113
59
  name: value.name,
114
60
  path: value.path,
115
61
  };
@@ -118,12 +64,15 @@ export const FiltersGrid = ({
118
64
  }
119
65
  };
120
66
 
121
- const onValueChange = (rowIndex, value, valueIndex) => {
67
+ const onValueChange = (rowIndex, value, modifier = null, valueIndex) => {
122
68
  const rowValue = _.nth(rowIndex)(rows);
123
69
  const value_type = _.path("operator.value_type")(rowValue);
124
70
 
125
71
  const firstValue = _.nth(0)(_.path("value")(rowValue));
126
72
  const secondValue = _.nth(1)(_.path("value")(rowValue));
73
+ const firstModifier = _.nth(0)(_.path("value_modifier")(rowValue));
74
+ const secondModifier = _.nth(1)(_.path("value_modifier")(rowValue));
75
+
127
76
  const arity = _.path("operator.arity")(rowValue)
128
77
  ? _.path("operator.arity")(rowValue)
129
78
  : 1;
@@ -132,11 +81,15 @@ export const FiltersGrid = ({
132
81
  ? [composeValue(value_type, value), secondValue]
133
82
  : [firstValue, composeValue(value_type, value)];
134
83
 
84
+ const updatedValueModifier =
85
+ valueIndex == 0 ? [modifier, secondModifier] : [firstModifier, modifier];
86
+
135
87
  setRowValue({
136
88
  index: rowIndex,
137
89
  value: {
138
90
  ...rowValue,
139
91
  value: _.take(arity)(updatedValue),
92
+ value_modifier: _.take(arity)(updatedValueModifier),
140
93
  population: null,
141
94
  },
142
95
  });
@@ -179,18 +132,18 @@ export const FiltersGrid = ({
179
132
  <FiltersGroup
180
133
  activeConditionIndex={activeConditionIndex}
181
134
  allOperators={allOperators}
135
+ operators={typeOperators}
182
136
  composeValue={composeValue}
183
137
  onConditionChange={onConditionChange}
184
138
  onOperatorChange={onOperatorChange}
185
139
  onStructureChange={onStructureChange}
186
140
  onValueChange={onValueChange}
141
+ onModifierChange={onModifierChange}
187
142
  parentStructures={parentStructures}
188
- getOperators={getOperators}
189
- getOperatorValue={getOperatorValue}
190
143
  rows={rows}
191
- scope={scope}
192
144
  setActiveConditionIndex={setActiveConditionIndex}
193
145
  setRowValue={setRowValue}
146
+ scope={scope}
194
147
  />
195
148
  </Grid>
196
149
  <Button onClick={onRowAddition} icon="plus circle" />
@@ -9,15 +9,15 @@ import FiltersFormGroup from "./FiltersFormGroup";
9
9
  const Filter = ({
10
10
  activeConditionIndex,
11
11
  allOperators,
12
+ operators,
12
13
  composeValue,
13
14
  clause,
14
- getOperators,
15
- getOperatorValue,
16
15
  index,
17
16
  onConditionChange,
18
17
  onOperatorChange,
19
18
  onStructureChange,
20
19
  onValueChange,
20
+ onModifierChange,
21
21
  parentStructures,
22
22
  setActiveConditionIndex,
23
23
  setRowValue,
@@ -54,14 +54,14 @@ const Filter = ({
54
54
  <Grid.Column width={14}>
55
55
  <FiltersFormGroup
56
56
  clause={clause}
57
- getOperators={getOperators}
58
- getOperatorValue={getOperatorValue}
59
57
  index={index}
60
58
  onOperatorChange={onOperatorChange}
61
59
  onStructureChange={onStructureChange}
62
60
  onValueChange={onValueChange}
61
+ onModifierChange={onModifierChange}
63
62
  parentStructures={parentStructures}
64
63
  scope={scope}
64
+ operators={operators}
65
65
  />
66
66
  </Grid.Column>
67
67
  <Grid.Column width={2} floated={"right"}>
@@ -106,9 +106,8 @@ const Filter = ({
106
106
  <Grid verticalAlign="middle">
107
107
  <ValueConditions
108
108
  allOperators={allOperators}
109
+ operators={operators}
109
110
  composeValue={composeValue}
110
- getOperators={getOperators}
111
- getOperatorValue={getOperatorValue}
112
111
  population={clause?.population || [{}]}
113
112
  onChange={onValueConditionChange}
114
113
  parentStructures={parentStructures}
@@ -126,31 +125,31 @@ const Filter = ({
126
125
  Filter.propTypes = {
127
126
  activeConditionIndex: PropTypes.number,
128
127
  allOperators: PropTypes.array,
128
+ operators: PropTypes.array,
129
129
  clause: PropTypes.object,
130
130
  composeValue: PropTypes.func,
131
131
  onConditionChange: PropTypes.func,
132
132
  onOperatorChange: PropTypes.func,
133
133
  onStructureChange: PropTypes.func,
134
134
  onValueChange: PropTypes.func,
135
+ onModifierChange: PropTypes.func,
135
136
  parentStructures: PropTypes.array,
136
137
  setActiveConditionIndex: PropTypes.func,
137
- getOperators: PropTypes.func,
138
- getOperatorValue: PropTypes.func,
139
138
  index: PropTypes.number,
140
- scope: PropTypes.func,
141
139
  setRowValue: PropTypes.func,
140
+ scope: PropTypes.string,
142
141
  };
143
142
 
144
143
  export const FiltersGroup = ({
145
144
  activeConditionIndex,
146
145
  allOperators,
146
+ operators,
147
147
  composeValue,
148
- getOperators,
149
- getOperatorValue,
150
148
  onConditionChange,
151
149
  onOperatorChange,
152
150
  onStructureChange,
153
151
  onValueChange,
152
+ onModifierChange,
154
153
  parentStructures,
155
154
  rows = [],
156
155
  setActiveConditionIndex,
@@ -162,15 +161,15 @@ export const FiltersGroup = ({
162
161
  key={index}
163
162
  activeConditionIndex={activeConditionIndex}
164
163
  allOperators={allOperators}
164
+ operators={operators}
165
165
  composeValue={composeValue}
166
166
  clause={clause}
167
- getOperators={getOperators}
168
- getOperatorValue={getOperatorValue}
169
167
  index={index}
170
168
  onConditionChange={onConditionChange}
171
169
  onOperatorChange={onOperatorChange}
172
170
  onStructureChange={onStructureChange}
173
171
  onValueChange={onValueChange}
172
+ onModifierChange={onModifierChange}
174
173
  parentStructures={parentStructures}
175
174
  setActiveConditionIndex={setActiveConditionIndex}
176
175
  setRowValue={setRowValue}
@@ -182,19 +181,19 @@ export const FiltersGroup = ({
182
181
  FiltersGroup.propTypes = {
183
182
  activeConditionIndex: PropTypes.number,
184
183
  allOperators: PropTypes.array,
184
+ operators: PropTypes.array,
185
185
  composeValue: PropTypes.func,
186
186
  onConditionChange: PropTypes.func,
187
187
  onOperatorChange: PropTypes.func,
188
188
  onStructureChange: PropTypes.func,
189
189
  onValueChange: PropTypes.func,
190
+ onModifierChange: PropTypes.func,
190
191
  rows: PropTypes.array,
191
192
  parentStructures: PropTypes.array,
192
193
  setActiveConditionIndex: PropTypes.func,
193
194
  siblingId: PropTypes.number,
194
- getOperators: PropTypes.func,
195
- getOperatorValue: PropTypes.func,
196
- scope: PropTypes.func,
197
195
  setRowValue: PropTypes.func,
196
+ scope: PropTypes.string,
198
197
  };
199
198
 
200
199
  export default FiltersGroup;
@@ -6,21 +6,18 @@ import { Grid, Icon, Segment } from "semantic-ui-react";
6
6
  import { dropAt, replaceAt } from "@truedat/core/services/arrays";
7
7
  import { FiltersGrid } from "./FiltersGrid";
8
8
 
9
- const PopulationTypeForm = ({ onSelect, selectAll }) => (
9
+ const PopulationTypeForm = ({ createFilter }) => (
10
10
  <Grid columns={2} textAlign="center">
11
11
  <Grid.Column>
12
- <Segment
13
- className={`population ${selectAll ? "active" : ""}`}
14
- onClick={() => onSelect(true)}
15
- >
12
+ <Segment className={`population active`}>
16
13
  <FormattedMessage id="populationForm.selectAll.text" />
17
- {selectAll && <Icon circular name="check" color="green" />}
14
+ <Icon circular name="check" color="green" />
18
15
  </Segment>
19
16
  </Grid.Column>
20
17
  <Grid.Column>
21
18
  <Segment
22
- className={`population selectable ${!selectAll ? "active" : ""}`}
23
- onClick={() => onSelect(false)}
19
+ className={`population selectable`}
20
+ onClick={() => createFilter()}
24
21
  >
25
22
  <Icon name="plus circle" />
26
23
  <FormattedMessage id="populationForm.createFilters.text" />
@@ -30,81 +27,39 @@ const PopulationTypeForm = ({ onSelect, selectAll }) => (
30
27
  );
31
28
 
32
29
  PopulationTypeForm.propTypes = {
33
- onSelect: PropTypes.func,
34
- selectAll: PropTypes.bool,
30
+ createFilter: PropTypes.func,
35
31
  };
36
32
 
37
- export class PopulationForm extends React.Component {
38
- static propTypes = {
39
- typeOperators: PropTypes.array,
40
- population: PropTypes.array,
41
- structures: PropTypes.array,
42
- setPopulation: PropTypes.func,
43
- };
44
-
45
- state = {
46
- selectAll: null,
47
- };
48
-
49
- componentDidMount() {
50
- this.setSelectAll(this.isEmptyPopulation());
51
- }
52
-
53
- componentDidUpdate(prevProps) {
54
- const { population } = this.props;
55
-
56
- if (prevProps.population != population) {
57
- this.setSelectAll(this.isEmptyPopulation());
58
- }
59
- }
60
-
61
- isEmptyPopulation() {
62
- const { population } = this.props;
63
- return (
64
- _.isEmpty(population) ||
65
- (population.length == 1 && _.isEmpty(_.nth(0)(population)))
66
- );
67
- }
68
-
69
- setSelectAll = (selectAll) => {
70
- this.setState({
71
- selectAll: selectAll,
72
- });
73
- };
74
-
75
- setPopulationField = ({ index, value }) => {
76
- const { setPopulation, population } = this.props;
33
+ export default function PopulationForm({
34
+ typeOperators,
35
+ population,
36
+ structures,
37
+ setPopulation,
38
+ }) {
39
+ const setPopulationField = ({ index, value }) => {
77
40
  if (_.isNil(index)) {
78
- setPopulation(_.isEmpty(population) ? [{}] : [...population, {}]);
41
+ setPopulation(_.isEmpty(population) ? [] : [...population, {}]);
79
42
  } else if (value) {
80
43
  const mergedValue = { ..._.nth(index)(population), ...value };
81
44
  setPopulation(replaceAt(index, mergedValue)(population));
82
45
  } else setPopulation(dropAt(index)(population));
83
46
  };
84
47
 
85
- render() {
86
- const { population, structures, typeOperators } = this.props;
87
- const { selectAll } = this.state;
88
-
89
- if (_.isNull(selectAll) || selectAll) {
90
- return (
91
- <PopulationTypeForm
92
- onSelect={this.setSelectAll}
93
- selectAll={selectAll}
94
- />
95
- );
96
- } else {
97
- return (
98
- <FiltersGrid
99
- rows={population}
100
- setRowValue={this.setPopulationField}
101
- structures={structures}
102
- typeOperators={typeOperators}
103
- scope="population"
104
- />
105
- );
106
- }
107
- }
48
+ return _.isEmpty(population) ? (
49
+ <PopulationTypeForm createFilter={() => setPopulation([{}])} />
50
+ ) : (
51
+ <FiltersGrid
52
+ rows={population}
53
+ setRowValue={setPopulationField}
54
+ structures={structures}
55
+ typeOperators={typeOperators}
56
+ scope="population"
57
+ />
58
+ );
108
59
  }
109
-
110
- export default PopulationForm;
60
+ PopulationForm.propTypes = {
61
+ typeOperators: PropTypes.array,
62
+ population: PropTypes.array,
63
+ structures: PropTypes.array,
64
+ setPopulation: PropTypes.func,
65
+ };
@@ -29,12 +29,9 @@ RuleImplementationStep.propTypes = {
29
29
 
30
30
  export const RuleImplementationForm = ({
31
31
  ruleImplementation,
32
- structures,
33
32
  setStructures,
34
- population,
35
33
  setPopulation,
36
34
  setImplementationKey,
37
- validations,
38
35
  setValidations,
39
36
  isSubmitting,
40
37
  handleSubmit,
@@ -54,6 +51,12 @@ export const RuleImplementationForm = ({
54
51
  const [activeStep, setActiveStep] = useState("information");
55
52
  const [selector, setSelector] = useState();
56
53
 
54
+ const {
55
+ dataset: structures,
56
+ population,
57
+ validations,
58
+ } = ruleImplementation || {};
59
+
57
60
  const validPopulation = () =>
58
61
  _.every(_.isEmpty)(population) || populationComplete();
59
62
 
@@ -278,12 +281,9 @@ RuleImplementationForm.propTypes = {
278
281
  ruleImplementation: PropTypes.object,
279
282
  handleSubmit: PropTypes.func.isRequired,
280
283
  isSubmitting: PropTypes.bool.isRequired,
281
- structures: PropTypes.array,
282
284
  setStructures: PropTypes.func,
283
- population: PropTypes.array,
284
285
  setPopulation: PropTypes.func,
285
286
  setImplementationKey: PropTypes.func,
286
- validations: PropTypes.array,
287
287
  setValidations: PropTypes.func,
288
288
  operators: PropTypes.object,
289
289
  onChange: PropTypes.func,