pro-components icon indicating copy to clipboard operation
pro-components copied to clipboard

🐛[BUG] ProFormList下的FormItem设置Preserve={false} 导致复制出的新行将失去数值

Open HAOYI99 opened this issue 1 year ago • 0 comments
trafficstars

提问前先看看:

https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md

🐛 bug 描述

ProFormList的children只要set了preserve={false},copy此行就会导致新增的行数据被删

📷 复现步骤

复制前 image 复制后的结果 image

🏞 期望结果

formItem不被render时候数据可以自动清理,并且copy该行也能保留数据

💻 复现代码

<ProFormList name='full' key={'full'}
		actionRef={printerStatusActionRef}
		alwaysShowItemLabel min={1}
		initialValue={[{ printerStatus: PrinterStatus.idle }]}
		creatorRecord={{ printerStatus: PrinterStatus.idle, duration: undefined }}
		creatorButtonProps={{ creatorButtonText: 'Next Printer Status' }}
		itemRender={(dom, listMeta) => (
			<ProCard
				bordered
				title={
					<Space direction='horizontal'>
						<>Sequence {listMeta.index + 1}</>
						<ProFormText name='sequenceTitle'
							width={'sm'} noStyle
							normalize={(value) => value.toUpperCase()} />
						<CustomTag content='PENDING' status={SequenceStatus.PENDING} />
					</Space>
				}
				extra={
					<Space>
						<Button icon={<DownOutlined />} onClick={() => {
							printerStatusActionRef.current?.move(listMeta.index, listMeta.index + 1)
						}} disabled={listMeta.fields.length === 1 || listMeta.index + 1 === listMeta.fields.length} />
						<Button icon={<UpOutlined />} onClick={() => {
							printerStatusActionRef.current?.move(listMeta.index, listMeta.index - 1)
						}} disabled={listMeta.fields.length === 1 || listMeta.index === 0} />
						<Button icon={<CopyOutlined />} type='primary'
							onClick={() => {
								const data = printerStatusActionRef.current?.get(listMeta.index)
								const { sequenceTitle, ...newData } = data; // remove sequenceTitle
								listMeta.operation.add(newData, listMeta.index + 1)
							}} />
						{listMeta.fields.length > 1 &&
							<Button icon={<DeleteOutlined />}
								type='primary' danger
								onClick={() => {
									listMeta.operation.remove(listMeta.index)
								}} />}
					</Space>
				}
				style={{
					marginBlockEnd: 8,
					border: '2px solid rgba(5, 5, 5, 0.1)',
					width: 1091
				}}
				bodyStyle={{ paddingBlockEnd: 0 }}
			>
				<Space>
					{dom.listDom}
				</Space>
			</ProCard>
		)}
	>
		{(_, rowIndex: number) => {
			return (
				<ProFormGroup>
					<ProFormSelect name='printerStatus'
						label='Printer Status'
						allowClear={false}
						width={'sm'}
						options={[
							{ label: 'BOOTING', value: PrinterStatus.booting },
							{ label: 'WAITING FOR PERIPHERALS', value: PrinterStatus.waiting_for_peripherals },
							{ label: 'IDLE', value: PrinterStatus.idle, },
							{ label: 'PRINTING', value: PrinterStatus.printing },
							{ label: 'ERROR', value: PrinterStatus.error },
							{ label: 'MAINTENANCE', value: PrinterStatus.maintenance },
							{ label: 'OFFLINE', value: PrinterStatus.offline },
						]}
						onChange={() => {
							listFormRef.current?.setFieldValue(['full', rowIndex, 'sequenceTitle'], undefined)
						}} />
					<ProFormDependency name={['printerStatus']}>
						{({ printerStatus }) => {
							switch (printerStatus) {
								case PrinterStatus.printing:
									return <>
										<Space size={35}>
											<ProFormText name='jobName'
												label='Job Name'
												width={'sm'}
												rules={[
													{ required: true }
												]}
												normalize={(value) => value.toUpperCase()}
											/>
											<ProFormSelect name='jobResult'
												label='Job Result'
												width={'sm'}
												rules={[{ required: true }]}
												options={[
													{ label: 'ABORTED', value: JobResult.aborted },
													{ label: 'FAILED', value: JobResult.failed },
													{ label: 'FINISHED', value: JobResult.finished },
												]} />
										</Space>
										// 一段很长的代码
                                                                        </>
								default:
									return <FormDurationPicker />
							}
						}}
					</ProFormDependency>
				</ProFormGroup>
			);
		}}
	</ProFormList>

FormDurationPicker 里设了 preserve false

const FormDurationPicker = () => {
    const durationFormat = "HH[h] mm[m] ss[s]";
    const defaultFormat = "YYYY-MM-DD HH:mm:ss";
    const outputFormat = "HH,mm,ss";

    return <ProFormTimePicker name="duration"
        preserve={false}
        label="Duration"
        width={'sm'}
        fieldProps={{
            showNow: false,
            secondStep: 10,
            minuteStep: 5,
            needConfirm: false,
            format: durationFormat
        }}
        rules={[
            { required: true, message: 'Please select Duration' }
        ]}
        transform={(value: any) => {
            // to handle value is different format
            let result = dayjs(value, [durationFormat, defaultFormat], true)
            return result.format(outputFormat)
        }} />;
}

© 版本信息

"@ant-design/pro-components": "^2.6.30",
"antd": "^5.14.2",

🚑 其他信息

HAOYI99 avatar Mar 06 '24 05:03 HAOYI99