diff --git a/frontend/cypress/integration/projects/overview.spec.ts b/frontend/cypress/integration/projects/overview.spec.ts index 1435e85e02..36eedbdb99 100644 --- a/frontend/cypress/integration/projects/overview.spec.ts +++ b/frontend/cypress/integration/projects/overview.spec.ts @@ -58,6 +58,7 @@ describe('project overview', () => { cy.visit('/projects/default'); cy.viewport(1920, 1080); cy.get("[data-testid='SEARCH_INPUT']").click().type(featureToggleName); + cy.get('body').type('{esc}'); cy.get('table tbody tr').should('have.length', 2); const counter = `[data-testid="${BATCH_SELECTED_COUNT}"]`; @@ -108,6 +109,7 @@ describe('project overview', () => { cy.get(`[data-testid='${SEARCH_INPUT}']`) .click() .type(featureToggleName); + cy.get('body').type('{esc}'); cy.get('table tbody tr').should('have.length', 2); cy.get(selectAll).click(); @@ -126,6 +128,8 @@ describe('project overview', () => { cy.get(`[data-testid='${SEARCH_INPUT}']`) .click() .type(featureToggleName); + cy.get('body').type('{esc}'); + cy.get('table tbody tr').should('have.length', 2); cy.get(selectAll).click(); diff --git a/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx b/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx index 7d0a762782..b5b19757b2 100644 --- a/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx +++ b/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx @@ -301,6 +301,8 @@ export const ChangeRequestsTabs = ({ } actions={ void; + onFocus?: () => void; + onBlur?: () => void; className?: string; placeholder?: string; hasFilters?: boolean; @@ -19,15 +21,18 @@ interface ISearchProps { getSearchContext?: () => IGetSearchContextOutput; containerStyles?: React.CSSProperties; debounceTime?: number; + expandable?: boolean; } -const StyledContainer = styled('div')(({ theme }) => ({ +const StyledContainer = styled('div', { + shouldForwardProp: prop => prop !== 'active', +})<{ active: boolean | undefined }>(({ theme, active }) => ({ display: 'flex', flexGrow: 1, alignItems: 'center', position: 'relative', backgroundColor: theme.palette.background.paper, - maxWidth: '400px', + maxWidth: active ? '100%' : '400px', [theme.breakpoints.down('md')]: { marginTop: theme.spacing(1), maxWidth: '100%', @@ -62,18 +67,24 @@ const StyledClose = styled(Close)(({ theme }) => ({ export const Search = ({ initialValue = '', onChange, + onFocus, + onBlur, className, placeholder: customPlaceholder, hasFilters, disabled, getSearchContext, containerStyles, + expandable = false, debounceTime = 200, }: ISearchProps) => { const searchInputRef = useRef(null); const suggestionsRef = useRef(null); const [showSuggestions, setShowSuggestions] = useState(false); - const hideSuggestions = () => setShowSuggestions(false); + const hideSuggestions = () => { + setShowSuggestions(false); + onBlur?.(); + }; const [value, setValue] = useState(initialValue); const debouncedOnChange = useAsyncDebounce(onChange, debounceTime); @@ -104,7 +115,10 @@ export const Search = ({ useOnClickOutside([searchInputRef, suggestionsRef], hideSuggestions); return ( - + onSearchChange(e.target.value)} - onFocus={() => setShowSuggestions(true)} + onFocus={() => { + setShowSuggestions(true); + onFocus?.(); + }} disabled={disabled} /> theme.spacing(4) }}> diff --git a/frontend/src/component/common/Search/SearchSuggestions/SearchInstructions/SearchInstructions.tsx b/frontend/src/component/common/Search/SearchSuggestions/SearchInstructions/SearchInstructions.tsx index 145d84aded..0a977c3c3a 100644 --- a/frontend/src/component/common/Search/SearchSuggestions/SearchInstructions/SearchInstructions.tsx +++ b/frontend/src/component/common/Search/SearchSuggestions/SearchInstructions/SearchInstructions.tsx @@ -1,6 +1,5 @@ import { styled } from '@mui/material'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { IGetSearchContextOutput } from 'hooks/useSearch'; import { VFC } from 'react'; const StyledHeader = styled('span')(({ theme }) => ({ @@ -11,26 +10,28 @@ const StyledHeader = styled('span')(({ theme }) => ({ const StyledCode = styled('span')(({ theme }) => ({ backgroundColor: theme.palette.background.elevation2, color: theme.palette.text.primary, - padding: theme.spacing(0, 0.5), + padding: theme.spacing(0.2, 1), borderRadius: theme.spacing(0.5), })); +const StyledFilterHint = styled('p')(({ theme }) => ({ + lineHeight: 1.75, +})); + interface ISearchInstructionsProps { filters: any[]; - getSearchContext: () => IGetSearchContextOutput; searchableColumnsString: string; } export const SearchInstructions: VFC = ({ filters, - getSearchContext, searchableColumnsString, }) => { return ( <> {filters.length > 0 - ? 'Filter your search with operators like:' + ? 'Filter your results by:' : `Start typing to search${ searchableColumnsString ? ` in ${searchableColumnsString}` @@ -38,8 +39,8 @@ export const SearchInstructions: VFC = ({ }`} {filters.map(filter => ( -

- Filter by {filter.header}:{' '} + + {filter.header}:{' '} {filter.name}:{filter.options[0]} @@ -55,7 +56,7 @@ export const SearchInstructions: VFC = ({ } /> -

+ ))} ); diff --git a/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.test.tsx b/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.test.tsx index afc95200d4..353176b09d 100644 --- a/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.test.tsx +++ b/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.test.tsx @@ -36,11 +36,9 @@ const searchContext = { test('displays search and filter instructions when no search value is provided', () => { render( searchContext} />); - expect( - screen.getByText(/Filter your search with operators like:/i) - ).toBeInTheDocument(); + expect(screen.getByText(/Filter your results by:/i)).toBeInTheDocument(); - expect(screen.getByText(/Filter by Environment:/i)).toBeInTheDocument(); + expect(screen.getByText(/Environment:/)).toBeInTheDocument(); expect( screen.getByText(/environment:"dev env",pre-prod/i) diff --git a/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.tsx b/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.tsx index 1287ca5105..ba249f066d 100644 --- a/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.tsx +++ b/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.tsx @@ -43,7 +43,7 @@ const StyledDivider = styled(Divider)(({ theme }) => ({ const StyledCode = styled('span')(({ theme }) => ({ backgroundColor: theme.palette.background.elevation2, color: theme.palette.text.primary, - padding: theme.spacing(0, 0.5), + padding: theme.spacing(0.2, 0.5), borderRadius: theme.spacing(0.5), })); @@ -127,7 +127,6 @@ export const SearchSuggestions: VFC = ({ elseShow={ = ({
- 0} - show="Combine filters and search." - /> -

- Example:{' '} + + 0} + show="Combine filters and search: " + /> {filters.map(filter => ( @@ -151,7 +149,7 @@ export const SearchSuggestions: VFC = ({ ))} {suggestedTextSearch} -

+ ); }; diff --git a/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx b/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx index 77f00e37e5..c0988141f6 100644 --- a/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx +++ b/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx @@ -303,6 +303,8 @@ export const FeatureToggleListTable: VFC = () => { show={ <> features.map(feature => ({ @@ -533,15 +535,23 @@ export const ProjectFeatureToggles = ({ className={styles.container} header={ setShowTitle(false)} + onBlur={() => setShowTitle(true)} hasFilters getSearchContext={getSearchContext} />