diff --git a/libs/i18n/locales/en/translation.json b/libs/i18n/locales/en/translation.json index 66fe652ea..a8ddd2750 100644 --- a/libs/i18n/locales/en/translation.json +++ b/libs/i18n/locales/en/translation.json @@ -1491,6 +1491,7 @@ "Expand row": "Expand row", "{page} of <2>{totalPages}": "{page} of <2>{totalPages}", "{{ numberOfItems }} items": "{{ numberOfItems }} items", + "Search value cannot contain spaces": "Search value cannot contain spaces", "Waiting for terminal session to open...": "Waiting for terminal session to open...", "Architecture": "Architecture", "Agent version": "Agent version", diff --git a/libs/ui-components/src/components/Device/DevicesPage/DecommissionedDevicesTable.tsx b/libs/ui-components/src/components/Device/DevicesPage/DecommissionedDevicesTable.tsx index 54d6fa4b9..f55a658e0 100644 --- a/libs/ui-components/src/components/Device/DevicesPage/DecommissionedDevicesTable.tsx +++ b/libs/ui-components/src/components/Device/DevicesPage/DecommissionedDevicesTable.tsx @@ -103,6 +103,7 @@ const DecommissionedDevicesTable = ({ {t('Show decommissioned devices')}} + aria-checked isChecked onChange={() => { setOnlyDecommissioned(false); diff --git a/libs/ui-components/src/components/Device/DevicesPage/EnrolledDevicesTable.tsx b/libs/ui-components/src/components/Device/DevicesPage/EnrolledDevicesTable.tsx index f0e6f06bd..9e813fbb8 100644 --- a/libs/ui-components/src/components/Device/DevicesPage/EnrolledDevicesTable.tsx +++ b/libs/ui-components/src/components/Device/DevicesPage/EnrolledDevicesTable.tsx @@ -172,6 +172,7 @@ const EnrolledDevicesTable = ({ id="enrolled-devices-switch" label={{t('Show decommissioned devices')}} isChecked={false} + aria-checked={false} onChange={() => { clearAllFilters(); setOnlyDecommissioned(true); diff --git a/libs/ui-components/src/components/Table/TableTextSearch.tsx b/libs/ui-components/src/components/Table/TableTextSearch.tsx index 71b664198..8bb2826a6 100644 --- a/libs/ui-components/src/components/Table/TableTextSearch.tsx +++ b/libs/ui-components/src/components/Table/TableTextSearch.tsx @@ -1,22 +1,70 @@ import * as React from 'react'; +import { HelperText, HelperTextItem, SearchInput, SearchInputProps, Stack, StackItem } from '@patternfly/react-core'; -import { SearchInput, SearchInputProps } from '@patternfly/react-core'; +import { useTranslation } from '../../hooks/useTranslation'; -export type TableTextSearchProps = Omit & { +export type TableTextSearchProps = Omit & { setValue: (val: string) => void; - onClear?: VoidFunction; }; -const TableTextSearch: React.FC = ({ value, setValue, placeholder, onClear, ...rest }) => { +const TableTextSearch: React.FC = ({ value, setValue, placeholder, ...rest }) => { + const { t } = useTranslation(); + const [hasError, setHasError] = React.useState(false); + const [actualValue, setActualValue] = React.useState(value || ''); + + React.useEffect(() => { + // When the value is cleared externally, reset the component state + if (value === '') { + setActualValue(''); + setHasError(false); + } + }, [value]); + + const handleClear = React.useCallback(() => { + setActualValue(''); + setValue(''); + setHasError(false); + }, [setValue]); + + const handleChange = React.useCallback( + (_event: React.FormEvent, newValue: string) => { + setActualValue(newValue); + + if (newValue === '') { + handleClear(); + } else { + const stripped = newValue.replace(/\s/g, ''); + if (stripped === newValue) { + setValue(stripped); + setHasError(false); + } else { + setHasError(true); + } + } + }, + [handleClear, setValue], + ); + return ( - (value === '' && onClear ? onClear() : setValue(value))} - value={value} - placeholder={placeholder} - onClear={() => (onClear ? onClear() : setValue(''))} - {...rest} - /> + + + + + {hasError && ( + + + {t('Search value cannot contain spaces')} + + + )} + ); };