diff --git a/app/package-lock.json b/app/package-lock.json index 52a4fa1c79..1496c3ecfc 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -12,7 +12,7 @@ "@formatjs/intl-pluralrules": "1.3.9", "@formatjs/intl-relativetimeformat": "4.5.1", "@formatjs/intl-utils": "1.6.0", - "@reportportal/ui-kit": "^0.0.1-alpha.16", + "@reportportal/ui-kit": "^0.0.1-alpha.18", "axios": "1.6.4", "c3": "0.7.20", "chart.js": "2.9.4", @@ -3463,9 +3463,9 @@ "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" }, "node_modules/@reportportal/ui-kit": { - "version": "0.0.1-alpha.16", - "resolved": "https://registry.npmjs.org/@reportportal/ui-kit/-/ui-kit-0.0.1-alpha.16.tgz", - "integrity": "sha512-eCYriILNrqgtTZCukGFOqKaJazWC+tHJq7UCaYvqnyKbvjFKkAJeVAagSrLiihMHT8fILq9t4Wgm5Fwn/PxLug==", + "version": "0.0.1-alpha.18", + "resolved": "https://registry.npmjs.org/@reportportal/ui-kit/-/ui-kit-0.0.1-alpha.18.tgz", + "integrity": "sha512-+oqS6YUpoUKIzDxPFQTSKn1i9pXKwPD1EhYUzsS8lMMmJs746o1lFs27Jd7IDdJxbwbXGYW2qhcKDOeaWu3caw==", "dependencies": { "@floating-ui/react": "^0.26.16", "@floating-ui/react-dom": "^2.0.1", diff --git a/app/package.json b/app/package.json index 106405169c..ccb1974b0d 100644 --- a/app/package.json +++ b/app/package.json @@ -25,7 +25,7 @@ "@formatjs/intl-pluralrules": "1.3.9", "@formatjs/intl-relativetimeformat": "4.5.1", "@formatjs/intl-utils": "1.6.0", - "@reportportal/ui-kit": "^0.0.1-alpha.16", + "@reportportal/ui-kit": "^0.0.1-alpha.18", "axios": "1.6.4", "c3": "0.7.20", "chart.js": "2.9.4", diff --git a/app/src/layouts/organizationsControl/organizationsPopover/organizationsItem/organizationsItem.jsx b/app/src/layouts/organizationsControl/organizationsPopover/organizationsItem/organizationsItem.jsx index fdccfca368..5daa79b630 100644 --- a/app/src/layouts/organizationsControl/organizationsPopover/organizationsItem/organizationsItem.jsx +++ b/app/src/layouts/organizationsControl/organizationsPopover/organizationsItem/organizationsItem.jsx @@ -18,7 +18,7 @@ import PropTypes from 'prop-types'; import classNames from 'classnames/bind'; import { useIntl, defineMessages } from 'react-intl'; import Parser from 'html-react-parser'; -import { useLayoutEffect, useRef, useState } from 'react'; +import { useEffect, useLayoutEffect, useRef, useState } from 'react'; import { NavLink } from 'components/main/navLink'; import { ORGANIZATION_PROJECTS_PAGE } from 'controllers/pages/constants'; import ArrowDownIcon from './img/arrow-down-inline.svg'; @@ -45,6 +45,7 @@ export const OrganizationsItem = ({ isActive, onClick, currentProject, + isAllOpen, }) => { const { formatMessage } = useIntl(); const [isCollapsed, setIsCollapsed] = useState(isOpen); @@ -61,6 +62,10 @@ export const OrganizationsItem = ({ } }, [isActive]); + useEffect(() => { + setIsCollapsed(isAllOpen); + }, [isAllOpen]); + const onShowOpenButton = () => { setIsShowOpenButton(true); }; @@ -168,6 +173,7 @@ OrganizationsItem.propTypes = { organizationSlug: PropTypes.string.isRequired, projects: PropTypes.array.isRequired, isOpen: PropTypes.bool.isRequired, + isAllOpen: PropTypes.bool.isRequired, isActive: PropTypes.bool.isRequired, onClick: PropTypes.func.isRequired, currentProject: PropTypes.string.isRequired, diff --git a/app/src/layouts/organizationsControl/organizationsPopover/organizationsPopover.jsx b/app/src/layouts/organizationsControl/organizationsPopover/organizationsPopover.jsx index 7e85edaf58..97a96d451c 100644 --- a/app/src/layouts/organizationsControl/organizationsPopover/organizationsPopover.jsx +++ b/app/src/layouts/organizationsControl/organizationsPopover/organizationsPopover.jsx @@ -14,8 +14,10 @@ * limitations under the License. */ +import { useMemo, useState } from 'react'; import PropTypes from 'prop-types'; import { useIntl, defineMessages } from 'react-intl'; +import { FieldText, SearchIcon, ThemeProvider } from '@reportportal/ui-kit'; import classNames from 'classnames/bind'; import { useSelector } from 'react-redux'; import { availableProjectsSelector } from 'controllers/user'; @@ -23,6 +25,7 @@ import { urlProjectSlugSelector, urlOrganizationSlugSelector } from 'controllers import { ScrollWrapper } from 'components/main/scrollWrapper'; import { ALL_ORGANIZATIONS_PAGE } from 'controllers/pages/constants'; import { NavLink } from 'components/main/navLink'; +import { COMMON_LOCALE_KEYS } from 'common/constants/localization'; import { OrganizationsItem } from './organizationsItem'; import styles from './organizationsPopover.scss'; @@ -45,15 +48,59 @@ export const OrganizationsPopover = ({ closePopover, closeSidebar }) => { const availableProjects = useSelector(availableProjectsSelector); const currentOrganization = useSelector(urlOrganizationSlugSelector); const projectSlug = useSelector(urlProjectSlugSelector); + const [valueSearch, setValueSearch] = useState(''); const maxHeightPopover = window.innerHeight - MARGIN_TOP_AND_MARGIN_BOTTOM; + const filteredProjects = useMemo( + () => + availableProjects.reduce((acc, { organizationSlug, organizationName, projects }) => { + const isOrganization = organizationName.toLowerCase().includes(valueSearch.toLowerCase()); + const searchProjects = projects.filter(({ projectName }) => + projectName.toLowerCase().includes(valueSearch.toLowerCase()), + ); + + return isOrganization || searchProjects.length > 0 + ? [ + ...acc, + { + organizationSlug, + organizationName, + projects: searchProjects, + }, + ] + : acc; + }, []), + [valueSearch, availableProjects], + ); + const onClose = () => { closeSidebar(); closePopover(); }; + const handleChange = (event) => { + setValueSearch(event.target.value); + }; + + const handleClear = () => { + setValueSearch(''); + }; + return (