From da5d47cdd9dcf6dd8b5fc6c9b5230e29f304ac10 Mon Sep 17 00:00:00 2001 From: Revanshu Paliwal Date: Thu, 17 Aug 2023 11:42:52 +0200 Subject: [PATCH] SONAR-19709 Fixing placeholder issue in assignee search --- .../src/components/TagsSelector.tsx | 3 - .../src/components/__tests__/Tags-test.tsx | 1 - .../src/components/input/InputSearch.tsx | 73 +++++++------ .../src/components/input/MultiSelectMenu.tsx | 3 - .../src/components/input/SearchSelect.tsx | 13 +-- .../input/SearchSelectControlledInput.tsx | 100 ++++++++++++++++++ .../components/input/SearchSelectDropdown.tsx | 2 - .../input/__tests__/InputSearch-test.tsx | 2 - .../input/__tests__/MultiSelectMenu-test.tsx | 1 - .../SearchSelectControlledInput-test.tsx | 57 ++++++++++ .../components/global-search/GlobalSearch.tsx | 2 - .../__tests__/GlobalSearch-it.tsx | 2 +- .../nav/component/branch-like/Menu.tsx | 1 - .../main/js/apps/code/components/Search.tsx | 1 - .../Azure/AzureProjectCreateRenderer.tsx | 1 - .../BitbucketCloudSearchForm.tsx | 1 - .../BitbucketImportRepositoryForm.tsx | 1 - .../Github/GitHubProjectCreateRenderer.tsx | 1 - .../Gitlab/GitlabProjectSelectionForm.tsx | 3 +- .../apps/issues/components/AssigneeSelect.tsx | 1 - .../js/apps/issues/components/TagsSelect.tsx | 1 - .../js/apps/issues/sidebar/ListStyleFacet.tsx | 2 - .../ListStyleFacet-test.tsx.snap | 14 --- .../about/components/MetaTags.tsx | 1 - .../apps/projects/components/PageHeader.tsx | 4 +- .../security-hotspots/components/Assignee.tsx | 1 - .../apps/web-api-v2/components/ApiSidebar.tsx | 1 - .../activity-graph/AddGraphMetricPopup.tsx | 1 - .../issue/components/IssueAssign.tsx | 1 - .../issue/popups/IssueTagsPopup.tsx | 1 - 30 files changed, 203 insertions(+), 93 deletions(-) create mode 100644 server/sonar-web/design-system/src/components/input/SearchSelectControlledInput.tsx create mode 100644 server/sonar-web/design-system/src/components/input/__tests__/SearchSelectControlledInput-test.tsx diff --git a/server/sonar-web/design-system/src/components/TagsSelector.tsx b/server/sonar-web/design-system/src/components/TagsSelector.tsx index 4e1f7b47f70..55eaac13c04 100644 --- a/server/sonar-web/design-system/src/components/TagsSelector.tsx +++ b/server/sonar-web/design-system/src/components/TagsSelector.tsx @@ -21,7 +21,6 @@ import { MultiSelectMenu } from './input/MultiSelectMenu'; interface Props { allowNewElements?: boolean; - clearIconAriaLabel: string; createElementLabel: string; headerLabel: string; noResultsLabel: string; @@ -38,7 +37,6 @@ const LIST_SIZE = 10; export function TagsSelector(props: Props) { const { allowNewElements, - clearIconAriaLabel, createElementLabel, headerLabel, noResultsLabel, @@ -50,7 +48,6 @@ export function TagsSelector(props: Props) { return ( {headerLabel}} diff --git a/server/sonar-web/design-system/src/components/__tests__/Tags-test.tsx b/server/sonar-web/design-system/src/components/__tests__/Tags-test.tsx index 2974d489803..73a623cee34 100644 --- a/server/sonar-web/design-system/src/components/__tests__/Tags-test.tsx +++ b/server/sonar-web/design-system/src/components/__tests__/Tags-test.tsx @@ -84,7 +84,6 @@ function Wrapper(overrides: Partial> = {}) { const overlay = ( ; loading?: boolean; @@ -50,7 +50,6 @@ interface Props { placeholder?: string; searchInputAriaLabel?: string; size?: InputSizeKeys; - tooShortText?: string; value?: string; } @@ -72,14 +71,20 @@ export function InputSearch({ maxLength = DEFAULT_MAX_LENGTH, size = 'medium', value: parentValue, - tooShortText, searchInputAriaLabel, - clearIconAriaLabel, - children, }: PropsWithChildren) { + const intl = useIntl(); const input = useRef(null); const [value, setValue] = useState(parentValue ?? ''); - const debouncedOnChange = useMemo(() => debounce(onChange, DEBOUNCE_DELAY), [onChange]); + const [dirty, setDirty] = useState(false); + const debouncedOnChange = useMemo( + () => + debounce((val: string) => { + onChange(val); + setDirty(false); + }, DEBOUNCE_DELAY), + [onChange] + ); const tooShort = isDefined(minLength) && value.length > 0 && value.length < minLength; const inputClassName = classNames('js-input-search', { @@ -87,13 +92,8 @@ export function InputSearch({ 'sw-pr-10': value.length > 0, }); - /* - * ParentValue is useful as an initial value for a page load - * And when the parent component wants to empty the search (facet search) - * After that the input value is controlled by this component - */ useEffect(() => { - if (parentValue === '' || (parentValue !== undefined && value === '')) { + if (parentValue !== undefined && !dirty) { setValue(parentValue); } }, [parentValue]); // eslint-disable-line @@ -113,6 +113,7 @@ export function InputSearch({ const handleInputChange = (event: React.SyntheticEvent) => { const eventValue = event.currentTarget.value; setValue(eventValue); + setDirty(true); changeValue(eventValue); }; @@ -140,42 +141,44 @@ export function InputSearch({ id={id} onMouseDown={onMouseDown} style={{ '--inputSize': INPUT_SIZES[size] }} - title={tooShort && tooShortText && isDefined(minLength) ? tooShortText : ''} + title={ + tooShort && isDefined(minLength) + ? intl.formatMessage({ id: 'select2.tooShort' }, { 0: minLength }) + : '' + } > - {children ?? ( - - )} + {value && ( )} - {tooShort && tooShortText && isDefined(minLength) && ( + {tooShort && isDefined(minLength) && ( - {tooShortText} + {intl.formatMessage({ id: 'select2.tooShort' }, { 0: minLength })} )} @@ -237,7 +240,7 @@ export const StyledInputWrapper = styled.div` } `; -const StyledSearchIcon = styled(SearchIcon)` +export const StyledSearchIcon = styled(SearchIcon)` color: ${themeColor('inputBorder')}; top: calc((${theme('height.control')} - ${theme('spacing.4')}) / 2); @@ -251,7 +254,7 @@ export const StyledInteractiveIcon = styled(InteractiveIcon)` ${tw`sw-right-2`} `; -const StyledNote = styled.span` +export const StyledNote = styled.span` color: ${themeColor('inputPlaceholder')}; top: calc(1px + ${theme('inset.2')}); diff --git a/server/sonar-web/design-system/src/components/input/MultiSelectMenu.tsx b/server/sonar-web/design-system/src/components/input/MultiSelectMenu.tsx index 191de5d27f8..bd73d4672ec 100644 --- a/server/sonar-web/design-system/src/components/input/MultiSelectMenu.tsx +++ b/server/sonar-web/design-system/src/components/input/MultiSelectMenu.tsx @@ -28,7 +28,6 @@ import { MultiSelectMenuOption } from './MultiSelectMenuOption'; interface Props { allowNewElements?: boolean; allowSelection?: boolean; - clearIconAriaLabel: string; createElementLabel: string; elements: string[]; footerNode?: React.ReactNode; @@ -262,7 +261,6 @@ export class MultiSelectMenu extends PureComponent { headerNode = '', footerNode = '', inputId, - clearIconAriaLabel, noResultsLabel, searchInputAriaLabel, } = this.props; @@ -280,7 +278,6 @@ export class MultiSelectMenu extends PureComponent { = GroupBase