Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
GGCE
GGCE Web
Commits
8c3d8530
Commit
8c3d8530
authored
Apr 28, 2021
by
Matija Obreza
Browse files
Merge branch '234-password-change' into 'main'
Password change Closes
#234
See merge request grin-global/grin-global-ui!219
parent
e0a7b45f
Changes
17
Hide whitespace changes
Inline
Side-by-side
workspaces/client/locales/en/client.json
View file @
8c3d8530
...
...
@@ -8,7 +8,8 @@
"maxCharacters"
:
"Must be {{count, number}} characters or less"
,
"invalidEmail"
:
"Invalid email address"
,
"minValue"
:
"Should be greater or equal to {{count, min}}"
,
"invalidDoi"
:
"Invalid DOI. Must start with 10.[digits]/[something]"
"invalidDoi"
:
"Invalid DOI. Must start with 10.[digits]/[something]"
,
"invalidNewPassword"
:
"New passwords doesn`t match"
},
"model"
:
{
"_"
:
{
...
...
workspaces/client/src/action/profile.ts
0 → 100644
View file @
8c3d8530
import
{
call
,
put
,
takeEvery
}
from
'
redux-saga/effects
'
;
// constants
export
const
CHANGE_PASSWORD_FAIL
=
'
CHANGE_PASSWORD_FAIL
'
;
export
const
CHANGE_PASSWORD_SAGA
=
'
saga/login/CHANGE_PASSWORD
'
;
export
const
CLEAR_CHANGE_PASSWORD_FAIL_SAGA
=
'
saga/login/CLEAR_CHANGE_PASSWORD_FAIL_SAGA
'
;
// service
import
{
ProfileService
}
from
'
@gringlobal-ce/client/service
'
;
export
const
profileSagas
=
[
takeEvery
(
CHANGE_PASSWORD_SAGA
,
changePasswordSaga
),
takeEvery
(
CLEAR_CHANGE_PASSWORD_FAIL_SAGA
,
clearChangePasswordErrorSaga
)
];
export
const
changePasswordAction
=
(
data
)
=>
({
type
:
CHANGE_PASSWORD_SAGA
,
payload
:
{
data
},
});
function
*
changePasswordSaga
(
action
)
{
const
{
currentPassword
,
newPassword
,
closeDialog
}
=
action
.
payload
.
data
;
try
{
yield
call
(
ProfileService
.
changePassword
,
newPassword
,
currentPassword
);
closeDialog
?.();
}
catch
(
e
)
{
yield
put
({
type
:
CHANGE_PASSWORD_FAIL
,
error
:
e
.
data
?.
error
,
});
}
}
export
const
clearChangePasswordErrorAction
=
()
=>
({
type
:
CLEAR_CHANGE_PASSWORD_FAIL_SAGA
,
});
function
*
clearChangePasswordErrorSaga
(
action
)
{
yield
put
({
type
:
CHANGE_PASSWORD_FAIL
,
error
:
null
,
});
}
workspaces/client/src/action/saga.ts
View file @
8c3d8530
import
{
takeEvery
}
from
'
redux-saga/effects
'
;
import
{
loginSagas
}
from
'
./login
'
;
import
{
applicationConfigSagas
}
from
'
./applicationConfig
'
;
import
{
profileSagas
}
from
'
./profile
'
;
export
const
coreSagas
=
[
process
.
env
.
NODE_ENV
===
'
development
'
?
takeEvery
((
action
)
=>
/^api
\/
/
.
test
(
action
.
type
),
logApi
)
:
{},
...
loginSagas
,
...
applicationConfigSagas
,
...
profileSagas
,
];
function
*
logApi
(
action
)
{
...
...
workspaces/client/src/reducer/index.ts
View file @
8c3d8530
...
...
@@ -7,6 +7,7 @@ import historyReducer from '@gringlobal-ce/client/reducer/history';
import
login
from
'
@gringlobal-ce/client/reducer/login
'
;
import
pageTitle
from
'
@gringlobal-ce/client/reducer/pageTitle
'
;
import
snackbar
from
'
@gringlobal-ce/client/reducer/snackbar
'
;
import
profile
from
'
@gringlobal-ce/client/reducer/profile
'
;
const
coreReducers
=
(
history
?)
=>
({
// lib reducers
...
...
@@ -19,6 +20,7 @@ const coreReducers = (history?) => ({
login
,
pageTitle
,
snackbar
,
profile
,
// model reducers
});
...
...
workspaces/client/src/reducer/profile.ts
0 → 100644
View file @
8c3d8530
// constants
import
{
CHANGE_PASSWORD_FAIL
}
from
'
@gringlobal-ce/client/action/profile
'
;
const
INITIAL_STATE
=
{
error
:
null
,
};
const
profile
=
(
state
=
INITIAL_STATE
,
action
)
=>
{
const
{
type
,
...
rest
}
=
action
;
switch
(
type
)
{
case
CHANGE_PASSWORD_FAIL
:
{
return
{
...
state
,
...
rest
};
}
default
:
return
state
;
}
};
export
default
profile
;
workspaces/client/src/service/ProfileService.ts
0 → 100644
View file @
8c3d8530
import
*
as
QueryString
from
'
query-string
'
;
import
{
AxiosInstance
,
AxiosRequestConfig
}
from
'
axios
'
;
import
OAuthClient
from
'
@gringlobal-ce/client/model/gringlobal/OAuthClient
'
;
import
SysUser
from
'
@gringlobal-ce/client/model/gringlobal/SysUser
'
;
const
URL_CHANGE_PASSWORD
=
`/api/v1/me/password`
;
const
URL_GET_PROFILE
=
`/api/v1/me/user`
;
const
URL_GET_CLIENT
=
`/api/v1/me/client`
;
/**
* Profile service
*
* GRIN-Global CE API
*/
class
ProfileService
{
private
_axios
:
AxiosInstance
;
public
constructor
(
axios
:
AxiosInstance
)
{
this
.
_axios
=
axios
;
}
/**
* changePassword at /api/v1/me/password
*
* @param newPassword string
* @param oldPassword string
* @param xhrConfig additional xhr config
*/
public
changePassword
=
(
newPassword
:
string
,
oldPassword
:
string
,
xhrConfig
?:
AxiosRequestConfig
):
Promise
<
string
>
=>
{
const
qs
=
QueryString
.
stringify
({
new
:
newPassword
||
undefined
,
old
:
oldPassword
||
undefined
,
},
{});
const
apiUrl
=
URL_CHANGE_PASSWORD
+
(
qs
?
`?
${
qs
}
`
:
''
);
// console.log(`Fetching from ${apiUrl}`);
const
content
=
{
/* No content in request body */
};
return
this
.
_axios
.
request
({
...
xhrConfig
,
url
:
apiUrl
,
method
:
'
POST
'
,
...
content
,
}).
then
(({
data
})
=>
data
as
string
);
}
/**
* getProfile at /api/v1/me/user
*
* @param xhrConfig additional xhr config
*/
public
getProfile
=
(
xhrConfig
?:
AxiosRequestConfig
):
Promise
<
SysUser
>
=>
{
const
apiUrl
=
URL_GET_PROFILE
;
// console.log(`Fetching from ${apiUrl}`);
const
content
=
{
/* No content in request body */
};
return
this
.
_axios
.
request
({
...
xhrConfig
,
url
:
apiUrl
,
method
:
'
GET
'
,
...
content
,
}).
then
(({
data
})
=>
data
as
SysUser
);
}
/**
* getClient at /api/v1/me/client
*
* @param xhrConfig additional xhr config
*/
public
getClient
=
(
xhrConfig
?:
AxiosRequestConfig
):
Promise
<
OAuthClient
>
=>
{
const
apiUrl
=
URL_GET_CLIENT
;
// console.log(`Fetching from ${apiUrl}`);
const
content
=
{
/* No content in request body */
};
return
this
.
_axios
.
request
({
...
xhrConfig
,
url
:
apiUrl
,
method
:
'
GET
'
,
...
content
,
}).
then
(({
data
})
=>
data
as
OAuthClient
);
}
}
export
default
ProfileService
;
workspaces/client/src/service/UserService.ts
View file @
8c3d8530
...
...
@@ -13,6 +13,7 @@ const URL_UPDATE_USER = '/api/v1/admin/user';
const
URL_CREATE_USER
=
'
/api/v1/admin/user
'
;
const
URL_ENABLE_USER
=
UrlTemplate
.
parse
(
'
/api/v1/admin/user/{id}/enable
'
);
const
URL_DISABLE_USER
=
UrlTemplate
.
parse
(
'
/api/v1/admin/user/{id}/disable
'
);
const
URL_SET_PASSWORD
=
UrlTemplate
.
parse
(
`/api/v1/admin/user/{id}/password`
);
const
URL_GET_GROUP
=
UrlTemplate
.
parse
(
'
/api/v1/admin/group/{id}
'
);
const
URL_REMOVE_GROUP
=
UrlTemplate
.
parse
(
'
/api/v1/admin/group/{id}
'
);
...
...
@@ -174,6 +175,30 @@ export default class UserService {
}).
then
(({
data
})
=>
data
as
SysUser
);
};
/**
* setPassword at /api/v1/admin/user/{id}/password
*
* @param id
* @param pass
* @param xhrConfig additional xhr config
*/
public
setPassword
=
(
id
:
number
,
pass
:
string
,
xhrConfig
?:
AxiosRequestConfig
):
Promise
<
boolean
>
=>
{
const
qs
=
QueryString
.
stringify
({
pass
:
pass
||
undefined
,
},
{});
const
apiUrl
=
URL_SET_PASSWORD
.
expand
({
id
})
+
(
qs
?
`?
${
qs
}
`
:
''
);
// console.log(`Fetching from ${apiUrl}`);
const
content
=
{
/* No content in request body */
};
return
this
.
_axios
.
request
({
...
xhrConfig
,
url
:
apiUrl
,
method
:
'
POST
'
,
...
content
,
}).
then
(({
data
})
=>
data
as
boolean
);
}
/**
* get at /api/v1/admin/group/{id}
*
...
...
workspaces/client/src/service/index.ts
View file @
8c3d8530
import
CooperatorService
from
'
@gringlobal-ce/client/service/CooperatorService
'
;
import
UserService
from
'
@gringlobal-ce/client/service/UserService
'
;
import
LoginService
from
'
@gringlobal-ce/client/service/LoginService
'
;
import
ProfileService
from
'
@gringlobal-ce/client/service/ProfileService
'
;
import
TaxonomyService
from
'
@gringlobal-ce/client/service/TaxonomyService
'
;
import
AccessionService
from
'
@gringlobal-ce/client/service/AccessionService
'
;
import
InventoryService
from
'
@gringlobal-ce/client/service/InventoryService
'
;
...
...
@@ -102,6 +103,7 @@ const ConfiguredTaxonomyService = new TaxonomyService(serviceAxios);
const
ConfiguredCooperatorService
=
new
CooperatorService
(
serviceAxios
);
const
ConfiguredUserService
=
new
UserService
(
serviceAxios
);
const
ConfiguredLoginService
=
new
LoginService
(
serviceAxios
);
const
ConfiguredProfileService
=
new
ProfileService
(
serviceAxios
);
const
ConfiguredAccessionService
=
new
AccessionService
(
serviceAxios
);
const
ConfiguredInventoryService
=
new
InventoryService
(
serviceAxios
);
...
...
@@ -132,6 +134,7 @@ export {
ConfiguredCooperatorService
as
CooperatorService
,
ConfiguredUserService
as
UserService
,
ConfiguredLoginService
as
LoginService
,
ConfiguredProfileService
as
ProfileService
,
ConfiguredTaxonomyService
as
TaxonomyService
,
ConfiguredAccessionService
as
AccessionService
,
ConfiguredInventoryService
as
InventoryService
,
...
...
workspaces/client/src/translations.json
View file @
8c3d8530
...
...
@@ -8,6 +8,7 @@
"maxCharacters"
:
"Must be {{count, number}} characters or less"
,
"invalidEmail"
:
"Invalid email address"
,
"minValue"
:
"Should be greater or equal to {{count, min}}"
,
"invalidDoi"
:
"Invalid DOI. Must start with 10.[digits]/[something]"
"invalidDoi"
:
"Invalid DOI. Must start with 10.[digits]/[something]"
,
"invalidNewPassword"
:
"New passwords doesn`t match"
}
}
workspaces/client/src/utilities/validators.ts
View file @
8c3d8530
export
const
composeValidators
=
(...
validators
)
=>
(
value
)
=>
validators
.
reduce
((
error
,
validator
)
=>
error
||
validator
(
value
),
undefined
);
export
const
composeValidators
=
(...
validators
)
=>
(
value
,
allValues
)
=>
validators
.
reduce
((
error
,
validator
)
=>
error
||
validator
(
value
,
allValues
),
undefined
);
export
const
required
=
(
value
,
allValues
,
meta
)
=>
!
value
?
'
client:validations.required
'
:
undefined
;
...
...
@@ -16,3 +16,5 @@ export const emailAddress = (value) => !value || value.match(/^(?:[A-Za-z0-9!#$%
export
const
minValue
=
(
min
)
=>
(
value
)
=>
(
value
===
undefined
||
isNaN
(
value
)
||
value
>=
min
)
?
undefined
:
[
'
client:validations.minValue
'
,
{
count
:
min
}
];
// `Should be greater than ${min}`;
export
const
validDoi
=
(
value
)
=>
!
value
||
value
.
match
(
/^10
\.\d
+
\/
.+/gi
)
?
undefined
:
'
client:validations.invalidDoi
'
;
export
const
newPasswordsMatch
=
(
value
,
allValues
)
=>
value
&&
allValues
?.
newPassword
&&
value
!==
allValues
.
newPassword
?
'
client:validations.invalidNewPassword
'
:
undefined
;
workspaces/ui-express/locales/en/express.json
View file @
8c3d8530
...
...
@@ -8,6 +8,7 @@
"users"
:
"Users"
,
"login"
:
"Login"
,
"logout"
:
"Logout"
,
"changePassword"
:
"Change password"
,
"accessions"
:
"Accessions"
,
"inventory"
:
"Inventory"
,
"inventorygroup"
:
"Groups"
,
...
...
@@ -873,6 +874,20 @@
"placeholder"
:
"Your password"
}
}
},
"c"
:
{
"changePassword"
:
{
"title"
:
"Change password"
,
"currentPassword"
:
{
"placeholder"
:
"Your current password"
},
"newPassword"
:
{
"placeholder"
:
"Enter new password"
},
"newPasswordRepeat"
:
{
"placeholder"
:
"Repeat new password"
}
}
}
},
"admin"
:
{
...
...
@@ -886,7 +901,9 @@
"profile"
:
"{{username}} profile information"
,
"enable"
:
"Enable"
,
"disable"
:
"Disable"
,
"assign"
:
"Assign groups"
"setPassword"
:
"Set password"
,
"assign"
:
"Assign groups"
,
"passwordUpdated"
:
"Password successfully updated!"
},
"edit"
:
{
"title"
:
"Update user profile"
,
...
...
@@ -921,6 +938,9 @@
},
"common"
:
{
"password"
:
"Password"
,
"currentPassword"
:
"Current password"
,
"newPassword"
:
"New password"
,
"newPasswordRepeat"
:
"Repeat new password"
,
"oAuth"
:
{
"authorities"
:
{
"CLIENT"
:
"Client"
,
...
...
workspaces/ui-express/src/_layout/PublicLayout.tsx
View file @
8c3d8530
...
...
@@ -9,10 +9,21 @@ import { UserRole } from '@gringlobal-ce/client/model/gringlobal/SysUser';
import
{
bindActionCreators
,
compose
}
from
'
redux
'
;
import
{
logoutUserAction
}
from
'
@gringlobal-ce/client/action/login
'
;
import
{
UISecurity
as
P
}
from
'
@gringlobal-ce/client/service
'
;
import
ChangePasswordForm
from
'
user/ui/c/form/ChangePasswordForm
'
;
import
{
changePasswordAction
,
clearChangePasswordErrorAction
}
from
'
@gringlobal-ce/client/action/profile
'
;
function
PublicMenu
(
props
:
{
login
:
any
,
logoutUserAction
:
()
=>
void
;
}):
JSX
.
Element
{
function
PublicMenu
(
props
:
{
login
:
any
,
profile
:
any
,
logoutUserAction
:
()
=>
void
,
changePasswordAction
:
(
data
)
=>
void
,
clearChangePasswordErrorAction
:
()
=>
void
}):
JSX
.
Element
{
const
{
t
}
=
useTranslation
();
const
[
changePasswordDialogIsOpen
,
setChangePasswordDialogIsOpen
]
=
React
.
useState
(
false
);
const
openChangePasswordDialog
=
()
=>
{
setChangePasswordDialogIsOpen
(
true
)
}
const
closeChangePasswordDialog
=
()
=>
{
setChangePasswordDialogIsOpen
(
false
)
}
return
(
<
List
>
...
...
@@ -124,22 +135,43 @@ function PublicMenu(props: { login: any, logoutUserAction: () => void; }): JSX.E
</
ListItem
>
</
Link
>
:
<
Link
to
=
"/"
>
<
ListItem
button
onClick
=
{
props
.
logoutUserAction
}
>
<
ListItemText
primary
=
{
t
(
'
navigation.logout
'
)
}
/>
<>
<
Link
to
=
"/"
>
<
ListItem
button
onClick
=
{
props
.
logoutUserAction
}
>
<
ListItemText
primary
=
{
t
(
'
navigation.logout
'
)
}
/>
</
ListItem
>
</
Link
>
<
ListItem
button
onClick
=
{
openChangePasswordDialog
}
>
<
ListItemText
primary
=
{
t
(
'
navigation.changePassword
'
)
}
/>
</
ListItem
>
</
Link
>
</>
}
<
Authorize
roles
=
{
[
UserRole
.
USER
]
}
>
<
ChangePasswordForm
isOpen
=
{
changePasswordDialogIsOpen
}
onClose
=
{
closeChangePasswordDialog
}
onSubmit
=
{
(
data
)
=>
props
.
changePasswordAction
({...
data
,
closeDialog
:
closeChangePasswordDialog
})
}
formId
=
'change-password-form'
title
=
{
t
(
'
user.public.c.changePassword.title
'
)
}
size
=
'sm'
error
=
{
props
.
profile
?.
error
}
resetError
=
{
props
.
clearChangePasswordErrorAction
}
/>
</
Authorize
>
</
List
>
);
}
const
mapStateToProps
=
(
state
)
=>
({
login
:
state
.
login
,
profile
:
state
.
profile
});
const
mapDispatchToProps
=
(
dispatch
)
=>
bindActionCreators
({
logoutUserAction
,
changePasswordAction
,
clearChangePasswordErrorAction
,
},
dispatch
);
const
composedPublicLayout
=
compose
(
connect
(
mapStateToProps
,
mapDispatchToProps
))(
PublicMenu
)
...
...
workspaces/ui-express/src/translations.json
View file @
8c3d8530
...
...
@@ -8,6 +8,7 @@
"users"
:
"Users"
,
"login"
:
"Login"
,
"logout"
:
"Logout"
,
"changePassword"
:
"Change password"
,
"accessions"
:
"Accessions"
,
"inventory"
:
"Inventory"
,
"inventorygroup"
:
"Groups"
,
...
...
workspaces/ui-express/src/user/translations.json
View file @
8c3d8530
...
...
@@ -12,6 +12,20 @@
"placeholder"
:
"Your password"
}
}
},
"c"
:
{
"changePassword"
:
{
"title"
:
"Change password"
,
"currentPassword"
:
{
"placeholder"
:
"Your current password"
},
"newPassword"
:
{
"placeholder"
:
"Enter new password"
},
"newPasswordRepeat"
:
{
"placeholder"
:
"Repeat new password"
}
}
}
},
"admin"
:
{
...
...
@@ -25,7 +39,9 @@
"profile"
:
"{{username}} profile information"
,
"enable"
:
"Enable"
,
"disable"
:
"Disable"
,
"assign"
:
"Assign groups"
"setPassword"
:
"Set password"
,
"assign"
:
"Assign groups"
,
"passwordUpdated"
:
"Password successfully updated!"
},
"edit"
:
{
"title"
:
"Update user profile"
,
...
...
@@ -60,6 +76,9 @@
},
"common"
:
{
"password"
:
"Password"
,
"currentPassword"
:
"Current password"
,
"newPassword"
:
"New password"
,
"newPasswordRepeat"
:
"Repeat new password"
,
"oAuth"
:
{
"authorities"
:
{
"CLIENT"
:
"Client"
,
...
...
workspaces/ui-express/src/user/ui/admin/BrowsePage.tsx
View file @
8c3d8530
...
...
@@ -50,10 +50,10 @@ class UserBrowsePage extends React.Component<IBrowsePageProps> {
console
.
log
(
`Column
${
toggledColumn
}
was toggled. Have
${
selectedColumns
}
`
);
};
private
handleSubmit
=
(
userData
)
=>
{
private
handleSubmit
=
(
{
cooperator
,
username
,
password
}
)
=>
{
const
{
receiveUser
,
navigateTo
}
=
this
.
props
;
this
.
setState
({
error
:
null
});
UserService
.
upd
ate
(
user
Data
)
UserService
.
cre
ate
(
user
name
,
password
,
cooperator
?.
id
)
.
then
((
user
:
User
)
=>
{
this
.
closeUserDialog
();
receiveUser
(
user
);
...
...
workspaces/ui-express/src/user/ui/admin/DetailsPage.tsx
View file @
8c3d8530
...
...
@@ -38,6 +38,7 @@ import AssignSysGroupsDialog from './c/AssignSysGroupsDialog';
import
ContentHeader
from
'
@gringlobal-ce/client/ui/common/heading/ContentHeader
'
;
import
{
GridContainer
,
GridItem
}
from
'
@gringlobal-ce/client/ui/common/grid
'
;
import
UserForm
from
'
user/ui/admin/c/UserForm
'
;
import
ChangePasswordForm
from
'
user/ui/c/form/ChangePasswordForm
'
;
const
styles
=
(
theme
)
=>
createStyles
({
action
:
{
...
...
@@ -77,6 +78,7 @@ class UserDetailsPage extends React.Component<IUserDetailsPage> {
groupsDialogIsOpen
:
false
,
userDialogIsOpen
:
false
,
submitError
:
null
,
changePasswordDialogIsOpen
:
false
,
};
public
componentDidMount
()
{
...
...
@@ -133,6 +135,19 @@ class UserDetailsPage extends React.Component<IUserDetailsPage> {
});
};
private
handleSetPassword
=
({
newPassword
})
=>
{
const
{
userCall
,
showSnackbar
,
t
}
=
this
.
props
;
this
.
resetError
();
UserService
.
setPassword
(
userCall
.
data
.
id
,
newPassword
)
.
then
(()
=>
{
this
.
closeChangePasswordDialog
();
showSnackbar
(
t
(
'
user.admin.p.details.passwordUpdated
'
))
})
.
catch
((
e
)
=>
{
this
.
setState
({
submitError
:
e
.
data
&&
e
.
data
.
error
||
e
.
toString
()
});
});
};
private
resetError
=
()
=>
{
return
this
.
setState
({
submitError
:
null
});
}
...
...
@@ -145,9 +160,13 @@ class UserDetailsPage extends React.Component<IUserDetailsPage> {
private
closeGroupsDialog
=
()
=>
this
.
setState
({
groupsDialogIsOpen
:
false
});
private
openChangePasswordDialog
=
()
=>
this
.
setState
({
changePasswordDialogIsOpen
:
true
});
private
closeChangePasswordDialog
=
()
=>
this
.
setState
({
changePasswordDialogIsOpen
:
false
});
public
render
()
{
const
{
userCall
,
t
,
classes
}
=
this
.
props
;
const
{
groupsDialogIsOpen
,
userDialogIsOpen
,
submitError
}
=
this
.
state
;
const
{
groupsDialogIsOpen
,
userDialogIsOpen
,
submitError
,
changePasswordDialogIsOpen
}
=
this
.
state
;
if
(
!
userCall
)
{
return
null
;
...
...
@@ -211,6 +230,11 @@ class UserDetailsPage extends React.Component<IUserDetailsPage> {
<
CardActions
>
<
ButtonBar
>
{
YesNoToBoolean
(
user
.
isEnabled
)
?
[
<
ActionButton
key
=
"setPassword"
title
=
{
t
(
'
user.admin.p.details.setPassword
'
)
}
action
=
{
this
.
openChangePasswordDialog
}
/>,
<
ActionButton
key
=
"disable"
title
=
{
t
(
'
user.admin.p.details.disable
'
)
}
...
...
@@ -284,6 +308,17 @@ class UserDetailsPage extends React.Component<IUserDetailsPage> {
error
=
{
submitError
}
resetError
=
{
this
.
resetError
}
/>
<
ChangePasswordForm
isOpen
=
{
changePasswordDialogIsOpen
}
onClose
=
{
this
.
closeChangePasswordDialog
}
onSubmit
=
{
this
.
handleSetPassword
}
formId
=
'change-password-form'
title
=
{
t
(
'
user.public.c.changePassword.title
'
)
}
size
=
'sm'
error
=
{
submitError
}
resetError
=
{
this
.
resetError
}
setPassword
/>
</
div
>
</>
);
...
...
workspaces/ui-express/src/user/ui/c/form/ChangePasswordForm.tsx
0 → 100644
View file @
8c3d8530
import
*
as
React
from
'
react
'
;
import
{
Form
,
Field
,
FormProps
,
FormRenderProps
}
from
'
react-final-form
'
;
import
{
withTranslation
,
WithTranslation
}
from
'
react-i18next
'
;
// UI
import
{
TextField
}
from
'
@gringlobal-ce/client/ui/common/form/TextField
'
;
import
{
Grid
}
from
'
@material-ui/core
'
;
import
{
withStyles
,
WithStyles
}
from
'
@material-ui/core/styles
'
;
import
withDialog
from
'
ui/common/withDialog
'
;
// Utils
import
{
composeValidators
,
newPasswordsMatch
,
required
}
from
'
@gringlobal-ce/client/utilities/validators
'
;
const
styles
=
(
theme
)
=>
({
textField
:
{
},
});
const
ChangePasswordForm
=
({
t
,
onSubmit
,
initialValues
,
classes
,
setPassword
,
error
}:
FormProps
&
WithTranslation
&
WithStyles
)
=>
<
Form
initialValues
=
{
initialValues
}
onSubmit
=
{
onSubmit
}
>
{
(
props
:
FormRenderProps
&
WithStyles
)
=>
(
<
form
onSubmit
=
{
props
.
handleSubmit
}
id
=
"change-password-form"
>
<
Grid
container
spacing
=
{
4
}
>
{
!
setPassword
&&
<
Grid
item
xs
=
{
12
}
>
<
Field
label
=
{
t
(
'
user.common.currentPassword
'
)
}
helperText
=
{
t
(
'
user.public.c.changePassword.currentPassword.placeholder
'
)
}
name
=
"currentPassword"
type
=
"password"
component
=
{
TextField
}
required
validate
=
{
required
}
/>
</
Grid
>
}
<
Grid
item
xs
=
{
12
}
>
<
Field
label
=
{
t
(
'
user.common.newPassword
'
)
}
helperText
=
{
t
(
'
user.public.c.changePassword.newPassword.placeholder
'
)
}
name
=
"newPassword"
type
=
"password"