|
|
@@ -374,8 +374,13 @@ const CanvasDropZone: React.FC<{
|
|
|
const targetFieldId = fieldId;
|
|
|
console.log('Drop field event:', { draggedFieldId, targetFieldId, parentId, fieldIndex, hasOnMoveField: !!onMoveField, fieldId });
|
|
|
|
|
|
+ if (!draggedFieldId || !onMoveField) {
|
|
|
+ console.warn('⚠️ Cannot move field - missing draggedFieldId or onMoveField');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// 如果拖拽的字段ID和目标字段ID都存在,且不相同,则进行互换
|
|
|
- if (draggedFieldId && targetFieldId && draggedFieldId !== targetFieldId && onMoveField) {
|
|
|
+ if (targetFieldId && draggedFieldId !== targetFieldId) {
|
|
|
console.log('✅ Moving field:', draggedFieldId, 'to target field:', targetFieldId, 'parent:', parentId);
|
|
|
// 调用移动函数,传递目标字段ID进行互换
|
|
|
console.log('✅ Calling onMoveField with:', { fieldId: draggedFieldId, targetFieldId, targetParentId: parentId });
|
|
|
@@ -386,16 +391,27 @@ const CanvasDropZone: React.FC<{
|
|
|
console.error('❌ Error calling onMoveField:', error);
|
|
|
}
|
|
|
return;
|
|
|
- } else {
|
|
|
- console.warn('⚠️ Cannot move field - missing required params or same field:', {
|
|
|
- draggedFieldId,
|
|
|
- targetFieldId,
|
|
|
- hasOnMoveField: !!onMoveField,
|
|
|
- actualItem,
|
|
|
- fieldId,
|
|
|
- parentId,
|
|
|
- isSameField: draggedFieldId === targetFieldId
|
|
|
- });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果没有目标字段ID,但有索引,则插入到指定位置
|
|
|
+ if (fieldIndex !== undefined && fieldIndex >= 0) {
|
|
|
+ console.log('✅ Moving field to index:', draggedFieldId, 'to index:', fieldIndex, 'parent:', parentId);
|
|
|
+ try {
|
|
|
+ onMoveField(draggedFieldId, parentId, fieldIndex);
|
|
|
+ console.log('✅ onMoveField called successfully (by index)');
|
|
|
+ } catch (error) {
|
|
|
+ console.error('❌ Error calling onMoveField:', error);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果都没有,添加到末尾
|
|
|
+ console.log('✅ Moving field to end:', draggedFieldId, 'parent:', parentId);
|
|
|
+ try {
|
|
|
+ onMoveField(draggedFieldId, parentId);
|
|
|
+ console.log('✅ onMoveField called successfully (to end)');
|
|
|
+ } catch (error) {
|
|
|
+ console.error('❌ Error calling onMoveField:', error);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -2148,40 +2164,65 @@ export default function FormDesigner() {
|
|
|
} : undefined}
|
|
|
>
|
|
|
<div style={gridStyle} className={layoutColumns === 1 ? 'space-y-4' : ''}>
|
|
|
- {fields.map((field) => (
|
|
|
+ {fields.map((field, index) => (
|
|
|
<div
|
|
|
key={field.id}
|
|
|
style={
|
|
|
layoutColumns > 1
|
|
|
- ? { gridColumn: `span ${Math.min(layoutColumns, field.span || 1)}` }
|
|
|
- : undefined
|
|
|
+ ? {
|
|
|
+ gridColumn: `span ${Math.min(layoutColumns, field.span || 1)}`,
|
|
|
+ position: 'relative',
|
|
|
+ minHeight: '80px'
|
|
|
+ }
|
|
|
+ : { position: 'relative', minHeight: '80px' }
|
|
|
}
|
|
|
>
|
|
|
- <FieldRenderer
|
|
|
- field={field}
|
|
|
- isSelected={selectedFieldId === field.id}
|
|
|
- onSelect={() => setSelectedFieldId(field.id)}
|
|
|
- onDelete={() => deleteField(field.id)}
|
|
|
- onAddFieldToContainer={(parentId, type, uploadType, layoutCols) => {
|
|
|
- addField(type, uploadType, layoutCols, parentId);
|
|
|
+ <CanvasDropZone
|
|
|
+ onDrop={(type, uploadType, layoutCols) => {
|
|
|
+ addField(type, uploadType, layoutCols);
|
|
|
}}
|
|
|
onMoveField={moveFieldToPosition}
|
|
|
- onUpdateField={updateField}
|
|
|
- onDeleteField={deleteField}
|
|
|
- onSelectField={setSelectedFieldId}
|
|
|
- onCopyField={copyField}
|
|
|
- formConfig={formConfig}
|
|
|
- selectedFieldId={selectedFieldId}
|
|
|
- allFields={fields}
|
|
|
- draggingFieldId={draggingFieldId}
|
|
|
- hoverTargetId={hoverTargetId}
|
|
|
- onDragStart={(fieldId) => setDraggingFieldId(fieldId)}
|
|
|
- onDragEnd={() => {
|
|
|
- setDraggingFieldId(null);
|
|
|
- setHoverTargetId(null);
|
|
|
+ onHover={(item, monitor) => {
|
|
|
+ if (monitor.getItemType() === 'field') {
|
|
|
+ // 拖拽到组件上时,设置悬停目标用于视觉反馈
|
|
|
+ setHoverTargetId(field.id);
|
|
|
+ }
|
|
|
}}
|
|
|
- onHoverTarget={(fieldId) => setHoverTargetId(fieldId)}
|
|
|
- />
|
|
|
+ onHoverTarget={(targetFieldId) => {
|
|
|
+ // 设置悬停目标,用于显示视觉反馈
|
|
|
+ setHoverTargetId(targetFieldId);
|
|
|
+ }}
|
|
|
+ fieldIndex={index}
|
|
|
+ fieldId={field.id}
|
|
|
+ className="w-full h-full"
|
|
|
+ style={{ width: '100%', height: '100%', minHeight: '80px' }}
|
|
|
+ >
|
|
|
+ <FieldRenderer
|
|
|
+ field={field}
|
|
|
+ isSelected={selectedFieldId === field.id}
|
|
|
+ onSelect={() => setSelectedFieldId(field.id)}
|
|
|
+ onDelete={() => deleteField(field.id)}
|
|
|
+ onAddFieldToContainer={(parentId, type, uploadType, layoutCols) => {
|
|
|
+ addField(type, uploadType, layoutCols, parentId);
|
|
|
+ }}
|
|
|
+ onMoveField={moveFieldToPosition}
|
|
|
+ onUpdateField={updateField}
|
|
|
+ onDeleteField={deleteField}
|
|
|
+ onSelectField={setSelectedFieldId}
|
|
|
+ onCopyField={copyField}
|
|
|
+ formConfig={formConfig}
|
|
|
+ selectedFieldId={selectedFieldId}
|
|
|
+ allFields={fields}
|
|
|
+ draggingFieldId={draggingFieldId}
|
|
|
+ hoverTargetId={hoverTargetId}
|
|
|
+ onDragStart={(fieldId) => setDraggingFieldId(fieldId)}
|
|
|
+ onDragEnd={() => {
|
|
|
+ setDraggingFieldId(null);
|
|
|
+ setHoverTargetId(null);
|
|
|
+ }}
|
|
|
+ onHoverTarget={(fieldId) => setHoverTargetId(fieldId)}
|
|
|
+ />
|
|
|
+ </CanvasDropZone>
|
|
|
</div>
|
|
|
))}
|
|
|
</div>
|