diff --git a/src/Routing.tsx b/src/Routing.tsx index 6fa19413f..b036c6907 100644 --- a/src/Routing.tsx +++ b/src/Routing.tsx @@ -44,16 +44,34 @@ const AddGroupServiceAccounts = lazy(() => import('./smart-components/group/serv const RemoveServiceAccountFromGroup = lazy(() => import('./smart-components/group/service-account/remove-group-service-accounts')); const QuickstartsTest = lazy(() => import('./smart-components/quickstarts/quickstarts-test')); -const UsersAndUserGroups = lazy(() => import('./smart-components/access-management/users-and-user-groups')); +const UsersAndUserGroups = lazy(() => import('./smart-components/access-management/users-and-user-groups/users-and-user-groups')); +const UsersView = lazy(() => import('./smart-components/access-management/users-and-user-groups/users/UsersView')); +const UserGroupsView = lazy(() => import('./smart-components/access-management/users-and-user-groups/user-groups/UserGroupsView')); const getRoutes = ({ enableServiceAccounts, isITLess, isWorkspacesFlag, isCommonAuthModel }: Record) => [ { path: pathnames['users-and-user-groups'].path, element: UsersAndUserGroups, childRoutes: [ - isCommonAuthModel && { - path: pathnames['invite-group-users'].path, - element: InviteUsersModalCommonAuth, + { + path: pathnames['users-new'].path, + element: UsersView, + childRoutes: [ + isCommonAuthModel && { + path: pathnames['invite-group-users'].path, + element: InviteUsersModalCommonAuth, + }, + ], + }, + { + path: pathnames['user-groups'].path, + element: UserGroupsView, + childRoutes: [ + { + path: pathnames['create-user-group'].path, + element: AddGroupWizard, + }, + ], }, ], }, diff --git a/src/smart-components/access-management/users-and-user-groups.tsx b/src/smart-components/access-management/users-and-user-groups.tsx deleted file mode 100644 index 08ff15542..000000000 --- a/src/smart-components/access-management/users-and-user-groups.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import React, { useEffect } from 'react'; -import { useIntl } from 'react-intl'; -import { PageSection, PageSectionVariants, Tab, TabContent, Tabs } from '@patternfly/react-core'; -import ContentHeader from '@patternfly/react-component-groups/dist/dynamic/ContentHeader'; -import Messages from '../../Messages'; -import UsersTable from './UsersTable'; -import UserGroupsTable from './UserGroupsTable'; -import { useLocation, useNavigate } from 'react-router-dom'; -import AddUserGroupModal from './AddUserGroupModal'; -import { User } from '../../redux/reducers/user-reducer'; -import { Group } from '../../redux/reducers/group-reducer'; -import GroupDetailsDrawer from './GroupDetailsDrawer'; -import { DataViewEventsProvider } from '@patternfly/react-data-view'; -import UserDetailsDrawer from './UserDetailsDrawer'; - -const TAB_NAMES = ['users', 'user-groups']; - -const UsersAndUserGroups: React.FunctionComponent = () => { - const intl = useIntl(); - const [activeTabKey, setActiveTabKey] = React.useState(0); - const [isAddUserGroupModalOpen, setIsAddUserGroupModalOpen] = React.useState(false); - const [selectedUsers, setSelectedUsers] = React.useState([]); - const [focusedUser, setFocusedUser] = React.useState(undefined); - const [focusedGroup, setFocusedGroup] = React.useState(undefined); - const usersRef = React.createRef(); - const groupsRef = React.createRef(); - - const navigate = useNavigate(); - const location = useLocation(); - - const updateURL = (tabKey: string) => { - const params = new URLSearchParams(location.search); - params.set('activeTab', tabKey.toString()); - navigate({ search: params.toString() }); - }; - - const handleTabSelect = (_: React.MouseEvent, key: string | number) => { - const activeTab = Number(key); - setActiveTabKey(activeTab); - updateURL(TAB_NAMES[activeTab]); - }; - - const handleOpenAddUserModal = (selected: User[]) => { - if (selected.length > 0) { - setSelectedUsers(selected); - setIsAddUserGroupModalOpen(true); - } - }; - - useEffect(() => { - const params = new URLSearchParams(location.search); - const tabKey = params.get('activeTab'); - tabKey && setActiveTabKey(Number(TAB_NAMES.findIndex((val) => val === tabKey))); - }, [location.search]); - - return ( - - - - - - - - - - - {activeTabKey === 0 && ( - - - - - - - - )} - {activeTabKey === 1 && ( - - - - - - - - )} - - - ); -}; - -export default UsersAndUserGroups; diff --git a/src/smart-components/access-management/UserGroupsTable.tsx b/src/smart-components/access-management/users-and-user-groups/user-groups/UserGroupsTable.tsx similarity index 89% rename from src/smart-components/access-management/UserGroupsTable.tsx rename to src/smart-components/access-management/users-and-user-groups/user-groups/UserGroupsTable.tsx index ec383ade1..d0f348d5f 100644 --- a/src/smart-components/access-management/UserGroupsTable.tsx +++ b/src/smart-components/access-management/users-and-user-groups/user-groups/UserGroupsTable.tsx @@ -1,24 +1,25 @@ -import React, { useEffect, useCallback, useMemo, useState, Fragment } from 'react'; +import React, { useEffect, useCallback, useMemo, useState, Fragment, Suspense } from 'react'; +import { formatDistanceToNow } from 'date-fns'; +import { FormattedMessage, useIntl } from 'react-intl'; import { useSelector, useDispatch } from 'react-redux'; +import { Outlet, useSearchParams } from 'react-router-dom'; import { useDataViewSelection, useDataViewPagination } from '@patternfly/react-data-view/dist/dynamic/Hooks'; import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect'; import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView'; import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar'; import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable'; import { ButtonVariant, EmptyState, EmptyStateBody, EmptyStateHeader, EmptyStateIcon, Pagination, Tooltip } from '@patternfly/react-core'; -import { ActionsColumn } from '@patternfly/react-table'; -import { mappedProps } from '../../helpers/shared/helpers'; -import { RBACStore } from '../../redux/store'; -import { useSearchParams } from 'react-router-dom'; -import { fetchGroups, removeGroups } from '../../redux/actions/group-actions'; -import { formatDistanceToNow } from 'date-fns'; -import { FormattedMessage, useIntl } from 'react-intl'; -import messages from '../../Messages'; -import { Group } from '../../redux/reducers/group-reducer'; import { DataViewTrObject, DataViewState, EventTypes, useDataViewEventsContext } from '@patternfly/react-data-view'; import { SearchIcon } from '@patternfly/react-icons'; +import { ActionsColumn } from '@patternfly/react-table'; import { ResponsiveAction, ResponsiveActions, SkeletonTableBody, SkeletonTableHead, WarningModal } from '@patternfly/react-component-groups'; -import AddGroupWizard from '../group/add-group/add-group-wizard'; +import { mappedProps } from '../../../../helpers/shared/helpers'; +import { RBACStore } from '../../../../redux/store'; +import { fetchGroups, removeGroups } from '../../../../redux/actions/group-actions'; +import { Group } from '../../../../redux/reducers/group-reducer'; +import useAppNavigate from '../../../../hooks/useAppNavigate'; +import pathnames from '../../../../utilities/pathnames'; +import messages from '../../../../Messages'; const COLUMNS: string[] = ['User group name', 'Description', 'Users', 'Service accounts', 'Roles', 'Workspaces', 'Last modified']; @@ -67,11 +68,12 @@ const UserGroupsTable: React.FunctionComponent = ({ focusedGroup, }) => { const [isDeleteModalOpen, setIsDeleteModalOpen] = React.useState(false); - const [isAddGroupWizardOpen, setIsAddGroupWizardOpen] = React.useState(false); const [currentGroups, setCurrentGroups] = React.useState([]); const dispatch = useDispatch(); const [activeState, setActiveState] = useState(DataViewState.loading); const intl = useIntl(); + const navigate = useAppNavigate(); + const search = useSearchParams(); const { trigger } = useDataViewEventsContext(); const handleDeleteModalToggle = (groups: Group[]) => { @@ -228,11 +230,6 @@ const UserGroupsTable: React.FunctionComponent = ({ return ( - {isAddGroupWizardOpen && ( -
- -
- )} {isDeleteModalOpen && ( = ({ } actions={ - setIsAddGroupWizardOpen(true)}> + navigate(pathnames['create-user-group'].link)}> {intl.formatMessage(messages.createUserGroup)} = ({ /> + + { + navigate({ pathname: pathnames['user-groups'].link }); + }, + onCancel: () => + navigate({ + pathname: pathnames['user-groups'].link, + search: search.toString(), + }), + enableRoles: false, + pagination: { limit: perPage }, + filters: {}, + postMethod: fetchData, + }, + }} + /> +
); }; diff --git a/src/smart-components/access-management/users-and-user-groups/user-groups/UserGroupsView.tsx b/src/smart-components/access-management/users-and-user-groups/user-groups/UserGroupsView.tsx new file mode 100644 index 000000000..82661543f --- /dev/null +++ b/src/smart-components/access-management/users-and-user-groups/user-groups/UserGroupsView.tsx @@ -0,0 +1,26 @@ +import { DataViewEventsProvider } from '@patternfly/react-data-view'; +import React from 'react'; +import GroupDetailsDrawer from './user-group-detail/GroupDetailsDrawer'; +import { TabContent } from '@patternfly/react-core'; +import UserGroupsTable from './UserGroupsTable'; +import { Group } from '../../../../redux/reducers/group-reducer'; + +interface UserGroupsViewProps { + groupsRef?: React.Ref; +} + +const UserGroupsView: React.FunctionComponent = ({ groupsRef }) => { + const [focusedGroup, setFocusedGroup] = React.useState(undefined); + + return ( + + + + + + + + ); +}; + +export default UserGroupsView; diff --git a/src/smart-components/access-management/GroupDetailsDrawer.tsx b/src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsDrawer.tsx similarity index 97% rename from src/smart-components/access-management/GroupDetailsDrawer.tsx rename to src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsDrawer.tsx index 2cda0b7ee..83addd70b 100644 --- a/src/smart-components/access-management/GroupDetailsDrawer.tsx +++ b/src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsDrawer.tsx @@ -16,8 +16,8 @@ import { import React, { useEffect } from 'react'; import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons'; import { useIntl } from 'react-intl'; -import messages from '../../Messages'; -import { Group } from '../../redux/reducers/group-reducer'; +import messages from '../../../../../Messages'; +import { Group } from '../../../../../redux/reducers/group-reducer'; import GroupDetailsRolesView from './GroupDetailsRolesView'; import GroupDetailsServiceAccountsView from './GroupDetailsServiceAccountsView'; import GroupDetailsUsersView from './GroupDetailsUsersView'; diff --git a/src/smart-components/access-management/GroupDetailsRolesView.tsx b/src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsRolesView.tsx similarity index 87% rename from src/smart-components/access-management/GroupDetailsRolesView.tsx rename to src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsRolesView.tsx index 634dfb0f0..a3b772f25 100644 --- a/src/smart-components/access-management/GroupDetailsRolesView.tsx +++ b/src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsRolesView.tsx @@ -1,10 +1,10 @@ import { DataView, DataViewTable } from '@patternfly/react-data-view'; import React, { useCallback, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { RBACStore } from '../../redux/store'; -import messages from '../../Messages'; +import { RBACStore } from '../../../../../redux/store'; +import messages from '../../../../../Messages'; import { useIntl } from 'react-intl'; -import { fetchRolesForGroup } from '../../redux/actions/group-actions'; +import { fetchRolesForGroup } from '../../../../../redux/actions/group-actions'; interface GroupRolesViewProps { groupId: string; diff --git a/src/smart-components/access-management/GroupDetailsServiceAccountsView.tsx b/src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsServiceAccountsView.tsx similarity index 88% rename from src/smart-components/access-management/GroupDetailsServiceAccountsView.tsx rename to src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsServiceAccountsView.tsx index 0321fc113..674e283bc 100644 --- a/src/smart-components/access-management/GroupDetailsServiceAccountsView.tsx +++ b/src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsServiceAccountsView.tsx @@ -1,10 +1,10 @@ import { DataView, DataViewTable } from '@patternfly/react-data-view'; +import { useIntl } from 'react-intl'; import React, { useCallback, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { RBACStore } from '../../redux/store'; -import messages from '../../Messages'; -import { useIntl } from 'react-intl'; -import { fetchServiceAccountsForGroup } from '../../redux/actions/group-actions'; +import { RBACStore } from '../../../../../redux/store'; +import messages from '../../../../../Messages'; +import { fetchServiceAccountsForGroup } from '../../../../../redux/actions/group-actions'; interface GroupDetailsServiceAccountsViewProps { groupId: string; diff --git a/src/smart-components/access-management/GroupDetailsUsersView.tsx b/src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsUsersView.tsx similarity index 88% rename from src/smart-components/access-management/GroupDetailsUsersView.tsx rename to src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsUsersView.tsx index c11da0fdc..f2074c910 100644 --- a/src/smart-components/access-management/GroupDetailsUsersView.tsx +++ b/src/smart-components/access-management/users-and-user-groups/user-groups/user-group-detail/GroupDetailsUsersView.tsx @@ -1,10 +1,10 @@ import { DataView, DataViewTable } from '@patternfly/react-data-view'; import React, { useCallback, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { RBACStore } from '../../redux/store'; -import messages from '../../Messages'; +import { RBACStore } from '../../../../../redux/store'; +import messages from '../../../../../Messages'; import { useIntl } from 'react-intl'; -import { fetchMembersForGroup } from '../../redux/actions/group-actions'; +import { fetchMembersForGroup } from '../../../../../redux/actions/group-actions'; interface GroupDetailsUsersViewProps { groupId: string; diff --git a/src/smart-components/access-management/users-and-user-groups/users-and-user-groups.tsx b/src/smart-components/access-management/users-and-user-groups/users-and-user-groups.tsx new file mode 100644 index 000000000..3fbe115a0 --- /dev/null +++ b/src/smart-components/access-management/users-and-user-groups/users-and-user-groups.tsx @@ -0,0 +1,70 @@ +import React, { useEffect, useMemo } from 'react'; +import { useIntl } from 'react-intl'; +import { Outlet, useLocation } from 'react-router-dom'; +import { PageSection, PageSectionVariants, Tab, Tabs } from '@patternfly/react-core'; +import ContentHeader from '@patternfly/react-component-groups/dist/dynamic/ContentHeader'; +import useAppNavigate from '../../../hooks/useAppNavigate'; +import pathnames from '../../../utilities/pathnames'; +import Messages from '../../../Messages'; + +const UsersAndUserGroups: React.FunctionComponent = () => { + const intl = useIntl(); + const usersRef = React.createRef(); + const groupsRef = React.createRef(); + + const navigate = useAppNavigate('/iam/access-management'); + const location = useLocation(); + const activeTabIndex = useMemo(() => Number(location.pathname.endsWith(pathnames['user-groups'].link)), [location.pathname]); + + useEffect(() => { + location.pathname.endsWith(pathnames['users-and-user-groups'].link) && navigate(pathnames['users-new'].link, { replace: true }); + }, [location.pathname, navigate]); + + const handleTabSelect = (_: React.MouseEvent, key: string | number) => { + activeTabIndex !== Number(key) && + navigate((activeTabIndex ? pathnames['users-new'] : pathnames['user-groups']).link, { + replace: true, + }); + }; + + return ( + + + + + + + + + + + + + ); +}; + +export default UsersAndUserGroups; diff --git a/src/smart-components/access-management/UsersTable.tsx b/src/smart-components/access-management/users-and-user-groups/users/UsersTable.tsx similarity index 94% rename from src/smart-components/access-management/UsersTable.tsx rename to src/smart-components/access-management/users-and-user-groups/users/UsersTable.tsx index 857c43243..b5d589104 100644 --- a/src/smart-components/access-management/UsersTable.tsx +++ b/src/smart-components/access-management/users-and-user-groups/users/UsersTable.tsx @@ -1,5 +1,8 @@ import React, { useEffect, useCallback, useState, Fragment, useMemo, Suspense } from 'react'; +import { FormattedMessage, useIntl } from 'react-intl'; import { useSelector, useDispatch } from 'react-redux'; +import { Outlet, useSearchParams } from 'react-router-dom'; +import { SkeletonTableBody, SkeletonTableHead, WarningModal } from '@patternfly/react-component-groups'; import { useDataViewSelection, useDataViewPagination } from '@patternfly/react-data-view/dist/dynamic/Hooks'; import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect'; import { ResponsiveAction } from '@patternfly/react-component-groups/dist/dynamic/ResponsiveAction'; @@ -9,19 +12,16 @@ import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataVi import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable'; import { ButtonVariant, Pagination, EmptyState, EmptyStateHeader, EmptyStateIcon, EmptyStateBody } from '@patternfly/react-core'; import { ActionsColumn } from '@patternfly/react-table'; -import { fetchUsers } from '../../redux/actions/user-actions'; -import { mappedProps } from '../../helpers/shared/helpers'; -import { RBACStore } from '../../redux/store'; -import { User } from '../../redux/reducers/user-reducer'; -import { FormattedMessage, useIntl } from 'react-intl'; -import messages from '../../Messages'; -import { Outlet, useSearchParams } from 'react-router-dom'; -import { SkeletonTableBody, SkeletonTableHead, WarningModal } from '@patternfly/react-component-groups'; -import paths from '../../utilities/pathnames'; -import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; -import useAppNavigate from '../../hooks/useAppNavigate'; import { DataViewState, EventTypes, useDataViewEventsContext } from '@patternfly/react-data-view'; import { SearchIcon } from '@patternfly/react-icons'; +import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; +import useAppNavigate from '../../../../hooks/useAppNavigate'; +import { fetchUsers } from '../../../../redux/actions/user-actions'; +import { mappedProps } from '../../../../helpers/shared/helpers'; +import { RBACStore } from '../../../../redux/store'; +import { User } from '../../../../redux/reducers/user-reducer'; +import messages from '../../../../Messages'; +import paths from '../../../../utilities/pathnames'; const COLUMNS: string[] = ['Username', 'Email', 'First name', 'Last name', 'Status', 'Org admin']; @@ -142,7 +142,7 @@ const UsersTable: React.FunctionComponent = ({ onAddUserClick, onAddUserClick([user]), }, { @@ -223,11 +223,12 @@ const UsersTable: React.FunctionComponent = ({ onAddUserClick, isDisabled={selected.length === 0} ouiaId={`${OUIA_ID}-add-user-button`} > - {intl.formatMessage(messages['usersAndUserGroupsAddToGroup'])} + {intl.formatMessage(messages['addToUserGroup'])} { + console.log('fooo'); appNavigate(paths['invite-group-users'].link); }} > @@ -250,6 +251,7 @@ const UsersTable: React.FunctionComponent = ({ onAddUserClick, { appNavigate(paths['users-and-user-groups'].link); }, diff --git a/src/smart-components/access-management/users-and-user-groups/users/UsersView.tsx b/src/smart-components/access-management/users-and-user-groups/users/UsersView.tsx new file mode 100644 index 000000000..06f3e3f31 --- /dev/null +++ b/src/smart-components/access-management/users-and-user-groups/users/UsersView.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { DataViewEventsProvider } from '@patternfly/react-data-view'; +import { TabContent } from '@patternfly/react-core'; +import UserDetailsDrawer from './user-detail/UserDetailsDrawer'; +import UsersTable from './UsersTable'; +import { User } from '../../../../redux/reducers/user-reducer'; +import AddUserToGroupModal from './add-user-to-group/AddUserToGroupModal'; + +interface UsersViewProps { + usersRef?: React.Ref; +} + +const UsersView: React.FunctionComponent = ({ usersRef }) => { + const [focusedUser, setFocusedUser] = React.useState(undefined); + const [selectedUsers, setSelectedUsers] = React.useState([]); + const [isAddUserGroupModalOpen, setIsAddUserGroupModalOpen] = React.useState(false); + + const handleOpenAddUserToGroupModal = (selected: User[]) => { + if (selected.length > 0) { + setSelectedUsers(selected); + setIsAddUserGroupModalOpen(true); + } + }; + + return ( + <> + + + + + + + + + + ); +}; + +export default UsersView; diff --git a/src/smart-components/access-management/AddUserGroupModal.tsx b/src/smart-components/access-management/users-and-user-groups/users/add-user-to-group/AddUserToGroupModal.tsx similarity index 75% rename from src/smart-components/access-management/AddUserGroupModal.tsx rename to src/smart-components/access-management/users-and-user-groups/users/add-user-to-group/AddUserToGroupModal.tsx index 9198e1e5a..06c53e01d 100644 --- a/src/smart-components/access-management/AddUserGroupModal.tsx +++ b/src/smart-components/access-management/users-and-user-groups/users/add-user-to-group/AddUserToGroupModal.tsx @@ -1,18 +1,18 @@ -import { Button, Modal } from '@patternfly/react-core'; import React from 'react'; -import UserGroupsTable from './UserGroupsTable'; -import { useDispatch } from 'react-redux'; -import { addMembersToGroup } from '../../redux/actions/group-actions'; +import { Button, Modal, ModalVariant } from '@patternfly/react-core'; import { FormattedMessage, useIntl } from 'react-intl'; -import messages from '../../Messages'; +import UserGroupsTable from '../../user-groups/UserGroupsTable'; +import { useDispatch } from 'react-redux'; +import { addMembersToGroup } from '../../../../../redux/actions/group-actions'; +import messages from '../../../../../Messages'; -interface AddUserGroupModalProps { +interface AddUserToGroupModalProps { isOpen: boolean; setIsOpen: (isOpen: boolean) => void; selectedUsers: any[]; } -export const AddUserGroupModal: React.FunctionComponent = ({ isOpen, setIsOpen, selectedUsers }) => { +export const AddUserToGroupModal: React.FunctionComponent = ({ isOpen, setIsOpen, selectedUsers }) => { const [selectedGroups, setSelectedGroups] = React.useState([]); const handleUserGroupsChange = (groups: any[]) => setSelectedGroups(groups); const dispatch = useDispatch(); @@ -30,7 +30,8 @@ export const AddUserGroupModal: React.FunctionComponent return ( ); }; -export default AddUserGroupModal; +export default AddUserToGroupModal; diff --git a/src/smart-components/access-management/UserDetailsDrawer.tsx b/src/smart-components/access-management/users-and-user-groups/users/user-detail/UserDetailsDrawer.tsx similarity index 96% rename from src/smart-components/access-management/UserDetailsDrawer.tsx rename to src/smart-components/access-management/users-and-user-groups/users/user-detail/UserDetailsDrawer.tsx index 419a84136..cbfc9f70c 100644 --- a/src/smart-components/access-management/UserDetailsDrawer.tsx +++ b/src/smart-components/access-management/users-and-user-groups/users/user-detail/UserDetailsDrawer.tsx @@ -1,3 +1,5 @@ +import React, { useEffect } from 'react'; +import { useIntl } from 'react-intl'; import { Drawer, DrawerActions, @@ -15,14 +17,12 @@ import { TextContent, Title, } from '@patternfly/react-core'; -import React, { useEffect } from 'react'; -import { User } from '../../redux/reducers/user-reducer'; import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons'; -import { useIntl } from 'react-intl'; -import messages from '../../Messages'; +import { EventTypes, useDataViewEventsContext } from '@patternfly/react-data-view'; +import { User } from '../../../../../redux/reducers/user-reducer'; +import messages from '../../../../../Messages'; import UserDetailsGroupsView from './UserDetailsGroupsView'; import UserDetailsRolesView from './UserDetailsRolesView'; -import { EventTypes, useDataViewEventsContext } from '@patternfly/react-data-view'; interface UserDetailsProps { focusedUser?: User; diff --git a/src/smart-components/access-management/UserDetailsGroupsView.tsx b/src/smart-components/access-management/users-and-user-groups/users/user-detail/UserDetailsGroupsView.tsx similarity index 84% rename from src/smart-components/access-management/UserDetailsGroupsView.tsx rename to src/smart-components/access-management/users-and-user-groups/users/user-detail/UserDetailsGroupsView.tsx index 5051ad2e6..91e62f19d 100644 --- a/src/smart-components/access-management/UserDetailsGroupsView.tsx +++ b/src/smart-components/access-management/users-and-user-groups/users/user-detail/UserDetailsGroupsView.tsx @@ -1,11 +1,11 @@ -import { DataView, DataViewTable } from '@patternfly/react-data-view'; import React, { useCallback, useEffect } from 'react'; import { useIntl } from 'react-intl'; import { useDispatch, useSelector } from 'react-redux'; -import { mappedProps } from '../../helpers/shared/helpers'; -import { fetchGroups } from '../../redux/actions/group-actions'; -import { RBACStore } from '../../redux/store'; -import messages from '../../Messages'; +import { DataView, DataViewTable } from '@patternfly/react-data-view'; +import { mappedProps } from '../../../../../helpers/shared/helpers'; +import { fetchGroups } from '../../../../../redux/actions/group-actions'; +import { RBACStore } from '../../../../../redux/store'; +import messages from '../../../../../Messages'; interface UserGroupsViewProps { userId: string; diff --git a/src/smart-components/access-management/UserDetailsRolesView.tsx b/src/smart-components/access-management/users-and-user-groups/users/user-detail/UserDetailsRolesView.tsx similarity index 84% rename from src/smart-components/access-management/UserDetailsRolesView.tsx rename to src/smart-components/access-management/users-and-user-groups/users/user-detail/UserDetailsRolesView.tsx index 6ca781cd4..be7ae6c9f 100644 --- a/src/smart-components/access-management/UserDetailsRolesView.tsx +++ b/src/smart-components/access-management/users-and-user-groups/users/user-detail/UserDetailsRolesView.tsx @@ -1,11 +1,11 @@ -import { DataView, DataViewTable } from '@patternfly/react-data-view'; import React, { useCallback, useEffect } from 'react'; +import { DataView, DataViewTable } from '@patternfly/react-data-view'; import { useDispatch, useSelector } from 'react-redux'; -import { RBACStore } from '../../redux/store'; -import messages from '../../Messages'; import { useIntl } from 'react-intl'; -import { fetchRoles } from '../../redux/actions/role-actions'; -import { mappedProps } from '../../helpers/shared/helpers'; +import { RBACStore } from '../../../../../redux/store'; +import messages from '../../../../../Messages'; +import { fetchRoles } from '../../../../../redux/actions/role-actions'; +import { mappedProps } from '../../../../../helpers/shared/helpers'; interface UserRolesViewProps { userId: string; diff --git a/src/smart-components/group/add-group/add-group-wizard.js b/src/smart-components/group/add-group/add-group-wizard.js index 4c4f94682..cc400dc33 100644 --- a/src/smart-components/group/add-group/add-group-wizard.js +++ b/src/smart-components/group/add-group/add-group-wizard.js @@ -2,6 +2,7 @@ import React, { useState, createContext, useRef } from 'react'; import PropTypes from 'prop-types'; import { useDispatch } from 'react-redux'; import { useIntl } from 'react-intl'; +import { useSearchParams } from 'react-router-dom'; import { Wizard } from '@patternfly/react-core/deprecated'; import { addNotification } from '@redhat-cloud-services/frontend-components-notifications/'; import FormRenderer from '@data-driven-forms/react-form-renderer/form-renderer'; @@ -58,15 +59,17 @@ export const onCancel = (emptyCallback, nonEmptyCallback, setGroupData) => (form } }; -const AddGroupWizard = ({ postMethod, pagination, filters, orderBy, enableRoles = true, setIsWizardOpen }) => { +const AddGroupWizard = ({ postMethod, pagination, filters, orderBy }) => { const dispatch = useDispatch(); const intl = useIntl(); const container = useRef(document.createElement('div')); const { isBeta } = useChrome(); + const enableWorkspaces = useFlag('platform.rbac.workspaces'); const enableServiceAccounts = (isBeta() && useFlag('platform.rbac.group-service-accounts')) || (!isBeta() && useFlag('platform.rbac.group-service-accounts.stable')); - const schema = useRef(schemaBuilder(container.current, enableServiceAccounts, enableRoles)); + const schema = useRef(schemaBuilder(container.current, enableServiceAccounts, !enableWorkspaces)); const navigate = useAppNavigate(); + const search = useSearchParams(); const [groupData, setGroupData] = useState({}); const [wizardContextValue, setWizardContextValue] = useState({ success: false, @@ -84,12 +87,17 @@ const AddGroupWizard = ({ postMethod, pagination, filters, orderBy, enableRoles description: intl.formatMessage(messages.addingGroupCanceledDescription), }) ); - setIsWizardOpen - ? setIsWizardOpen(false) - : navigate({ - pathname: paths.groups.link, - search: createQueryParams({ page: 1, per_page: pagination.limit, ...filters }), - }); + navigate( + enableWorkspaces + ? { + pathname: paths['user-groups'].link, + search: search.toString(), + } + : { + pathname: paths.groups.link, + search: createQueryParams({ page: 1, per_page: pagination.limit, ...filters }), + } + ); }; const setWizardError = (error) => setWizardContextValue((prev) => ({ ...prev, error })); @@ -104,7 +112,7 @@ const AddGroupWizard = ({ postMethod, pagination, filters, orderBy, enableRoles name: formData['group-name'], description: formData['group-description'], user_list: formData['users-list'].map((user) => ({ username: user.label })), - roles_list: enableRoles ? formData['roles-list'].map((role) => role.uuid) : [], + roles_list: enableWorkspaces ? [] : formData['roles-list'].map((role) => role.uuid), }; dispatch(addGroup(groupData)).then(({ value }) => { setWizardContextValue((prev) => ({ @@ -126,12 +134,17 @@ const AddGroupWizard = ({ postMethod, pagination, filters, orderBy, enableRoles const onClose = () => { setWizardContextValue((prev) => ({ ...prev, success: false, hideForm: false })); postMethod({ limit: pagination.limit, offset: 0, orderBy, filters: {} }); - setIsWizardOpen - ? setIsWizardOpen(false) - : navigate({ - pathname: paths.groups.link, - search: createQueryParams({ page: 1, per_page: pagination.limit }), - }); + navigate( + enableWorkspaces + ? { + pathname: paths['user-groups'].link, + search: search.toString(), + } + : { + pathname: paths.groups.link, + search: createQueryParams({ page: 1, per_page: pagination.limit, ...filters }), + } + ); }; return ( @@ -149,7 +162,7 @@ const AddGroupWizard = ({ postMethod, pagination, filters, orderBy, enableRoles {intl.formatMessage(messages.discardedInputsWarning)} {wizardContextValue.hideForm ? ( - wizardContextValue.success ? ( + wizardContextValue.success && ( - ) : null + ) ) : (