diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index a58e2d82adfcb801fa24535dcc59e0da38e0d92e..200d57798ccc910faadb66ba36d0c54c56975c12 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -5,7 +5,9 @@ import { useAuth } from 'src/services/auth'; import Gravatar from 'react-gravatar'; import { Link, useLocation } from 'react-router-dom'; import clsx from 'clsx'; -import { CurrentUserModal } from './components/CurrentUserModal'; +import _ from 'lodash'; + +import { UserModal } from '../UserModal'; const navigation = [ { name: 'Dashboard', to: '/dashboard', requiresAdmin: false }, @@ -29,14 +31,20 @@ interface HeaderProps {} const Header: React.FC<HeaderProps> = () => { const [currentUserModal, setCurrentUserModal] = useState(false); + const [currentUserId, setCurrentUserId] = useState(null); const { logOut, currentUser, isAdmin } = useAuth(); const { pathname } = useLocation(); - const currentUserModalOpen = () => { + const currentUserModalOpen = (id: any) => { + setCurrentUserId(id); setCurrentUserModal(true); }; - const currentUserModalClose = () => setCurrentUserModal(false); + + const currentUserModalClose = () => { + setCurrentUserModal(false); + setCurrentUserId(null); + }; const navigationItems = filterNavigationByDashboardRole(isAdmin); @@ -106,7 +114,7 @@ const Header: React.FC<HeaderProps> = () => { <Menu.Item> {({ active }) => ( <a - onClick={() => currentUserModalOpen()} + onClick={() => currentUserModalOpen(currentUser?.id)} className={classNames( active ? 'bg-gray-100 cursor-pointer' : '', 'block px-4 py-2 text-sm text-gray-700 cursor-pointer', @@ -119,7 +127,7 @@ const Header: React.FC<HeaderProps> = () => { <Menu.Item> {({ active }) => ( <a - onClick={() => logOut()} + onClick={logOut} className={classNames( active ? 'bg-gray-100 cursor-pointer' : '', 'block px-4 py-2 text-sm text-gray-700 cursor-pointer', @@ -160,7 +168,7 @@ const Header: React.FC<HeaderProps> = () => { )} </Disclosure> - <CurrentUserModal open={currentUserModal} onClose={currentUserModalClose} user={currentUser} /> + <UserModal open={currentUserModal} onClose={currentUserModalClose} userId={currentUserId} setUserId={_.noop} /> </> ); }; diff --git a/src/components/Header/components/CurrentUserModal/CurrentUserModal.tsx b/src/components/Header/components/CurrentUserModal/CurrentUserModal.tsx deleted file mode 100644 index aaa29c215aa51925347e68003cbcafab045938f6..0000000000000000000000000000000000000000 --- a/src/components/Header/components/CurrentUserModal/CurrentUserModal.tsx +++ /dev/null @@ -1,168 +0,0 @@ -import _ from 'lodash'; -import React, { useEffect } from 'react'; -import { useFieldArray, useForm } from 'react-hook-form'; -import { Modal } from 'src/components'; -import { Input, Select } from 'src/components/Form'; -import { useAuth } from 'src/services/auth'; -import { User, UserRole, useUsers } from 'src/services/users'; -import { appAccessList, initialUserForm } from './consts'; -import { UserModalProps } from './types'; - -export const CurrentUserModal = ({ open, onClose, user }: UserModalProps) => { - const { editUserById, userModalLoading } = useUsers(); - const { isAdmin } = useAuth(); - - const { control, reset, handleSubmit } = useForm<User>({ - defaultValues: initialUserForm, - }); - - const { fields } = useFieldArray({ - control, - name: 'app_roles', - }); - - useEffect(() => { - if (user && !_.isEmpty(user)) { - reset(user); - } - - return () => { - reset(initialUserForm); - }; - }, [user, reset]); - - const handleSave = async () => { - try { - if (user) { - await handleSubmit((data) => editUserById(data))(); - } - - onClose(); - } catch (e: any) { - // Continue - } - }; - - const handleKeyPress = (e: any) => { - if (e.key === 'Enter' || e.key === 'NumpadEnter') { - handleSave(); - } - }; - - const handleClose = () => { - onClose(); - }; - - return ( - <Modal onClose={handleClose} open={open} onSave={handleSave} isLoading={userModalLoading} useCancelButton> - <div className="bg-white px-4"> - <div className="space-y-10 divide-y divide-gray-200"> - <div> - <div> - <h3 className="text-lg leading-6 font-medium text-gray-900">Profile</h3> - </div> - - <div className="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6"> - <div className="sm:col-span-3"> - <Input control={control} name="name" label="Name" onKeyPress={handleKeyPress} /> - </div> - - <div className="sm:col-span-3"> - <Input control={control} name="email" label="Email" type="email" onKeyPress={handleKeyPress} /> - </div> - - {isAdmin && ( - <> - <div className="sm:col-span-3"> - {fields - .filter((field) => field.name === 'dashboard') - .map((item, index) => ( - <Select - key={item.id} - control={control} - name={`app_roles.${index}.role`} - label="Role" - options={[ - { value: UserRole.NoAccess, name: 'No access' }, - { value: UserRole.Admin, name: 'Admin' }, - { value: UserRole.User, name: 'User' }, - ]} - /> - ))} - </div> - - <div className="sm:col-span-3 opacity-40 cursor-default pointer-events-none select-none"> - {/* <Select control={control} name="status" label="Status" options={['Admin', 'Inactive']} /> */} - <label htmlFor="status" className="block text-sm font-medium text-gray-700"> - Status - </label> - <div className="mt-1"> - <select - id="status" - name="status" - className="shadow-sm focus:ring-primary-500 focus:border-primary-500 block w-full sm:text-sm border-gray-300 rounded-md" - > - <option>Active</option> - <option>Inactive</option> - <option>Banned</option> - </select> - </div> - </div> - </> - )} - </div> - </div> - - {isAdmin && ( - <div> - <div className="mt-8"> - <h3 className="text-lg leading-6 font-medium text-gray-900">App Access</h3> - </div> - - <div> - <div className="flow-root mt-6"> - <ul className="-my-5 divide-y divide-gray-200 "> - {fields.map((item, index) => { - if (item.name === 'dashboard') { - return null; - } - - return ( - <li className="py-4" key={item.name}> - <div className="flex items-center space-x-4"> - <div className="flex-shrink-0 flex-1 flex items-center"> - <img - className="h-10 w-10 rounded-md overflow-hidden" - src={_.find(appAccessList, ['name', item.name!])?.image} - alt={item.name ?? 'Image'} - /> - <h3 className="ml-4 text-md leading-6 font-medium text-gray-900"> - {_.find(appAccessList, ['name', item.name!])?.label} - </h3> - </div> - <div> - <Select - key={item.id} - control={control} - name={`app_roles.${index}.role`} - options={[ - { value: UserRole.NoAccess, name: 'No access' }, - { value: UserRole.Admin, name: 'Admin' }, - { value: UserRole.User, name: 'User' }, - ]} - /> - </div> - </div> - </li> - ); - })} - </ul> - </div> - </div> - </div> - )} - </div> - </div> - </Modal> - ); -}; diff --git a/src/components/Header/components/CurrentUserModal/index.ts b/src/components/Header/components/CurrentUserModal/index.ts deleted file mode 100644 index 7a5fd1aaaa7c2ddbc4414bb04c0ed24a0665e079..0000000000000000000000000000000000000000 --- a/src/components/Header/components/CurrentUserModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { CurrentUserModal } from './CurrentUserModal'; diff --git a/src/components/Header/components/CurrentUserModal/types.ts b/src/components/Header/components/CurrentUserModal/types.ts deleted file mode 100644 index aa11c0eba5a76bed2a9e63a03cf7e4ccf08ceec0..0000000000000000000000000000000000000000 --- a/src/components/Header/components/CurrentUserModal/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { User } from 'src/services/users'; - -export type UserModalProps = { - open: boolean; - onClose: () => void; - user: User | null; -}; diff --git a/src/components/Header/components/index.ts b/src/components/Header/components/index.ts deleted file mode 100644 index 7a5fd1aaaa7c2ddbc4414bb04c0ed24a0665e079..0000000000000000000000000000000000000000 --- a/src/components/Header/components/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { CurrentUserModal } from './CurrentUserModal'; diff --git a/src/modules/users/components/UserModal/UserModal.tsx b/src/components/UserModal/UserModal.tsx similarity index 100% rename from src/modules/users/components/UserModal/UserModal.tsx rename to src/components/UserModal/UserModal.tsx diff --git a/src/components/Header/components/CurrentUserModal/consts.ts b/src/components/UserModal/consts.ts similarity index 100% rename from src/components/Header/components/CurrentUserModal/consts.ts rename to src/components/UserModal/consts.ts diff --git a/src/modules/users/components/UserModal/index.ts b/src/components/UserModal/index.ts similarity index 100% rename from src/modules/users/components/UserModal/index.ts rename to src/components/UserModal/index.ts diff --git a/src/modules/users/components/UserModal/types.ts b/src/components/UserModal/types.ts similarity index 100% rename from src/modules/users/components/UserModal/types.ts rename to src/components/UserModal/types.ts diff --git a/src/components/index.ts b/src/components/index.ts index 5e1d96b923cb8f145b0a0f3ca3e45300e2746c71..565e17d3790a54e2f7c8a2757fa444d443539cfd 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -4,3 +4,4 @@ export { Table } from './Table'; export { Banner } from './Banner'; export { Tabs } from './Tabs'; export { Modal, ConfirmationModal } from './Modal'; +export { UserModal } from './UserModal'; diff --git a/src/modules/users/Users.tsx b/src/modules/users/Users.tsx index 6ba32657e1483aaa0b7d486441fb3551ce7615e7..3832926ccdb913c91292a9108ae40bb14927574b 100644 --- a/src/modules/users/Users.tsx +++ b/src/modules/users/Users.tsx @@ -6,7 +6,8 @@ import { useUsers } from 'src/services/users'; import { Table } from 'src/components'; import { debounce } from 'lodash'; import { useAuth } from 'src/services/auth'; -import { UserModal } from './components/UserModal'; + +import { UserModal } from '../../components/UserModal'; export const Users: React.FC = () => { const [selectedRowsIds, setSelectedRowsIds] = useState({}); diff --git a/src/modules/users/components/UserModal/consts.ts b/src/modules/users/components/UserModal/consts.ts deleted file mode 100644 index 1b02fa3be748878dba0ba5afa3df3bae8628f851..0000000000000000000000000000000000000000 --- a/src/modules/users/components/UserModal/consts.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { UserRole } from 'src/services/users'; - -export const appAccessList = [ - { - name: 'wekan', - image: '/assets/wekan.svg', - label: 'Wekan', - }, - { - name: 'wordpress', - image: '/assets/wordpress.svg', - label: 'Wordpress', - }, - { - name: 'nextcloud', - image: '/assets/nextcloud.svg', - label: 'NextCloud', - }, - { - name: 'zulip', - image: '/assets/zulip.svg', - label: 'Zulip', - }, -]; - -const initialAppRoles = [ - { - name: 'dashboard', - role: UserRole.User, - }, - { - name: 'wekan', - role: UserRole.NoAccess, - }, - { - name: 'wordpress', - role: UserRole.NoAccess, - }, - { - name: 'nextcloud', - role: UserRole.NoAccess, - }, - { - name: 'zulip', - role: UserRole.NoAccess, - }, -]; - -export const initialUserForm = { - id: '', - name: '', - email: '', - app_roles: initialAppRoles, - status: '', -}; diff --git a/src/modules/users/components/index.ts b/src/modules/users/components/index.ts deleted file mode 100644 index cc3d9bd6afb1b4495e992e95c429f4d4c6b1718b..0000000000000000000000000000000000000000 --- a/src/modules/users/components/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { UserModal } from './UserModal';