@@ -15,19 +15,19 @@ import {
1515 useDisclosure ,
1616 Text ,
1717 useToast ,
18+ Input ,
1819} from '@chakra-ui/react' ;
1920import { useClient } from 'urql' ;
20- import { FaSave } from 'react-icons/fa' ;
21+ import { FaSave , FaPlus } from 'react-icons/fa' ;
2122import InputField from './InputField' ;
2223import {
2324 DateInputType ,
2425 MultiSelectInputType ,
2526 SelectInputType ,
2627 TextInputType ,
2728} from '../constants' ;
28- import { getObjectDiff } from '../utils' ;
29+ import { getObjectDiff , getGraphQLErrorMessage } from '../utils' ;
2930import { UpdateUser } from '../graphql/mutation' ;
30- import { GetAvailableRolesQuery } from '../graphql/queries' ;
3131
3232const GenderTypes = {
3333 Undisclosed : null ,
@@ -46,7 +46,7 @@ interface userDataTypes {
4646 birthdate : string ;
4747 phone_number : string ;
4848 picture : string ;
49- roles : [ string ] | [ ] ;
49+ roles : string [ ] ;
5050}
5151
5252const EditUserModal = ( {
@@ -58,7 +58,7 @@ const EditUserModal = ({
5858} ) => {
5959 const client = useClient ( ) ;
6060 const toast = useToast ( ) ;
61- const [ availableRoles , setAvailableRoles ] = useState < string [ ] > ( [ ] ) ;
61+ const [ newRole , setNewRole ] = useState ( '' ) ;
6262 const { isOpen, onOpen, onClose } = useDisclosure ( ) ;
6363 const [ userData , setUserData ] = useState < userDataTypes > ( {
6464 id : '' ,
@@ -73,19 +73,13 @@ const EditUserModal = ({
7373 picture : '' ,
7474 roles : [ ] ,
7575 } ) ;
76+ // Available roles for multiselect: current user roles (no env query)
77+ const availableRoles = Array . from (
78+ new Set ( [ ...( userData . roles || [ ] ) , ...( user . roles || [ ] ) ] ) ,
79+ ) ;
7680 React . useEffect ( ( ) => {
7781 setUserData ( user ) ;
78- fetchAvailableRoles ( ) ;
79- } , [ ] ) ;
80- const fetchAvailableRoles = async ( ) => {
81- const res = await client . query ( GetAvailableRolesQuery ) . toPromise ( ) ;
82- if ( res . data ?. _env ?. ROLES && res . data ?. _env ?. PROTECTED_ROLES ) {
83- setAvailableRoles ( [
84- ...res . data . _env . ROLES ,
85- ...res . data . _env . PROTECTED_ROLES ,
86- ] ) ;
87- }
88- } ;
82+ } , [ user ] ) ;
8983 const saveHandler = async ( ) => {
9084 const diff = getObjectDiff ( user , userData ) ;
9185 const updatedUserData = diff . reduce (
@@ -101,7 +95,7 @@ const EditUserModal = ({
10195 . toPromise ( ) ;
10296 if ( res . error ) {
10397 toast ( {
104- title : 'User data update failed' ,
98+ title : getGraphQLErrorMessage ( res . error , 'User data update failed' ) ,
10599 isClosable : true ,
106100 status : 'error' ,
107101 position : 'top-right' ,
@@ -229,13 +223,45 @@ const EditUserModal = ({
229223 < Flex w = "30%" justifyContent = "start" alignItems = "center" >
230224 < Text fontSize = "sm" > Roles:</ Text >
231225 </ Flex >
232- < Center w = "70%" >
226+ < Center w = "70%" flexDirection = "column" alignItems = "stretch" >
233227 < InputField
234228 variables = { userData }
235229 setVariables = { setUserData }
236230 availableRoles = { availableRoles }
237231 inputType = { MultiSelectInputType . USER_ROLES }
238232 />
233+ < Flex mt = { 2 } gap = { 2 } >
234+ < Input
235+ size = "sm"
236+ placeholder = "Add role"
237+ value = { newRole }
238+ onChange = { ( e ) => setNewRole ( e . target . value ) }
239+ onKeyDown = { ( e ) => {
240+ if ( e . key === 'Enter' && newRole . trim ( ) ) {
241+ setUserData ( {
242+ ...userData ,
243+ roles : [ ...( userData . roles || [ ] ) , newRole . trim ( ) ] ,
244+ } ) ;
245+ setNewRole ( '' ) ;
246+ }
247+ } }
248+ />
249+ < Button
250+ size = "sm"
251+ leftIcon = { < FaPlus /> }
252+ onClick = { ( ) => {
253+ if ( newRole . trim ( ) ) {
254+ setUserData ( {
255+ ...userData ,
256+ roles : [ ...( userData . roles || [ ] ) , newRole . trim ( ) ] ,
257+ } ) ;
258+ setNewRole ( '' ) ;
259+ }
260+ } }
261+ >
262+ Add
263+ </ Button >
264+ </ Flex >
239265 </ Center >
240266 </ Flex >
241267 </ Stack >
0 commit comments