2021-11-10 13:45:47 +00:00
|
|
|
import React, { useEffect } from "react";
|
|
|
|
|
import FormControl from "pages/Editor/FormControl";
|
|
|
|
|
import Icon, { IconSize } from "components/ads/Icon";
|
|
|
|
|
import styled from "styled-components";
|
2021-12-14 10:42:21 +00:00
|
|
|
import { FieldArray, getFormValues } from "redux-form";
|
2021-11-10 13:45:47 +00:00
|
|
|
import { ControlProps } from "./BaseControl";
|
2021-12-14 10:42:21 +00:00
|
|
|
import _ from "lodash";
|
|
|
|
|
import { useSelector } from "react-redux";
|
2022-02-26 03:52:06 +00:00
|
|
|
import { getBindingOrConfigPathsForWhereClauseControl } from "entities/Action/actionProperties";
|
|
|
|
|
import { WhereClauseSubComponent } from "./utils";
|
2022-03-27 13:40:48 +00:00
|
|
|
import Tooltip from "components/ads/Tooltip";
|
|
|
|
|
|
|
|
|
|
//Dropdwidth and Icon have fixed widths
|
|
|
|
|
const DropdownWidth = 100; //pixel value
|
|
|
|
|
const Margin = 8; //pixel value, space between two adjacent fields
|
|
|
|
|
//Offsets are pixel values adjusted for Margin = 8px, and DropdownWidth = 100px
|
|
|
|
|
//Offsets are used to calculate flexible width of Key and Value fields
|
|
|
|
|
//TODO: add logic to calculate width using DropdownWidth and Margin
|
|
|
|
|
const Offset = [
|
|
|
|
|
[116, 248],
|
|
|
|
|
[274, 406],
|
|
|
|
|
[432, 564],
|
|
|
|
|
[590, 722],
|
|
|
|
|
];
|
2021-11-10 13:45:47 +00:00
|
|
|
|
|
|
|
|
// Type of the value for each condition
|
|
|
|
|
export type whereClauseValueType = {
|
|
|
|
|
condition?: string;
|
|
|
|
|
children?: [whereClauseValueType];
|
|
|
|
|
key?: string;
|
|
|
|
|
value?: string;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Form config for the value field
|
|
|
|
|
const valueFieldConfig: any = {
|
|
|
|
|
key: "value",
|
|
|
|
|
controlType: "QUERY_DYNAMIC_INPUT_TEXT",
|
|
|
|
|
placeholderText: "value",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Form config for the key field
|
|
|
|
|
const keyFieldConfig: any = {
|
|
|
|
|
key: "key",
|
|
|
|
|
controlType: "QUERY_DYNAMIC_INPUT_TEXT",
|
|
|
|
|
placeholderText: "key",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Form config for the condition field
|
|
|
|
|
const conditionFieldConfig: any = {
|
|
|
|
|
key: "operator",
|
|
|
|
|
controlType: "DROP_DOWN",
|
|
|
|
|
initialValue: "EQ",
|
|
|
|
|
options: [],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Form config for the operator field
|
|
|
|
|
const logicalFieldConfig: any = {
|
|
|
|
|
key: "condition",
|
|
|
|
|
controlType: "DROP_DOWN",
|
|
|
|
|
initialValue: "EQ",
|
|
|
|
|
};
|
|
|
|
|
|
2022-03-27 13:40:48 +00:00
|
|
|
const LogicalFieldValue: any = styled.p`
|
|
|
|
|
height: 38px;
|
|
|
|
|
line-height: 36px;
|
|
|
|
|
margin: 8px 0px;
|
|
|
|
|
border: solid 1.2px transparent;
|
|
|
|
|
text-align: right;
|
|
|
|
|
color: var(--appsmith-color-black-400);
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
:first-child {
|
|
|
|
|
margin-top: 0px;
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
2021-11-10 13:45:47 +00:00
|
|
|
// Component for the delete Icon
|
2022-01-14 13:50:54 +00:00
|
|
|
const CenteredIcon = styled(Icon)<{
|
|
|
|
|
alignSelf?: string;
|
2022-03-27 13:40:48 +00:00
|
|
|
top?: string;
|
2022-01-14 13:50:54 +00:00
|
|
|
}>`
|
2022-03-27 13:40:48 +00:00
|
|
|
position: relative;
|
|
|
|
|
margin-left: 4px;
|
|
|
|
|
margin-right: 8px;
|
|
|
|
|
align-self: ${(props) => (props.alignSelf ? props.alignSelf : "center")};
|
|
|
|
|
top: ${(props) => (props.top ? props.top : "0px")};
|
2021-11-10 13:45:47 +00:00
|
|
|
&.hide {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
// Wrapper inside the main box, contains the dropdown and ConditionWrapper
|
2022-03-27 13:40:48 +00:00
|
|
|
const SecondaryBox = styled.div<{ showBorder: boolean }>`
|
2021-11-10 13:45:47 +00:00
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
2022-03-27 13:40:48 +00:00
|
|
|
position: relative;
|
|
|
|
|
border: solid 1.2px #e0dede;
|
|
|
|
|
width: max-content;
|
|
|
|
|
border-width: ${(props) => (props?.showBorder ? "1.2px" : "0px")};
|
|
|
|
|
margin: ${(props) => (props?.showBorder ? "0px 8px" : "0px")};
|
|
|
|
|
padding: ${(props) => (props?.showBorder ? "8px" : "0px")};
|
|
|
|
|
padding-bottom: 24px;
|
2021-11-10 13:45:47 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
// Wrapper to contain either a ConditionComponent or ConditionBlock
|
|
|
|
|
const ConditionWrapper = styled.div`
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
2022-03-27 13:40:48 +00:00
|
|
|
width: 100%;
|
2021-11-10 13:45:47 +00:00
|
|
|
justify-content: space-between;
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
// Wrapper to contain a single condition statement
|
|
|
|
|
const ConditionBox = styled.div`
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
2022-03-27 13:40:48 +00:00
|
|
|
width: 100%;
|
|
|
|
|
margin: 4px 0px;
|
|
|
|
|
:first-child {
|
|
|
|
|
margin-top: 0px;
|
|
|
|
|
}
|
2021-11-10 13:45:47 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
// Box containing the action buttons to add more filters
|
2022-03-27 13:40:48 +00:00
|
|
|
const ActionBox = styled.div<{ marginLeft: string }>`
|
2021-11-10 13:45:47 +00:00
|
|
|
display: flex;
|
|
|
|
|
margin-top: 16px;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
width: max-content;
|
|
|
|
|
justify-content: space-between;
|
2022-03-27 13:40:48 +00:00
|
|
|
position: absolute;
|
|
|
|
|
height: 24px;
|
|
|
|
|
text-transform: uppercase;
|
|
|
|
|
background-color: inherit;
|
|
|
|
|
bottom: 0px;
|
|
|
|
|
margin-left: ${(props) => props.marginLeft};
|
2021-11-10 13:45:47 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
// The final button to add more filters/ filter groups
|
2022-03-27 13:40:48 +00:00
|
|
|
const AddMoreAction = styled.div<{ isDisabled?: boolean }>`
|
2021-11-10 13:45:47 +00:00
|
|
|
cursor: pointer;
|
2022-03-27 13:40:48 +00:00
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
line-height: 14px;
|
|
|
|
|
letter-spacing: 0.6px;
|
|
|
|
|
margin-right: 20px;
|
|
|
|
|
color: ${(props) =>
|
|
|
|
|
props.isDisabled ? "var(--appsmith-color-black-300)" : "#858282;"};
|
2021-11-10 13:45:47 +00:00
|
|
|
`;
|
|
|
|
|
|
2022-03-27 13:40:48 +00:00
|
|
|
const StyledTooltip = styled(Tooltip)`
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
.bp3-tooltip.ads-global-tooltip .bp3-popover-content {
|
|
|
|
|
padding: 8px 12px;
|
|
|
|
|
line-height: 16px;
|
|
|
|
|
text-transform: none;
|
|
|
|
|
}
|
|
|
|
|
.bp3-tooltip.ads-global-tooltip .bp3-popover-arrow[style*="left"] {
|
|
|
|
|
left: auto !important;
|
|
|
|
|
right: 0px;
|
|
|
|
|
}
|
|
|
|
|
`;
|
2021-11-10 13:45:47 +00:00
|
|
|
// Component to display single line of condition, includes 2 inputs and 1 dropdown
|
|
|
|
|
function ConditionComponent(props: any, index: number) {
|
|
|
|
|
// Custom styles have to be passed as props, otherwise the UI will be disproportional
|
2022-01-14 13:50:54 +00:00
|
|
|
|
2022-02-26 03:52:06 +00:00
|
|
|
const keyPath = getBindingOrConfigPathsForWhereClauseControl(
|
|
|
|
|
props.field,
|
|
|
|
|
WhereClauseSubComponent.Key,
|
|
|
|
|
);
|
|
|
|
|
const valuePath = getBindingOrConfigPathsForWhereClauseControl(
|
|
|
|
|
props.field,
|
|
|
|
|
WhereClauseSubComponent.Value,
|
|
|
|
|
);
|
|
|
|
|
const conditionPath = getBindingOrConfigPathsForWhereClauseControl(
|
|
|
|
|
props.field,
|
|
|
|
|
WhereClauseSubComponent.Condition,
|
|
|
|
|
);
|
|
|
|
|
|
2022-03-27 13:40:48 +00:00
|
|
|
//flexWidth is the width of one Key or Value field
|
|
|
|
|
//It is a function of DropdownWidth and Margin
|
|
|
|
|
//fexWidth = maxWidth(set By WhereClauseControl) - Offset Values based on DropdownWidth and Margin
|
|
|
|
|
const numberOfDropdowns = props.currentNumberOfFields > 1 ? 1 : 0;
|
|
|
|
|
const flexWidth = `${props.maxWidth / 2}vw - ${Offset[
|
|
|
|
|
props.currentNestingLevel
|
|
|
|
|
][numberOfDropdowns] / 2}px`;
|
|
|
|
|
|
2021-11-10 13:45:47 +00:00
|
|
|
return (
|
|
|
|
|
<ConditionBox key={index}>
|
|
|
|
|
{/* Component to input the LHS for single condition */}
|
|
|
|
|
<FormControl
|
|
|
|
|
config={{
|
|
|
|
|
...keyFieldConfig,
|
2022-03-27 13:40:48 +00:00
|
|
|
customStyles: {
|
|
|
|
|
width: `calc(${flexWidth})`,
|
|
|
|
|
margin: `${
|
|
|
|
|
props.currentNumberOfFields > 1 ? "0 8px" : "0px 8px 0px 0px"
|
|
|
|
|
}`,
|
|
|
|
|
},
|
2022-02-26 03:52:06 +00:00
|
|
|
configProperty: keyPath,
|
2021-11-10 13:45:47 +00:00
|
|
|
}}
|
|
|
|
|
formName={props.formName}
|
|
|
|
|
/>
|
|
|
|
|
{/* Component to select the operator for the 2 inputs */}
|
|
|
|
|
<FormControl
|
|
|
|
|
config={{
|
|
|
|
|
...conditionFieldConfig,
|
2022-03-27 13:40:48 +00:00
|
|
|
customStyles: { width: `${DropdownWidth}px`, margin: "0 8px" },
|
2022-02-26 03:52:06 +00:00
|
|
|
configProperty: conditionPath,
|
2021-11-10 13:45:47 +00:00
|
|
|
options: props.comparisonTypes,
|
|
|
|
|
initialValue: props.comparisonTypes[0].value,
|
|
|
|
|
}}
|
|
|
|
|
formName={props.formName}
|
|
|
|
|
/>
|
|
|
|
|
{/* Component to input the RHS for single component */}
|
|
|
|
|
<FormControl
|
|
|
|
|
config={{
|
|
|
|
|
...valueFieldConfig,
|
2022-03-27 13:40:48 +00:00
|
|
|
customStyles: {
|
|
|
|
|
width: `calc(${flexWidth})`,
|
|
|
|
|
margin: "0 8px",
|
|
|
|
|
},
|
2022-02-26 03:52:06 +00:00
|
|
|
configProperty: valuePath,
|
2021-11-10 13:45:47 +00:00
|
|
|
}}
|
|
|
|
|
formName={props.formName}
|
|
|
|
|
/>
|
|
|
|
|
{/* Component to render the delete icon */}
|
2022-03-27 13:40:48 +00:00
|
|
|
{index ? (
|
|
|
|
|
<CenteredIcon
|
|
|
|
|
name="cross"
|
|
|
|
|
onClick={(e) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
props.onDeletePressed(index);
|
|
|
|
|
}}
|
|
|
|
|
size={IconSize.SMALL}
|
|
|
|
|
top="-1px"
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
2021-11-10 13:45:47 +00:00
|
|
|
</ConditionBox>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This is the block which contains an operator and multiple conditions/ condition blocks
|
|
|
|
|
function ConditionBlock(props: any) {
|
2021-12-14 10:42:21 +00:00
|
|
|
const formValues: any = useSelector((state) =>
|
|
|
|
|
getFormValues(props.formName)(state),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const onDeletePressed = (index: number) => {
|
|
|
|
|
props.fields.remove(index);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// sometimes, this condition runs before the appropriate formValues has been initialized with the correct query values.
|
2021-11-10 13:45:47 +00:00
|
|
|
useEffect(() => {
|
2021-12-14 10:42:21 +00:00
|
|
|
// so make sure the new formValue has been initialized with the where object,
|
|
|
|
|
// especially when switching between various queries across the same Query editor form.
|
|
|
|
|
const whereConfigValue = _.get(formValues, props.configProperty);
|
|
|
|
|
// if the where object exists then it means the initialization of the form has been completed.
|
|
|
|
|
// if the where object exists and the length of children field is less than one, add a new field.
|
|
|
|
|
if (props.fields.length < 1 && !!whereConfigValue) {
|
2021-11-10 13:45:47 +00:00
|
|
|
if (props.currentNestingLevel === 0) {
|
|
|
|
|
props.fields.push({
|
|
|
|
|
condition: props.comparisonTypes[0].value,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
props.onDeletePressed(props.index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, [props.fields.length]);
|
2021-12-14 10:42:21 +00:00
|
|
|
|
2021-11-10 13:45:47 +00:00
|
|
|
let isDisabled = false;
|
|
|
|
|
if (props.logicalTypes.length === 1) {
|
|
|
|
|
isDisabled = true;
|
|
|
|
|
}
|
2022-03-27 13:40:48 +00:00
|
|
|
const logicalFieldPath = getBindingOrConfigPathsForWhereClauseControl(
|
2022-02-26 03:52:06 +00:00
|
|
|
props.configProperty,
|
|
|
|
|
WhereClauseSubComponent.Condition,
|
|
|
|
|
);
|
2022-03-27 13:40:48 +00:00
|
|
|
const logicalFieldValue = _.get(formValues, logicalFieldPath);
|
2022-02-26 03:52:06 +00:00
|
|
|
|
2021-11-10 13:45:47 +00:00
|
|
|
return (
|
2022-03-27 13:40:48 +00:00
|
|
|
<SecondaryBox showBorder={props.currentNestingLevel >= 1}>
|
|
|
|
|
{/* Component to render the joining operator between multiple conditions */}
|
|
|
|
|
{props.fields.length > 1 ? (
|
|
|
|
|
<div style={{}}>
|
|
|
|
|
{props.fields.map((field: any, index: number) => {
|
|
|
|
|
if (index == 0) {
|
|
|
|
|
return <LogicalFieldValue>Where</LogicalFieldValue>;
|
|
|
|
|
} else if (index == 1) {
|
|
|
|
|
return (
|
|
|
|
|
<FormControl
|
|
|
|
|
config={{
|
|
|
|
|
...logicalFieldConfig,
|
|
|
|
|
customStyles: { width: `${DropdownWidth}px` },
|
|
|
|
|
configProperty: logicalFieldPath,
|
|
|
|
|
options: props.logicalTypes,
|
|
|
|
|
initialValue: props.logicalTypes[0].value,
|
|
|
|
|
isDisabled,
|
|
|
|
|
}}
|
|
|
|
|
formName={props.formName}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
return <LogicalFieldValue>{logicalFieldValue}</LogicalFieldValue>;
|
|
|
|
|
}
|
|
|
|
|
})}
|
|
|
|
|
</div>
|
|
|
|
|
) : null}
|
|
|
|
|
<ConditionWrapper>
|
|
|
|
|
{props.fields &&
|
|
|
|
|
props.fields.length > 0 &&
|
|
|
|
|
props.fields.map((field: any, index: number) => {
|
|
|
|
|
const fieldValue: whereClauseValueType = props.fields.get(index);
|
|
|
|
|
if (!!fieldValue && "children" in fieldValue) {
|
|
|
|
|
// If the value contains children in it, that means it is a ConditionBlock
|
|
|
|
|
return (
|
|
|
|
|
<ConditionBox>
|
|
|
|
|
<FieldArray
|
|
|
|
|
component={ConditionBlock}
|
|
|
|
|
key={`${field}.children`}
|
|
|
|
|
name={`${field}.children`}
|
|
|
|
|
props={{
|
|
|
|
|
maxWidth: props.maxWidth,
|
|
|
|
|
configProperty: `${field}`,
|
|
|
|
|
formName: props.formName,
|
|
|
|
|
logicalTypes: props.logicalTypes,
|
|
|
|
|
comparisonTypes: props.comparisonTypes,
|
|
|
|
|
nestedLevels: props.nestedLevels,
|
|
|
|
|
currentNestingLevel: props.currentNestingLevel + 1,
|
|
|
|
|
onDeletePressed,
|
|
|
|
|
index,
|
|
|
|
|
}}
|
|
|
|
|
rerenderOnEveryChange={false}
|
|
|
|
|
/>
|
|
|
|
|
<CenteredIcon
|
|
|
|
|
alignSelf={"start"}
|
|
|
|
|
name="cross"
|
|
|
|
|
onClick={(e) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
onDeletePressed(index);
|
|
|
|
|
}}
|
|
|
|
|
size={IconSize.SMALL}
|
|
|
|
|
top={"14px"}
|
|
|
|
|
/>
|
|
|
|
|
</ConditionBox>
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
// Render a single condition component
|
|
|
|
|
return ConditionComponent(
|
|
|
|
|
{
|
|
|
|
|
onDeletePressed,
|
|
|
|
|
field,
|
|
|
|
|
formName: props.formName,
|
|
|
|
|
comparisonTypes: props.comparisonTypes,
|
|
|
|
|
maxWidth: props.maxWidth,
|
|
|
|
|
currentNumberOfFields: props.fields.length,
|
|
|
|
|
currentNestingLevel: props.currentNestingLevel,
|
|
|
|
|
},
|
|
|
|
|
index,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
})}
|
|
|
|
|
</ConditionWrapper>
|
|
|
|
|
|
|
|
|
|
<ActionBox
|
|
|
|
|
marginLeft={`${props.fields.length > 1 ? DropdownWidth + Margin : 0}px`}
|
|
|
|
|
>
|
2021-11-10 13:45:47 +00:00
|
|
|
<AddMoreAction
|
|
|
|
|
onClick={() =>
|
|
|
|
|
props.fields.push({ condition: props.comparisonTypes[0].value })
|
|
|
|
|
}
|
|
|
|
|
>
|
2022-03-27 13:40:48 +00:00
|
|
|
<Icon name="add-more-fill" size={IconSize.XL} />
|
|
|
|
|
<span style={{ marginLeft: "8px" }}>Add A Condition</span>
|
2021-11-10 13:45:47 +00:00
|
|
|
</AddMoreAction>
|
|
|
|
|
{/* Check if the config allows more nesting, if it does, allow for adding more blocks */}
|
2022-03-27 13:40:48 +00:00
|
|
|
<StyledTooltip
|
|
|
|
|
content={
|
|
|
|
|
<span>
|
|
|
|
|
For S3 only 4 nested where <br /> condition group is allowed.
|
|
|
|
|
</span>
|
|
|
|
|
}
|
|
|
|
|
disabled={props.currentNestingLevel < props.nestedLevels}
|
|
|
|
|
donotUsePortal
|
|
|
|
|
position="bottom"
|
|
|
|
|
>
|
2021-11-10 13:45:47 +00:00
|
|
|
<AddMoreAction
|
2022-03-27 13:40:48 +00:00
|
|
|
isDisabled={!(props.currentNestingLevel < props.nestedLevels)}
|
2021-11-10 13:45:47 +00:00
|
|
|
onClick={() => {
|
2022-03-27 13:40:48 +00:00
|
|
|
if (props.currentNestingLevel < props.nestedLevels) {
|
|
|
|
|
props.fields.push({
|
|
|
|
|
condition: props.logicalTypes[0].value,
|
|
|
|
|
children: [
|
|
|
|
|
{
|
|
|
|
|
condition: props.comparisonTypes[0].value,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-11-10 13:45:47 +00:00
|
|
|
}}
|
|
|
|
|
>
|
2022-03-27 13:40:48 +00:00
|
|
|
<Icon name="add-more-fill" size={IconSize.XL} />
|
|
|
|
|
<span style={{ marginLeft: "8px" }}>Add A Group Condition</span>
|
2021-11-10 13:45:47 +00:00
|
|
|
</AddMoreAction>
|
2022-03-27 13:40:48 +00:00
|
|
|
</StyledTooltip>
|
2021-11-10 13:45:47 +00:00
|
|
|
</ActionBox>
|
2022-03-27 13:40:48 +00:00
|
|
|
</SecondaryBox>
|
2021-11-10 13:45:47 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default function WhereClauseControl(props: WhereClauseControlProps) {
|
|
|
|
|
const {
|
|
|
|
|
comparisonTypes, // All possible keys for the comparison
|
|
|
|
|
configProperty, // JSON path for the where clause data
|
|
|
|
|
formName, // Name of the form, used by redux-form lib to store the data in redux store
|
|
|
|
|
logicalTypes, // All possible keys for the logical operators joining multiple conditions
|
|
|
|
|
nestedLevels, // Number of nested levels allowed
|
|
|
|
|
} = props;
|
|
|
|
|
|
|
|
|
|
// Max width is designed in a way that the proportion stays same even after nesting
|
2022-03-27 13:40:48 +00:00
|
|
|
const maxWidth = 60; //in vw
|
2021-11-10 13:45:47 +00:00
|
|
|
return (
|
2021-12-27 12:04:45 +00:00
|
|
|
<FieldArray
|
|
|
|
|
component={ConditionBlock}
|
|
|
|
|
key={`${configProperty}.children`}
|
|
|
|
|
name={`${configProperty}.children`}
|
|
|
|
|
props={{
|
|
|
|
|
configProperty,
|
|
|
|
|
maxWidth,
|
|
|
|
|
formName,
|
|
|
|
|
logicalTypes,
|
|
|
|
|
comparisonTypes,
|
|
|
|
|
nestedLevels,
|
|
|
|
|
currentNestingLevel: 0,
|
|
|
|
|
}}
|
|
|
|
|
rerenderOnEveryChange={false}
|
|
|
|
|
/>
|
2021-11-10 13:45:47 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type WhereClauseControlProps = ControlProps;
|