UNPKG

@carbon/ibm-products

Version:

Carbon for IBM Products

351 lines (344 loc) 11.7 kB
/** * Copyright IBM Corp. 2020, 2025 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { extends as _extends } from '../../../_virtual/_rollupPluginBabelHelpers.js'; import React__default, { useContext, useState } from 'react'; import { Close } from '@carbon/react/icons'; import { ConditionBuilderItem } from '../ConditionBuilderItem/ConditionBuilderItem.js'; import PropTypes from '../../../_virtual/index.js'; import cx from 'classnames'; import ConditionConnector from '../ConditionBuilderConnector/ConditionConnector.js'; import { ConditionBuilderItemNumber } from '../ConditionBuilderItem/ConditionBuilderItemNumber/ConditionBuilderItemNumber.js'; import { ConditionBuilderItemText } from '../ConditionBuilderItem/ConditionBuilderItemText/ConditionBuilderItemText.js'; import { ConditionBuilderItemDate } from '../ConditionBuilderItem/ConditionBuilderItemDate/ConditionBuilderItemDate.js'; import { ConditionBuilderContext } from '../ConditionBuilderContext/ConditionBuilderProvider.js'; import { ConditionBuilderButton } from '../ConditionBuilderButton/ConditionBuilderButton.js'; import { blockClass, HIERARCHICAL_VARIANT, NON_HIERARCHICAL_VARIANT, checkIsValid, focusThisField } from '../utils/util.js'; import { ConditionBuilderItemTime } from '../ConditionBuilderItem/ConditionBuilderItemTime/ConditionBuilderItemTime.js'; import ConditionBuilderAdd from '../ConditionBuilderAdd/ConditionBuilderAdd.js'; import { ItemOption } from '../ConditionBuilderItem/ConditionBuilderItemOption/ItemOption.js'; import { ItemOptionForValueField } from '../ConditionBuilderItem/ConditionBuilderItemOption/ItemOptionForValueField.js'; import { useTranslations } from '../utils/useTranslations.js'; import { useDataConfigs } from '../utils/useDataConfigs.js'; /** * This component build each block of condition consisting of property, operator value and close button. */ const ConditionBlock = props => { const { onRemove, onChange, condition = {}, conjunction, onConnectorOperatorChange, isStatement, group, onStatementChange, conditionIndex, addConditionHandler, addConditionSubGroupHandler, aria, hideConditionSubGroupPreviewHandler, showConditionSubGroupPreviewHandler, hideConditionPreviewHandler, showConditionPreviewHandler, isLastCondition } = props; const { property, value, operator } = condition; const { inputConfig, variant, conditionBuilderRef } = useContext(ConditionBuilderContext); const [showDeletionPreview, setShowDeletionPreview] = useState(false); const [showAllActions, setShowAllActions] = useState(false); const [conditionRowText, conditionText, propertyText, operatorText, removeConditionText] = useTranslations(['conditionRowText', 'conditionText', 'propertyText', 'operatorText', 'removeConditionText']); const { statementConfig, operatorConfig } = useDataConfigs(); //filtering the current property to access its properties and config options const getCurrentConfig = property => { return inputConfig?.properties?.find(eachProperty => eachProperty.id == property) ?? {}; }; const { icon, type, config, label, description } = getCurrentConfig(property); //Below possible input types expected for value field. const itemComponents = { text: ConditionBuilderItemText, number: ConditionBuilderItemNumber, date: ConditionBuilderItemDate, time: ConditionBuilderItemTime, option: ItemOptionForValueField, custom: config?.component, textarea: ConditionBuilderItemText }; const ItemComponent = itemComponents[type]; const showAllActionsHandler = () => { setShowAllActions(true); }; const hideAllActionsHandler = () => { setShowAllActions(false); }; const onStatementChangeHandler = (v, evt) => { focusThisField(evt, conditionBuilderRef); onStatementChange?.(v); }; const onPropertyChangeHandler = newProperty => { onChange({ ...condition, property: newProperty, operator: undefined, value: '', popoverToOpen: checkIsValid(newProperty) ? 'operatorField' : '' }); }; const onOperatorChangeHandler = newOperator => { onChange({ ...condition, operator: newOperator, value: undefined, popoverToOpen: checkIsValid(newOperator) ? 'valueField' : '' }); }; const onValueChangeHandler = newValue => { const currentCondition = { ...condition }; delete currentCondition.popoverToOpen; onChange({ ...currentCondition, value: newValue }); }; const handleShowDeletionPreview = () => { setShowDeletionPreview(true); }; const handleHideDeletionPreview = () => { setShowDeletionPreview(false); }; const manageActionButtons = (conditionIndex, conditions) => { if (variant === HIERARCHICAL_VARIANT) { return true; } return isLastCondition(conditionIndex, conditions); }; const getOperators = () => { if (config?.operators) { return config?.operators; } return operatorConfig.filter(operator => operator.type.indexOf(type) != -1 || operator.type == 'all'); }; const getAriaAttributes = () => { return variant == HIERARCHICAL_VARIANT ? { 'aria-level': aria.level, 'aria-posinset': aria.posinset, 'aria-setsize': aria.setsize } : {}; }; const renderChildren = popoverRef => { return /*#__PURE__*/React__default.createElement(ItemComponent, { conditionState: { property, operator, value }, onChange: onValueChangeHandler, config: config, "data-name": "valueField", parentRef: popoverRef, type: type }); }; return /*#__PURE__*/React__default.createElement("div", _extends({ className: cx(`${blockClass}__condition-block`, { [`${blockClass}__condition__deletion-preview`]: showDeletionPreview }, { [`${blockClass}__gap-bottom`]: variant == HIERARCHICAL_VARIANT }, { [`${blockClass}__gap ${blockClass}__gap-bottom`]: variant == NON_HIERARCHICAL_VARIANT }, { [`${blockClass}__condition--interacting`]: showAllActions }), role: "row", "aria-label": conditionRowText }, getAriaAttributes(), { tabIndex: -1, onMouseEnter: showAllActionsHandler, onMouseLeave: hideAllActionsHandler, onBlur: hideAllActionsHandler }), conjunction ? /*#__PURE__*/React__default.createElement(ConditionConnector, { className: `${blockClass}__gap`, operator: conjunction, onChange: op => onConnectorOperatorChange?.(op) }) : '', isStatement && /*#__PURE__*/React__default.createElement(ConditionBuilderItem, { label: group.statement, title: conditionText, "data-name": "connectorField", popOverClassName: `${blockClass}__gap`, className: `${blockClass}__statement-button`, tabIndex: 0 }, /*#__PURE__*/React__default.createElement(ItemOption, { conditionState: { value: group.statement, label: conditionText }, onChange: onStatementChangeHandler, config: { options: statementConfig, isStatement: true } })), /*#__PURE__*/React__default.createElement(ConditionBuilderItem, { label: label ?? condition?.property, title: propertyText, renderIcon: icon ?? undefined, className: `${blockClass}__property-field`, "data-name": "propertyField", condition: condition, type: type, description: description, onChange: onPropertyChangeHandler }, /*#__PURE__*/React__default.createElement(ItemOption, { conditionState: { value: property, label: propertyText }, onChange: onPropertyChangeHandler, config: { options: inputConfig?.properties } })), checkIsValid(property) && /*#__PURE__*/React__default.createElement(ConditionBuilderItem, { label: operator, title: operatorText, "data-name": "operatorField", condition: condition, type: type, config: config, onChange: onOperatorChangeHandler }, /*#__PURE__*/React__default.createElement(ItemOption, { config: { options: getOperators() }, conditionState: { value: operator, label: operatorText }, onChange: onOperatorChangeHandler })), checkIsValid(property) && checkIsValid(operator) && /*#__PURE__*/React__default.createElement(ConditionBuilderItem, { label: value, type: type, title: label, showToolTip: true, "data-name": "valueField", condition: condition, config: config, onChange: onValueChangeHandler, renderChildren: renderChildren }), /*#__PURE__*/React__default.createElement("span", { role: "gridcell", "aria-label": removeConditionText }, /*#__PURE__*/React__default.createElement(ConditionBuilderButton, { hideLabel: true, label: removeConditionText, onClick: onRemove, onMouseEnter: handleShowDeletionPreview, onMouseLeave: handleHideDeletionPreview, onFocus: handleShowDeletionPreview, onBlur: handleHideDeletionPreview, renderIcon: Close, className: `${blockClass}__close-condition`, "data-name": "closeCondition", wrapperClassName: `${blockClass}__close-condition-wrapper` })), manageActionButtons(conditionIndex, group.conditions) && /*#__PURE__*/React__default.createElement(ConditionBuilderAdd, { onClick: () => { addConditionHandler?.(conditionIndex); }, addConditionSubGroupHandler: () => { addConditionSubGroupHandler?.(conditionIndex); }, showConditionSubGroupPreviewHandler: showConditionSubGroupPreviewHandler, hideConditionSubGroupPreviewHandler: hideConditionSubGroupPreviewHandler, enableSubGroup: variant == HIERARCHICAL_VARIANT, showConditionPreviewHandler: showConditionPreviewHandler, hideConditionPreviewHandler: hideConditionPreviewHandler, className: `${blockClass}__gap ${blockClass}__gap-left`, group: group })); }; ConditionBlock.propTypes = { /** * callback to add a new condition */ addConditionHandler: PropTypes.func, /** * callback to add a new condition subgroup */ addConditionSubGroupHandler: PropTypes.func, /** * object hold aria attributes */ aria: PropTypes.object, condition: PropTypes.object, conditionIndex: PropTypes.number, /** * string that decides to show the condition connector */ conjunction: PropTypes.string, /** * object that hold the current group object where is condition is part of */ group: PropTypes.object, /** * handler for hiding sub group preview */ hideConditionPreviewHandler: PropTypes.func, /** * handler for hiding sub group preview */ hideConditionSubGroupPreviewHandler: PropTypes.func, isLastCondition: PropTypes.func, /** * boolean that decides to show the statement(if/ excl.if) */ isStatement: PropTypes.bool, /** * callback to update the current condition of the state tree */ onChange: PropTypes.func, /** * callback to handle the connector(and/or) change */ onConnectorOperatorChange: PropTypes.func, /** * callback for Remove a condition */ onRemove: PropTypes.func, /** * callback to handle the statement(if/ excl.if) change */ onStatementChange: PropTypes.func, /** * handler for showing add condition preview */ showConditionPreviewHandler: PropTypes.func, /** * handler for showing sub group preview */ showConditionSubGroupPreviewHandler: PropTypes.func, /** * object that hold the current condition */ state: PropTypes.object }; export { ConditionBlock as default };