diff --git a/ui/v2.5/src/components/List/FilterTags.tsx b/ui/v2.5/src/components/List/FilterTags.tsx index 8d9b24e40..6812edcf7 100644 --- a/ui/v2.5/src/components/List/FilterTags.tsx +++ b/ui/v2.5/src/components/List/FilterTags.tsx @@ -9,31 +9,37 @@ import { Badge, BadgeProps, Button, Overlay, Popover } from "react-bootstrap"; import { Criterion } from "src/models/list-filter/criteria/criterion"; import { FormattedMessage, useIntl } from "react-intl"; import { Icon } from "../Shared/Icon"; -import { faTimes } from "@fortawesome/free-solid-svg-icons"; +import { faMagnifyingGlass, faTimes } from "@fortawesome/free-solid-svg-icons"; import { BsPrefixProps, ReplaceProps } from "react-bootstrap/esm/helpers"; import { CustomFieldsCriterion } from "src/models/list-filter/criteria/custom-fields"; import { useDebounce } from "src/hooks/debounce"; +import cx from "classnames"; type TagItemProps = PropsWithChildren< ReplaceProps<"span", BsPrefixProps<"span"> & BadgeProps> >; export const TagItem: React.FC = (props) => { - const { children } = props; + const { className, children, ...others } = props; return ( - + {children} ); }; export const FilterTag: React.FC<{ + className?: string; label: React.ReactNode; onClick: React.MouseEventHandler; onRemove: React.MouseEventHandler; -}> = ({ label, onClick, onRemove }) => { +}> = ({ className, label, onClick, onRemove }) => { return ( - + {label} - )} - + if (searchTerm && searchTerm.length > 0) { + filterTags.unshift( + + + {searchTerm} + + } + onClick={() => onEditSearchTerm?.()} + onRemove={() => onRemoveSearchTerm?.()} + /> ); } + const visibleCriteria = cutoff ? filterTags.slice(0, cutoff) : filterTags; + const hiddenCriteria = cutoff ? filterTags.slice(cutoff) : []; + return (
- {filterTags} - {criteria.length >= 3 && ( + {visibleCriteria} + + {filterTags.length >= 3 && (
@@ -520,6 +533,9 @@ export const FilteredSceneList = (props: IFilteredScenes) => { const intl = useIntl(); const history = useHistory(); + const searchFocus = useFocus(); + const [, setSearchFocus] = searchFocus; + const { filterHook, defaultSort, view, alterQuery, fromGroupId } = props; // States @@ -774,6 +790,7 @@ export const FilteredSceneList = (props: IFilteredScenes) => { sidebarOpen={showSidebar} onClose={() => setShowSidebar(false)} count={cachedResult.loading ? undefined : totalCount} + focus={searchFocus} />
@@ -783,6 +800,7 @@ export const FilteredSceneList = (props: IFilteredScenes) => { })} > { onToggleSidebar={() => setShowSidebar(!showSidebar)} onEditCriterion={(c) => showEditFilter(c.criterionOption.type)} onRemoveCriterion={removeCriterion} - onRemoveAllCriterion={() => clearAllCriteria()} + onRemoveAllCriterion={() => clearAllCriteria(true)} + onEditSearchTerm={() => { + setShowSidebar(true); + setSearchFocus(true); + }} + onRemoveSearchTerm={() => setFilter(filter.clearSearchTerm())} onSelectAll={() => onSelectAll()} onSelectNone={() => onSelectNone()} onEdit={onEdit} diff --git a/ui/v2.5/src/index.scss b/ui/v2.5/src/index.scss index c013b852a..fb4d82a1c 100755 --- a/ui/v2.5/src/index.scss +++ b/ui/v2.5/src/index.scss @@ -698,8 +698,10 @@ div.dropdown-menu { } .tag-item { + align-items: center; background-color: $muted-gray; color: $dark-text; + display: flex; font-size: 12px; font-weight: 400; line-height: 16px; @@ -710,17 +712,20 @@ div.dropdown-menu { cursor: pointer; } + .search-term svg { + margin-left: 0; + } + .btn { background: none; border: none; bottom: 2px; color: $dark-text; font-size: 12px; - line-height: 1rem; + line-height: 16px; margin-right: -0.5rem; opacity: 0.5; padding: 0 0.5rem; - position: relative; &:active, &:hover { diff --git a/ui/v2.5/src/models/list-filter/filter.ts b/ui/v2.5/src/models/list-filter/filter.ts index ac9d9de1e..2a68cd6a2 100644 --- a/ui/v2.5/src/models/list-filter/filter.ts +++ b/ui/v2.5/src/models/list-filter/filter.ts @@ -476,13 +476,23 @@ export class ListFilterModel { return this.setCriteria(criteria); } - public clearCriteria() { + public clearCriteria(clearSearchTerm = false) { const ret = this.clone(); + if (clearSearchTerm) { + ret.searchTerm = ""; + } ret.criteria = []; ret.currentPage = 1; return ret; } + public clearSearchTerm() { + const ret = this.clone(); + ret.searchTerm = ""; + ret.currentPage = 1; // reset to first page + return ret; + } + public setCriteria(criteria: Criterion[]) { const ret = this.clone(); ret.criteria = criteria; diff --git a/ui/v2.5/src/utils/focus.ts b/ui/v2.5/src/utils/focus.ts index f1ede47f9..cf1b20a88 100644 --- a/ui/v2.5/src/utils/focus.ts +++ b/ui/v2.5/src/utils/focus.ts @@ -2,10 +2,14 @@ import { useRef, useEffect, useCallback } from "react"; const useFocus = () => { const htmlElRef = useRef(null); - const setFocus = useCallback(() => { + const setFocus = useCallback((selectAll?: boolean) => { const currentEl = htmlElRef.current; if (currentEl) { - currentEl.focus(); + if (selectAll) { + currentEl.select(); + } else { + currentEl.focus(); + } } }, []);