import React, { useEffect, useState } from "react"; import { QueryBuilder } from "react-querybuilder"; import "react-querybuilder/dist/query-builder.css"; import { QueryBuilderDnD } from "@react-querybuilder/dnd"; import * as ReactDnD from "react-dnd"; import * as ReactDndHtml5Backend from "react-dnd-html5-backend"; import useFetchTags from "./hooks/useFetchTags"; import { Button, ButtonGroup } from "reactstrap"; import cx from "classnames"; import { uniqueId } from "lodash"; import ToastUtil from "@common-utils/ToastUtil"; import { DUPLICATE_CRITERIA_ERROR_MSG } from "./constants"; //P.S, the component is not developed for nested rules const CouponCriteriaCreation = ({ criteria, setCriteria }) => { const initialQueryState = { combinator: "and", rules: [] }; const [query, setQuery] = useState(initialQueryState); const [readableJSON, setReadableJSON] = useState(""); const { tags, isLoading } = useFetchTags(); useEffect(() => { init(); () => { //setting query to initial state after ruleCreation unmounting setQuery(initialQueryState); }; }, []); useEffect(() => { fetchReadableJSONQuery(); }, [query]); const init = () => { updateQueryIfCriteriaAlreadyPresent(); }; const fetchReadableJSONQuery = () => { if (!isValidQuery(query)) return; const queryInJSONFormat = convertQueryToJSON(query); const readableString = ruleToReadableFormat(queryInJSONFormat); setReadableJSON(readableString); console.log({ queryInJSONFormat, readableString }); setFormattedCriteria(queryInJSONFormat); }; const isValidQuery = query => { const { combinator = null, rules = null } = query; if (combinator && rules && isValidAndNonRepeatedTagInput(rules)) { return true; } else { return false; } }; const isValidAndNonRepeatedTagInput = existingRules => { let isRepeated = false; let isValid = true; const configNames = []; existingRules.map(rule => { if (configNames.includes(rule.field)) { isRepeated = true; } else { configNames.push(rule.field); } if (rule.value === "") isValid = false; }); if (isRepeated) ToastUtil.error(`${DUPLICATE_CRITERIA_ERROR_MSG}`, "INVALID_CRITERIA"); return isValid && !isRepeated; }; const convertQueryToJSON = (jsonQuery = query) => { const COMBINATOR_LABELS = { and: "AND", or: "OR" //in criteria scenario there is only "AND" combinator }; const { combinator, rules } = jsonQuery; // console.log({ combinator, rules }); const queryInJSONFormat = { [COMBINATOR_LABELS[combinator]]: [ ...rules.map(rule => { const value = rule.value; return { [rule.field]: value }; }) ] }; return queryInJSONFormat; }; const ruleToReadableFormat = rules => { let readableString = ""; let newRule = {}; if (rules["AND"]) { newRule = rules["AND"]; newRule.map((rulePair, index) => { const key = Object.keys(rulePair)[0]; const value = JSON.stringify(rulePair[key]); readableString += `(${key} == ${value})`; if (index !== Object.keys(newRule).length - 1) readableString += " && "; }); } else { newRule = rules; Object.keys(newRule).map((rulePair, index) => { const value = JSON.stringify(newRule[rulePair]); readableString += `(${rulePair} == ${value})`; if (index !== Object.keys(newRule).length - 1) readableString += " && "; }); } // console.log({ rules, readableString, newRule }); return readableString; }; const setFormattedCriteria = jsonRule => { let criteria = []; if (jsonRule["AND"]) { Object.keys(jsonRule["AND"]).map(ruleIndex => { const predicate = Object.keys(jsonRule["AND"][ruleIndex])[0]; criteria = [ ...criteria, { predicate: predicate, pValue: jsonRule["AND"][ruleIndex][predicate] } ]; }); } else { criteria = jsonRule; } setCriteria(criteria); }; const updateQueryIfCriteriaAlreadyPresent = () => { const query = getJSONQuery(criteria); setQuery({ ...query }); }; const getJSONQuery = preExistingCriteria => { //this needs to be changed for edit criterias part if nested rules are added const formattedRules = preExistingCriteria.map(rule => ({ field: rule.predicate, id: uniqueId("config"), //uniqueID for config rendering operator: "=", valueSource: "value", value: rule.pValue.toString() })); return { combinator: "and", rules: [...formattedRules] }; }; return (
{readableJSON !== "" &&
{`Readable Criteria : ${readableJSON}`}
} ( <>
{props.fieldData?.operatorLabel}
), addGroupAction: () => null, addRuleAction: props => ( ), removeRuleAction: props => ( ), removeGroupAction: () => null, combinatorSelector: props => { return ( ); } }} style={{ border: "1px solid #ccc", borderRadius: "0.25rem", padding: "10px" }} showCombinatorsBetweenRules query={query} onQueryChange={newQuery => setQuery(newQuery)} />
); }; export default CouponCriteriaCreation;