Wizard güncellemesi
This commit is contained in:
parent
4099ef9079
commit
877d0e7397
2 changed files with 422 additions and 371 deletions
|
|
@ -879,21 +879,11 @@
|
|||
"RequiredPermissionName": "App.Contact",
|
||||
"IsDisabled": false
|
||||
},
|
||||
{
|
||||
"ParentCode": "App.Administration",
|
||||
"Code": "App.Listforms.Wizard",
|
||||
"DisplayName": "App.Listforms.Wizard",
|
||||
"Order": 5,
|
||||
"Url": "/admin/listform/wizard",
|
||||
"Icon": "FcFlashAuto",
|
||||
"RequiredPermissionName": "App.Listforms.Wizard",
|
||||
"IsDisabled": false
|
||||
},
|
||||
{
|
||||
"ParentCode": "App.Administration",
|
||||
"Code": "App.Routes",
|
||||
"DisplayName": "App.Routes",
|
||||
"Order": 6,
|
||||
"Order": 5,
|
||||
"Url": "/admin/list/App.Routes",
|
||||
"Icon": "FaSynagogue",
|
||||
"RequiredPermissionName": "App.Routes",
|
||||
|
|
@ -903,7 +893,7 @@
|
|||
"ParentCode": "App.Administration",
|
||||
"Code": "App.Menus",
|
||||
"DisplayName": "App.Menus",
|
||||
"Order": 7,
|
||||
"Order": 6,
|
||||
"Url": null,
|
||||
"Icon": "FaSchlix",
|
||||
"RequiredPermissionName": null,
|
||||
|
|
@ -933,7 +923,7 @@
|
|||
"ParentCode": "App.Administration",
|
||||
"Code": "App.Files",
|
||||
"DisplayName": "App.Files",
|
||||
"Order": 8,
|
||||
"Order": 7,
|
||||
"Url": "/admin/files",
|
||||
"Icon": "FcFolder",
|
||||
"RequiredPermissionName": "App.Files",
|
||||
|
|
@ -943,7 +933,7 @@
|
|||
"ParentCode": "App.Administration",
|
||||
"Code": "App.Reports.Management",
|
||||
"DisplayName": "App.Reports.Management",
|
||||
"Order": 9,
|
||||
"Order": 8,
|
||||
"Url": null,
|
||||
"Icon": "FcDocument",
|
||||
"RequiredPermissionName": null,
|
||||
|
|
@ -973,7 +963,7 @@
|
|||
"ParentCode": "App.Administration",
|
||||
"Code": "App.DeveloperKit",
|
||||
"DisplayName": "App.DeveloperKit",
|
||||
"Order": 10,
|
||||
"Order": 9,
|
||||
"Url": null,
|
||||
"Icon": "FcAndroidOs",
|
||||
"RequiredPermissionName": null,
|
||||
|
|
@ -1059,6 +1049,16 @@
|
|||
"RequiredPermissionName": "App.SqlQueryManager",
|
||||
"IsDisabled": false
|
||||
},
|
||||
{
|
||||
"ParentCode": "App.Administration",
|
||||
"Code": "App.Listforms.Wizard",
|
||||
"DisplayName": "App.Listforms.Wizard",
|
||||
"Order": 10,
|
||||
"Url": "/admin/listform/wizard",
|
||||
"Icon": "FcFlashAuto",
|
||||
"RequiredPermissionName": "App.Listforms.Wizard",
|
||||
"IsDisabled": false
|
||||
},
|
||||
{
|
||||
"ParentCode": "App.Administration",
|
||||
"Code": "App.Forum",
|
||||
|
|
|
|||
|
|
@ -6,14 +6,15 @@ import {
|
|||
Input,
|
||||
Notification,
|
||||
Select,
|
||||
Steps,
|
||||
toast,
|
||||
} from '@/components/ui'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import { ListFormWizardDto } from '@/proxy/admin/list-form/models'
|
||||
import { SelectBoxOption } from '@/types/shared'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Field, FieldProps, Form, Formik, FormikProps } from 'formik'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import CreatableSelect from 'react-select/creatable'
|
||||
|
|
@ -47,19 +48,22 @@ const initialValues: ListFormWizardDto = {
|
|||
keyFieldDbSourceType: DbTypeEnum.Int32, // Select: Enum dbSourceTypeOptions
|
||||
}
|
||||
|
||||
const listFormValidationSchema = Yup.object().shape({
|
||||
const step1ValidationSchema = Yup.object().shape({
|
||||
listFormCode: Yup.string().required(),
|
||||
permissionGroupName: Yup.string().required(),
|
||||
menuParentCode: Yup.string().required(),
|
||||
menuIcon: Yup.string(),
|
||||
languageTextMenuEn: Yup.string(),
|
||||
languageTextMenuTr: Yup.string(),
|
||||
languageTextMenuParentEn: Yup.string(),
|
||||
languageTextMenuParentTr: Yup.string(),
|
||||
})
|
||||
|
||||
const step2ValidationSchema = Yup.object().shape({
|
||||
languageTextTitleEn: Yup.string(),
|
||||
languageTextTitleTr: Yup.string(),
|
||||
languageTextDescEn: Yup.string(),
|
||||
languageTextDescTr: Yup.string(),
|
||||
languageTextMenuParentEn: Yup.string(),
|
||||
languageTextMenuParentTr: Yup.string(),
|
||||
permissionGroupName: Yup.string().required(),
|
||||
menuParentCode: Yup.string().required(),
|
||||
menuIcon: Yup.string(),
|
||||
dataSourceCode: Yup.string(),
|
||||
dataSourceConnectionString: Yup.string(),
|
||||
selectCommandType: Yup.string().required(),
|
||||
|
|
@ -68,8 +72,12 @@ const listFormValidationSchema = Yup.object().shape({
|
|||
keyFieldDbSourceType: Yup.string().required(),
|
||||
})
|
||||
|
||||
const listFormValidationSchema = step1ValidationSchema.concat(step2ValidationSchema)
|
||||
|
||||
const Wizard = () => {
|
||||
const { translate } = useLocalization()
|
||||
const [currentStep, setCurrentStep] = useState(0)
|
||||
|
||||
const [isLoadingDataSource, setIsLoadingDataSource] = useState(false)
|
||||
const [dataSourceList, setDataSourceList] = useState<SelectBoxOption[]>([])
|
||||
const [isDataSourceNew, setIsDataSourceNew] = useState(false)
|
||||
|
|
@ -106,7 +114,6 @@ const Wizard = () => {
|
|||
|
||||
const [isLoadingPermissionGroup, setIsLoadingPermissionGroup] = useState(false)
|
||||
const [permissionGroupList, setPermissionGroupList] = useState<SelectBoxOption[]>([])
|
||||
const [isPermissionGroupNew, setIsPermissionGroupNew] = useState(false)
|
||||
const getPermissionGroupList = async () => {
|
||||
setIsLoadingPermissionGroup(true)
|
||||
const response = await getPermissions('R', '')
|
||||
|
|
@ -128,6 +135,27 @@ const Wizard = () => {
|
|||
}, [])
|
||||
|
||||
const navigate = useNavigate()
|
||||
const formikRef = useRef<FormikProps<ListFormWizardDto>>(null)
|
||||
|
||||
const handleNext = async () => {
|
||||
if (!formikRef.current) return
|
||||
const errors = await formikRef.current.validateForm()
|
||||
const step1Fields = Object.keys(step1ValidationSchema.fields)
|
||||
const hasStep1Errors = step1Fields.some((f) => errors[f as keyof ListFormWizardDto])
|
||||
// Touch all step 1 fields so errors appear
|
||||
const touchedStep1 = step1Fields.reduce(
|
||||
(acc, key) => ({ ...acc, [key]: true }),
|
||||
{} as Record<string, boolean>,
|
||||
)
|
||||
formikRef.current.setTouched({ ...formikRef.current.touched, ...touchedStep1 })
|
||||
if (!hasStep1Errors) {
|
||||
setCurrentStep(1)
|
||||
}
|
||||
}
|
||||
|
||||
const handleBack = () => {
|
||||
setCurrentStep(0)
|
||||
}
|
||||
|
||||
return (
|
||||
<Container>
|
||||
|
|
@ -137,8 +165,16 @@ const Wizard = () => {
|
|||
defaultTitle={APP_NAME}
|
||||
></Helmet>
|
||||
|
||||
<div className="mb-8">
|
||||
<Steps current={currentStep}>
|
||||
<Steps.Item title={translate('::ListForms.Wizard.BasicInfo') || 'Basic Info'} />
|
||||
<Steps.Item title={translate('::ListForms.Wizard.DataSettings') || 'Data Settings'} />
|
||||
</Steps>
|
||||
</div>
|
||||
|
||||
<div className="grid lg:grid-cols-2 xl:grid-cols-3">
|
||||
<Formik
|
||||
innerRef={formikRef}
|
||||
initialValues={{ ...initialValues }}
|
||||
validationSchema={listFormValidationSchema}
|
||||
onSubmit={async (values, { setSubmitting }) => {
|
||||
|
|
@ -172,6 +208,9 @@ const Wizard = () => {
|
|||
{({ touched, errors, isSubmitting, values }) => (
|
||||
<Form>
|
||||
<FormContainer size="sm">
|
||||
{/* ─── Step 1: Basic Info ─────────────────────────────── */}
|
||||
{currentStep === 0 && (
|
||||
<>
|
||||
<FormItem
|
||||
label="ListForm Code"
|
||||
invalid={errors.listFormCode && touched.listFormCode}
|
||||
|
|
@ -186,6 +225,7 @@ const Wizard = () => {
|
|||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="Permission Group Name"
|
||||
invalid={errors.permissionGroupName && touched.permissionGroupName}
|
||||
|
|
@ -204,7 +244,9 @@ const Wizard = () => {
|
|||
options={permissionGroupList}
|
||||
value={
|
||||
values.permissionGroupName
|
||||
? (menuList?.find((o) => o.value === values.permissionGroupName) ?? {
|
||||
? (permissionGroupList?.find(
|
||||
(o) => o.value === values.permissionGroupName,
|
||||
) ?? {
|
||||
label: values.permissionGroupName,
|
||||
value: values.permissionGroupName,
|
||||
})
|
||||
|
|
@ -212,14 +254,12 @@ const Wizard = () => {
|
|||
}
|
||||
onChange={(option) => {
|
||||
form.setFieldValue(field.name, option?.value)
|
||||
setIsPermissionGroupNew(
|
||||
!!option?.value && !menuList.some((a) => a.value === option?.value),
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</FormItem>
|
||||
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Menu Parent Code"
|
||||
|
|
@ -248,18 +288,19 @@ const Wizard = () => {
|
|||
onChange={(option) => {
|
||||
form.setFieldValue(field.name, option?.value)
|
||||
setIsMenuNew(
|
||||
!!option?.value && !menuList.some((a) => a.value === option?.value),
|
||||
!!option?.value &&
|
||||
!menuList.some((a) => a.value === option?.value),
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="Menu Icon"
|
||||
invalid={errors.menuIcon && touched.menuIcon}
|
||||
errorMessage={errors.menuIcon}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
|
|
@ -270,50 +311,145 @@ const Wizard = () => {
|
|||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
|
||||
{isMenuNew && (
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Parent Menu Code (En)"
|
||||
invalid={errors.languageTextMenuParentEn && touched.languageTextMenuParentEn}
|
||||
label="Parent Menu Text (En)"
|
||||
invalid={
|
||||
errors.languageTextMenuParentEn && touched.languageTextMenuParentEn
|
||||
}
|
||||
errorMessage={errors.languageTextMenuParentEn}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextMenuParentEn"
|
||||
placeholder="Parent Menu Code (En)"
|
||||
placeholder="Parent Menu Text (En)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="Parent Menu Code (Tr)"
|
||||
invalid={errors.languageTextMenuParentTr && touched.languageTextMenuParentTr}
|
||||
label="Parent Menu Text (Tr)"
|
||||
invalid={
|
||||
errors.languageTextMenuParentTr && touched.languageTextMenuParentTr
|
||||
}
|
||||
errorMessage={errors.languageTextMenuParentTr}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextMenuParentTr"
|
||||
placeholder="Parent Menu Code (Tr)"
|
||||
placeholder="Parent Menu Text (Tr)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Menu Text (En)"
|
||||
invalid={errors.languageTextMenuEn && touched.languageTextMenuEn}
|
||||
errorMessage={errors.languageTextMenuEn}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextMenuEn"
|
||||
placeholder="Menu Text (En)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="Menu Text (Tr)"
|
||||
invalid={errors.languageTextMenuTr && touched.languageTextMenuTr}
|
||||
errorMessage={errors.languageTextMenuTr}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextMenuTr"
|
||||
placeholder="Menu Text (Tr)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
|
||||
<Button block className="mt-4" variant="solid" type="button" onClick={handleNext}>
|
||||
{translate('::Next') || 'Next'}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* ─── Step 2: Data Settings ───────────────────────────── */}
|
||||
{currentStep === 1 && (
|
||||
<>
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Title (En)"
|
||||
invalid={errors.languageTextTitleEn && touched.languageTextTitleEn}
|
||||
errorMessage={errors.languageTextTitleEn}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextTitleEn"
|
||||
placeholder="Title (En)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="Title (Tr)"
|
||||
invalid={errors.languageTextTitleTr && touched.languageTextTitleTr}
|
||||
errorMessage={errors.languageTextTitleTr}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextTitleTr"
|
||||
placeholder="Title (Tr)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Description (En)"
|
||||
invalid={errors.languageTextDescEn && touched.languageTextDescEn}
|
||||
errorMessage={errors.languageTextDescEn}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextDescEn"
|
||||
placeholder="Description (En)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="Description (Tr)"
|
||||
invalid={errors.languageTextDescTr && touched.languageTextDescTr}
|
||||
errorMessage={errors.languageTextDescTr}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextDescTr"
|
||||
placeholder="Description (Tr)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Data Source Code"
|
||||
invalid={errors.dataSourceCode && touched.dataSourceCode}
|
||||
errorMessage={errors.dataSourceCode}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="dataSourceCode"
|
||||
placeholder="Data Source Code"
|
||||
>
|
||||
<Field type="text" autoComplete="off" name="dataSourceCode">
|
||||
{({ field, form }: FieldProps<string>) => (
|
||||
<Select
|
||||
componentAs={CreatableSelect}
|
||||
|
|
@ -325,7 +461,9 @@ const Wizard = () => {
|
|||
options={dataSourceList}
|
||||
value={
|
||||
values.dataSourceCode
|
||||
? (dataSourceList?.find((o) => o.value === values.dataSourceCode) ?? {
|
||||
? (dataSourceList?.find(
|
||||
(o) => o.value === values.dataSourceCode,
|
||||
) ?? {
|
||||
label: values.dataSourceCode,
|
||||
value: values.dataSourceCode,
|
||||
})
|
||||
|
|
@ -342,6 +480,7 @@ const Wizard = () => {
|
|||
)}
|
||||
</Field>
|
||||
</FormItem>
|
||||
|
||||
{isDataSourceNew && (
|
||||
<FormItem
|
||||
label="Connection String"
|
||||
|
|
@ -360,6 +499,7 @@ const Wizard = () => {
|
|||
</FormItem>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Select Command Type"
|
||||
|
|
@ -367,24 +507,21 @@ const Wizard = () => {
|
|||
errorMessage={errors.selectCommandType}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="selectCommandType"
|
||||
placeholder="Select Command Type"
|
||||
component={Input}
|
||||
>
|
||||
<Field type="text" autoComplete="off" name="selectCommandType">
|
||||
{({ field, form }: FieldProps<SelectCommandTypeEnum>) => (
|
||||
<Select
|
||||
field={field}
|
||||
form={form}
|
||||
options={selectCommandTypeOptions}
|
||||
value={selectCommandTypeOptions.find((o: any) => o.value === field.value)}
|
||||
value={selectCommandTypeOptions.find(
|
||||
(o: any) => o.value === field.value,
|
||||
)}
|
||||
onChange={(o) => form.setFieldValue(field.name, o?.value)}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="Select Command"
|
||||
invalid={errors.selectCommand && touched.selectCommand}
|
||||
|
|
@ -400,6 +537,7 @@ const Wizard = () => {
|
|||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Key Field Name"
|
||||
|
|
@ -415,19 +553,14 @@ const Wizard = () => {
|
|||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="Key Field Db Source Type"
|
||||
invalid={errors.keyFieldDbSourceType && touched.keyFieldDbSourceType}
|
||||
errorMessage={errors.keyFieldDbSourceType}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="keyFieldDbSourceType"
|
||||
placeholder="Key Field Db Source Type"
|
||||
component={Input}
|
||||
>
|
||||
<Field type="text" autoComplete="off" name="keyFieldDbSourceType">
|
||||
{({ field, form }: FieldProps<DbTypeEnum>) => (
|
||||
<Select
|
||||
field={field}
|
||||
|
|
@ -442,99 +575,17 @@ const Wizard = () => {
|
|||
</Field>
|
||||
</FormItem>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Menu Text (En)"
|
||||
invalid={errors.languageTextMenuEn && touched.languageTextMenuEn}
|
||||
errorMessage={errors.languageTextMenuEn}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextMenuEn"
|
||||
placeholder="Menu Text (En)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="Menu Text (Tr)"
|
||||
invalid={errors.languageTextMenuTr && touched.languageTextMenuTr}
|
||||
errorMessage={errors.languageTextMenuTr}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextMenuTr"
|
||||
placeholder="Menu Text (Tr)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Title (En)"
|
||||
invalid={errors.languageTextTitleEn && touched.languageTextTitleEn}
|
||||
errorMessage={errors.languageTextTitleEn}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextTitleEn"
|
||||
placeholder="Title (En)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="Title (Tr)"
|
||||
invalid={errors.languageTextTitleTr && touched.languageTextTitleTr}
|
||||
errorMessage={errors.languageTextTitleTr}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextTitleTr"
|
||||
placeholder="Title (Tr)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<FormItem
|
||||
label="Description (En)"
|
||||
invalid={errors.languageTextDescEn && touched.languageTextDescEn}
|
||||
errorMessage={errors.languageTextDescEn}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextDescEn"
|
||||
placeholder="Description (En)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="Description (Tr)"
|
||||
invalid={errors.languageTextDescTr && touched.languageTextDescTr}
|
||||
errorMessage={errors.languageTextDescTr}
|
||||
asterisk={true}
|
||||
>
|
||||
<Field
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
name="languageTextDescTr"
|
||||
placeholder="Description (Tr)"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
<Button block className="mt-4" variant="solid" loading={isSubmitting} type="submit">
|
||||
|
||||
<div className="flex gap-2 mt-4">
|
||||
<Button block variant="default" type="button" onClick={handleBack}>
|
||||
{translate('::Back') || 'Back'}
|
||||
</Button>
|
||||
<Button block variant="solid" loading={isSubmitting} type="submit">
|
||||
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</FormContainer>
|
||||
</Form>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Reference in a new issue