UNPKG

@hitachivantara/uikit-react-core

Version:
117 lines (116 loc) 4.27 kB
import { useControlled } from "../hooks/useControlled.js"; import { useLabels } from "../hooks/useLabels.js"; import { isEqual } from "../utils/helpers.js"; import { ConfirmationDialog } from "./ConfirmationDialog.js"; import { HvQueryBuilderProvider, defaultCombinators, defaultLabels, defaultOperators } from "./Context.js"; import { useClasses } from "./QueryBuilder.styles.js"; import { clearNodeIds, emptyGroup, setNodeIds } from "./utils/index.js"; import { RuleGroup } from "./RuleGroup.js"; import reducer from "./utils/reducer.js"; import { useDefaultProps } from "@hitachivantara/uikit-react-utils"; import { useEffect, useMemo, useReducer, useRef, useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; //#region src/QueryBuilder/QueryBuilder.tsx /** * This component allows you to create conditions and group them using logical operators. * It outputs a structured set of rules which can be easily parsed to create SQL/NoSQL/whatever queries. * * Take a look at the [usage page](https://pentaho.github.io/uikit-docs/master/components/query-builder) to learn more about this component. */ var HvQueryBuilder = (props) => { const { attributes, renderers, value, defaultValue, onChange, disableConfirmation = false, allowRepeatedAttributes = false, operators = defaultOperators, combinators = defaultCombinators, maxDepth = 1, labels: labelsProp, readOnly = false, emptyRenderer = ["Empty", "IsNotEmpty"], classes: classesProp } = useDefaultProps("HvQueryBuilder", props); const { classes } = useClasses(classesProp); const currentAttributes = useRef(null); const controlled = useRef(value != null); const initialQuery = useRef(value ?? defaultValue ?? emptyGroup()); const [query, setQuery] = useControlled(value, initialQuery.current); const prevQuery = useRef(query); const [pendingAction, setPendingAction] = useState(); const [initialState, setInitialState] = useState(true); const [state, dispatchAction] = useReducer(reducer, setNodeIds(structuredClone(initialQuery.current))); const labels = useLabels(defaultLabels, labelsProp); const contextValue = useMemo(() => ({ dispatchAction, askAction: setPendingAction, attributes, operators, combinators, maxDepth, labels, initialTouched: initialState, readOnly, renderers, disableConfirmation, allowRepeatedAttributes, emptyRenderer }), [ attributes, operators, combinators, maxDepth, labels, readOnly, initialState, renderers, disableConfirmation, emptyRenderer, allowRepeatedAttributes ]); useEffect(() => { if (currentAttributes.current == null) currentAttributes.current = attributes; else if (currentAttributes.current !== attributes) { currentAttributes.current = attributes; dispatchAction({ type: "reset-query" }); } }, [attributes]); useEffect(() => { if (!isEqual(prevQuery.current, query)) { dispatchAction({ type: "set-query", query: setNodeIds(structuredClone(query), state) }); prevQuery.current = query; } else if (!isEqual(clearNodeIds(structuredClone(state)), clearNodeIds(structuredClone(query)))) { setInitialState(false); if (!controlled.current) onChange?.(clearNodeIds(structuredClone(state), true)); else onChange?.(clearNodeIds(structuredClone(state))); prevQuery.current = state; setQuery(state); } }, [ onChange, query, setQuery, state ]); const handleConfirm = () => { if (pendingAction) { setPendingAction(void 0); pendingAction.actions.forEach((action) => dispatchAction(action)); } }; const handleCancel = () => { setPendingAction(void 0); }; return /* @__PURE__ */ jsxs(HvQueryBuilderProvider, { value: contextValue, children: [/* @__PURE__ */ jsx(RuleGroup, { level: 0, id: state.id, combinator: state.combinator, rules: state.rules, classes }), /* @__PURE__ */ jsx(ConfirmationDialog, { open: pendingAction != null, onConfirm: handleConfirm, onCancel: handleCancel, title: pendingAction?.dialog.dialogTitle, message: pendingAction?.dialog.dialogMessage, confirmButtonLabel: pendingAction?.dialog.dialogConfirm, cancelButtonLabel: pendingAction?.dialog.dialogCancel, buttonTitle: pendingAction?.dialog.dialogCloseTooltip })] }); }; //#endregion export { HvQueryBuilder };