diff --git a/frontend/src/components/search/search-filters/filter-by-creator.js b/frontend/src/components/search/search-filters/filter-by-creator.js index bc998f4f65..ec503139a4 100644 --- a/frontend/src/components/search/search-filters/filter-by-creator.js +++ b/frontend/src/components/search/search-filters/filter-by-creator.js @@ -11,11 +11,12 @@ import ModalPortal from '../../modal-portal'; import toaster from '../../toast'; import { SEARCH_FILTERS_KEY } from '../../../constants'; -const FilterByCreator = ({ creatorList, onSelect }) => { +const FilterByCreator = ({ creatorList, onChange }) => { const [isOpen, setIsOpen] = useState(false); const [options, setOptions] = useState([]); const [selectedOptions, setSelectedOptions] = useState(creatorList || []); const [searchValue, setSearchValue] = useState(''); + const [inputFocus, setInputFocus] = useState(false); const toggle = useCallback((e) => { setIsOpen(!isOpen); @@ -28,7 +29,7 @@ const FilterByCreator = ({ creatorList, onSelect }) => { }); }, [options, searchValue]); - const onSelectOption = useCallback((e) => { + const onChangeOption = useCallback((e) => { e.preventDefault(); e.stopPropagation(); const name = Utils.getEventData(e, 'toggle') ?? e.currentTarget.getAttribute('data-toggle'); @@ -40,17 +41,17 @@ const FilterByCreator = ({ creatorList, onSelect }) => { updated = updated.filter((option) => option.name !== name); } setSelectedOptions(updated); - onSelect(SEARCH_FILTERS_KEY.CREATOR_LIST, updated); + onChange(SEARCH_FILTERS_KEY.CREATOR_LIST, updated); if (displayOptions.length === 1) { setSearchValue(''); } - }, [selectedOptions, displayOptions, options, onSelect]); + }, [selectedOptions, displayOptions, options, onChange]); const handleCancel = useCallback((e, name) => { const updated = selectedOptions.filter((option) => option.name !== name); setSelectedOptions(updated); - onSelect(SEARCH_FILTERS_KEY.CREATOR_LIST, updated); - }, [selectedOptions, onSelect]); + onChange(SEARCH_FILTERS_KEY.CREATOR_LIST, updated); + }, [selectedOptions, onChange]); const handleInputChange = useCallback((e) => { const v = e.target.value; @@ -100,7 +101,7 @@ const FilterByCreator = ({ creatorList, onSelect }) => { -
+
{selectedOptions.map((option) => ( { type="text" placeholder={selectedOptions.length ? '' : gettext('Search user')} value={searchValue} + autoFocus onChange={handleInputChange} onKeyDown={handleInputKeyDown} + onFocus={() => setInputFocus(true)} + onBlur={() => setInputFocus(false)} />
@@ -126,7 +130,7 @@ const FilterByCreator = ({ creatorList, onSelect }) => { tabIndex="-1" data-toggle={option.name} onMouseDown={(e) => e.preventDefault()} - onClick={onSelectOption} + onClick={onChangeOption} toggle={false} > {isOpen && } @@ -142,7 +146,7 @@ const FilterByCreator = ({ creatorList, onSelect }) => { FilterByCreator.propTypes = { creatorList: PropTypes.array.isRequired, - onSelect: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, }; export default FilterByCreator; diff --git a/frontend/src/components/search/search-filters/filter-by-date.js b/frontend/src/components/search/search-filters/filter-by-date.js index 0acb0f09de..2b7cf6d046 100644 --- a/frontend/src/components/search/search-filters/filter-by-date.js +++ b/frontend/src/components/search/search-filters/filter-by-date.js @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import PropTypes from 'prop-types'; import { Dropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap'; import dayjs from 'dayjs'; @@ -7,14 +7,19 @@ import { Utils } from '../../../utils/utils'; import Picker from '../../date-and-time-picker'; import ModalPortal from '../../modal-portal'; import { SEARCH_FILTERS_KEY, SEARCH_FILTER_BY_DATE_OPTION_KEY, SEARCH_FILTER_BY_DATE_TYPE_KEY } from '../../../constants'; +import classNames from 'classnames'; const DATE_INPUT_WIDTH = 118; -const FilterByDate = ({ date, onSelect }) => { +const FilterByDate = ({ date, onChange }) => { const [value, setValue] = useState(date.value); const [isOpen, setIsOpen] = useState(false); const [isTypeOpen, setIsTypeOpen] = useState(false); const [isCustomDate, setIsCustomDate] = useState(date.value === SEARCH_FILTER_BY_DATE_OPTION_KEY.CUSTOM); + const [time, setTime] = useState({ + from: date.from, + to: date.to, + }); const [type, setType] = useState(date.type); const typeLabel = useMemo(() => { @@ -28,6 +33,11 @@ const FilterByDate = ({ date, onSelect }) => { } }, [type]); + const label = useMemo(() => { + if (!value || value.length === 0) return gettext('Date'); + return typeLabel; + }, [typeLabel, value]); + const typeOptions = useMemo(() => { return [ { @@ -40,28 +50,6 @@ const FilterByDate = ({ date, onSelect }) => { ]; }, []); - const label = useMemo(() => { - if (!value || value.length === 0) return gettext('Date'); - const formatDate = (date) => dayjs(date).format('YYYY-MM-DD'); - const today = dayjs(); - const prefix = `${typeLabel}: `; - - switch (value) { - case SEARCH_FILTER_BY_DATE_OPTION_KEY.TODAY: - return `${prefix}${formatDate(today)}`; - case SEARCH_FILTER_BY_DATE_OPTION_KEY.LAST_7_DAYS: - return `${prefix}${formatDate(today.subtract(6, 'day'))} - ${formatDate(today)}`; - case SEARCH_FILTER_BY_DATE_OPTION_KEY.LAST_30_DAYS: - return `${prefix}${formatDate(today.subtract(29, 'day'))} - ${formatDate(today)}`; - case SEARCH_FILTER_BY_DATE_OPTION_KEY.CUSTOM: - return date.start && date.end - ? `${prefix}${formatDate(date.start)} - ${formatDate(date.end)}` - : gettext('Select date range'); - default: - return gettext('Date'); - } - }, [date, value, typeLabel]); - const options = useMemo(() => { return [ { @@ -90,96 +78,102 @@ const FilterByDate = ({ date, onSelect }) => { const option = Utils.getEventData(e, 'toggle') ?? e.currentTarget.getAttribute('data-toggle'); if (option === type) return; setType(option); - onSelect(SEARCH_FILTERS_KEY.DATE, { - ...date, - type: option, - }); - }, [type, onSelect, date]); + }, [type]); const onClearDate = useCallback(() => { setValue(''); setIsCustomDate(false); - onSelect(SEARCH_FILTERS_KEY.DATE, ''); - }, [onSelect]); + setTime({ + from: null, + to: null, + }); + setIsOpen(false); + }, []); const onOptionClick = useCallback((e) => { const option = Utils.getEventData(e, 'toggle') ?? e.currentTarget.getAttribute('data-toggle'); if (option === value) return; const today = dayjs().endOf('day'); - setIsCustomDate(option === SEARCH_FILTER_BY_DATE_OPTION_KEY.CUSTOM); + const isCustomOption = option === SEARCH_FILTER_BY_DATE_OPTION_KEY.CUSTOM; + setIsCustomDate(isCustomOption); setValue(option); + setIsOpen(isCustomOption); switch (option) { case SEARCH_FILTER_BY_DATE_OPTION_KEY.TODAY: { - onSelect(SEARCH_FILTERS_KEY.DATE, { - value: option, - start: dayjs().startOf('day').unix(), - end: today.unix() + setTime({ + from: dayjs().startOf('day').unix(), + to: today.unix() }); break; } case SEARCH_FILTER_BY_DATE_OPTION_KEY.LAST_7_DAYS: { - onSelect(SEARCH_FILTERS_KEY.DATE, { - value: option, - start: dayjs().subtract(6, 'day').startOf('day').unix(), - end: today.unix() + setTime({ + from: dayjs().subtract(6, 'day').startOf('day').unix(), + to: today.unix() }); break; } case SEARCH_FILTER_BY_DATE_OPTION_KEY.LAST_30_DAYS: { - onSelect(SEARCH_FILTERS_KEY.DATE, { - value: option, - start: dayjs().subtract(30, 'day').startOf('day').unix(), - end: today.unix() + setTime({ + from: dayjs().subtract(30, 'day').startOf('day').unix(), + to: today.unix() }); break; } case SEARCH_FILTER_BY_DATE_OPTION_KEY.CUSTOM: { - onSelect(SEARCH_FILTERS_KEY.DATE, { - value: option, - start: null, - end: null, + setTime({ + from: null, + to: null, }); break; } } - }, [value, onSelect]); + }, [value]); const disabledStartDate = useCallback((startDate) => { if (!startDate) return false; const today = dayjs(); - const endValue = date.end; + const endValue = time.to; if (!endValue) { return startDate.isAfter(today); } return endValue.isBefore(startDate) || startDate.isAfter(today); - }, [date]); + }, [time]); const disabledEndDate = useCallback((endDate) => { if (!endDate) return false; const today = dayjs(); - const startValue = date.start; + const startValue = time.from; if (!startValue) { return endDate.isAfter(today); } return endDate.isBefore(startValue) || endDate.isAfter(today); - }, [date]); + }, [time]); - const onChangeCustomDate = useCallback((customDate) => { - const newDate = { - ...date, - ...customDate, - }; - onSelect(SEARCH_FILTERS_KEY.DATE, newDate); - }, [date, onSelect]); + useEffect(() => { + if (!isOpen) { + if (type !== date.type || time.from !== date.from || time.to !== date.to) { + onChange(SEARCH_FILTERS_KEY.DATE, { + type, + value, + from: time.from, + to: time.to, + }); + } + } + }, [isOpen, date, time, type, value, onChange]); return (
- +
{label}
{ e.stopPropagation(); toggle(); @@ -193,7 +187,7 @@ const FilterByDate = ({ date, onSelect }) => {
{typeLabel}
{ e.stopPropagation(); toggleType(); @@ -241,8 +235,8 @@ const FilterByDate = ({ date, onSelect }) => { onChangeCustomDate({ start: value })} + value={time.from} + onChange={(value) => setTime({ ...time, from: value })} inputWidth={DATE_INPUT_WIDTH} />
@@ -251,8 +245,8 @@ const FilterByDate = ({ date, onSelect }) => { onChangeCustomDate({ end: value })} + value={time.to} + onChange={(value) => setTime({ ...time, to: value })} inputWidth={DATE_INPUT_WIDTH} /> @@ -272,7 +266,7 @@ FilterByDate.propTypes = { start: PropTypes.oneOfType([PropTypes.number, PropTypes.object]), end: PropTypes.oneOfType([PropTypes.number, PropTypes.object]), }), - onSelect: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, }; export default FilterByDate; diff --git a/frontend/src/components/search/search-filters/filter-by-suffix.js b/frontend/src/components/search/search-filters/filter-by-suffix.js index 13e081d1c2..f2ac8badc5 100644 --- a/frontend/src/components/search/search-filters/filter-by-suffix.js +++ b/frontend/src/components/search/search-filters/filter-by-suffix.js @@ -1,4 +1,4 @@ -import React, { useCallback, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { Dropdown, DropdownMenu, DropdownToggle } from 'reactstrap'; import PropTypes from 'prop-types'; import classNames from 'classnames'; @@ -6,18 +6,16 @@ import { gettext } from '../../../utils/constants'; import ModalPortal from '../../modal-portal'; import { SEARCH_FILTERS_KEY } from '../../../constants'; -const FilterBySuffix = ({ suffixes, onSelect }) => { +const FilterBySuffix = ({ suffixes, onChange }) => { const [isOpen, setIsOpen] = useState(false); - const [inputValue, setInputValue] = useState(suffixes.join(', ')); + const [inputValue, setInputValue] = useState(suffixes); const inputRef = useRef(null); const toggle = useCallback(() => setIsOpen(!isOpen), [isOpen]); const handleInput = useCallback((e) => { setInputValue(e.target.value); - const suffixes = e.target.value.split(',').map(suffix => suffix.trim()).filter(Boolean); - onSelect(SEARCH_FILTERS_KEY.SUFFIXES, suffixes); - }, [onSelect]); + }, []); const handleKeyDown = useCallback((e) => { e.stopPropagation(); @@ -26,30 +24,48 @@ const FilterBySuffix = ({ suffixes, onSelect }) => { } }, []); + const handleClearInput = useCallback(() => { + setInputValue(''); + setIsOpen(false); + }, []); + + useEffect(() => { + if (!isOpen && inputValue !== suffixes) { + onChange(SEARCH_FILTERS_KEY.SUFFIXES, inputValue.replace(/\./g, '')); + } + }, [isOpen, inputValue, suffixes, onChange]); + return (
0, - 'highlighted': suffixes.length > 0, + 'active': isOpen && inputValue.length > 0, + 'highlighted': inputValue.length > 0, })} onClick={toggle}>
{gettext('File suffix')}
- +
- -
- -
+ + + {inputValue.length > 0 && ( + + )}
@@ -58,8 +74,8 @@ const FilterBySuffix = ({ suffixes, onSelect }) => { }; FilterBySuffix.propTypes = { - suffixes: PropTypes.array.isRequired, - onSelect: PropTypes.func.isRequired, + suffixes: PropTypes.string.isRequired, + onChange: PropTypes.func.isRequired, }; export default FilterBySuffix; diff --git a/frontend/src/components/search/search-filters/filter-by-text.js b/frontend/src/components/search/search-filters/filter-by-text.js index 930802dfa7..dbb405667f 100644 --- a/frontend/src/components/search/search-filters/filter-by-text.js +++ b/frontend/src/components/search/search-filters/filter-by-text.js @@ -6,7 +6,7 @@ import { Utils } from '../../../utils/utils'; import { gettext } from '../../../utils/constants'; import { SEARCH_FILTERS_KEY } from '../../../constants'; -const FilterByText = ({ searchFilenameOnly, onSelect }) => { +const FilterByText = ({ searchFilenameOnly, onChange }) => { const [isOpen, setIsOpen] = useState(false); const [value, setValue] = useState(searchFilenameOnly ? SEARCH_FILTERS_KEY.SEARCH_FILENAME_ONLY : SEARCH_FILTERS_KEY.SEARCH_FILENAME_AND_CONTENT); @@ -27,8 +27,8 @@ const FilterByText = ({ searchFilenameOnly, onSelect }) => { const option = Utils.getEventData(e, 'toggle') ?? e.currentTarget.getAttribute('data-toggle'); setValue(option); const isSearchFilenameOnly = option === SEARCH_FILTERS_KEY.SEARCH_FILENAME_ONLY; - onSelect(SEARCH_FILTERS_KEY.SEARCH_FILENAME_ONLY, isSearchFilenameOnly); - }, [onSelect]); + onChange(SEARCH_FILTERS_KEY.SEARCH_FILENAME_ONLY, isSearchFilenameOnly); + }, [onChange]); const label = options.find((option) => option.key === value).label; @@ -59,7 +59,7 @@ const FilterByText = ({ searchFilenameOnly, onSelect }) => { FilterByText.propTypes = { searchFilenameOnly: PropTypes.bool.isRequired, - onSelect: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, }; export default FilterByText; diff --git a/frontend/src/components/search/search-filters/index.css b/frontend/src/components/search/search-filters/index.css index bc09d89ba7..804d3c842e 100644 --- a/frontend/src/components/search/search-filters/index.css +++ b/frontend/src/components/search/search-filters/index.css @@ -32,6 +32,10 @@ background-color: #efefef; } +.search-filter-toggle .sf3-font-down { + color: #666; +} + .search-filters-container .search-filter .filter-label { width: fit-content; display: inline-block; @@ -57,6 +61,28 @@ .search-filter-menu.filter-by-suffix-menu { width: 400px; + position: relative; +} + +.search-filter-menu.filter-by-suffix-menu .clear-icon-right { + width: 20px; + height: 20px; + position: absolute; + top: 16px; + right: 16px; + display: flex; + justify-content: center; + align-items: center; + color: #666; + margin: 9px; + border: 0; + border-radius: 3px; + background-color: transparent; + padding: 0; +} + +.search-filter-menu.filter-by-suffix-menu .clear-icon-right:hover { + background-color: #efefef; } .search-filters-container .search-filters-dropdown-item { @@ -91,6 +117,14 @@ gap: 4px; } +.search-filter-menu .input-container.focus { + background-color: #fff; + border-color: #1991eb; + box-shadow: 0 0 0 2px rgba(70, 127, 207, .25); + color: #495057; + outline: 0; +} + .search-filter-menu .input-container .search-input-wrapper { display: flex; align-items: center; @@ -150,6 +184,10 @@ align-items: center; } +.filter-by-date-menu .filter-by-date-menu-toolbar .filter-by-date-type-toggle .filter-label { + color: #7d7d7d; +} + .filter-by-date-menu .filter-by-date-menu-toolbar .delete-btn { display: flex; align-items: center; @@ -184,12 +222,12 @@ font-size: 14px; } -.search-filters-container .search-filter-toggle.active, .search-filters-container .search-filter-toggle.active:hover, .search-filters-container .search-filter-toggle.highlighted:hover { background-color: rgba(255, 152, 0, 0.2); } -.search-filters-container .search-filter-toggle.highlighted { +.search-filters-container .search-filter-toggle.highlighted, +.search-filter-toggle.highlighted .sf3-font-down { color: #ff9800; } diff --git a/frontend/src/components/search/search-filters/index.js b/frontend/src/components/search/search-filters/index.js index 3a704e2543..c0cfe807a2 100644 --- a/frontend/src/components/search/search-filters/index.js +++ b/frontend/src/components/search/search-filters/index.js @@ -10,10 +10,10 @@ import './index.css'; const SearchFilters = ({ filters, onChange }) => { return (
- - - - + + + +
); }; diff --git a/frontend/src/components/search/search.js b/frontend/src/components/search/search.js index ce66ff5196..e8093a1086 100644 --- a/frontend/src/components/search/search.js +++ b/frontend/src/components/search/search.js @@ -12,7 +12,7 @@ import { Utils } from '../../utils/utils'; import toaster from '../toast'; import Loading from '../loading'; import { SEARCH_MASK, SEARCH_CONTAINER } from '../../constants/zIndexes'; -import { PRIVATE_FILE_TYPE, SEARCH_FILTER_BY_DATE_OPTION_KEY, SEARCH_FILTER_BY_DATE_TYPE_KEY, SEARCH_FILTERS_SHOW_KEY } from '../../constants'; +import { PRIVATE_FILE_TYPE, SEARCH_FILTER_BY_DATE_OPTION_KEY, SEARCH_FILTER_BY_DATE_TYPE_KEY, SEARCH_FILTERS_KEY, SEARCH_FILTERS_SHOW_KEY } from '../../constants'; import SearchFilters from './search-filters'; import SearchTags from './search-tags'; import IconBtn from '../icon-btn'; @@ -61,10 +61,10 @@ class Search extends Component { date: { type: SEARCH_FILTER_BY_DATE_TYPE_KEY.CREATE_TIME, value: '', - start: null, - end: null, + from: null, + to: null, }, - suffixes: [], + suffixes: '', }, }; this.highlightRef = null; @@ -530,7 +530,7 @@ class Search extends Component { start: null, end: null, }, - suffixes: [], + suffixes: '', } }); } @@ -558,7 +558,7 @@ class Search extends Component { } } - const filteredItems = this.filterResults(resultItems); + const filteredItems = this.filterByCreator(resultItems); if (isLoading) { return ; } @@ -668,72 +668,34 @@ class Search extends Component { } searchRepo = () => { - const { value, filters } = this.state; + const { value } = this.state; const queryData = { q: value, search_repo: this.props.repoID, search_ftypes: 'all', - search_filename_only: filters.search_filename_only, }; - this.getSearchResult(queryData); + this.getSearchResult(this.buildSearchParams(queryData)); }; searchFolder = () => { - const { value, filters } = this.state; + const { value } = this.state; const queryData = { q: value, search_repo: this.props.repoID, search_ftypes: 'all', search_path: this.props.path, - search_filename_only: filters.search_filename_only, }; - this.getSearchResult(queryData); + this.getSearchResult(this.buildSearchParams(queryData)); }; searchAllRepos = () => { - const { value, filters } = this.state; + const { value } = this.state; const queryData = { q: value, search_repo: 'all', search_ftypes: 'all', - search_filename_only: filters.search_filename_only, }; - this.getSearchResult(queryData); - }; - - filterResults = (results) => { - const { filters } = this.state; - return results.filter(item => { - if (filters.creator_list && filters.creator_list.length > 0) { - if (!filters.creator_list.some(creator => creator.email === item.repo_owner_email)) { - return false; - } - } - - let startDate = filters.date.start; - let endDate = filters.date.end; - if (filters.date.value === SEARCH_FILTER_BY_DATE_OPTION_KEY.CUSTOM) { - startDate = filters.date.start?.unix(); - endDate = filters.date.end?.unix(); - } - - if (startDate && item.mtime < startDate) { - return false; - } - if (endDate && item.mtime > endDate) { - return false; - } - - if (filters.suffixes && filters.suffixes.length > 0) { - const pathParts = item.path.split('.'); - const suffix = pathParts.length > 1 ? `.${pathParts.pop()}` : ''; - if (!filters.suffixes.includes(suffix)) { - return false; - } - } - - return true; - }); + this.getSearchResult(this.buildSearchParams(queryData)); }; renderResults = (resultItems, isVisited) => { @@ -785,26 +747,79 @@ class Search extends Component { this.setState({ isFiltersShow: !isFiltersShow }); } + buildSearchParams = (baseParams) => { + const { filters } = this.state; + const params = { ...baseParams }; + + if (filters.search_filename_only) { + params.search_filename_only = filters.search_filename_only; + } + + if (filters.date.value) { + const isCustom = filters.date.value === SEARCH_FILTER_BY_DATE_OPTION_KEY.CUSTOM; + params.time_from = isCustom ? filters.date.start?.unix() : filters.date.from; + params.time_to = isCustom ? filters.date.end?.unix() : filters.date.to; + } + + if (filters.suffixes) { + params.input_fexts = filters.suffixes; + params.search_ftypes = 'custom'; + } + + if (filters.creator_list.length > 0) { + params.creator_emails = filters.creator_list.map(c => c.email).join(','); + } + + return params; + }; + handleFiltersChange = (key, value) => { - const newFilters = { ...this.state.filters, [key]: value}; - if (newFilters.search_filename_only !== this.state.filters.search_filename_only) { - this.setState({ filters: newFilters }, () => { - const newQueryData = { - ...this.queryData, - search_filename_only: newFilters.search_filename_only, - } - this.getSearchResult(newQueryData); - }); + const newFilters = { ...this.state.filters, [key]: value }; + const hasActiveFilter = newFilters.suffixes || newFilters.creator_list.length > 0 || newFilters.date.value; + this.setState({ filters: newFilters, isFilterControllerActive: hasActiveFilter }); + + // build query data + if (!this.state.value || !this.state.isResultGotten) return; + const queryUpdates = {}; + + if (key === SEARCH_FILTERS_KEY.CREATOR_LIST) return; + if (key === SEARCH_FILTERS_KEY.SEARCH_FILENAME_ONLY) { + queryUpdates.search_filename_only = value; + } + if (key === SEARCH_FILTERS_KEY.SUFFIXES) { + queryUpdates.search_ftypes = 'custom'; + queryUpdates.input_fexts = value; + if (!value) { + queryUpdates.search_ftypes = 'all'; + } + } + if (key === SEARCH_FILTERS_KEY.DATE) { + const date = value; + const isCustom = date.value === SEARCH_FILTER_BY_DATE_OPTION_KEY.CUSTOM; + queryUpdates.time_from = isCustom ? value.from?.unix() : value.from; + queryUpdates.time_to = isCustom ? value.to?.unix() : value.to; } - let isFilterControllerActive = false; - if (newFilters.creator_list.length > 0 || newFilters.date || newFilters.suffixes.length > 0) { - isFilterControllerActive = true; - } + const newQueryData = { + ...this.queryData, + ...queryUpdates, + }; - this.setState({ filters: newFilters, isFilterControllerActive }, () => this.forceUpdate()); + this.getSearchResult(newQueryData); } + filterByCreator = (results) => { + const { filters } = this.state; + return results.filter(item => { + if (filters.creator_list && filters.creator_list.length > 0) { + if (!filters.creator_list.some(creator => creator.email === item.repo_owner_email)) { + return false; + } + } + return true; + }); + }; + handleSelectTag = (tag) => { this.props.onSelectTag(tag); this.resetToDefault(); diff --git a/frontend/src/css/search.css b/frontend/src/css/search.css index 23110aa764..e8c1e5bef4 100644 --- a/frontend/src/css/search.css +++ b/frontend/src/css/search.css @@ -53,6 +53,10 @@ color: #ff9800; } +.search-container.show .input-icon .search-icon-right.search-filter-controller.active:hover { + background-color: rgba(255, 152, 0, 0.2); +} + .search-icon-left { display: flex; }