setIsFocused(true)}\r\n onBlur={e => e.relatedTarget === null && setIsFocused(false)}\r\n >\r\n {searchTabs && Object.keys(searchTabs).length > 1 &&\r\n
\r\n \r\n {Object.entries(searchTabs).map(([key, value]) => {\r\n return (\r\n \r\n )\r\n })}\r\n
\r\n }\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default QuickFind;\r\n","import { useState, useEffect, useMemo, useCallback, forwardRef } from 'react';\r\nimport MuiAutocomplete, { createFilterOptions } from '@mui/material/Autocomplete';\r\nimport Backdrop from '@mui/material/Backdrop';\r\nimport CircularProgress from '@mui/material/CircularProgress';\r\nimport Popper from '@mui/material/Popper';\r\nimport IconButton from '@mui/material/IconButton';\r\nimport SearchIcon from '@mui/icons-material/Search';\r\nimport TextField from '@mui/material/TextField';\r\nimport throttle from 'lodash/throttle';\r\nimport parse from 'autosuggest-highlight/parse';\r\nimport match from 'autosuggest-highlight/match';\r\nimport { styled } from '@mui/material/styles';\r\nimport { sandhillsRequest } from '@Components/Utilities/SandhillsUtility';\r\nimport { trackAutocompleteSearchAction } from '@Components/Utilities/Tracking';\r\nimport translator from '@Components/Utilities/Translator';\r\nimport atoms from '@Components/Utilities/SandhillsAtoms';\r\nimport { useRecoilValue } from 'recoil';\r\nimport { setSearchHistoryCookie, getSearchHistoryValues } from '@Components/Utilities/CookieHelper';\r\nimport ListSubheader from '@mui/material/ListSubheader';\r\n\r\nconst Autocomplete = forwardRef((props, ref) => {\r\n\r\n const [history, setHistory] = useState();\r\n const SearchIconButton = styled(IconButton)(({ theme }) => ({\r\n color: theme.palette.common.white,\r\n backgroundColor: theme.palette.common.black,\r\n '&:hover': {\r\n backgroundColor: theme.palette.primary.main,\r\n color: theme.palette.primary.contrastText,\r\n }\r\n }));\r\n\r\n const quickFindRegex = /^([a-z]{2})(\\d{2})([a-z]{2})$/i;\r\n const defaultFilterOptions = createFilterOptions();\r\n const routes = useRecoilValue(atoms.routes);\r\n const onFilterOptions = (options, state) => {\r\n if (options?.some(op => op.isParent)) {\r\n let filteredOps = defaultFilterOptions(options, state);\r\n let valsToKeep = [];\r\n for (var i = 0; i < filteredOps.length; i++) {\r\n if (filteredOps[i].parentValue) {\r\n valsToKeep.push(filteredOps[i].parentValue);\r\n }\r\n valsToKeep.push(filteredOps[i].value);\r\n }\r\n return options.filter(op => valsToKeep.includes(op.value));\r\n }\r\n else {\r\n return defaultFilterOptions(options, state);\r\n }\r\n };\r\n\r\n\r\n const ajaxOptions = {\r\n enabled: true,\r\n url: routes.ListingsAutocomplete,\r\n method: 'get',\r\n additionalData: null,\r\n dataKey: 'keywords',\r\n minLength: 3,\r\n onSearch: (active, searchValue, searchType) => {\r\n if (searchType != 'Part') {\r\n setIsLoading(true);\r\n\r\n let url = ajaxOptions.url;\r\n if (ajaxOptions.method == 'get') {\r\n url = buildUrl(url, ajaxOptions.dataKey, searchValue);\r\n\r\n if (searchType == 'Attachment') {\r\n url += `&SearchType=Attachment`;\r\n } else if (searchType == 'Dismantled') {\r\n url += `&Condition=Dismantled`;\r\n }\r\n\r\n if (ajaxOptions.additionalData) {\r\n for (var key in ajaxOptions.additionalData) {\r\n url += `&${key}=${ajaxOptions.additionalData[key]}`;\r\n }\r\n }\r\n }\r\n\r\n sandhillsRequest({\r\n url: url,\r\n method: ajaxOptions.method,\r\n errorHandling: {\r\n useConsole: false,\r\n useAlert: false\r\n }\r\n }).then((data) => {\r\n if (active) {\r\n let newOptions = [];\r\n\r\n if (data) {\r\n newOptions = [...newOptions, ...data];\r\n }\r\n\r\n setOptions(newOptions);\r\n setIsLoading(false);\r\n }\r\n });\r\n } else {\r\n setOptions([]);\r\n }\r\n },\r\n ...props.ajaxOptions\r\n };\r\n\r\n const searchOptions = {\r\n enabled: true,\r\n url: routes.Listings,\r\n text: translator.translate('sandhills.search'),\r\n additionalData: null,\r\n dataKey: 'keywords',\r\n useSubmitBehavior: false,\r\n onSearch: null,\r\n isQuickFindCode: (v) => quickFindRegex.test(v),\r\n runQuickFindCheck: () => {\r\n var qfOption = options.find(o => o.TermType == 'QuickFind');\r\n if (qfOption) {\r\n window.location.href = qfOption.Url;\r\n } else {\r\n sandhillsRequest({\r\n url: routes.GetQuickFindUrl,\r\n data: {\r\n quickFindCode: inputValue\r\n },\r\n errorHandling: {\r\n useConsole: false,\r\n useAlert: false\r\n }\r\n }).then((data) => {\r\n if (data) {\r\n window.location.href = data;\r\n } else {\r\n searchOptions.defaultSearch();\r\n }\r\n }).catch(() => {\r\n searchOptions.defaultSearch();\r\n });\r\n }\r\n },\r\n defaultSearch: () => {\r\n var url = '';\r\n if (searchType == 'Part') {\r\n url = buildUrl(props.partsUrl, 'PartNumber', inputValue);\r\n searchOptions.additionalData = { SearchType: 'Start' };\r\n }\r\n else if (searchType == 'Attachment') {\r\n url = buildUrl(props.attachmentsUrl, searchOptions.dataKey, inputValue);\r\n }\r\n else if (searchType == 'Dismantled') {\r\n url = buildUrl(routes.Dismantled, searchOptions.dataKey, inputValue);\r\n }\r\n else {\r\n url = buildUrl(searchOptions.url, searchOptions.dataKey, inputValue);\r\n } \r\n if (searchOptions.additionalData) {\r\n for (var key in searchOptions.additionalData) {\r\n url += `&${key}=${searchOptions.additionalData[key]}`;\r\n }\r\n }\r\n if (props.showHistory) {\r\n setSearchHistoryCookie(inputValue, url);\r\n }\r\n\r\n window.location.href = url;\r\n },\r\n runSearch: () => {\r\n setOpen(false);\r\n if (searchOptions.useSubmitBehavior) {\r\n return; // Means this is wrapped in a Form Tag\r\n } else if (searchOptions.url && !searchOptions.onSearch) {\r\n setOpenBackdrop(true);\r\n trackingOptions.save(inputValue);\r\n\r\n if (searchOptions.isQuickFindCode(inputValue)) {\r\n searchOptions.runQuickFindCheck();\r\n } else {\r\n searchOptions.defaultSearch();\r\n }\r\n\r\n } else {\r\n if (searchOptions.onSearch && typeof searchOptions.onSearch === 'function') {\r\n searchOptions.onSearch(inputValue);\r\n }\r\n }\r\n setTimeout(() => {\r\n setOpenBackdrop(false);\r\n setIsLoading(false);\r\n }, 1500);\r\n },\r\n ...props.searchOptions\r\n };\r\n\r\n const trackingOptions = {\r\n url: routes.SaveAction,\r\n enabled: true,\r\n save: (value) => {\r\n if (trackingOptions.enabled) {\r\n trackAutocompleteSearchAction(trackingOptions.url, value);\r\n }\r\n },\r\n ...props.trackingOptions\r\n };\r\n\r\n const styles = {\r\n bgVariant: null,\r\n fontWeight: {\r\n normal: 400,\r\n highlight: 700\r\n },\r\n listbox: {\r\n maxHeight: 500,\r\n border: '1px solid #ccc'\r\n },\r\n ...props.styles\r\n };\r\n\r\n const inputOptions = {\r\n startAdornment: null,\r\n endAdornment: (value, endAdornment) => {\r\n const newChildren = React.Children.map(endAdornment?.props?.children || [], c => c);\r\n\r\n if (isLoading) {\r\n newChildren?.unshift(