mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentral-ui-libs.git
				synced 2025-11-01 03:07:47 +00:00 
			
		
		
		
	Edit user, edit profile, create user form
This commit is contained in:
		
							
								
								
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,12 +1,12 @@ | |||||||
| { | { | ||||||
|   "name": "ucentral-libs", |   "name": "ucentral-libs", | ||||||
|   "version": "0.8.15", |   "version": "0.8.16", | ||||||
|   "lockfileVersion": 2, |   "lockfileVersion": 2, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "packages": { |   "packages": { | ||||||
|     "": { |     "": { | ||||||
|       "name": "ucentral-libs", |       "name": "ucentral-libs", | ||||||
|       "version": "0.8.15", |       "version": "0.8.16", | ||||||
|       "devDependencies": { |       "devDependencies": { | ||||||
|         "@babel/core": "^7.14.6", |         "@babel/core": "^7.14.6", | ||||||
|         "@babel/plugin-proposal-class-properties": "^7.14.5", |         "@babel/plugin-proposal-class-properties": "^7.14.5", | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "ucentral-libs", |   "name": "ucentral-libs", | ||||||
|   "version": "0.8.15", |   "version": "0.8.16", | ||||||
|   "main": "dist/index.js", |   "main": "dist/index.js", | ||||||
|   "source": "src/index.js", |   "source": "src/index.js", | ||||||
|   "engines": { |   "engines": { | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ const CreateUserForm = ({ t, fields, updateField, createUser, loading, policies | |||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <CForm> |     <CForm> | ||||||
|       <CFormGroup row> |       <CFormGroup row className="pb-3"> | ||||||
|         <CLabel sm="2" col htmlFor="email"> |         <CLabel sm="2" col htmlFor="email"> | ||||||
|           {t('user.email_address')} |           {t('user.email_address')} | ||||||
|         </CLabel> |         </CLabel> | ||||||
| @@ -42,14 +42,41 @@ const CreateUserForm = ({ t, fields, updateField, createUser, loading, policies | |||||||
|           /> |           /> | ||||||
|           <CInvalidFeedback>{t('user.provide_email')}</CInvalidFeedback> |           <CInvalidFeedback>{t('user.provide_email')}</CInvalidFeedback> | ||||||
|         </CCol> |         </CCol> | ||||||
|  |         <CLabel sm="2" col htmlFor="userRole"> | ||||||
|  |           {t('user.user_role')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="4"> | ||||||
|  |           <CSelect custom id="userRole" defaultValue="Admin" onChange={updateField}> | ||||||
|  |             <option value="admin">Admin</option> | ||||||
|  |             <option value="csr">CSR</option> | ||||||
|  |             <option value="root">Root</option> | ||||||
|  |             <option value="special">Special</option> | ||||||
|  |             <option value="sub">Sub</option> | ||||||
|  |             <option value="system">System</option> | ||||||
|  |           </CSelect> | ||||||
|  |         </CCol> | ||||||
|  |       </CFormGroup> | ||||||
|  |       <CFormGroup row> | ||||||
|         <CLabel sm="2" col htmlFor="name"> |         <CLabel sm="2" col htmlFor="name"> | ||||||
|           {t('user.name')} |           {t('user.name')} | ||||||
|         </CLabel> |         </CLabel> | ||||||
|         <CCol sm="4"> |         <CCol sm="4"> | ||||||
|           <CInput id="name" value={fields.name.value} onChange={updateField} maxLength="20" /> |           <CInput id="name" value={fields.name.value} onChange={updateField} maxLength="20" /> | ||||||
|         </CCol> |         </CCol> | ||||||
|  |         <CLabel sm="2" col htmlFor="description"> | ||||||
|  |           {t('user.description')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="4"> | ||||||
|  |           <CInput | ||||||
|  |             id="description" | ||||||
|  |             value={fields.description.value} | ||||||
|  |             onChange={updateField} | ||||||
|  |             maxLength="50" | ||||||
|  |           /> | ||||||
|  |           <small className="text-muted">{t('common.optional')}</small> | ||||||
|  |         </CCol> | ||||||
|       </CFormGroup> |       </CFormGroup> | ||||||
|       <CFormGroup row> |       <CFormGroup row className="pb-3"> | ||||||
|         <CLabel sm="2" col htmlFor="currentPassword"> |         <CLabel sm="2" col htmlFor="currentPassword"> | ||||||
|           {t('user.password')} |           {t('user.password')} | ||||||
|         </CLabel> |         </CLabel> | ||||||
| @@ -89,19 +116,6 @@ const CreateUserForm = ({ t, fields, updateField, createUser, loading, policies | |||||||
|         </CCol> |         </CCol> | ||||||
|       </CFormGroup> |       </CFormGroup> | ||||||
|       <CFormGroup row> |       <CFormGroup row> | ||||||
|         <CLabel sm="2" col htmlFor="userRole"> |  | ||||||
|           {t('user.user_role')} |  | ||||||
|         </CLabel> |  | ||||||
|         <CCol sm="4"> |  | ||||||
|           <CSelect custom id="userRole" defaultValue="Admin" onChange={updateField}> |  | ||||||
|             <option value="admin">Admin</option> |  | ||||||
|             <option value="csr">CSR</option> |  | ||||||
|             <option value="root">Root</option> |  | ||||||
|             <option value="special">Special</option> |  | ||||||
|             <option value="sub">Sub</option> |  | ||||||
|             <option value="system">System</option> |  | ||||||
|           </CSelect> |  | ||||||
|         </CCol> |  | ||||||
|         <CLabel sm="2" col htmlFor="notes"> |         <CLabel sm="2" col htmlFor="notes"> | ||||||
|           {t('user.note')} |           {t('user.note')} | ||||||
|         </CLabel> |         </CLabel> | ||||||
| @@ -110,35 +124,9 @@ const CreateUserForm = ({ t, fields, updateField, createUser, loading, policies | |||||||
|           <small className="text-muted">{t('common.optional')}</small> |           <small className="text-muted">{t('common.optional')}</small> | ||||||
|         </CCol> |         </CCol> | ||||||
|       </CFormGroup> |       </CFormGroup> | ||||||
|       <CFormGroup row> |  | ||||||
|         <CLabel sm="2" col htmlFor="description"> |  | ||||||
|           {t('user.description')} |  | ||||||
|         </CLabel> |  | ||||||
|         <CCol sm="4"> |  | ||||||
|           <CInput |  | ||||||
|             id="description" |  | ||||||
|             value={fields.description.value} |  | ||||||
|             onChange={updateField} |  | ||||||
|             maxLength="50" |  | ||||||
|           /> |  | ||||||
|           <small className="text-muted">{t('common.optional')}</small> |  | ||||||
|         </CCol> |  | ||||||
|         <CLabel sm="2" col /> |  | ||||||
|         <CCol sm="4" /> |  | ||||||
|       </CFormGroup> |  | ||||||
|       <CRow> |       <CRow> | ||||||
|         <CCol /> |         <CCol /> | ||||||
|         <CCol xs={3} className="mt-2 text-right"> |         <CCol xs={2} className="mt-2 text-right"> | ||||||
|           <CLink |  | ||||||
|             className="c-subheader-nav-link" |  | ||||||
|             aria-current="page" |  | ||||||
|             href={policies.accessPolicy} |  | ||||||
|             target="_blank" |  | ||||||
|             style={{ paddingRight: '30px' }} |  | ||||||
|             hidden={policies.accessPolicy.length === 0} |  | ||||||
|           > |  | ||||||
|             {t('common.access_policy')} |  | ||||||
|           </CLink> |  | ||||||
|           <CLink |           <CLink | ||||||
|             className="c-subheader-nav-link" |             className="c-subheader-nav-link" | ||||||
|             aria-current="page" |             aria-current="page" | ||||||
| @@ -149,10 +137,10 @@ const CreateUserForm = ({ t, fields, updateField, createUser, loading, policies | |||||||
|             {t('common.password_policy')} |             {t('common.password_policy')} | ||||||
|           </CLink> |           </CLink> | ||||||
|         </CCol> |         </CCol> | ||||||
|         <CCol xs={1} className="text-right"> |         <CCol xs={2} className="text-center"> | ||||||
|           <LoadingButton |           <LoadingButton | ||||||
|             label={t('user.create')} |             label={t('user.create')} | ||||||
|             isLoadingLabel={t('common.loading_ellipsis')} |             isLoadingLabel={t('user.creating')} | ||||||
|             isLoading={loading} |             isLoading={loading} | ||||||
|             action={createUser} |             action={createUser} | ||||||
|             block={false} |             block={false} | ||||||
|   | |||||||
							
								
								
									
										140
									
								
								src/components/EditMyProfile/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								src/components/EditMyProfile/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | import { | ||||||
|  |   CButton, | ||||||
|  |   CCol, | ||||||
|  |   CForm, | ||||||
|  |   CFormGroup, | ||||||
|  |   CInput, | ||||||
|  |   CInputGroup, | ||||||
|  |   CInputGroupAppend, | ||||||
|  |   CInvalidFeedback, | ||||||
|  |   CLabel, | ||||||
|  |   CLink, | ||||||
|  |   CPopover, | ||||||
|  |   CRow, | ||||||
|  |   CSelect, | ||||||
|  | } from '@coreui/react'; | ||||||
|  | import PropTypes from 'prop-types'; | ||||||
|  | import CIcon from '@coreui/icons-react'; | ||||||
|  | import NotesTable from '../NotesTable'; | ||||||
|  | import LoadingButton from '../LoadingButton'; | ||||||
|  |  | ||||||
|  | const EditMyProfile = ({ t, user, updateUserWithId, loading, saveUser, policies, addNote }) => { | ||||||
|  |   const [showPassword, setShowPassword] = useState(false); | ||||||
|  |  | ||||||
|  |   const toggleShowPassword = () => { | ||||||
|  |     setShowPassword(!showPassword); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <CForm> | ||||||
|  |       <CFormGroup row> | ||||||
|  |         <CLabel sm="2" col htmlFor="name"> | ||||||
|  |           {t('user.name')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="4"> | ||||||
|  |           <CInput id="name" value={user.name.value} onChange={updateUserWithId} maxLength="20" /> | ||||||
|  |         </CCol> | ||||||
|  |         <CLabel sm="2" col htmlFor="description"> | ||||||
|  |           {t('user.description')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="4"> | ||||||
|  |           <CInput | ||||||
|  |             id="description" | ||||||
|  |             value={user.description.value} | ||||||
|  |             onChange={updateUserWithId} | ||||||
|  |             maxLength="50" | ||||||
|  |           /> | ||||||
|  |         </CCol> | ||||||
|  |       </CFormGroup> | ||||||
|  |       <CFormGroup row> | ||||||
|  |         <CLabel sm="2" col htmlFor="userRole"> | ||||||
|  |           {t('user.user_role')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="4"> | ||||||
|  |           <CSelect custom id="userRole" onChange={updateUserWithId} value={user.userRole.value}> | ||||||
|  |             <option value="admin">Admin</option> | ||||||
|  |             <option value="csr">CSR</option> | ||||||
|  |             <option value="root">Root</option> | ||||||
|  |             <option value="special">Special</option> | ||||||
|  |             <option value="sub">Sub</option> | ||||||
|  |             <option value="system">System</option> | ||||||
|  |           </CSelect> | ||||||
|  |         </CCol> | ||||||
|  |         <CLabel sm="2" col htmlFor="currentPassword"> | ||||||
|  |           {t('login.new_password')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="4"> | ||||||
|  |           <CInputGroup> | ||||||
|  |             <CInput | ||||||
|  |               type={showPassword ? 'text' : 'password'} | ||||||
|  |               id="currentPassword" | ||||||
|  |               value={user.currentPassword.value} | ||||||
|  |               onChange={updateUserWithId} | ||||||
|  |               invalid={user.currentPassword.error} | ||||||
|  |               maxLength="50" | ||||||
|  |             /> | ||||||
|  |             <CInputGroupAppend> | ||||||
|  |               <CPopover content={t('user.show_hide_password')}> | ||||||
|  |                 <CButton type="button" onClick={toggleShowPassword} color="secondary"> | ||||||
|  |                   <CIcon | ||||||
|  |                     name={showPassword ? 'cil-envelope-open' : 'cil-envelope-closed'} | ||||||
|  |                     size="sm" | ||||||
|  |                   /> | ||||||
|  |                 </CButton> | ||||||
|  |               </CPopover> | ||||||
|  |             </CInputGroupAppend> | ||||||
|  |             <CInvalidFeedback>{t('user.provide_password')}</CInvalidFeedback> | ||||||
|  |           </CInputGroup> | ||||||
|  |         </CCol> | ||||||
|  |       </CFormGroup> | ||||||
|  |       <CFormGroup row> | ||||||
|  |         <CCol sm="6"> | ||||||
|  |           <NotesTable | ||||||
|  |             t={t} | ||||||
|  |             notes={user.notes.value} | ||||||
|  |             addNote={addNote} | ||||||
|  |             loading={loading} | ||||||
|  |             size="lg" | ||||||
|  |           /> | ||||||
|  |         </CCol> | ||||||
|  |       </CFormGroup> | ||||||
|  |       <CRow> | ||||||
|  |         <CCol /> | ||||||
|  |         <CCol xs={1} className="mt-2 text-right"> | ||||||
|  |           <CLink | ||||||
|  |             className="c-subheader-nav-link" | ||||||
|  |             aria-current="page" | ||||||
|  |             href={policies.passwordPolicy} | ||||||
|  |             target="_blank" | ||||||
|  |             hidden={policies.passwordPolicy.length === 0} | ||||||
|  |           > | ||||||
|  |             {t('common.password_policy')} | ||||||
|  |           </CLink> | ||||||
|  |         </CCol> | ||||||
|  |         <CCol xs={1} className="text-center"> | ||||||
|  |           <LoadingButton | ||||||
|  |             label={t('common.save')} | ||||||
|  |             isLoadingLabel={t('common.saving')} | ||||||
|  |             isLoading={loading} | ||||||
|  |             action={saveUser} | ||||||
|  |             block={false} | ||||||
|  |             disabled={loading} | ||||||
|  |           /> | ||||||
|  |         </CCol> | ||||||
|  |       </CRow> | ||||||
|  |     </CForm> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | EditMyProfile.propTypes = { | ||||||
|  |   t: PropTypes.func.isRequired, | ||||||
|  |   user: PropTypes.instanceOf(Object).isRequired, | ||||||
|  |   updateUserWithId: PropTypes.func.isRequired, | ||||||
|  |   loading: PropTypes.bool.isRequired, | ||||||
|  |   saveUser: PropTypes.func.isRequired, | ||||||
|  |   policies: PropTypes.instanceOf(Object).isRequired, | ||||||
|  |   addNote: PropTypes.func.isRequired, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default React.memo(EditMyProfile); | ||||||
							
								
								
									
										149
									
								
								src/components/EditUserForm/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								src/components/EditUserForm/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | import { | ||||||
|  |   CButton, | ||||||
|  |   CCol, | ||||||
|  |   CForm, | ||||||
|  |   CFormGroup, | ||||||
|  |   CInput, | ||||||
|  |   CInputGroup, | ||||||
|  |   CInputGroupAppend, | ||||||
|  |   CInvalidFeedback, | ||||||
|  |   CLabel, | ||||||
|  |   CLink, | ||||||
|  |   CPopover, | ||||||
|  |   CRow, | ||||||
|  |   CSelect, | ||||||
|  |   CSwitch, | ||||||
|  | } from '@coreui/react'; | ||||||
|  | import PropTypes from 'prop-types'; | ||||||
|  | import CIcon from '@coreui/icons-react'; | ||||||
|  | import NotesTable from '../NotesTable'; | ||||||
|  | import LoadingButton from '../LoadingButton'; | ||||||
|  |  | ||||||
|  | const EditUserForm = ({ t, user, updateUserWithId, loading, saveUser, policies, addNote }) => { | ||||||
|  |   const [showPassword, setShowPassword] = useState(false); | ||||||
|  |  | ||||||
|  |   const toggleShowPassword = () => { | ||||||
|  |     setShowPassword(!showPassword); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <CForm> | ||||||
|  |       <CFormGroup row> | ||||||
|  |         <CLabel sm="2" col htmlFor="name"> | ||||||
|  |           {t('user.name')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="4"> | ||||||
|  |           <CInput id="name" value={user.name.value} onChange={updateUserWithId} maxLength="20" /> | ||||||
|  |         </CCol> | ||||||
|  |         <CLabel sm="2" col htmlFor="description"> | ||||||
|  |           {t('user.description')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="4"> | ||||||
|  |           <CInput | ||||||
|  |             id="description" | ||||||
|  |             value={user.description.value} | ||||||
|  |             onChange={updateUserWithId} | ||||||
|  |             maxLength="50" | ||||||
|  |           /> | ||||||
|  |         </CCol> | ||||||
|  |       </CFormGroup> | ||||||
|  |       <CFormGroup row> | ||||||
|  |         <CLabel sm="2" col htmlFor="userRole"> | ||||||
|  |           {t('user.user_role')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="4"> | ||||||
|  |           <CSelect custom id="userRole" onChange={updateUserWithId} value={user.userRole.value}> | ||||||
|  |             <option value="admin">Admin</option> | ||||||
|  |             <option value="csr">CSR</option> | ||||||
|  |             <option value="root">Root</option> | ||||||
|  |             <option value="special">Special</option> | ||||||
|  |             <option value="sub">Sub</option> | ||||||
|  |             <option value="system">System</option> | ||||||
|  |           </CSelect> | ||||||
|  |         </CCol> | ||||||
|  |         <CLabel sm="2" col htmlFor="currentPassword"> | ||||||
|  |           {t('login.new_password')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="4"> | ||||||
|  |           <CInputGroup> | ||||||
|  |             <CInput | ||||||
|  |               type={showPassword ? 'text' : 'password'} | ||||||
|  |               id="currentPassword" | ||||||
|  |               value={user.currentPassword.value} | ||||||
|  |               onChange={updateUserWithId} | ||||||
|  |               invalid={user.currentPassword.error} | ||||||
|  |               maxLength="50" | ||||||
|  |             /> | ||||||
|  |             <CInputGroupAppend> | ||||||
|  |               <CPopover content={t('user.show_hide_password')}> | ||||||
|  |                 <CButton type="button" onClick={toggleShowPassword} color="secondary"> | ||||||
|  |                   <CIcon | ||||||
|  |                     name={showPassword ? 'cil-envelope-open' : 'cil-envelope-closed'} | ||||||
|  |                     size="sm" | ||||||
|  |                   /> | ||||||
|  |                 </CButton> | ||||||
|  |               </CPopover> | ||||||
|  |             </CInputGroupAppend> | ||||||
|  |             <CInvalidFeedback>{t('user.provide_password')}</CInvalidFeedback> | ||||||
|  |           </CInputGroup> | ||||||
|  |         </CCol> | ||||||
|  |       </CFormGroup> | ||||||
|  |       <CFormGroup row> | ||||||
|  |         <CLabel sm="3" col htmlFor="changePassword"> | ||||||
|  |           {t('user.force_password_change')} | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm="1"> | ||||||
|  |           <CInputGroup> | ||||||
|  |             <CSwitch | ||||||
|  |               id="changePassword" | ||||||
|  |               color="success" | ||||||
|  |               defaultChecked={user.changePassword.value} | ||||||
|  |               onClick={updateUserWithId} | ||||||
|  |               size="lg" | ||||||
|  |             /> | ||||||
|  |           </CInputGroup> | ||||||
|  |         </CCol> | ||||||
|  |         <CCol sm="8"> | ||||||
|  |           <NotesTable t={t} notes={user.notes.value} addNote={addNote} loading={loading} /> | ||||||
|  |         </CCol> | ||||||
|  |       </CFormGroup> | ||||||
|  |       <CRow> | ||||||
|  |         <CCol /> | ||||||
|  |         <CCol xs={2} className="mt-2 text-right"> | ||||||
|  |           <CLink | ||||||
|  |             className="c-subheader-nav-link" | ||||||
|  |             aria-current="page" | ||||||
|  |             href={policies.passwordPolicy} | ||||||
|  |             target="_blank" | ||||||
|  |             hidden={policies.passwordPolicy.length === 0} | ||||||
|  |           > | ||||||
|  |             {t('common.password_policy')} | ||||||
|  |           </CLink> | ||||||
|  |         </CCol> | ||||||
|  |         <CCol xs={2} className="text-center"> | ||||||
|  |           <LoadingButton | ||||||
|  |             label={t('common.save')} | ||||||
|  |             isLoadingLabel={t('common.saving')} | ||||||
|  |             isLoading={loading} | ||||||
|  |             action={saveUser} | ||||||
|  |             block={false} | ||||||
|  |             disabled={loading} | ||||||
|  |           /> | ||||||
|  |         </CCol> | ||||||
|  |       </CRow> | ||||||
|  |     </CForm> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | EditUserForm.propTypes = { | ||||||
|  |   t: PropTypes.func.isRequired, | ||||||
|  |   user: PropTypes.instanceOf(Object).isRequired, | ||||||
|  |   updateUserWithId: PropTypes.func.isRequired, | ||||||
|  |   loading: PropTypes.bool.isRequired, | ||||||
|  |   saveUser: PropTypes.func.isRequired, | ||||||
|  |   policies: PropTypes.instanceOf(Object).isRequired, | ||||||
|  |   addNote: PropTypes.func.isRequired, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default React.memo(EditUserForm); | ||||||
							
								
								
									
										49
									
								
								src/components/EditUserModal/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/components/EditUserModal/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | import React from 'react'; | ||||||
|  | import PropTypes from 'prop-types'; | ||||||
|  | import { CModal, CModalBody, CModalHeader, CModalTitle } from '@coreui/react'; | ||||||
|  | import EditUserForm from '../EditUserForm'; | ||||||
|  |  | ||||||
|  | const EditUserModal = ({ | ||||||
|  |   t, | ||||||
|  |   user, | ||||||
|  |   updateUserWithId, | ||||||
|  |   saveUser, | ||||||
|  |   loading, | ||||||
|  |   policies, | ||||||
|  |   show, | ||||||
|  |   toggle, | ||||||
|  |   addNote, | ||||||
|  | }) => ( | ||||||
|  |   <CModal show={show} onClose={toggle} size="xl"> | ||||||
|  |     <CModalHeader> | ||||||
|  |       <CModalTitle> | ||||||
|  |         {t('user.edit')} {user.email.value} | ||||||
|  |       </CModalTitle> | ||||||
|  |     </CModalHeader> | ||||||
|  |     <CModalBody> | ||||||
|  |       <EditUserForm | ||||||
|  |         t={t} | ||||||
|  |         user={user} | ||||||
|  |         updateUserWithId={updateUserWithId} | ||||||
|  |         saveUser={saveUser} | ||||||
|  |         loading={loading} | ||||||
|  |         policies={policies} | ||||||
|  |         addNote={addNote} | ||||||
|  |       /> | ||||||
|  |     </CModalBody> | ||||||
|  |   </CModal> | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | EditUserModal.propTypes = { | ||||||
|  |   t: PropTypes.func.isRequired, | ||||||
|  |   user: PropTypes.instanceOf(Object).isRequired, | ||||||
|  |   updateUserWithId: PropTypes.func.isRequired, | ||||||
|  |   loading: PropTypes.bool.isRequired, | ||||||
|  |   saveUser: PropTypes.func.isRequired, | ||||||
|  |   policies: PropTypes.instanceOf(Object).isRequired, | ||||||
|  |   show: PropTypes.bool.isRequired, | ||||||
|  |   toggle: PropTypes.func.isRequired, | ||||||
|  |   addNote: PropTypes.func.isRequired, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default React.memo(EditUserModal); | ||||||
							
								
								
									
										87
									
								
								src/components/NotesTable/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/components/NotesTable/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | |||||||
|  | import React, { useEffect, useState } from 'react'; | ||||||
|  | import PropTypes from 'prop-types'; | ||||||
|  | import { CDataTable, CRow, CCol, CLabel, CInput } from '@coreui/react'; | ||||||
|  | import { prettyDate } from '../../utils/formatting'; | ||||||
|  | import LoadingButton from '../LoadingButton'; | ||||||
|  |  | ||||||
|  | const NotesTable = ({ t, notes, addNote, loading, size }) => { | ||||||
|  |   const [currentNote, setCurrentNote] = useState(''); | ||||||
|  |  | ||||||
|  |   const columns = [ | ||||||
|  |     { key: 'created', label: t('common.date'), _style: { width: '30%' } }, | ||||||
|  |     { key: 'createdBy', label: t('common.created_by'), _style: { width: '20%' } }, | ||||||
|  |     { key: 'note', label: t('configuration.note'), _style: { width: '50%' } }, | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   const saveNote = () => { | ||||||
|  |     addNote(currentNote); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   useEffect(() => { | ||||||
|  |     setCurrentNote(''); | ||||||
|  |   }, [notes]); | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <div> | ||||||
|  |       <CRow> | ||||||
|  |         <CLabel col sm="2"> | ||||||
|  |           {t('configuration.notes')} : | ||||||
|  |         </CLabel> | ||||||
|  |         <CCol sm={size === 'm' ? '7' : '8'}> | ||||||
|  |           <CInput | ||||||
|  |             id="notes-input" | ||||||
|  |             name="text-input" | ||||||
|  |             value={currentNote} | ||||||
|  |             onChange={(e) => setCurrentNote(e.target.value)} | ||||||
|  |           /> | ||||||
|  |         </CCol> | ||||||
|  |         <CCol sm={size === 'm' ? '3' : '2'}> | ||||||
|  |           <LoadingButton | ||||||
|  |             label={t('common.add')} | ||||||
|  |             isLoadingLabel={t('common.adding_ellipsis')} | ||||||
|  |             isLoading={loading} | ||||||
|  |             action={saveNote} | ||||||
|  |             disabled={loading || currentNote === ''} | ||||||
|  |           /> | ||||||
|  |         </CCol> | ||||||
|  |       </CRow> | ||||||
|  |       <CRow className="pt-3"> | ||||||
|  |         <CCol> | ||||||
|  |           <div className="overflow-auto" style={{ height: '200px' }}> | ||||||
|  |             <CDataTable | ||||||
|  |               striped | ||||||
|  |               responsive | ||||||
|  |               border | ||||||
|  |               loading={loading} | ||||||
|  |               fields={columns} | ||||||
|  |               items={notes || []} | ||||||
|  |               noItemsView={{ noItems: t('common.no_items') }} | ||||||
|  |               sorterValue={{ column: 'created', desc: 'true' }} | ||||||
|  |               scopedSlots={{ | ||||||
|  |                 created: (item) => ( | ||||||
|  |                   <td> | ||||||
|  |                     {item.created && item.created !== 0 ? prettyDate(item.created) : t('common.na')} | ||||||
|  |                   </td> | ||||||
|  |                 ), | ||||||
|  |               }} | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |         </CCol> | ||||||
|  |       </CRow> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | NotesTable.propTypes = { | ||||||
|  |   t: PropTypes.func.isRequired, | ||||||
|  |   notes: PropTypes.instanceOf(Array).isRequired, | ||||||
|  |   addNote: PropTypes.func.isRequired, | ||||||
|  |   loading: PropTypes.bool.isRequired, | ||||||
|  |   size: PropTypes.string, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | NotesTable.defaultProps = { | ||||||
|  |   size: 'm', | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default NotesTable; | ||||||
| @@ -2,18 +2,17 @@ import React, { useState } from 'react'; | |||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import ReactPaginate from 'react-paginate'; | import ReactPaginate from 'react-paginate'; | ||||||
| import { | import { | ||||||
|  |   CButton, | ||||||
|   CCard, |   CCard, | ||||||
|   CCardHeader, |  | ||||||
|   CSelect, |  | ||||||
|   CCol, |  | ||||||
|   CRow, |  | ||||||
|   CCardBody, |   CCardBody, | ||||||
|  |   CCardHeader, | ||||||
|  |   CCol, | ||||||
|   CDataTable, |   CDataTable, | ||||||
|   CPopover, |   CPopover, | ||||||
|   CButton, |   CRow, | ||||||
|   CLink, |   CSelect, | ||||||
| } from '@coreui/react'; | } from '@coreui/react'; | ||||||
| import { cilBan, cilCheckCircle, cilInfo, cilPlus, cilTrash } from '@coreui/icons'; | import { cilBan, cilCheckCircle, cilPencil, cilSync, cilTrash } from '@coreui/icons'; | ||||||
| import CIcon from '@coreui/icons-react'; | import CIcon from '@coreui/icons-react'; | ||||||
| import { capitalizeFirstLetter, prettyDate } from '../../utils/formatting'; | import { capitalizeFirstLetter, prettyDate } from '../../utils/formatting'; | ||||||
| import DeleteModal from '../DeleteModal'; | import DeleteModal from '../DeleteModal'; | ||||||
| @@ -28,6 +27,9 @@ const UserListTable = ({ | |||||||
|   setPage, |   setPage, | ||||||
|   deleteUser, |   deleteUser, | ||||||
|   deleteLoading, |   deleteLoading, | ||||||
|  |   toggleCreate, | ||||||
|  |   toggleEdit, | ||||||
|  |   refreshUsers, | ||||||
| }) => { | }) => { | ||||||
|   const [idToDelete, setIdToDelete] = useState(''); |   const [idToDelete, setIdToDelete] = useState(''); | ||||||
|   const [showDeleteModal, setShowDeleteModal] = useState(false); |   const [showDeleteModal, setShowDeleteModal] = useState(false); | ||||||
| @@ -50,13 +52,20 @@ const UserListTable = ({ | |||||||
|     { key: 'email', label: t('user.login_id'), _style: { width: '20%' } }, |     { key: 'email', label: t('user.login_id'), _style: { width: '20%' } }, | ||||||
|     { key: 'name', label: t('user.name'), _style: { width: '20%' } }, |     { key: 'name', label: t('user.name'), _style: { width: '20%' } }, | ||||||
|     { key: 'userRole', label: t('user.user_role'), _style: { width: '5%' } }, |     { key: 'userRole', label: t('user.user_role'), _style: { width: '5%' } }, | ||||||
|     { key: 'description', label: t('user.description'), _style: { width: '25%' } }, |     { key: 'description', label: t('user.description'), _style: { width: '24%' } }, | ||||||
|     { key: 'validated', label: t('user.validated'), _style: { width: '5%' } }, |     { key: 'validated', label: t('user.validated'), _style: { width: '5%' } }, | ||||||
|     { key: 'lastLogin', label: t('user.last_login'), _style: { width: '20%' } }, |     { key: 'lastLogin', label: t('user.last_login'), _style: { width: '20%' } }, | ||||||
|     { |     { | ||||||
|       key: 'user_actions', |       key: 'user_details', | ||||||
|       label: '', |       label: '', | ||||||
|       _style: { width: '5%' }, |       _style: { width: '3%' }, | ||||||
|  |       sorter: false, | ||||||
|  |       filter: false, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       key: 'user_delete', | ||||||
|  |       label: '', | ||||||
|  |       _style: { width: '3%' }, | ||||||
|       sorter: false, |       sorter: false, | ||||||
|       filter: false, |       filter: false, | ||||||
|     }, |     }, | ||||||
| @@ -68,17 +77,44 @@ const UserListTable = ({ | |||||||
|         <CCardHeader> |         <CCardHeader> | ||||||
|           <CRow> |           <CRow> | ||||||
|             <CCol /> |             <CCol /> | ||||||
|             <CCol xs={1}> |             <CCol xs={2}> | ||||||
|               <CSelect |               <CRow> | ||||||
|                 custom |                 <CCol xs={5}> | ||||||
|                 defaultValue={usersPerPage} |                   <div className="text-right"> | ||||||
|                 onChange={(e) => setUsersPerPage(e.target.value)} |                     <CSelect | ||||||
|                 disabled={loading} |                       custom | ||||||
|               > |                       defaultValue={usersPerPage} | ||||||
|                 <option value="10">10</option> |                       onChange={(e) => setUsersPerPage(e.target.value)} | ||||||
|                 <option value="25">25</option> |                       disabled={loading} | ||||||
|                 <option value="50">50</option> |                     > | ||||||
|               </CSelect> |                       <option value="10">10</option> | ||||||
|  |                       <option value="25">25</option> | ||||||
|  |                       <option value="50">50</option> | ||||||
|  |                     </CSelect> | ||||||
|  |                   </div> | ||||||
|  |                 </CCol> | ||||||
|  |                 <CCol xs={5}> | ||||||
|  |                   <div className="text-right"> | ||||||
|  |                     <CButton | ||||||
|  |                       color="primary" | ||||||
|  |                       variant="outline" | ||||||
|  |                       shape="square" | ||||||
|  |                       onClick={toggleCreate} | ||||||
|  |                     > | ||||||
|  |                       {t('user.create')} | ||||||
|  |                     </CButton> | ||||||
|  |                   </div> | ||||||
|  |                 </CCol> | ||||||
|  |                 <CCol xs={2}> | ||||||
|  |                   <div className="text-center"> | ||||||
|  |                     <CPopover content={t('common.refresh')}> | ||||||
|  |                       <CButton onClick={refreshUsers} color="primary" variant="outline"> | ||||||
|  |                         <CIcon name="cil-sync" content={cilSync} /> | ||||||
|  |                       </CButton> | ||||||
|  |                     </CPopover> | ||||||
|  |                   </div> | ||||||
|  |                 </CCol> | ||||||
|  |               </CRow> | ||||||
|             </CCol> |             </CCol> | ||||||
|           </CRow> |           </CRow> | ||||||
|         </CCardHeader> |         </CCardHeader> | ||||||
| @@ -89,23 +125,6 @@ const UserListTable = ({ | |||||||
|             loading={loading} |             loading={loading} | ||||||
|             hover |             hover | ||||||
|             border |             border | ||||||
|             columnHeaderSlot={{ |  | ||||||
|               user_actions: ( |  | ||||||
|                 <div className="text-center"> |  | ||||||
|                   <CPopover content={t('user.create')}> |  | ||||||
|                     <CLink |  | ||||||
|                       className="c-subheader-nav-link" |  | ||||||
|                       aria-current="page" |  | ||||||
|                       to={() => `/users/create`} |  | ||||||
|                     > |  | ||||||
|                       <CButton color="primary" variant="outline" shape="square" size="sm"> |  | ||||||
|                         <CIcon name="cil-info" content={cilPlus} size="sm" /> |  | ||||||
|                       </CButton> |  | ||||||
|                     </CLink> |  | ||||||
|                   </CPopover> |  | ||||||
|                 </div> |  | ||||||
|               ), |  | ||||||
|             }} |  | ||||||
|             scopedSlots={{ |             scopedSlots={{ | ||||||
|               validated: (item) => ( |               validated: (item) => ( | ||||||
|                 <td className="text-center"> |                 <td className="text-center"> | ||||||
| @@ -120,35 +139,33 @@ const UserListTable = ({ | |||||||
|               userRole: (item) => ( |               userRole: (item) => ( | ||||||
|                 <td>{item.userRole ? capitalizeFirstLetter(item.userRole) : ''}</td> |                 <td>{item.userRole ? capitalizeFirstLetter(item.userRole) : ''}</td> | ||||||
|               ), |               ), | ||||||
|               user_actions: (item) => ( |               user_details: (item) => ( | ||||||
|                 <td className="py-2 text-center"> |                 <td className="py-2 text-center"> | ||||||
|                   <CRow> |                   <CPopover content={t('common.edit')}> | ||||||
|                     <CCol> |                     <CButton | ||||||
|                       <CPopover content={t('configuration.details')}> |                       color="primary" | ||||||
|                         <CLink |                       variant="outline" | ||||||
|                           className="c-subheader-nav-link" |                       shape="square" | ||||||
|                           aria-current="page" |                       size="sm" | ||||||
|                           to={() => `/users/${item.Id}`} |                       onClick={() => toggleEdit(item.Id)} | ||||||
|                         > |                     > | ||||||
|                           <CButton color="primary" variant="outline" shape="square" size="sm"> |                       <CIcon name="cil-pencil" content={cilPencil} size="sm" /> | ||||||
|                             <CIcon name="cil-info" content={cilInfo} size="sm" /> |                     </CButton> | ||||||
|                           </CButton> |                   </CPopover> | ||||||
|                         </CLink> |                 </td> | ||||||
|                       </CPopover> |               ), | ||||||
|                     </CCol> |               user_delete: (item) => ( | ||||||
|                     <CCol> |                 <td className="py-2 text-center"> | ||||||
|                       <CPopover content={t('common.delete')}> |                   <CPopover content={t('common.delete')}> | ||||||
|                         <CButton |                     <CButton | ||||||
|                           onClick={() => handleDeleteClick(item.Id)} |                       onClick={() => handleDeleteClick(item.Id)} | ||||||
|                           color="primary" |                       color="primary" | ||||||
|                           variant="outline" |                       variant="outline" | ||||||
|                           size="sm" |                       size="sm" | ||||||
|                         > |                     > | ||||||
|                           <CIcon content={cilTrash} size="sm" /> |                       <CIcon content={cilTrash} size="sm" /> | ||||||
|                         </CButton> |                     </CButton> | ||||||
|                       </CPopover> |                   </CPopover> | ||||||
|                     </CCol> |  | ||||||
|                   </CRow> |  | ||||||
|                 </td> |                 </td> | ||||||
|               ), |               ), | ||||||
|             }} |             }} | ||||||
| @@ -196,6 +213,9 @@ UserListTable.propTypes = { | |||||||
|   setPage: PropTypes.func.isRequired, |   setPage: PropTypes.func.isRequired, | ||||||
|   deleteUser: PropTypes.func.isRequired, |   deleteUser: PropTypes.func.isRequired, | ||||||
|   deleteLoading: PropTypes.bool.isRequired, |   deleteLoading: PropTypes.bool.isRequired, | ||||||
|  |   toggleCreate: PropTypes.func.isRequired, | ||||||
|  |   toggleEdit: PropTypes.func.isRequired, | ||||||
|  |   refreshUsers: PropTypes.func.isRequired, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| export default React.memo(UserListTable); | export default React.memo(UserListTable); | ||||||
|   | |||||||
| @@ -1,139 +0,0 @@ | |||||||
| import React, { useState } from 'react'; |  | ||||||
| import { |  | ||||||
|   CButton, |  | ||||||
|   CCard, |  | ||||||
|   CCardBody, |  | ||||||
|   CCardHeader, |  | ||||||
|   CCol, |  | ||||||
|   CForm, |  | ||||||
|   CFormGroup, |  | ||||||
|   CInput, |  | ||||||
|   CInputGroup, |  | ||||||
|   CInputGroupAppend, |  | ||||||
|   CInvalidFeedback, |  | ||||||
|   CLabel, |  | ||||||
|   CPopover, |  | ||||||
|   CRow, |  | ||||||
|   CSelect, |  | ||||||
|   CSwitch, |  | ||||||
| } from '@coreui/react'; |  | ||||||
| import PropTypes from 'prop-types'; |  | ||||||
| import LoadingButton from 'components/LoadingButton'; |  | ||||||
| import CIcon from '@coreui/icons-react'; |  | ||||||
|  |  | ||||||
| const CreateUserForm = ({ t, user, updateUserWithId, loading, saveUser }) => { |  | ||||||
|   const [showPassword, setShowPassword] = useState(false); |  | ||||||
|  |  | ||||||
|   const toggleShowPassword = () => { |  | ||||||
|     setShowPassword(!showPassword); |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <CCard> |  | ||||||
|       <CCardHeader>{t('common.details')}</CCardHeader> |  | ||||||
|       <CCardBody> |  | ||||||
|         <CForm> |  | ||||||
|           <CFormGroup row> |  | ||||||
|             <CCol> |  | ||||||
|               <CLabel htmlFor="email">{t('user.email_address')}</CLabel> |  | ||||||
|               <p className="form-control-static mt-2">{user.email.value}</p> |  | ||||||
|             </CCol> |  | ||||||
|             <CCol> |  | ||||||
|               <CLabel htmlFor="name">{t('user.name')}</CLabel> |  | ||||||
|               <CInput |  | ||||||
|                 id="name" |  | ||||||
|                 value={user.name.value} |  | ||||||
|                 onChange={updateUserWithId} |  | ||||||
|                 maxLength="20" |  | ||||||
|               /> |  | ||||||
|             </CCol> |  | ||||||
|             <CCol> |  | ||||||
|               <CLabel htmlFor="changePassword">{t('user.force_password_change')}</CLabel> |  | ||||||
|               <CInputGroup> |  | ||||||
|                 <CSwitch |  | ||||||
|                   id="changePassword" |  | ||||||
|                   color="success" |  | ||||||
|                   defaultChecked={user.changePassword.value} |  | ||||||
|                   onClick={updateUserWithId} |  | ||||||
|                   size="lg" |  | ||||||
|                 /> |  | ||||||
|               </CInputGroup> |  | ||||||
|             </CCol> |  | ||||||
|           </CFormGroup> |  | ||||||
|           <CFormGroup row> |  | ||||||
|             <CCol> |  | ||||||
|               <CLabel htmlFor="userRole">{t('user.user_role')}</CLabel> |  | ||||||
|               <CSelect custom id="userRole" defaultValue="Admin" onChange={updateUserWithId}> |  | ||||||
|                 <option value="admin">Admin</option> |  | ||||||
|                 <option value="csr">CSR</option> |  | ||||||
|                 <option value="root">Root</option> |  | ||||||
|                 <option value="special">Special</option> |  | ||||||
|                 <option value="sub">Sub</option> |  | ||||||
|                 <option value="system">System</option> |  | ||||||
|               </CSelect> |  | ||||||
|             </CCol> |  | ||||||
|             <CCol> |  | ||||||
|               <CLabel htmlFor="newPascurrentPasswordsword">{t('login.new_password')}</CLabel> |  | ||||||
|               <CInputGroup> |  | ||||||
|                 <CInput |  | ||||||
|                   type={showPassword ? 'text' : 'password'} |  | ||||||
|                   id="currentPassword" |  | ||||||
|                   value={user.currentPassword.value} |  | ||||||
|                   onChange={updateUserWithId} |  | ||||||
|                   invalid={user.currentPassword.error} |  | ||||||
|                   maxLength="50" |  | ||||||
|                 /> |  | ||||||
|                 <CInputGroupAppend> |  | ||||||
|                   <CPopover content={t('user.show_hide_password')}> |  | ||||||
|                     <CButton type="button" onClick={toggleShowPassword} color="secondary"> |  | ||||||
|                       <CIcon |  | ||||||
|                         name={showPassword ? 'cil-envelope-open' : 'cil-envelope-closed'} |  | ||||||
|                         size="sm" |  | ||||||
|                       /> |  | ||||||
|                     </CButton> |  | ||||||
|                   </CPopover> |  | ||||||
|                 </CInputGroupAppend> |  | ||||||
|                 <CInvalidFeedback>{t('user.provide_password')}</CInvalidFeedback> |  | ||||||
|               </CInputGroup> |  | ||||||
|             </CCol> |  | ||||||
|           </CFormGroup> |  | ||||||
|           <CFormGroup row> |  | ||||||
|             <CCol> |  | ||||||
|               <CLabel htmlFor="description">{t('user.description')}</CLabel> |  | ||||||
|               <CInput |  | ||||||
|                 id="description" |  | ||||||
|                 value={user.description.value} |  | ||||||
|                 onChange={updateUserWithId} |  | ||||||
|                 maxLength="50" |  | ||||||
|               /> |  | ||||||
|             </CCol> |  | ||||||
|             <CCol /> |  | ||||||
|           </CFormGroup> |  | ||||||
|           <CRow> |  | ||||||
|             <CCol /> |  | ||||||
|             <CCol xs={3} className="text-right"> |  | ||||||
|               <LoadingButton |  | ||||||
|                 label={t('common.save')} |  | ||||||
|                 isLoadingLabel={t('common.saving')} |  | ||||||
|                 isLoading={loading} |  | ||||||
|                 action={saveUser} |  | ||||||
|                 block={false} |  | ||||||
|                 disabled={loading} |  | ||||||
|               /> |  | ||||||
|             </CCol> |  | ||||||
|           </CRow> |  | ||||||
|         </CForm> |  | ||||||
|       </CCardBody> |  | ||||||
|     </CCard> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| CreateUserForm.propTypes = { |  | ||||||
|   t: PropTypes.func.isRequired, |  | ||||||
|   user: PropTypes.instanceOf(Object).isRequired, |  | ||||||
|   updateUserWithId: PropTypes.func.isRequired, |  | ||||||
|   loading: PropTypes.bool.isRequired, |  | ||||||
|   saveUser: PropTypes.func.isRequired, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| export default React.memo(CreateUserForm); |  | ||||||
| @@ -18,7 +18,7 @@ export default (initialState) => { | |||||||
|     (key, newValues) => { |     (key, newValues) => { | ||||||
|       setUser({ |       setUser({ | ||||||
|         ...user, |         ...user, | ||||||
|         [user]: { |         [key]: { | ||||||
|           ...user[key], |           ...user[key], | ||||||
|           ...newValues, |           ...newValues, | ||||||
|         }, |         }, | ||||||
|   | |||||||
| @@ -10,7 +10,9 @@ export { default as UserListTable } from './components/UserListTable'; | |||||||
| export { default as CreateUserForm } from './components/CreateUserForm'; | export { default as CreateUserForm } from './components/CreateUserForm'; | ||||||
| export { default as LoadingButton } from './components/LoadingButton'; | export { default as LoadingButton } from './components/LoadingButton'; | ||||||
| export { default as ConfirmFooter } from './components/ConfirmFooter'; | export { default as ConfirmFooter } from './components/ConfirmFooter'; | ||||||
| export { default as UserProfileCard } from './components/UserProfileCard'; | export { default as EditUserModal } from './components/EditUserModal'; | ||||||
|  | export { default as EditUserForm } from './components/EditUserForm'; | ||||||
|  | export { default as EditMyProfile } from './components/EditMyProfile'; | ||||||
|  |  | ||||||
| // Pages | // Pages | ||||||
| export { default as LoginPage } from './components/LoginPage'; | export { default as LoginPage } from './components/LoginPage'; | ||||||
|   | |||||||
| @@ -62,7 +62,7 @@ const Header = ({ | |||||||
|       <CHeaderNav className="px-1"> |       <CHeaderNav className="px-1"> | ||||||
|         <CDropdown inNav className="c-header-nav-items mx-2" direction="down"> |         <CDropdown inNav className="c-header-nav-items mx-2" direction="down"> | ||||||
|           <CDropdownToggle className="c-header-nav-link" caret={false}> |           <CDropdownToggle className="c-header-nav-link" caret={false}> | ||||||
|             <div className="c-avatar"> |             <div className="c-avatar avatar"> | ||||||
|               <ImgWithFallback |               <ImgWithFallback | ||||||
|                 src={user.avatar && user.avatar !== '' ? user.avatar : '/'} |                 src={user.avatar && user.avatar !== '' ? user.avatar : '/'} | ||||||
|                 fallback={() => emailToName(user.email)} |                 fallback={() => emailToName(user.email)} | ||||||
| @@ -70,11 +70,11 @@ const Header = ({ | |||||||
|             </div> |             </div> | ||||||
|           </CDropdownToggle> |           </CDropdownToggle> | ||||||
|           <CDropdownMenu className="pt-0" placement="bottom-end"> |           <CDropdownMenu className="pt-0" placement="bottom-end"> | ||||||
|             <CDropdownItem> |             <CDropdownItem to={() => '/myprofile'}> | ||||||
|               <div className="px-3">My Account</div> |               <div className="px-3">{t('user.my_profile')}</div> | ||||||
|             </CDropdownItem> |             </CDropdownItem> | ||||||
|             <CDropdownItem onClick={() => logout(authToken, endpoints.ucentralsec)}> |             <CDropdownItem onClick={() => logout(authToken, endpoints.ucentralsec)}> | ||||||
|               <strong className="px-3">Logout</strong> |               <strong className="px-3">{t('common.logout')}</strong> | ||||||
|               <CIcon name="cilAccountLogout" content={cilAccountLogout} /> |               <CIcon name="cilAccountLogout" content={cilAccountLogout} /> | ||||||
|             </CDropdownItem> |             </CDropdownItem> | ||||||
|           </CDropdownMenu> |           </CDropdownMenu> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 bourquecharles
					bourquecharles