@hitachivantara/uikit-react-core
Version:
UI Kit Core React components.
117 lines (116 loc) • 4.27 kB
JavaScript
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 };