forked from ddrilling/asb_cloud_front
95 lines
3.4 KiB
TypeScript
Executable File
95 lines
3.4 KiB
TypeScript
Executable File
import { memo, useCallback, useMemo, useState } from 'react'
|
||
import { Rule } from 'antd/lib/form'
|
||
import { Form, Input, Modal, FormProps } from 'antd'
|
||
|
||
import { AuthService, UserDto } from '@api'
|
||
import { getUserId, getUserLogin } from '@utils/storage'
|
||
import { passwordRules, createPasswordRules } from '@utils/validationRules'
|
||
|
||
import LoaderPortal from './LoaderPortal'
|
||
import { invokeWebApiWrapperAsync } from './factory'
|
||
import { UserView } from './views'
|
||
|
||
const formLayout: FormProps = { labelCol: { span: 11 }, wrapperCol: { span: 16 } }
|
||
|
||
export type ChangePasswordProps = {
|
||
user?: UserDto
|
||
visible?: boolean
|
||
onCancel?: () => void
|
||
onOk?: () => void
|
||
}
|
||
|
||
const fieldRules = [...passwordRules, ...createPasswordRules]
|
||
|
||
const confirmPasswordRules: Rule[] = [({ getFieldValue }) => ({ validator(_, value: string) {
|
||
if (value !== getFieldValue('new-password'))
|
||
return Promise.reject('Пароли не совпадают!')
|
||
return Promise.resolve()
|
||
}})]
|
||
|
||
export const ChangePassword = memo<ChangePasswordProps>(({ user, visible, onCancel, onOk }) => {
|
||
const [showLoader, setShowLoader] = useState<boolean>(false)
|
||
const [isDisabled, setIsDisabled] = useState(true)
|
||
|
||
const userData = useMemo(() => user ?? { id: getUserId(), login: getUserLogin() } as UserDto, [user])
|
||
|
||
const [form] = Form.useForm()
|
||
|
||
const onFormChange = async () => await form.validateFields()
|
||
.then(() => setIsDisabled(false))
|
||
.catch(() => setIsDisabled(true))
|
||
|
||
const onModalCancel = () => {
|
||
form.resetFields()
|
||
onCancel?.()
|
||
}
|
||
|
||
const onFormFinish = useCallback((values: any) => invokeWebApiWrapperAsync(
|
||
async() => {
|
||
await AuthService.changePassword(userData.id ?? -1, `${values['new-password']}`)
|
||
onOk?.()
|
||
},
|
||
setShowLoader,
|
||
`Не удалось сменить пароль пользователя ${userData.login}`,
|
||
'Смена пароля пользователя'
|
||
), [userData, onOk])
|
||
|
||
return (
|
||
<Modal
|
||
centered
|
||
title={(
|
||
<>
|
||
Сменить пароль
|
||
{user && <> (<UserView user={user} />)</>}
|
||
</>
|
||
)}
|
||
visible={visible}
|
||
onCancel={onModalCancel}
|
||
onOk={() => form.submit()}
|
||
okText={'Сохранить'}
|
||
okButtonProps={{
|
||
disabled: isDisabled
|
||
}}
|
||
// getContainer={false} // Исправляет ошибку с формой, но портит вид модалки при вызове из user menu
|
||
// TODO: разобраться
|
||
>
|
||
<LoaderPortal show={showLoader}>
|
||
<Form
|
||
{...formLayout}
|
||
form={form}
|
||
name={'change-password'}
|
||
onFinish={onFormFinish}
|
||
onChange={onFormChange}
|
||
>
|
||
<Form.Item required rules={fieldRules} name={'new-password'} label={'Новый пароль'}>
|
||
<Input.Password />
|
||
</Form.Item>
|
||
<Form.Item required name={'confirm-password'} rules={confirmPasswordRules} label={'Подтверждение пароля'}>
|
||
<Input.Password />
|
||
</Form.Item>
|
||
</Form>
|
||
</LoaderPortal>
|
||
</Modal>
|
||
)
|
||
})
|