/
githubmirror
/
gitness
Обзор
Документация
Войти
/
githubmirror
/
gitness
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
web/src/components/UserManagementFlows/AddUserModal.tsx
249 строк
8 KB
Johannes Batzill
[OPEN-SOURCE] Prepare Repository (#605)
24 сен 2023, 10:33
24 сен 2023, 10:33
a83cd21
Код
Авторство
О чём код?
/* * Copyright 2023 Harness, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import React, { useState } from 'react' import { Button, ButtonVariation, Container, Dialog, FlexExpander, FormikForm, FormInput, Layout, Text, useToaster } from '@harnessio/uicore' import { Icon } from '@harnessio/icons' import { Color, FontVariation } from '@harnessio/design-system' import { Formik, FormikHelpers, useFormikContext } from 'formik' import { get } from 'lodash-es' import { Else, Match, Render, Truthy } from 'react-jsx-match' import * as Yup from 'yup' import { useModalHook } from 'hooks/useModalHook' import { useStrings } from 'framework/strings' import { OpenapiAdminUsersCreateRequest, TypesUser, useAdminCreateUser, useAdminUpdateUser } from 'services/code' import { generateAlphaNumericHash, getErrorMessage, REGEX_VALID_REPO_NAME } from 'utils/Utils' import { CodeIcon } from 'utils/GitUtils' import { CopyButton } from 'components/CopyButton/CopyButton' import css from './UserManagementFlows.module.scss' const useAddUserModal = ({ onClose }: { onClose: () => Promise<void> }) => { const { getString } = useStrings() const { showSuccess, showError } = useToaster() const [isEditMode, setIsEditMode] = useState(false) const [userDetails, setUserDetails] = useState<TypesUser>() const [isUserCreated, setIsUserCreated] = useState(false) const { mutate: createUser } = useAdminCreateUser({}) const { mutate: updateUser } = useAdminUpdateUser({ user_uid: userDetails?.uid || '' }) const onSubmit = async (values: TypesUser, formikHelpers: FormikHelpers<TypesUser>) => { try { const mutate = isEditMode ? updateUser : createUser let payload: OpenapiAdminUsersCreateRequest = { ...values } if (!payload.display_name) { payload.display_name = payload.uid formikHelpers.setFieldValue('display_name', payload.uid) } if (!isEditMode) { const password = generateAlphaNumericHash(10) formikHelpers.setFieldValue('password', password) payload = { ...payload, password } setIsUserCreated(true) } await mutate(payload) if (isEditMode) { showSuccess(getString('newUserModal.userUpdated')) hideModal() onClose() } else { showSuccess(getString('newUserModal.userCreated')) } } catch (error) { showError(getErrorMessage(error)) } } const onModalClose = () => { hideModal() onClose() setIsUserCreated(false) } const [openModal, hideModal] = useModalHook( () => ( <Dialog isOpen enforceFocus={false} onClose={onModalClose} style={{ height: isEditMode ? 420 : 530 }} title={isEditMode ? getString('updateUser') : getString('createNewUser')} chidrenClassName={css.dialogCtn}> <Formik<OpenapiAdminUsersCreateRequest> validationSchema={Yup.object().shape({ uid: Yup.string() .required(getString('validation.uidRequired')) .matches(REGEX_VALID_REPO_NAME, getString('validation.uidInvalid')), email: Yup.string() .required(getString('validation.emailRequired')) .email(getString('validation.emailInvalid')), display_name: Yup.string() })} initialValues={{ uid: userDetails?.uid || '', display_name: userDetails?.display_name || '', email: userDetails?.email || '' }} onSubmit={onSubmit}> {formikProps => { return ( <FormikForm className={css.formikForm}> <FormInputWithCopyButton name="uid" placeholder={getString('newUserModal.uidPlaceholder')} label={ <Layout.Horizontal style={{ alignItems: 'center' }} spacing="small"> <Text color={Color.GREY_600} font={{ variation: FontVariation.BODY2 }}> {getString('userId')} </Text> <Render when={!isEditMode}> <Text icon="tooltip-icon" iconProps={{ size: 12, color: Color.PRIMARY_7 }} font={{ variation: FontVariation.BODY2 }} color={Color.PRIMARY_7}> {getString('newUserModal.uidWarning')} </Text> </Render> </Layout.Horizontal> } disabled={isEditMode || isUserCreated} /> <FormInputWithCopyButton name="email" label={getString('email')} placeholder={getString('newUserModal.emailPlaceholder')} disabled={isUserCreated} /> <FormInputWithCopyButton name="display_name" label={getString('displayName')} placeholder={getString('newUserModal.displayNamePlaceholder')} disabled={isUserCreated} isOptional /> <Render when={isUserCreated}> <GeneratedPassword password={formikProps.values.password || ''} /> </Render> <FlexExpander /> <Container> <Match expr={isUserCreated}> <Truthy> <Button text={getString('close')} variation={ButtonVariation.TERTIARY} onClick={onModalClose} /> </Truthy> <Else> <Button type="submit" text={isEditMode ? getString('save') : getString('createUser')} variation={ButtonVariation.PRIMARY} /> </Else> </Match> </Container> </FormikForm> ) }} </Formik> </Dialog> ), [isEditMode, onSubmit, userDetails, isUserCreated] ) return { openModal: ({ isEditing, userInfo }: { isEditing?: boolean; userInfo?: TypesUser }) => { openModal() setIsEditMode(Boolean(isEditing)) setUserDetails(userInfo) } } } export default useAddUserModal export const GeneratedPassword: React.FC<{ password: string }> = ({ password }) => { const { getString } = useStrings() return ( <Container background={Color.GREEN_50} className={css.passwordCtn}> <Text color={Color.GREY_600} font={{ variation: FontVariation.BODY2 }} margin={{ bottom: 'xsmall' }}> {getString('password')} </Text> <Layout.Horizontal style={{ alignItems: 'center' }} margin={{ bottom: 'small' }}> <Layout.Horizontal className={css.layout}> <Text className={css.text}>{password}</Text> <FlexExpander /> <CopyButton content={password} id={css.copyBtn} icon={CodeIcon.Copy} iconProps={{ size: 14 }} /> </Layout.Horizontal> <Icon name="command-artifact-check" color={Color.GREEN_700} padding={{ left: 'small' }} /> </Layout.Horizontal> <Text font={{ variation: FontVariation.TINY_SEMI }} color={Color.GREEN_900}> {getString('newUserModal.passwordHelptext')} </Text> </Container> ) } export const FormInputWithCopyButton: React.FC< React.ComponentProps<typeof FormInput.Text> & { copyContent?: string } > = props => { const { values } = useFormikContext() || {} return ( <FormInput.Text {...props} className={css.inputWrapper} inputGroup={{ ...props.inputGroup, rightElement: ( <Render when={props.disabled}> <CopyButton content={get(values, props.name, props.copyContent || '')} id={css.copyBtn} icon={CodeIcon.Copy} iconProps={{ size: 14 }} /> </Render> ) }} /> ) }