Skip to content

Commit

Permalink
Get filter working with input
Browse files Browse the repository at this point in the history
  • Loading branch information
ibolton336 committed Jan 24, 2024
1 parent d575f20 commit fd455a1
Showing 1 changed file with 165 additions and 30 deletions.
195 changes: 165 additions & 30 deletions client/src/app/components/FilterToolbar/MultiselectFilterControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
MenuToggleElement,
Select,
SelectGroup,
SelectList,
SelectOption,
SelectOptionProps,
TextInputGroup,
Expand Down Expand Up @@ -63,6 +64,15 @@ export const MultiselectFilterControl = <TItem,>({
console.log("selectOptions", selectOptions);
console.log("category.selectOptions", category.selectOptions);

const [focusedItemIndex, setFocusedItemIndex] = React.useState<number | null>(
null
);
// const [selected, setSelected] = React.useState<string[]>([]);

const [activeItem, setActiveItem] = React.useState<string | null>(null);
const textInputRef = React.useRef<HTMLInputElement>();
const [inputValue, setInputValue] = React.useState<string>("");

const getOptionKeyFromOptionValue = (
optionValue: string | SelectOptionProps
) => flatOptions.find((option) => option?.value === optionValue)?.key;
Expand Down Expand Up @@ -92,11 +102,14 @@ export const MultiselectFilterControl = <TItem,>({

const onFilterClear = (chip: string | ToolbarChip) => {
const chipKey = typeof chip === "string" ? chip : chip.key;
const optionKey = getOptionKeyFromChip(chipKey);
const newValue = filterValue
? filterValue.filter((val) => val !== optionKey)
: [];
setFilterValue(newValue.length > 0 ? newValue : null);

// Directly compute the new state
const newFilterValue = filterValue
? filterValue.filter((selection) => selection !== chipKey)
: filterValue;

// Pass the new state to setFilterValue
setFilterValue(newFilterValue);
};

// Select expects "selections" to be an array of the "value" props from the relevant optionProps
Expand Down Expand Up @@ -126,6 +139,27 @@ export const MultiselectFilterControl = <TItem,>({
return chip;
});

// // Updated chip creation logic

// const chips = filterValue.map((key, index) => {
// const value = getOptionValueFromOptionKey(key) ?? "";
// const idx = value.indexOf(CHIP_BREAK_DELINEATOR);

// if (idx > 0) {
// const tooltip = value.substring(0, idx);
// const text = value.substring(idx + CHIP_BREAK_DELINEATOR.length);
// return {
// key: key,
// node: (
// <Tooltip id={`tooltip-chip-${index}`} content={<div>{tooltip}</div>}>
// <div>{text}</div>
// </Tooltip>
// ),
// } as ToolbarChip;
// }
// return value;
// });

const renderSelectOptions = (
filter: (option: FilterSelectOptionProps, groupName?: string) => boolean
) =>
Expand Down Expand Up @@ -153,8 +187,16 @@ export const MultiselectFilterControl = <TItem,>({
return (
<SelectOption
{...optionProps}
// key={optionProps.key}
key={`${index}-${optionProps.value}`}
{...(!optionProps.isDisabled && { hasCheckbox: true })}
key={optionProps.value || optionProps.children}
isFocused={focusedItemIndex === index}
id={`select-multi-typeahead-${optionProps.value.replace(
" ",
"-"
)}`}
ref={null}
isSelected={filterValue?.includes(optionProps.value)}

// isSelected={optionProps.value === filterValue}
>
{optionProps.value}
Expand Down Expand Up @@ -202,29 +244,33 @@ export const MultiselectFilterControl = <TItem,>({
// </MenuToggle>
// );
// };
const [focusedItemIndex, setFocusedItemIndex] = React.useState<number | null>(
null
);
const [selected, setSelected] = React.useState<string>("");
const [activeItem, setActiveItem] = React.useState<string | null>(null);
const textInputRef = React.useRef<HTMLInputElement>();
const [inputValue, setInputValue] = React.useState<string>("");

const onSelect = (
_event: React.MouseEvent<Element, MouseEvent> | undefined,
value: string | number | undefined
) => {
// eslint-disable-next-line no-console
const onSelect = (value: string | undefined) => {
console.log("selected", value);

if (value && value !== "no results") {
setInputValue(value as string);
setFilterValue(null);
setSelected(value as string);
const newFilterValue = filterValue ? [...filterValue, value] : [value];
setFilterValue(newFilterValue);
// setSelected(
// selected.includes(value)
// ? selected.filter((selection) => selection !== value)
// : [...selected, value]
// );
}
setIsFilterDropdownOpen(false);
setFocusedItemIndex(null);
setActiveItem(null);

textInputRef.current?.focus();
// // eslint-disable-next-line no-console
// console.log("selected", value);

// if (value && value !== "no results") {
// setInputValue(value as string);
// setFilterValue(null);
// setSelected(value as string);
// }
// setIsFilterDropdownOpen(false);
// setFocusedItemIndex(null);
// setActiveItem(null);
textInputRef.current?.focus();
};

const handleMenuArrowKeys = (key: string) => {
Expand Down Expand Up @@ -256,6 +302,45 @@ export const MultiselectFilterControl = <TItem,>({
setActiveItem(`select-typeahead-${focusedItem.value.replace(" ", "-")}`);
}
};
React.useEffect(() => {
let newSelectOptions = Array.isArray(category.selectOptions)
? category.selectOptions
: [];

// Filter menu items based on the text input value when one exists
if (inputValue) {
newSelectOptions = Array.isArray(category.selectOptions)
? category.selectOptions?.filter((menuItem) => {
console.log("menuItem", menuItem);
console.log("inputValue", inputValue);
return String(menuItem.value)
.toLowerCase()
.includes(inputValue.toLowerCase());
})
: [];

// When no options are found after filtering, display 'No results found'
if (!newSelectOptions.length) {
newSelectOptions = [
{
key: "no results",
isDisabled: false,
children: `No results found for "${inputValue}"`,
value: "no results",
},
];
}

// Open the menu when the input value changes and the new value is not empty
if (!isFilterDropdownOpen) {
setIsFilterDropdownOpen(true);
}
}

setSelectOptions(newSelectOptions);
setFocusedItemIndex(null);
setActiveItem(null);
}, [inputValue]);

const onInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
const enabledMenuItems = Array.isArray(selectOptions)
Expand All @@ -269,21 +354,68 @@ export const MultiselectFilterControl = <TItem,>({
const newSelectOptions = flatOptions.filter((menuItem) =>
menuItem.value.toLowerCase().includes(inputValue.toLowerCase())
);
const selectedItem =
newSelectOptions.find(
(option) => option.value.toLowerCase() === inputValue.toLowerCase()
) || focusedItem;
switch (event.key) {
// Select the first available option
case "Enter":
event.preventDefault();
setSelectOptions(newSelectOptions); // Update the select options based on the filter
setIsFilterDropdownOpen(true); // Optionally open the dropdown after filtering

// Determine the item to select based on input value or focused item

if (
isFilterDropdownOpen &&
selectedItem &&
selectedItem.value !== "no results"
) {
setInputValue("");

// Add the value of the selected item to the filterValue
const newFilterValue = [
...(filterValue || []),
getOptionValueFromOptionKey(selectedItem.value),
];
setFilterValue(newFilterValue);
setIsFilterDropdownOpen(false);
}

// event.preventDefault();
// setSelectOptions(newSelectOptions); // Update the select options based on the filter
// setIsFilterDropdownOpen(true); // Optionally open the dropdown after filtering

// if (
// isFilterDropdownOpen &&
// focusedItem &&
// focusedItem?.value !== "no results"
// ) {
// // setInputValue(String(focusedItem.children));
// setInputValue("");

// // Add the value of the focused item to the filterValue
// const newFilterValue = [
// ...(filterValue || []),
// getOptionValueFromOptionKey(focusedItem.value),
// ];
// setFilterValue(newFilterValue); // Update the filter value with the new selection

// setIsFilterDropdownOpen(false);
// }
// event.preventDefault();
// setSelectOptions(newSelectOptions); // Update the select options based on the filter
// setIsFilterDropdownOpen(true); // Optionally open the dropdown after filtering

// if (
// isFilterDropdownOpen &&
// focusedItem &&
// focusedItem?.value !== "no results"
// ) {
// setInputValue(String(focusedItem.children));
// setFilterValue(null);
// setSelected(String(focusedItem.children));
// // setFilterValue()
// // setSelected(String(focusedItem.children));
// setIsFilterDropdownOpen(false);
// }

Expand Down Expand Up @@ -380,7 +512,7 @@ export const MultiselectFilterControl = <TItem,>({
<Button
variant="plain"
onClick={() => {
setSelected("");
// setSelected([]);
setInputValue("");
setFilterValue(null);
textInputRef?.current?.focus();
Expand Down Expand Up @@ -409,10 +541,13 @@ export const MultiselectFilterControl = <TItem,>({
toggle={toggle}
selected={filterValue}
onOpenChange={(isOpen) => setIsFilterDropdownOpen(isOpen)}
onSelect={(_, value) => onFilterSelect(value as string)}
// onSelect={(_, value) => onFilterSelect(value as string)}
onSelect={(ev, selection) => onSelect(selection as string)}
isOpen={isFilterDropdownOpen}
>
{renderSelectOptions(() => true)}
<SelectList id="select-multi-typeahead-checkbox-listbox">
{renderSelectOptions(() => true)}
</SelectList>
</Select>
</ToolbarFilter>
);
Expand Down

0 comments on commit fd455a1

Please sign in to comment.