2022-02-22 21:58:21 +01:00
|
|
|
import React, { useState, useContext } from 'react';
|
2022-04-19 17:08:09 +02:00
|
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
|
|
|
import { useSelector } from 'react-redux';
|
|
|
|
///: END:ONLY_INCLUDE_IN
|
2022-02-22 21:58:21 +01:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import Fuse from 'fuse.js';
|
|
|
|
import InputAdornment from '@material-ui/core/InputAdornment';
|
|
|
|
import TextField from '../../../components/ui/text-field';
|
|
|
|
import { I18nContext } from '../../../contexts/i18n';
|
2022-06-21 17:18:35 +02:00
|
|
|
import SearchIcon from '../../../components/ui/icon/search-icon';
|
2022-03-07 19:54:36 +01:00
|
|
|
import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils';
|
2023-02-27 17:42:02 +01:00
|
|
|
import { Icon, ICON_NAMES } from '../../../components/component-library';
|
|
|
|
import { IconColor } from '../../../helpers/constants/design-system';
|
2022-04-19 17:08:09 +02:00
|
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
|
|
|
import { getSnapsRouteObjects } from '../../../selectors';
|
|
|
|
///: END:ONLY_INCLUDE_IN
|
2022-02-22 21:58:21 +01:00
|
|
|
|
|
|
|
export default function SettingsSearch({
|
|
|
|
onSearch,
|
|
|
|
error,
|
|
|
|
settingsRoutesList,
|
|
|
|
}) {
|
|
|
|
const t = useContext(I18nContext);
|
|
|
|
|
|
|
|
const [searchQuery, setSearchQuery] = useState('');
|
2022-03-18 18:35:43 +01:00
|
|
|
const [searchIconColor, setSearchIconColor] = useState(
|
|
|
|
'var(--color-icon-muted)',
|
|
|
|
);
|
2022-02-22 21:58:21 +01:00
|
|
|
|
|
|
|
const settingsRoutesListArray = Object.values(settingsRoutesList);
|
2022-04-19 17:08:09 +02:00
|
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
|
|
|
const snaps = useSelector(getSnapsRouteObjects);
|
|
|
|
settingsRoutesListArray.push(...snaps);
|
|
|
|
///: END:ONLY_INCLUDE_IN
|
2022-02-22 21:58:21 +01:00
|
|
|
const settingsSearchFuse = new Fuse(settingsRoutesListArray, {
|
|
|
|
shouldSort: true,
|
2023-03-08 12:04:45 +01:00
|
|
|
threshold: 0.3,
|
2022-02-22 21:58:21 +01:00
|
|
|
location: 0,
|
|
|
|
distance: 100,
|
|
|
|
maxPatternLength: 32,
|
|
|
|
minMatchCharLength: 1,
|
2022-04-06 22:27:08 +02:00
|
|
|
keys: ['tabMessage', 'sectionMessage', 'descriptionMessage'],
|
|
|
|
getFn: (routeObject, path) => routeObject[path](t),
|
2022-02-22 21:58:21 +01:00
|
|
|
});
|
|
|
|
|
2022-03-28 17:03:41 +02:00
|
|
|
const handleSearch = (_searchQuery) => {
|
2022-12-16 21:28:13 +01:00
|
|
|
const sanitizedSearchQuery = _searchQuery
|
|
|
|
.replace(/[^A-Za-z0-9\s&_]/gu, '')
|
2023-01-09 21:54:28 +01:00
|
|
|
.trimStart();
|
2022-03-28 17:03:41 +02:00
|
|
|
setSearchQuery(sanitizedSearchQuery);
|
|
|
|
if (sanitizedSearchQuery === '') {
|
2022-03-18 18:35:43 +01:00
|
|
|
setSearchIconColor('var(--color-icon-muted)');
|
2022-02-22 21:58:21 +01:00
|
|
|
} else {
|
2022-03-18 18:35:43 +01:00
|
|
|
setSearchIconColor('var(--color-icon-default)');
|
2022-02-22 21:58:21 +01:00
|
|
|
}
|
2022-03-28 17:03:41 +02:00
|
|
|
|
|
|
|
const fuseSearchResult = settingsSearchFuse.search(sanitizedSearchQuery);
|
2022-02-22 21:58:21 +01:00
|
|
|
const addressSearchResult = settingsRoutesListArray.filter((routes) => {
|
|
|
|
return (
|
2022-04-19 17:08:09 +02:00
|
|
|
routes.tabMessage &&
|
2022-03-28 17:03:41 +02:00
|
|
|
sanitizedSearchQuery &&
|
|
|
|
isEqualCaseInsensitive(routes.tab, sanitizedSearchQuery)
|
2022-02-22 21:58:21 +01:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
const results = [...addressSearchResult, ...fuseSearchResult];
|
2022-03-28 17:03:41 +02:00
|
|
|
onSearch({ searchQuery: sanitizedSearchQuery, results });
|
2022-02-22 21:58:21 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const renderStartAdornment = () => {
|
|
|
|
return (
|
|
|
|
<InputAdornment position="start" style={{ marginRight: '12px' }}>
|
|
|
|
<SearchIcon color={searchIconColor} />
|
|
|
|
</InputAdornment>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const renderEndAdornment = () => {
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
{searchQuery && (
|
|
|
|
<InputAdornment
|
|
|
|
className="imageclosectn"
|
|
|
|
position="end"
|
|
|
|
onClick={() => handleSearch('')}
|
|
|
|
style={{ cursor: 'pointer' }}
|
|
|
|
>
|
2023-02-27 17:42:02 +01:00
|
|
|
<Icon name={ICON_NAMES.CLOSE} color={IconColor.iconDefault} />
|
2022-02-22 21:58:21 +01:00
|
|
|
</InputAdornment>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<TextField
|
|
|
|
id="search-settings"
|
|
|
|
placeholder={t('searchSettings')}
|
|
|
|
type="text"
|
|
|
|
value={searchQuery}
|
|
|
|
onChange={(e) => handleSearch(e.target.value)}
|
|
|
|
error={error}
|
|
|
|
fullWidth
|
|
|
|
autoFocus
|
|
|
|
autoComplete="off"
|
|
|
|
startAdornment={renderStartAdornment()}
|
|
|
|
endAdornment={renderEndAdornment()}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
SettingsSearch.propTypes = {
|
|
|
|
onSearch: PropTypes.func,
|
|
|
|
error: PropTypes.string,
|
|
|
|
settingsRoutesList: PropTypes.array,
|
|
|
|
};
|