From 2351ee73e559519e8ec1feae38d60329b100f03b Mon Sep 17 00:00:00 2001 From: KumJungMin Date: Sat, 19 Oct 2024 14:42:12 +0900 Subject: [PATCH 1/2] remove: delete createGroupChildren function --- .../lib/multiselect/MultiSelectPanel.js | 45 ++----------------- 1 file changed, 4 insertions(+), 41 deletions(-) diff --git a/components/lib/multiselect/MultiSelectPanel.js b/components/lib/multiselect/MultiSelectPanel.js index a0da4f4206..5f5a7b4490 100644 --- a/components/lib/multiselect/MultiSelectPanel.js +++ b/components/lib/multiselect/MultiSelectPanel.js @@ -104,39 +104,6 @@ export const MultiSelectPanel = React.memo( } }; - const createGroupChildren = (optionGroup, style) => { - const groupChildren = props.getOptionGroupChildren(optionGroup); - - return groupChildren.map((option, j) => { - const optionLabel = props.getOptionLabel(option); - const optionKey = j + '_' + props.getOptionRenderKey(option); - const disabled = props.isOptionDisabled(option); - const selected = props.isSelected(option); - - return ( - - ); - }); - }; - const createEmptyFilter = () => { const emptyFilterMessage = ObjectUtils.getJSXElement(props.emptyFilterMessage, props) || localeOption('emptyFilterMessage'); @@ -174,9 +141,8 @@ export const MultiSelectPanel = React.memo( const createItem = (option, index, scrollerOptions = {}) => { const style = { height: scrollerOptions.props ? scrollerOptions.props.itemSize : undefined }; - if (props.optionGroupLabel) { + if (option.group && props.optionGroupLabel) { const groupContent = props.optionGroupTemplate ? ObjectUtils.getJSXElement(props.optionGroupTemplate, option, index) : props.getOptionGroupLabel(option); - const groupChildrenContent = createGroupChildren(option, style); const key = index + '_' + props.getOptionGroupRenderKey(option); const itemGroupProps = mergeProps( { @@ -187,12 +153,9 @@ export const MultiSelectPanel = React.memo( ); return ( - -
  • - {groupContent} -
  • - {groupChildrenContent} -
    +
  • + {groupContent} +
  • ); } From d63e8c2e9d5e221d5339082e44a4e285b5bc7e94 Mon Sep 17 00:00:00 2001 From: KumJungMin Date: Sat, 19 Oct 2024 14:43:53 +0900 Subject: [PATCH 2/2] refactor: optimize handling of grouped options by flattening structure --- components/lib/multiselect/MultiSelect.js | 65 +++++++++-------------- 1 file changed, 24 insertions(+), 41 deletions(-) diff --git a/components/lib/multiselect/MultiSelect.js b/components/lib/multiselect/MultiSelect.js index 20f3af5ebf..12cd740a3e 100644 --- a/components/lib/multiselect/MultiSelect.js +++ b/components/lib/multiselect/MultiSelect.js @@ -386,28 +386,11 @@ export const MultiSelect = React.memo( if (event.checked) { value = []; + } else { + const validOptions = visibleOptions.filter((option) => isValidOption(option) && !isOptionDisabled(option)); - if (visibleOptions) { - const selectedOptions = visibleOptions.filter((option) => isOptionDisabled(option) && isSelected(option)); - - value = selectedOptions.map((option) => getOptionValue(option)); - } - } else if (visibleOptions) { - const options = visibleOptions.filter((option) => !isOptionDisabled(option) || isSelected(option)); - - if (props.optionGroupLabel) { - value = []; - options.forEach( - (optionGroup) => - (value = [ - ...value, - ...getOptionGroupChildren(optionGroup) - .filter((option) => !isOptionDisabled(option)) - .map((option) => getOptionValue(option)) - ]) - ); - } else { - value = options.map((option) => getOptionValue(option)); + if (validOptions) { + value = validOptions.map((option) => getOptionValue(option)); } } @@ -622,21 +605,7 @@ export const MultiSelect = React.memo( return false; } - const options = visibleOptions.filter((option) => !isOptionDisabled(option)); - - if (props.optionGroupLabel) { - let areAllSelected = true; - - for (let optionGroup of options) { - const visibleOptionsGroupChildren = getOptionGroupChildren(optionGroup).filter((option) => !isOptionDisabled(option)); - - if (visibleOptionsGroupChildren.some((option) => !isSelected(option)) === true) { - areAllSelected = false; - } - } - - return areAllSelected; - } + const options = visibleOptions.filter((option) => !isOptionDisabled(option) && isValidOption(option)); return !options.some((option) => !isSelected(option)); }; @@ -697,7 +666,7 @@ export const MultiSelect = React.memo( }; const isOptionGroup = (option) => { - return props.optionGroupLabel && option.optionGroup && option.group; + return props.optionGroupLabel && option.group; }; const hasSelectedOption = () => { @@ -937,12 +906,14 @@ export const MultiSelect = React.memo( }; const getVisibleOptions = () => { + const options = props.optionGroupLabel ? flatOptions(props.options) : props.options; + if (hasFilter) { const filterValue = filterState.trim().toLocaleLowerCase(props.filterLocale); const searchFields = props.filterBy ? props.filterBy.split(',') : [props.optionLabel || 'label']; if (props.optionGroupLabel) { - let filteredGroups = []; + const filteredGroups = []; for (let optgroup of props.options) { let filteredSubOptions = FilterService.filter(getOptionGroupChildren(optgroup), searchFields, filterValue, props.filterMatchMode, props.filterLocale); @@ -952,13 +923,25 @@ export const MultiSelect = React.memo( } } - return filteredGroups; + return flatOptions(filteredGroups); } - return FilterService.filter(props.options, searchFields, filterValue, props.filterMatchMode, props.filterLocale); + return FilterService.filter(options, searchFields, filterValue, props.filterMatchMode, props.filterLocale); } - return props.options; + return options; + }; + + const flatOptions = (options) => { + return (options || []).reduce((result, option, index) => { + result.push({ ...option, group: true, index }); + + const optionGroupChildren = getOptionGroupChildren(option); + + optionGroupChildren && optionGroupChildren.forEach((o) => result.push(o)); + + return result; + }, []); }; React.useImperativeHandle(ref, () => ({