@carbon/ibm-products
Version:
Carbon for IBM Products
366 lines (359 loc) • 13 kB
JavaScript
/**
* 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';
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var React = require('react');
var index = require('../../_virtual/index.js');
var cx = require('classnames');
var react = require('@carbon/react');
var Tearsheet = require('../Tearsheet/Tearsheet.js');
var TearsheetNarrow = require('../Tearsheet/TearsheetNarrow.js');
require('../EmptyStates/EmptyState.js');
require('../EmptyStates/EmptyStateV2.js');
require('../EmptyStates/ErrorEmptyState/ErrorEmptyState.js');
require('../EmptyStates/NoDataEmptyState/NoDataEmptyState.js');
require('../EmptyStates/NoTagsEmptyState/NoTagsEmptyState.js');
var NotFoundEmptyState = require('../EmptyStates/NotFoundEmptyState/NotFoundEmptyState.js');
require('../EmptyStates/NotificationsEmptyState/NotificationsEmptyState.js');
require('../EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.js');
var AddSelectSidebar = require('./AddSelectSidebar.js');
var AddSelectBreadcrumbs = require('./AddSelectBreadcrumbs.js');
var AddSelectList = require('./AddSelectList.js');
var AddSelectColumn = require('./AddSelectColumn.js');
var AddSelectFilter = require('./AddSelectFilter.js');
var AddSelectSort = require('./AddSelectSort.js');
var addSelectUtils = require('./add-select-utils.js');
var useItemSort = require('./hooks/useItemSort.js');
var useParentSelect = require('./hooks/useParentSelect.js');
var usePath = require('./hooks/usePath.js');
var settings = require('../../settings.js');
const blockClass = `${settings.pkg.prefix}--add-select`;
const componentName = 'AddSelectBody';
const AddSelectBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
let {
className,
clearFiltersText,
closeIconDescription,
columnInputPlaceholder,
defaultModifiers,
description,
filterByLabel,
globalFilterOpts,
globalFiltersLabel,
globalFiltersIconDescription,
globalFiltersPlaceholderText,
globalFiltersPrimaryButtonText,
globalFiltersSecondaryButtonText,
globalSearchLabel,
globalSearchPlaceholder,
globalSortBy,
illustrationTheme,
influencerTitle,
items,
itemsLabel,
metaIconDescription,
metaPanelTitle,
multi,
navIconDescription,
noResultsDescription,
noResultsTitle,
noSelectionDescription,
noSelectionTitle,
normalizedItems,
onClose,
onCloseButtonText,
onSubmit,
onSubmitButtonText,
open,
portalTarget,
searchResultsTitle,
sortByLabel,
title,
useNormalizedItems,
...rest
} = _ref;
// hooks
const [singleSelection, setSingleSelection] = React.useState('');
const [multiSelection, setMultiSelection] = React.useState([]);
const [searchTerm, setSearchTerm] = React.useState('');
const [appliedGlobalFilters, setAppliedGlobalFilters] = React.useState({});
const [displayMetalPanel, setDisplayMetaPanel] = React.useState({});
const [appliedModifiers, setAppliedModifiers] = React.useState(defaultModifiers);
const {
sortDirection,
setSortDirection,
sortAttribute,
setSortAttribute
} = useItemSort.useItemSort();
const {
parentSelected,
setParentSelected
} = useParentSelect.default();
const {
path,
setPath,
pathOnclick,
resetPath
} = usePath.default(itemsLabel);
const resetState = () => {
setSingleSelection('');
setMultiSelection([]);
setSearchTerm('');
setAppliedGlobalFilters({});
setDisplayMetaPanel({});
setAppliedModifiers(defaultModifiers);
setSortAttribute('');
setSortDirection('');
setParentSelected(null);
resetPath();
};
const onCloseHandler = () => {
resetState();
onClose?.();
};
const tearsheetClassnames = cx(className, blockClass, {
[`${blockClass}__single`]: !multi,
[`${blockClass}__multi`]: multi
});
const globalFilterKeys = Object.keys(appliedGlobalFilters);
const globalFiltersApplied = globalFilterKeys.length > 0;
// handlers
const handleSearch = term => {
setSearchTerm(term);
};
const handleFilter = filters => {
setAppliedGlobalFilters(filters);
};
const submitHandler = () => {
if (multi && appliedModifiers && appliedModifiers?.length > 0) {
const selections = multiSelection.map(item => {
return appliedModifiers.find(mod => mod.id === item);
});
onSubmit?.(selections);
} else if (multi && appliedModifiers?.length === 0) {
onSubmit?.(multiSelection);
} else {
onSubmit?.(singleSelection);
}
onCloseHandler();
};
const setShowBreadsCrumbs = () => {
if (useNormalizedItems === false || searchTerm || globalFiltersApplied) {
return false;
}
return true;
};
const setShowTags = () => {
if (searchTerm) {
return true;
}
if (useNormalizedItems && multi) {
return false;
}
return true;
};
const parentSelectionHandler = (id, title, parentId) => {
setParentSelected(id);
setPath(id, title, parentId);
};
const sortFn = addSelectUtils.sortItems(sortAttribute, sortDirection);
const itemsToDisplay = addSelectUtils.getFilteredItems(useNormalizedItems, normalizedItems, searchTerm, globalFiltersApplied, globalFilterKeys, appliedGlobalFilters, sortFn, multi, items, path);
const hasResults = itemsToDisplay.length > 0;
const showBreadsCrumbs = setShowBreadsCrumbs();
const showSort = (searchTerm || globalFiltersApplied) && hasResults;
const showTags = setShowTags();
const commonListProps = {
displayMetalPanel,
metaIconDescription,
multi,
multiSelection,
navIconDescription,
path,
setMultiSelection,
setPath,
setSingleSelection,
singleSelection,
setDisplayMetaPanel,
parentId: path[0].id
};
const commonTearsheetProps = {
...rest,
className: tearsheetClassnames,
open,
title,
description,
actions: [{
label: onCloseButtonText,
kind: 'secondary',
onClick: onCloseHandler
}, {
label: onSubmitButtonText,
kind: 'primary',
onClick: submitHandler,
disabled: multi ? multiSelection.length === 0 : !singleSelection
}],
portalTarget,
ref
};
const sidebarProps = {
appliedModifiers,
closeIconDescription,
displayMetalPanel,
illustrationTheme,
influencerTitle,
items: useNormalizedItems ? normalizedItems : items?.entries,
metaPanelTitle,
modifiers: items?.modifiers,
multiSelection,
noSelectionDescription,
noSelectionTitle,
setDisplayMetaPanel
};
const displayColumnView = multi && useNormalizedItems && !searchTerm && !globalFiltersApplied;
// main content
const body = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
id: "add-select",
className: `${blockClass}__header`
}, /*#__PURE__*/React.createElement(AddSelectFilter.AddSelectFilter, {
inputLabel: globalSearchLabel,
inputPlaceholder: globalSearchPlaceholder,
searchTerm: searchTerm,
handleSearch: handleSearch,
multi: multi,
filterOpts: globalFilterOpts,
filtersLabel: globalFiltersLabel,
handleFilter: handleFilter,
primaryButtonText: globalFiltersPrimaryButtonText,
secondaryButtonText: globalFiltersSecondaryButtonText,
placeholder: globalFiltersPlaceholderText,
iconDescription: globalFiltersIconDescription,
appliedFilters: appliedGlobalFilters,
hasFiltersApplied: globalFiltersApplied,
clearFiltersText: clearFiltersText
}), /*#__PURE__*/React.createElement("div", {
className: cx(`${blockClass}__sub-header`, {
[`${blockClass}__sub-header-multi`]: multi
})
}, /*#__PURE__*/React.createElement("div", {
className: `${blockClass}__tags`
}, showBreadsCrumbs ? /*#__PURE__*/React.createElement(AddSelectBreadcrumbs.AddSelectBreadcrumbs, {
path: path,
onClick: pathOnclick,
multi: multi
}) : /*#__PURE__*/React.createElement("p", {
className: `${blockClass}__tags-label`
}, searchTerm ? searchResultsTitle : itemsLabel), showTags && /*#__PURE__*/React.createElement(react.Tag, {
type: "gray",
size: "sm"
}, itemsToDisplay.length)), showSort && /*#__PURE__*/React.createElement(AddSelectSort.AddSelectSort, {
setSortAttribute: setSortAttribute,
setSortDirection: setSortDirection,
sortBy: globalSortBy
}))), displayColumnView ? /*#__PURE__*/React.createElement("div", {
className: `${blockClass}__columns`
}, /*#__PURE__*/React.createElement(AddSelectColumn.AddSelectColumn, _rollupPluginBabelHelpers.extends({}, commonListProps, {
items: itemsToDisplay,
columnInputPlaceholder: columnInputPlaceholder,
header: path[0]?.title,
filterByLabel: filterByLabel,
sortByLabel: sortByLabel
}))) : /*#__PURE__*/React.createElement("div", null, hasResults ? /*#__PURE__*/React.createElement(AddSelectList.AddSelectList, _rollupPluginBabelHelpers.extends({}, commonListProps, {
filteredItems: itemsToDisplay,
modifiers: items?.modifiers,
appliedModifiers: appliedModifiers,
setAppliedModifiers: setAppliedModifiers,
setParentSelected: parentSelectionHandler,
parentSelected: parentSelected,
parentId: parentSelected || path[0].id
})) : /*#__PURE__*/React.createElement("div", {
className: `${blockClass}__body`
}, /*#__PURE__*/React.createElement(NotFoundEmptyState.NotFoundEmptyState, {
subtitle: noResultsDescription,
title: noResultsTitle,
illustrationTheme: illustrationTheme
}))));
if (multi) {
return /*#__PURE__*/React.createElement(Tearsheet.Tearsheet, _rollupPluginBabelHelpers.extends({}, commonTearsheetProps, {
influencer: multi && /*#__PURE__*/React.createElement(AddSelectSidebar.AddSelectSidebar, sidebarProps),
influencerPosition: "right"
}), body);
}
return /*#__PURE__*/React.createElement(TearsheetNarrow.TearsheetNarrow, commonTearsheetProps, body);
});
AddSelectBody.propTypes = {
className: index.default.string,
clearFiltersText: index.default.string,
closeIconDescription: index.default.string,
columnInputPlaceholder: index.default.string,
defaultModifiers: index.default.array,
description: index.default.string,
filterByLabel: index.default.string,
globalFilterOpts: index.default.array,
globalFiltersIconDescription: index.default.string,
globalFiltersLabel: index.default.string,
globalFiltersPlaceholderText: index.default.string,
globalFiltersPrimaryButtonText: index.default.string,
globalFiltersSecondaryButtonText: index.default.string,
globalSearchLabel: index.default.string.isRequired,
globalSearchPlaceholder: index.default.string,
globalSortBy: index.default.array,
illustrationTheme: index.default.oneOf(['light', 'dark']),
influencerTitle: index.default.string,
/**@ts-ignore */
items: index.default.shape({
modifiers: index.default.shape({
id: index.default.string,
label: index.default.string,
options: index.default.array,
multiSelect: index.default.bool
}),
sortBy: index.default.array,
filterBy: index.default.array,
entries: index.default.arrayOf(index.default.shape({
avatar: index.default.shape({
alt: index.default.string,
icon: index.default.oneOfType([index.default.func, index.default.object]),
src: index.default.string,
theme: index.default.oneOf(['light', 'dark'])
}),
children: index.default.object,
icon: index.default.oneOfType([index.default.func, index.default.object]),
id: index.default.string.isRequired,
meta: index.default.oneOfType([index.default.arrayOf(index.default.shape({
id: index.default.string,
title: index.default.string,
value: index.default.string
})), index.default.node]),
subtitle: index.default.string,
title: index.default.string.isRequired,
value: index.default.string.isRequired
}))
}),
itemsLabel: index.default.string,
metaIconDescription: index.default.string,
metaPanelTitle: index.default.string,
multi: index.default.bool,
navIconDescription: index.default.string,
noResultsDescription: index.default.string,
noResultsTitle: index.default.string,
noSelectionDescription: index.default.string,
noSelectionTitle: index.default.string,
normalizedItems: index.default.object,
onClose: index.default.func,
onCloseButtonText: index.default.string,
onSubmit: index.default.func,
onSubmitButtonText: index.default.string,
open: index.default.bool,
/**@ts-ignore */
portalTarget: index.default.node,
searchResultsTitle: index.default.string,
sortByLabel: index.default.string,
title: index.default.string,
useNormalizedItems: index.default.bool
};
AddSelectBreadcrumbs.AddSelectBreadcrumbs.displayName = componentName;
exports.AddSelectBody = AddSelectBody;