UNPKG

@carbon/ibm-products

Version:

Carbon for IBM Products

254 lines (246 loc) 9.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. */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHelpers.js'); var React = require('react'); var index = require('../../../_virtual/index.js'); var react = require('@carbon/react'); var icons = require('@carbon/react/icons'); var ConditionGroupBuilder = require('../ConditionGroupBuilder/ConditionGroupBuilder.js'); var ConditionBuilderProvider = require('../ConditionBuilderContext/ConditionBuilderProvider.js'); var ConditionBuilderButton = require('../ConditionBuilderButton/ConditionBuilderButton.js'); var uuidv4 = require('../../../global/js/utils/uuidv4.js'); var ConditionPreview = require('../ConditionPreview/ConditionPreview.js'); var GroupConnector = require('../ConditionBuilderConnector/GroupConnector.js'); var ConditionBuilderActions = require('../ConditionBuilderActions/ConditionBuilderActions.js'); var useTranslations = require('../utils/useTranslations.js'); var util = require('../utils/util.js'); var _GroupConnector; const ConditionBuilderContent = _ref => { let { startConditionLabel, getConditionState, getActionsState, initialState, actions } = _ref; const { rootState, setRootState, variant, actionState, onAddItem } = React.useContext(ConditionBuilderProvider.ConditionBuilderContext); const initialConditionState = React.useRef(initialState?.state ? JSON.parse(JSON.stringify(initialState?.state)) : null); const [isConditionBuilderActive, setIsConditionBuilderActive] = React.useState(false); const [showConditionGroupPreview, setShowConditionGroupPreview] = React.useState(false); const [addConditionGroupText, conditionHeadingText, conditionBuilderHierarchicalText] = useTranslations.useTranslations(['addConditionGroupText', 'conditionHeadingText', 'conditionBuilderHierarchicalText']); const showConditionGroupPreviewHandler = () => { setShowConditionGroupPreview(true); }; const hideConditionGroupPreviewHandler = () => { setShowConditionGroupPreview(false); }; React.useEffect(() => { if (rootState?.groups?.length) { setIsConditionBuilderActive(true); } else { setIsConditionBuilderActive(false); } if (getConditionState) { getConditionState(rootState ?? {}); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [rootState]); React.useEffect(() => { getActionsState?.(actionState ?? []); // eslint-disable-next-line react-hooks/exhaustive-deps }, [actionState]); React.useEffect(() => { if (initialState?.enabledDefault) { setRootState?.(initialState.state); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [initialState]); const onStartConditionBuilder = () => { //when add condition button is clicked. setIsConditionBuilderActive(true); if (initialConditionState?.current?.groups?.length) { setRootState?.(initialConditionState.current); initialConditionState.current = null; } else { setRootState?.(ConditionBuilderProvider.emptyState); //here we can set an empty skeleton object for an empty condition builder, } //or we can even pre-populate some existing builder and continue editing }; const onRemove = React.useCallback(groupId => { const groups = rootState?.groups?.filter(group => groupId !== group?.id); setRootState?.({ ...rootState, groups: rootState ? groups : [] }); //set the initial state to empty. if (groups?.length === 0) { initialConditionState.current = null; } }, [setRootState, rootState]); const onChangeHandler = (updatedGroup, groupIndex) => { /** * This method is triggered from inner components. This will be called every time when any change is to be updated in the rootState. * This gets the updated group as argument. */ if (rootState && rootState.groups) { const groups = [...(rootState.groups ? rootState.groups.slice(0, groupIndex) : []), updatedGroup, ...(rootState.groups ? rootState.groups.slice(groupIndex + 1) : [])]; setRootState?.({ ...rootState, groups }); } }; const addConditionGroupHandler = () => { const { preventAdd } = onAddItem?.({ type: 'group', state: rootState }) ?? {}; if (!preventAdd) { const newGroup = { statement: 'ifAll', groupOperator: 'and', id: uuidv4.default(), conditions: [{ property: undefined, operator: '', value: '', popoverToOpen: 'propertyField', id: uuidv4.default() }] }; setRootState?.({ ...rootState, groups: rootState && rootState.groups ? [...rootState.groups, newGroup] : [newGroup] }); } }; const getColorIndex = () => { const groupLength = rootState?.groups?.length ?? 0; return groupLength % 5; }; if (!isConditionBuilderActive) { return /*#__PURE__*/React.createElement(react.Button, { className: `${util.blockClass}__addConditionText-button`, renderIcon: props => /*#__PURE__*/React.createElement(icons.Add, props), iconDescription: startConditionLabel, kind: "ghost", size: "sm", onClick: onStartConditionBuilder }, startConditionLabel); } const wrapperRole = variant === util.HIERARCHICAL_VARIANT ? { role: 'treegrid', 'aria-label': conditionBuilderHierarchicalText } : null; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(react.Section, { className: `${util.blockClass}__heading`, level: 4 }, /*#__PURE__*/React.createElement(react.Heading, null, conditionHeadingText)), /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({ className: `${util.blockClass}__content-container` }, wrapperRole), rootState && rootState?.groups?.map((eachGroup, groupIndex) => /*#__PURE__*/React.createElement("div", { key: eachGroup.id, className: `${util.blockClass}__group-wrapper` }, /*#__PURE__*/React.createElement(ConditionGroupBuilder.default, { className: `${util.blockClass}__group`, aria: { level: 1, posinset: groupIndex * 2 + 1, setsize: (rootState.groups && rootState.groups.length * 2) ?? 0 }, group: eachGroup, onRemove: () => { onRemove(eachGroup.id); }, onChange: updatedGroup => { onChangeHandler(updatedGroup, groupIndex); } }), rootState.groups && groupIndex < rootState.groups.length - 1 && (_GroupConnector || (_GroupConnector = /*#__PURE__*/React.createElement(GroupConnector.default, null))))), variant == util.HIERARCHICAL_VARIANT && /*#__PURE__*/React.createElement("div", { role: "row", tabIndex: -1, "aria-level": 1, className: `${util.blockClass}__add-group` }, /*#__PURE__*/React.createElement(ConditionBuilderButton.ConditionBuilderButton, { renderIcon: icons.TextNewLine, onClick: addConditionGroupHandler, onMouseEnter: showConditionGroupPreviewHandler, onMouseLeave: hideConditionGroupPreviewHandler, onFocus: showConditionGroupPreviewHandler, onBlur: hideConditionGroupPreviewHandler, className: `${util.blockClass}__add-condition-group `, hideLabel: true, label: addConditionGroupText, wrapperProps: { role: 'gridcell', 'aria-label': addConditionGroupText } })), showConditionGroupPreview && /*#__PURE__*/React.createElement(ConditionPreview.default, { previewType: "newGroup", colorIndex: getColorIndex(), group: { groupOperator: rootState?.operator, id: uuidv4.default() } })), actions && /*#__PURE__*/React.createElement(ConditionBuilderActions.default, { actions: actions, className: `${util.blockClass}__actions-container` })); }; ConditionBuilderContent.propTypes = { /** * optional array of object that give the list of actions. */ actions: index.default.arrayOf(index.default.shape({ id: index.default.oneOfType([index.default.string, index.default.number]).isRequired, label: index.default.string.isRequired })), /** * callback functions that will provide the updated action state back. */ getActionsState: index.default.func, /** * This is a callback function that returns the updated state */ getConditionState: index.default.func.isRequired, /** * Optional prop if the condition building need to start from a predefined initial state */ initialState: index.default.shape({ state: index.default.shape({ groups: index.default.arrayOf(index.default.shape({ groupOperator: index.default.string, statement: index.default.string, conditions: index.default.arrayOf(index.default.oneOfType([index.default.shape({ property: index.default.string, operator: index.default.string, value: index.default.oneOfType([index.default.string, index.default.arrayOf(index.default.shape({ id: index.default.string, label: index.default.string })), index.default.shape({ id: index.default.string, label: index.default.string })]) }), index.default.object])) })), operator: index.default.string }), enabledDefault: index.default.bool }), /* Provide a label to the button that starts condition builder */ startConditionLabel: index.default.string.isRequired }; exports.default = ConditionBuilderContent;