Enhance WizardView component by adding support for controlled current step management and optional sub-step descriptions using Timeline. Introduce new props for sidebar width, button visibility, and step skipping functionality, improving user interaction and flexibility in the wizard flow.
This commit is contained in:
parent
0c6fe5cbac
commit
9442c9105b
@ -9,13 +9,15 @@ import {
|
||||
Divider,
|
||||
Progress,
|
||||
Button,
|
||||
Dropdown
|
||||
Dropdown,
|
||||
Timeline
|
||||
} from 'antd'
|
||||
import NewObjectButtons from './NewObjectButtons'
|
||||
|
||||
const { Title } = Typography
|
||||
|
||||
const WizardView = ({
|
||||
sizeBarWidth = '160px',
|
||||
showSteps = true,
|
||||
steps,
|
||||
title = 'Wizard View',
|
||||
@ -27,22 +29,76 @@ const WizardView = ({
|
||||
progress = 0,
|
||||
actions = [],
|
||||
sideBarGrow = false,
|
||||
disabled = false
|
||||
disabled = false,
|
||||
showButtons = true,
|
||||
showTitle = true,
|
||||
currentStep: controlledCurrentStep,
|
||||
currentSubStep = 0,
|
||||
onStepChange,
|
||||
showSkipButton = false,
|
||||
onSkip = () => {}
|
||||
}) => {
|
||||
const [currentStep, setCurrentStep] = useState(0)
|
||||
const [internalCurrentStep, setInternalCurrentStep] = useState(0)
|
||||
const currentStep = controlledCurrentStep ?? internalCurrentStep
|
||||
const isMobile = useMediaQuery({ maxWidth: 768 })
|
||||
|
||||
const setCurrentStep = (step) => {
|
||||
if (controlledCurrentStep === undefined) {
|
||||
setInternalCurrentStep(step)
|
||||
}
|
||||
onStepChange?.(step)
|
||||
}
|
||||
|
||||
return (
|
||||
<Flex gap='middle' style={{ width: '100%' }}>
|
||||
{!isMobile && showSteps == true ? (
|
||||
sideBar != null ? (
|
||||
sideBar
|
||||
) : (
|
||||
<div style={{ minWidth: sideBarGrow == true ? '100%' : '160px' }}>
|
||||
<div
|
||||
style={{ minWidth: sideBarGrow == true ? '100%' : sizeBarWidth }}
|
||||
>
|
||||
<Steps
|
||||
current={currentStep}
|
||||
items={steps.map((step, index) => ({
|
||||
items={steps.map(({ subSteps, ...step }, index) => ({
|
||||
...step,
|
||||
description: subSteps ? (
|
||||
<Timeline
|
||||
className='subSteps'
|
||||
items={subSteps.map((subStep, subStepIndex) => {
|
||||
const complete =
|
||||
index < currentStep ||
|
||||
(index === currentStep && subStepIndex < currentSubStep)
|
||||
const current =
|
||||
index === currentStep && subStepIndex === currentSubStep
|
||||
|
||||
const disabled = index < currentStep
|
||||
return {
|
||||
...subStep,
|
||||
children: subStep.title,
|
||||
dot: complete ? (
|
||||
<div
|
||||
className={`subSteps-dot ${disabled ? 'subSteps-dot-disabled' : ''}`}
|
||||
>
|
||||
<CheckIcon
|
||||
style={{
|
||||
fontSize: '5px',
|
||||
marginTop: '0px',
|
||||
marginRight: '0px',
|
||||
color: disabled
|
||||
? 'var(--color-primary)'
|
||||
: 'var(--layout-modal-bg)'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : undefined,
|
||||
color: complete ? 'blue' : current ? 'blue' : 'gray'
|
||||
}
|
||||
})}
|
||||
/>
|
||||
) : (
|
||||
step.description
|
||||
),
|
||||
icon:
|
||||
index < currentStep ? (
|
||||
<div className='ant-steps-item-icon'>
|
||||
@ -76,62 +132,83 @@ const WizardView = ({
|
||||
}
|
||||
>
|
||||
<Flex vertical gap='middle' style={{ flexGrow: 1, width: '100%' }}>
|
||||
<Title level={2} style={{ margin: '0 0 8px 0', lineHeight: 0.7 }}>
|
||||
{title}
|
||||
</Title>
|
||||
{showTitle ? (
|
||||
<Title level={2} style={{ margin: '0 0 8px 0', lineHeight: 0.7 }}>
|
||||
{title}
|
||||
</Title>
|
||||
) : null}
|
||||
<div style={{ minHeight: '260px', marginBottom: 4, width: '100%' }}>
|
||||
{steps[currentStep].content}
|
||||
</div>
|
||||
</Flex>
|
||||
<Flex gap={'middle'} align='center' justify='end'>
|
||||
{progress > 0 ? (
|
||||
<Progress
|
||||
style={{ maxWidth: '160px' }}
|
||||
showInfo={false}
|
||||
percent={progress}
|
||||
/>
|
||||
) : null}
|
||||
{(actions || []).map((action) => {
|
||||
if (action.steps.includes(steps[currentStep].key)) {
|
||||
if (action.children) {
|
||||
return (
|
||||
<Dropdown menu={{ items: action.children }} key={action.key}>
|
||||
{showButtons || progress > 0 || actions.length > 0 ? (
|
||||
<Flex
|
||||
gap={'middle'}
|
||||
align='center'
|
||||
justify={showSkipButton ? 'space-between' : 'end'}
|
||||
>
|
||||
{showSkipButton && showButtons && (
|
||||
<Button onClick={onSkip} disabled={disabled}>
|
||||
Skip
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<Flex gap={'middle'} align='center' justify='end'>
|
||||
{progress > 0 ? (
|
||||
<Progress
|
||||
style={{ maxWidth: '160px' }}
|
||||
showInfo={false}
|
||||
percent={progress}
|
||||
/>
|
||||
) : null}
|
||||
{(actions || []).map((action) => {
|
||||
if (action.steps.includes(steps[currentStep].key)) {
|
||||
if (action.children) {
|
||||
return (
|
||||
<Dropdown
|
||||
menu={{ items: action.children }}
|
||||
key={action.key}
|
||||
>
|
||||
<Button
|
||||
onClick={action?.onClick}
|
||||
disabled={action?.disabled || disabled}
|
||||
loading={action?.loading || false}
|
||||
>
|
||||
{action.label}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Button
|
||||
key={action.key}
|
||||
onClick={action?.onClick}
|
||||
disabled={action?.disabled || disabled}
|
||||
loading={action?.loading || false}
|
||||
>
|
||||
{action.label}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Button
|
||||
key={action.key}
|
||||
onClick={action?.onClick}
|
||||
disabled={action?.disabled || disabled}
|
||||
loading={action?.loading || false}
|
||||
>
|
||||
{action.label}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
return null
|
||||
})}
|
||||
)
|
||||
}
|
||||
return null
|
||||
})}
|
||||
|
||||
<NewObjectButtons
|
||||
disabled={disabled}
|
||||
currentStep={currentStep}
|
||||
totalSteps={steps.length}
|
||||
onPrevious={() => setCurrentStep((prev) => prev - 1)}
|
||||
onNext={() => setCurrentStep((prev) => prev + 1)}
|
||||
onSubmit={onSubmit}
|
||||
formValid={formValid}
|
||||
submitLoading={loading}
|
||||
submitText={submitText}
|
||||
/>
|
||||
</Flex>
|
||||
{showButtons && (
|
||||
<NewObjectButtons
|
||||
disabled={disabled}
|
||||
currentStep={currentStep}
|
||||
totalSteps={steps.length}
|
||||
onPrevious={() => setCurrentStep(currentStep - 1)}
|
||||
onNext={() => setCurrentStep(currentStep + 1)}
|
||||
onSubmit={onSubmit}
|
||||
formValid={formValid}
|
||||
submitLoading={loading}
|
||||
submitText={submitText}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
</Flex>
|
||||
) : null}
|
||||
</Flex>
|
||||
</Flex>
|
||||
)
|
||||
@ -149,7 +226,15 @@ WizardView.propTypes = {
|
||||
submitText: PropTypes.string,
|
||||
progress: PropTypes.number,
|
||||
actions: PropTypes.array,
|
||||
sideBarGrow: PropTypes.bool
|
||||
sideBarGrow: PropTypes.bool,
|
||||
showButtons: PropTypes.bool,
|
||||
showTitle: PropTypes.bool,
|
||||
currentStep: PropTypes.number,
|
||||
currentSubStep: PropTypes.number,
|
||||
onStepChange: PropTypes.func,
|
||||
showSkipButton: PropTypes.bool,
|
||||
onSkip: PropTypes.func,
|
||||
sizeBarWidth: PropTypes.string
|
||||
}
|
||||
|
||||
export default WizardView
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user