From da9eedc94e5a536dc17b39f4ec2b07dfa8ecee1d Mon Sep 17 00:00:00 2001 From: Valentino K Date: Tue, 17 May 2022 11:52:08 +0200 Subject: [PATCH] Added roles support --- .../CurrentUserModal/CurrentUserModal.tsx | 171 ++++++++------- .../components/CurrentUserModal/consts.ts | 12 +- .../components/CurrentUserModal/types.ts | 2 +- src/modules/users/Users.tsx | 57 ++--- .../users/components/UserModal/UserModal.tsx | 195 ++++++++++-------- .../users/components/UserModal/consts.ts | 45 +++- .../users/components/UserModal/types.ts | 1 + src/services/auth/hooks/use-auth.ts | 4 +- src/services/auth/redux/index.ts | 2 +- src/services/auth/redux/reducers.ts | 12 +- src/services/auth/redux/selectors.ts | 12 ++ src/services/auth/transformations.ts | 29 +-- src/services/auth/types.ts | 2 +- src/services/users/hooks/use-users.ts | 15 +- src/services/users/redux/actions.ts | 9 +- src/services/users/transformations.ts | 51 ++--- src/services/users/types.ts | 21 +- 17 files changed, 390 insertions(+), 250 deletions(-) diff --git a/src/components/Header/components/CurrentUserModal/CurrentUserModal.tsx b/src/components/Header/components/CurrentUserModal/CurrentUserModal.tsx index cf578cb..ca5732c 100644 --- a/src/components/Header/components/CurrentUserModal/CurrentUserModal.tsx +++ b/src/components/Header/components/CurrentUserModal/CurrentUserModal.tsx @@ -1,31 +1,39 @@ +import _ from 'lodash'; import React, { useEffect } from 'react'; -import { useForm } from 'react-hook-form'; -import { Modal, Banner } from 'src/components'; +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 } 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({ defaultValues: { - name: null, - email: null, - id: null, - role_id: null, - status: null, + name: '', + email: '', + id: '', + app_roles: [], + status: '', }, }); + const { fields } = useFieldArray({ + control, + name: 'app_roles', + }); + useEffect(() => { if (user) { reset(user); } return () => { - reset({ name: null, email: null, id: null }); + reset({ name: '', email: '', id: '' }); }; }, [user, reset]); @@ -54,7 +62,7 @@ export const CurrentUserModal = ({ open, onClose, user }: UserModalProps) => { return (
-
+

Profile

@@ -69,77 +77,90 @@ export const CurrentUserModal = ({ open, onClose, user }: UserModalProps) => {
-
- + ))} +
+ +
+ {/* + + + + +
+
+ + )} +
+
+ + {isAdmin && ( +
+
+

App Access

-
- -
- -
- {/* - - - - +
+
+
    + {fields + .filter((field) => field.name !== 'dashboard') + .map((item, index) => ( +
  • +
    +
    + {item.name +

    + {_.find(appAccessList, ['name', item.name!])?.label} +

    +
    +
    + - - - - -
    -
    -
  • - ); - })} -
-
-
-
+ )}
diff --git a/src/components/Header/components/CurrentUserModal/consts.ts b/src/components/Header/components/CurrentUserModal/consts.ts index 080c939..edcf83c 100644 --- a/src/components/Header/components/CurrentUserModal/consts.ts +++ b/src/components/Header/components/CurrentUserModal/consts.ts @@ -1,18 +1,22 @@ export const appAccessList = [ { + name: 'wekan', image: '/assets/wekan.svg', - name: 'Wekan', + label: 'Wekan', }, { + name: 'wordpress', image: '/assets/wordpress.svg', - name: 'Wordpress', + label: 'Wordpress', }, { + name: 'next-cloud', image: '/assets/nextcloud.svg', - name: 'NextCloud', + label: 'NextCloud', }, { + name: 'zulip', image: '/assets/zulip.svg', - name: 'Zulip', + label: 'Zulip', }, ]; diff --git a/src/components/Header/components/CurrentUserModal/types.ts b/src/components/Header/components/CurrentUserModal/types.ts index 00bc7d6..aa11c0e 100644 --- a/src/components/Header/components/CurrentUserModal/types.ts +++ b/src/components/Header/components/CurrentUserModal/types.ts @@ -3,5 +3,5 @@ import { User } from 'src/services/users'; export type UserModalProps = { open: boolean; onClose: () => void; - user: User; + user: User | null; }; diff --git a/src/modules/users/Users.tsx b/src/modules/users/Users.tsx index 899065a..6ba3265 100644 --- a/src/modules/users/Users.tsx +++ b/src/modules/users/Users.tsx @@ -5,6 +5,7 @@ import { CogIcon, TrashIcon } from '@heroicons/react/outline'; 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'; export const Users: React.FC = () => { @@ -13,6 +14,7 @@ export const Users: React.FC = () => { const [userId, setUserId] = useState(null); const [search, setSearch] = useState(''); const { users, loadUsers, userTableLoading } = useUsers(); + const { isAdmin } = useAuth(); const handleSearch = (event: any) => { setSearch(event.target.value); @@ -60,23 +62,27 @@ export const Users: React.FC = () => { Cell: (props: any) => { const { row } = props; - return ( -
- -
- ); + if (isAdmin) { + return ( +
+ +
+ ); + } + + return null; }, width: 'auto', }, ], - [], + [isAdmin], ); const selectedRows = useCallback((rows: Record) => { @@ -88,16 +94,19 @@ export const Users: React.FC = () => {

Users

-
- -
+ + {isAdmin && ( +
+ +
+ )}
@@ -153,7 +162,7 @@ export const Users: React.FC = () => {
- + ); diff --git a/src/modules/users/components/UserModal/UserModal.tsx b/src/modules/users/components/UserModal/UserModal.tsx index 5b3814b..b31d218 100644 --- a/src/modules/users/components/UserModal/UserModal.tsx +++ b/src/modules/users/components/UserModal/UserModal.tsx @@ -1,26 +1,27 @@ import React, { useEffect, useState } from 'react'; +import _ from 'lodash'; import { TrashIcon } from '@heroicons/react/outline'; -import { useForm } from 'react-hook-form'; -import { Modal, Banner, ConfirmationModal } from 'src/components'; +import { useFieldArray, useForm } from 'react-hook-form'; +import { Modal, ConfirmationModal } from 'src/components'; import { Input, Select } from 'src/components/Form'; import { User, UserRole, useUsers } from 'src/services/users'; import { useAuth } from 'src/services/auth'; -import { appAccessList } from './consts'; +import { appAccessList, initialUserForm } from './consts'; import { UserModalProps } from './types'; -export const UserModal = ({ open, onClose, userId }: UserModalProps) => { +export const UserModal = ({ open, onClose, userId, setUserId }: UserModalProps) => { const [deleteModal, setDeleteModal] = useState(false); - const { user, loadUser, editUserById, createNewUser, userModalLoading, deleteUserById } = useUsers(); - const { currentUser } = useAuth(); + const { user, loadUser, editUserById, createNewUser, userModalLoading, deleteUserById, clearSelectedUser } = + useUsers(); + const { currentUser, isAdmin } = useAuth(); const { control, reset, handleSubmit } = useForm({ - defaultValues: { - name: null, - email: null, - id: null, - role_id: null, - status: null, - }, + defaultValues: initialUserForm, + }); + + const { fields } = useFieldArray({ + control, + name: 'app_roles', }); useEffect(() => { @@ -28,19 +29,19 @@ export const UserModal = ({ open, onClose, userId }: UserModalProps) => { loadUser(userId); } - reset({ name: null, email: null, id: null, status: null }); + reset(initialUserForm); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [userId]); + }, [userId, open]); useEffect(() => { - if (user) { + if (!_.isEmpty(user)) { reset(user); } return () => { - reset({ name: null, email: null, id: null, status: null }); + reset(initialUserForm); }; - }, [user, reset]); + }, [user, reset, open]); const handleSave = async () => { try { @@ -48,13 +49,14 @@ export const UserModal = ({ open, onClose, userId }: UserModalProps) => { await handleSubmit((data) => editUserById(data))(); } else { await handleSubmit((data) => createNewUser(data))(); - reset({ name: null, email: null, id: null, status: null }); } - - onClose(); } catch (e: any) { // Continue } + + onClose(); + clearSelectedUser(); + setUserId(null); }; const handleKeyPress = (e: any) => { @@ -65,6 +67,8 @@ export const UserModal = ({ open, onClose, userId }: UserModalProps) => { const handleClose = () => { onClose(); + clearSelectedUser(); + setUserId(null); }; const deleteModalOpen = () => setDeleteModal(true); @@ -74,6 +78,9 @@ export const UserModal = ({ open, onClose, userId }: UserModalProps) => { if (userId) { deleteUserById(userId); } + + clearSelectedUser(); + setUserId(null); handleClose(); deleteModalClose(); }; @@ -87,7 +94,7 @@ export const UserModal = ({ open, onClose, userId }: UserModalProps) => { isLoading={userModalLoading} leftActions={ userId && - user.email !== currentUser.email && ( + user.email !== currentUser?.email && (