import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';可拖拽的包
可拖拽:DraggableRow/index.jsx 子组件
import React, { useState,useRef } from 'react';
import { Modal, Form, Select, Input, Button, Row, Col,Tooltip} from 'antd'
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
import { CloseCircleOutlined, ExclamationCircleOutlined} from '@ant-design/icons';
import styles from './index.less'
import { debounce } from 'lodash';
const grid = 8;
const getItemStyle = (isDragging, draggableStyle) => ({
// some basic styles to make the items look a bit nicer
userSelect: 'none',
// padding: grid * 4,
margin: `0 0 ${grid}px 0`,
// change background colour if dragging
background: isDragging ? '#fff' : '#fff',
// border: '1px solid #ddd',
margin: '0px auto 10px auto',
width:"70%",
// styles we need to apply on draggables
...draggableStyle,
});
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
let arr = [];
result.map((v, k) => {
arr.push(v);
});
return arr;
};
export default (props)=>{
const { list, config } = props;
const {
activeKey,
setHomeList,
setDuapList,
setVisible,
setIsEdit,
setCurrentEditItem,
setOtherVisible,
onRowDelete,
setEditOtherOrder,
setItemTypeCode,
renderOrder,
} = config
const onDragEnd = (result) => { //拖拽结束事件
console.log('result', result);
let arr = [...list]
if (!result.destination) {
return;
}
const newList = reorder(arr, result.source.index, result.destination.index);
let IdList = [];
if(!!newList && newList.length){
newList.map(item=>{
IdList.push(item.Id)
})
}
if(!!IdList && IdList.length){
renderOrder(IdList)
}
if (activeKey == "1001") {
setHomeList(newList)
}else{
setDuapList(newList)
}
}
const handleEditItem = (e,item,index) =>{
e.preventDefault();
e.stopPropagation();
Modal.confirm({
icon: <ExclamationCircleOutlined />,
content: 'Are you sure to delete?',
okText: 'Confirm',
cancelText: 'Cancel',
onOk() {
onRowDelete(item)
},
})
}
const handleEditOtherItem = (e, item, index, order) =>{
e.preventDefault();
e.stopPropagation();
setOtherVisible(true);
setIsEdit(true);
setItemTypeCode(item.DisplayItemDetailList[order-1].ItemType)
console.log('item', item);
console.log('index', index);
console.log('order', order);
setCurrentEditItem(item);
setEditOtherOrder(order);
}
const onIntroductionEdit = (e, item, index) =>{
e.preventDefault();
e.stopPropagation();
setCurrentEditItem(item);
setVisible(true);
setIsEdit(true);
}
const onVideoEdit = (e, item, index) =>{
e.preventDefault();
e.stopPropagation();
setCurrentEditItem(item);
setVisible(true);
setIsEdit(true);
}
return (
<div style={{background:"#fff",paddingBottom:'30px'}}>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="droppable">
{(provided, snapshot) => (
<div ref={provided.innerRef} {...provided.droppableProps}>
{list.map((item, index) => {
let dom;
if (item.FunctionType == 1001) { //
dom = <div
editform="false"
key={item.Id}
style={{ padding: "0 20px", background: "#fff", position: "relative" }}
// onClick={() => {
// this.showEditModal(item);
// }}
>
<Draggable
shouldRespectForcePress={true}
key={item.index}
draggableId={item.Id}
index={index}
>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
<div className={styles.droppableItem} onClick={(e) => { onIntroductionEdit(e,item,index)}}>Introduction</div>
</div>
)}
</Draggable>
<CloseCircleOutlined className='deleteDraggableItem' onClick={(e) => { handleEditItem(e, item, index) }} />
</div>
} else if (item.FunctionType == 1002){
dom = (
<div
editform="false"
key={item.Id}
style={{ padding: "0 20px", background: "#fff", position: "relative" }}
// onClick={() => {
// this.showEditModal(item);
// }}
>
<Draggable
shouldRespectForcePress={true}
key={item.index}
draggableId={item.Id}
index={index}
>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
<div className={styles.droppableItem} onClick={(e) => { onVideoEdit(e, item, index) }}>Video</div>
</div>
)}
</Draggable>
<CloseCircleOutlined className='deleteDraggableItem' onClick={(e) => { handleEditItem(e, item, index) }} />
</div>
);
} else if (item.FunctionType == 1003 && item.Quantity == 1){
dom = (
<div
editform="false"
key={item.Id}
style={{ padding: "0 20px", background: "#fff", position: "relative" }}
// onClick={() => {
// this.showEditModal(item);
// }}
>
<Draggable
shouldRespectForcePress={true}
key={item.index}
draggableId={item.Id}
index={index}
>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
<div className={styles.droppableItem} onClick={(e) => { handleEditOtherItem(e, item, index, 1) }}>
<p>{!!item.DisplayItemDetailList[0].ItemTypeString ? item.DisplayItemDetailList[0].ItemTypeString : ""}</p>
<p>{!!item.DisplayItemDetailList[0].Title ? item.DisplayItemDetailList[0].Title : "Click to select the display content"}</p>
</div>
</div>
)}
</Draggable>
<CloseCircleOutlined className='deleteDraggableItem' onClick={(e) => { handleEditItem(e, item, index) }} />
</div>
);
} else if (item.FunctionType == 1003 && item.Quantity == 2) {
dom = (
<div
editform="false"
key={item.Id}
style={{ padding: "0 20px", background: "#fff", position: "relative" }}
// onClick={() => {
// this.showEditModal(item);
// }}
>
<Draggable
shouldRespectForcePress={true}
key={item.index}
draggableId={item.Id}
index={index}
>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
<Row gutter={[16,16]}>
<Col span={8}>
<div className={styles.droppableItemDiv} onClick={(e) => { handleEditOtherItem(e, item, index, 1) }}>
<p>{!!item.DisplayItemDetailList[0].ItemTypeString ? item.DisplayItemDetailList[0].ItemTypeString : ""}</p>
<p>{!!item.DisplayItemDetailList[0].Title ? item.DisplayItemDetailList[0].Title : "Click to select the display content"}</p>
</div>
</Col>
<Col span={16}>
<div className={styles.droppableItemDiv} onClick={(e) => { handleEditOtherItem(e, item, index, 2) }}>
<p>{!!item.DisplayItemDetailList[1].ItemTypeString ? item.DisplayItemDetailList[1].ItemTypeString : ""}</p>
<p>{!!item.DisplayItemDetailList[1].Title ? item.DisplayItemDetailList[1].Title : "Click to select the display content"}</p>
</div>
</Col>
</Row>
</div>
)}
</Draggable>
<CloseCircleOutlined className='deleteDraggableItem' onClick={(e) => { handleEditItem(e, item, index) }} />
</div>
);
} else if (item.FunctionType == 1003 && item.Quantity == 3) {
dom = (
<div
editform="false"
key={item.Id}
style={{ padding: "0 20px", background: "#fff", position: "relative" }}
// onClick={() => {
// this.showEditModal(item);
// }}
>
<Draggable
shouldRespectForcePress={true}
key={item.index}
draggableId={item.Id}
index={index}
>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
<Row gutter={[16, 16]}>
<Col span={8}>
<div className={styles.droppableItemDiv} onClick={(e) => { handleEditOtherItem(e, item, index, 1) }}>
<p>{!!item.DisplayItemDetailList[0].ItemTypeString ? item.DisplayItemDetailList[0].ItemTypeString : ""}</p>
<p>{!!item.DisplayItemDetailList[0].Title ? item.DisplayItemDetailList[0].Title :"Click to select the display content"}</p>
</div>
</Col>
<Col span={8}>
<div className={styles.droppableItemDiv} onClick={(e) => { handleEditOtherItem(e, item, index, 2) }}>
<p>{!!item.DisplayItemDetailList[1].ItemTypeString ? item.DisplayItemDetailList[1].ItemTypeString : ""}</p>
<p>{!!item.DisplayItemDetailList[1].Title ? item.DisplayItemDetailList[1].Title : "Click to select the display content"}</p>
</div>
</Col>
<Col span={8}>
<div className={styles.droppableItemDiv} onClick={(e) => { handleEditOtherItem(e, item, index, 3) }}>
<p>{!!item.DisplayItemDetailList[2].ItemTypeString ? item.DisplayItemDetailList[2].ItemTypeString : ""}</p>
<p>{!!item.DisplayItemDetailList[2].Title ? item.DisplayItemDetailList[2].Title : "Click to select the display content"}</p>
</div>
</Col>
</Row>
</div>
)}
</Draggable>
<CloseCircleOutlined className='deleteDraggableItem' onClick={(e) => { handleEditItem(e, item, index) }} />
</div>
);
}
return dom;
})}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</div>
)
}
引入 拖拽组件:
父组件
import moment from 'moment';
import styles from './index.less';
import PanelTitle from '@/components/PanelTitle';
import React, { useEffect, useState } from 'react';
import { ExclamationCircleOutlined, EllipsisOutlined, PlusOutlined } from '@ant-design/icons';
import { Form, Input, Row, Col, Modal, Table, Button, Menu, Dropdown, message, Tooltip, Select, Radio } from 'antd';
import DisplaySettingModifyRow from '@/components/DisplaySettingModifyRow';
import DisplayOtherModifyModal from '@/components/DisplayOtherModifyModal';
// import DisplayApp from '@/components/DisplayApp';
import DraggableRow from '@/components/DraggableRow';
import {
GetRowTypeDropdown,
GetItemTypeDropdown,
GetDisplayList,
DisplayRowAdd,
DisplayRowItemEdit,
GetItemContentDropdown,
DisplayConfigPublish,
DisplayRowDelete,
DisplayOrderUpdate,
} from '@/services/displaySetting'
import { v4 as uuidv4 } from 'uuid';
import { history, Link } from 'umi';
import { debounce } from 'lodash';
import { get } from '@umijs/deps/compiled/lodash';
const { Option } = Select
export default () => {
const [form] = Form.useForm();
const [pageSize, setPageSize] = useState(10);
const [totalCount, setTotalCount] = useState(0);
const [dataSource, setDataSource] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [visible, setVisible] = useState(false); //添加或编辑一行的modal
const [otherVisible, setOtherVisible] = useState(false); //编辑某个other的modal
const [isEdit, setIsEdit] = useState(false); //是否是编辑
const [homeList, setHomeList] = useState([]); //Home Display的列表数据
const [duapList, setDuapList] = useState([]); //DUAP Display的列表数据
const [activeKey, setActiveKey] = useState('1001'); //当前激活的tab
const [rowType, setRowType] = useState([]); //
const [itemType, setItemType] = useState([]);
const [contentList, setContentList] = useState([]);
const [itemTypeCode, setItemTypeCode] = useState(1001);
const [currentEditItem, setCurrentEditItem] = useState({}); //当前编辑的数据
const [editOtherOrder, setEditOtherOrder] = useState(null); //编辑Other中的某条数据的Order
useEffect(() => { //加载初始数据
GetRowTypeDropdown({}).then(res => {
setRowType(res)
})
GetItemTypeDropdown({}).then(res => {
setItemType(res)
})
}, [])
useEffect(() => { //根据Other中的Type获取联动的Content数据
GetItemContentDropdown({
ItemType: itemTypeCode
}).then(res => {
if (!!res && res.length) {
setContentList(res)
} else {
setContentList([])
}
})
}, [itemTypeCode])
useEffect(() => { //切换tabs时获取列表数据
GetDisplayList({
PageType: activeKey,
IsPublished: false
}).then(res => {
if (!!res && res.length) {
if (activeKey == '1001') {
setHomeList(res)
} else if (activeKey == '1002') {
setDuapList(res)
}
}
})
}, [activeKey])
const getList = () => { //获取Home 或者 DUAP China的列表数据
GetDisplayList({
PageType: activeKey,
IsPublished: false
}).then(res => {
if (!!res && res.length) {
if (activeKey == '1001') {
setHomeList(res)
} else if (activeKey == '1002') {
setDuapList(res)
}
} else {
if (activeKey == '1001') {
setHomeList([])
} else if (activeKey == '1002') {
setDuapList([])
}
}
})
}
const onChange = (e) => { //切换tab
setActiveKey(e.target.value)
}
const handleAdd = () => { //添加一行
setIsEdit(false);
setVisible(!visible)
}
const onModifyRowFinish = (values) => { //Introduction 和 Video 以及Other中的每个模块编辑回调
switch (activeKey) {
case '1001':
if (isEdit) {
if (!!values.FunctionType) {
delete values.FunctionType
}
DisplayRowItemEdit(values).then(res => {
if (!!res && res.ReturnCode == 1001) {
message.success('Edit successfully')
getList();
} else {
message.error(res.MessageEnglish)
}
})
} else {
values.PageType = activeKey;
DisplayRowAdd(values).then(res => {
console.log(res);
if (!!res && res.ReturnCode == 1001) {
message.success("Add successfully");
getList();
} else {
message.error(res.MessageEnglish)
}
})
}
break;
case '1002':
if (isEdit) {
delete values.FunctionType
DisplayRowItemEdit(values).then(res => {
if (!!res && res.ReturnCode == 1001) {
message.success('Edit successfully')
getList();
} else {
message.error(res.MessageEnglish)
}
})
} else {
values.PageType = activeKey;
DisplayRowAdd(values).then(res => {
console.log(res);
if (!!res && res.ReturnCode == 1001) {
message.success("Add successfully");
getList();
} else {
message.error(res.MessageEnglish)
}
})
}
break;
default:
break;
}
}
const onRowDelete = (values) => { //删除一行
DisplayRowDelete({ Id: values.Id }).then(res => {
if (!!res && res.ReturnCode == 1001) {
message.success('Delete successfully');
getList()
} else {
message.error(res.MessageEnglish)
}
})
}
const onPublish = () => { //发布
DisplayConfigPublish({ PageType: activeKey }).then(res => {
if (!!res && res.ReturnCode == 1001) {
message.success('Publish successfully');
// location.reload();
GetDisplayList({
PageType: activeKey,
IsPublished: false
}).then(res => {
if (!!res && res.length) {
if (activeKey == '1001') {
setHomeList(res)
} else if (activeKey == '1002') {
setDuapList(res)
}
}
})
} else {
message.error(res.MessageEnglish)
}
})
}
const renderOrder = (IdList) => {
DisplayOrderUpdate({ IdList }).then(res => {
if (!!res && res.ReturnCode == 1001) {
message.success('Operation successful')
}
})
}
return (
<div className={styles.FeedbackContainer}>
<PanelTitle title="Homepage Setting" />
<div className={styles.FeedbackMain}>
<div className={styles.radioBtn}>
<Radio.Group onChange={onChange} defaultValue={activeKey}>
<Radio.Button value="1001">Home(PC)</Radio.Button>
<Radio.Button value="1002">DUAP China(PC)</Radio.Button>
{/* <Radio.Button value="1003">Display(APP)</Radio.Button> */}
</Radio.Group>
</div>
{
activeKey == '1001' || activeKey == '1002' ?
<div className={styles.displayContent}>
<div className={styles.displayContent_previewBtn}>
<Button style={{ marginRight: '15px' }} onClick={onPublish}>Publish</Button>
<Button onClick={() => { activeKey == '1001' ? window.open('/userInterface/home?preview=true') : window.open('/userInterface/duapChina?preview=true') }}>Preview</Button>
</div>
<div className={styles.displayContent_addBtn} onClick={handleAdd}>
Add
</div>
</div>
: ""
}
</div>
<DisplaySettingModifyRow
visible={visible}
onCancel={setVisible}
isEdit={isEdit}
setIsEdit={setIsEdit}
currentEditItem={currentEditItem}
onModifyRowFinish={onModifyRowFinish}
rowType={rowType}
/>
{
activeKey == '1001' || activeKey == "1002" ? <DraggableRow config={
{
activeKey,
setHomeList: setHomeList,
setDuapList: setDuapList,
setVisible: setVisible,
setIsEdit: setIsEdit,
setCurrentEditItem: setCurrentEditItem,
setOtherVisible: setOtherVisible,
onRowDelete: onRowDelete,
setEditOtherOrder: setEditOtherOrder,
setItemTypeCode: setItemTypeCode,
renderOrder: renderOrder,
}
} list={activeKey == "1001" ? homeList : activeKey == '1002' ? duapList : []} /> : ""
}
<DisplayOtherModifyModal
itemType={activeKey == '1001' ? itemType : [itemType[0]]}
visible={otherVisible}
onCancel={setOtherVisible}
contentList={contentList}
setItemTypeCode={setItemTypeCode}
onModifyRowFinish={onModifyRowFinish}
setIsEdit={setIsEdit}
isEdit={isEdit}
editOtherOrder={editOtherOrder}
currentEditItem={currentEditItem}
/>
{/* {
activeKey == '1003'?<DisplayApp/>:""
} */}
</div>
)
};
版权声明:本文为zhangyubababa原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。