import React, { useEffect, useRef, useState } from 'react'; import Icon from '../../Icon/index'; import LargeScreenLayerInput from '../LargeScreenLayerInput/index'; import ClickButtonUpload from '../../Unit/ClickButtonUpload/index'; import Selecto from 'react-selecto'; import Sortable from 'sortablejs'; import { Tooltip, Popover } from 'antd'; import { ILargeScreenLayerListProps, IContextMenus, IContent } from '../../../type/largeScreenLayer'; import { TabsActive } from '../../../store/page'; import { useRecoilState } from 'recoil'; import noData from '../no-layer-data.svg'; import fenduanhui from './fenduanhui.svg'; import lianxuhui from './lianxuhui.svg'; import qipaohui from './qipaohui.svg'; const LargeScreenElementCards: React.FC = ( props ) => { // const scrollerRef = useRef(null); const { content, contextMenus, layerListEvent, fristSelectedElement, hoverElement } = props; const [, setTabsActive] = useRecoilState(TabsActive); //tabs当前选中项 const listRef = useRef(null); // 图层列表容器ref const sortableRef = useRef(null); // sortable const dragRef = useRef(null); // 拖动开始 // const [scrollOptions, setScrollOptions] = useState({}); //框选时的滚动配置 // useEffect(() => { // setScrollOptions({ // container: scrollerRef.current, // throttleTime: 30, // threshold: 0 // }); // }, []); //暂时隐藏,组的内容拖拽未完成 // useEffect(() => { // if (content?.length > 0) { // initSort(); // } // }, []); //暂时隐藏,组的内容拖拽未完成 // useEffect(() => { // // 图层列表变化,需要重新初始化 // if (content?.length) { // sortableRef?.current?.destroy(); // initSort(); // } // }, [content?.length]); useEffect(() => { if (Array.isArray(content) && content?.length) { // 去除之前选中 const beforeSelectElements = document.getElementsByClassName('sortable-selected'); Array.from(beforeSelectElements)?.forEach((item) => { if (item) { Sortable.utils.deselect(item); } }); // 设置最新选中-因为需要画板与图层列表映射,多条目未点击时可拖动,使用Sortable源码utils方法解决此问题 content.forEach((item) => { if (item?.selected) { const el = document.getElementById(`layer-${item?.key}`); if (el) { Sortable.utils.select(el); } } }); } }, [content]); useEffect(() => { // 判断在不在视区范围内,不在的话,滚动到视区范围内 if (fristSelectedElement) { const el = document.getElementById('layer-' + fristSelectedElement); if (el) { const scroller = document.querySelector('.zl-lagre-screen-layer-data'); if (scroller) { const top = el.offsetTop; if (top + 36 > scroller.scrollTop + scroller.clientHeight) { scroller.scrollTo({ top: top + 36 - scroller.clientHeight }); } else if (top < scroller.scrollTop) { scroller.scrollTo({ top: top }); } layerListEvent?.(null, null, null, 'clearFristSelectedElement'); } } } }, [fristSelectedElement]); //双击事件 const _dbClick = (e: any, key: string | number, item: any) => { e.stopPropagation(); layerListEvent?.(e, key, item, 'dbClick'); }; //右键事件 const _contextMenu = (e: any, key: string | number, item: any) => { layerListEvent?.(e, key, item, 'contextMenu'); setTabsActive('page'); }; //input框的change事件 const _changeValue = ( type: string, value: string, key: string | number, item: any ) => { layerListEvent?.(value, key, item, type); }; //点击事件 const _click = ( e: any, key: string | number, item: any, type, clickType?: string ) => { layerListEvent?.(e, key, item, type, clickType); setTabsActive('page'); }; //右键事件 const menusClick = (key: string | number, item: any) => { layerListEvent?.(null, key, item, 'menusClick'); }; // //框选事件 // const selectEnd = (e) => { // const canBeSelect = []; // if (e.afterAdded?.length > 0) { // e.afterAdded.forEach((el) => { // const classList = el.className; // // 排除锁定和隐藏 // if ( // !classList?.includes('zl-ls-board-moveable-wrap-hidden') && // !classList?.includes('zl-ls-board-moveable-wrap-lock') // ) { // canBeSelect.push(el); // } // }); // } // layerListEvent?.( // null, // null, // { selectElements: canBeSelect }, // 'selectElementEnd' // ); // }; //判断单个元素菜单项的状态 const isMenuCanUse = (statusArr: string | string[], item: IContent) => { if (statusArr) { if (typeof statusArr === 'string') { statusArr = [statusArr]; } if (Array.isArray(statusArr) && statusArr?.length > 0) { return statusArr.some((arrItem) => { if (arrItem.indexOf('!') === -1) { return item[arrItem]; } else { return !item[arrItem.slice(1)]; } }); } } return false; }; //图层列表容器的点击事件 const wrapClick = (e) => { layerListEvent?.(e, null, null, 'wrapClick'); }; //菜单的显隐 const changeVisible = (flag: boolean) => { layerListEvent?.(null, null, flag, 'changeVisible'); }; // 初始化sortable const initSort = () => { let sortable; // 拖动配置 const ops = { animation: 200, // 动画延迟 group: 'name', className: 'zl-lagre-screen-filter-end', multiDrag: true, // 开启多选 multiDragKey: 'ctrl', // 多选按键 selectedClass: 'sortable-selected', // 选择的类名 ghostClass: 'sortable-ghostClass', // 选择的类名 forceFallback: true, fallbackTolerance: 3, selected: true, avoidImplicitDeselect: false, // true - if you don't want to deselect items on outside click onStart: function (evt) { dragRef.current = true; layerListEvent?.(null, null, '', 'leaveElement'); layerListEvent?.(null, null, '', 'clearFristElement'); // setDraging(true) }, onMove: function (evt) { layerListEvent?.(null, null, '', 'leaveElement'); // setDraging(true) }, onEnd: function (evt) { dragRef.current = false; }, // 更新 onUpdate: function (/**Event*/ evt) { const { from, newIndex } = evt; const list = updateSort(from); layerListEvent?.(null, null, '', 'leaveElement'); layerListEvent?.(null, null, list, 'sortElementList'); } }; //初始化 sortable = Sortable.create(listRef?.current, ops); sortableRef.current = sortable; }; // 更新排序 const updateSort = (fromEle) => { const list = []; [...fromEle?.children]?.forEach((item) => { const layerId = item?.getAttribute('data-layer-layerId'); if (layerId) { list.push(layerId); } }); return list; }; //可配置的菜单 const configurableMenu = (item: IContextMenus, itemValue: IContent) => { let disabled = isMenuCanUse(item?.disabled, itemValue); let hidden = isMenuCanUse(item?.hidden, itemValue); if (hidden) { return null; } if (item?.type === 'uploadElement') { return (
  • { //避免触发图层数据的事件 e.stopPropagation(); return false; }} onDoubleClick={(e) => { //避免触发图层数据的事件 e.stopPropagation(); return false; }} onClick={(e) => { e.preventDefault(); e.stopPropagation(); // 关闭上传弹窗打开时的当前右键弹窗 menusClick('closeCurEleAllModal', item); }} > { menusClick(item?.key, { value: rest }); }} labelIcon={} style={{ width: item?.fileStyle?.width, color: disabled ? item?.fileStyle?.disableColor : item?.fileStyle?.color, fontSize: item?.fileStyle?.fontSize, marginLeft: item?.fileStyle?.marginLeft // padding: item?.fileStyle?.padding }} labelWarpStyle={{ display: 'flex', alignItems: 'center' }} {...item} />
  • ); } else { return (
  • { //避免触发图层数据的事件 e.stopPropagation(); return false; }} onDoubleClick={(e) => { //避免触发图层数据的事件 e.stopPropagation(); return false; }} onClick={(e) => { e.stopPropagation(); if (disabled) { return false; } else { menusClick(item?.key, item); } }} > {item?.label}
  • ); } return (
  • { //避免触发图层数据的事件 e.stopPropagation(); return false; }} onDoubleClick={(e) => { //避免触发图层数据的事件 e.stopPropagation(); return false; }} onClick={(e) => { e.stopPropagation(); if (disabled) { return false; } else { menusClick(item?.key, item); } }} > {item?.label}
  • ); }; //定死的菜单 const setMenu = (item: IContextMenus, itemValue: IContent) => { return (
  • { //避免触发图层数据的事件 e.stopPropagation(); return false; }} onDoubleClick={(e) => { //避免触发图层数据的事件 e.stopPropagation(); return false; }} onClick={(e) => { e.stopPropagation(); if (item?.disabled) { return false; } else { menusClick(item?.key, item); } }} onMouseDown={(e) => { e.stopPropagation(); return false; }} > {item?.label}
  • ); }; //区分可配置的菜单 //单个元素的菜单是通过元素的item?.disabled和item?.hidden确定的 //成组没有办法加item?.disabled和item?.hidden 所以菜单定死 const menuListDisabled = (item: IContextMenus, itemValue: IContent) => { if (typeof item?.disabled !== 'boolean') { return configurableMenu(item, itemValue); } else { return setMenu(item, itemValue); } }; // 右键菜单 const menuList = (itemValue: IContent, mlist: IContextMenus[]) => { return ( ); }; const returnMap = (title) => { let url = ''; if (title === 'icon-_map_off') { url = fenduanhui; } else if (title === 'icon-_piecewisemap_off') { url = lianxuhui; } else if (title === 'icon-_scattermap_off') { url = qipaohui; } return url; }; const liChild = (list) => ( <> {Array.isArray(list) && list?.length > 0 && list?.map((item) => { return (
  • { !dragRef.current && layerListEvent?.(null, null, item?.key, 'enterElement'); }} onMouseLeave={() => { !dragRef.current && layerListEvent?.(null, null, item?.key, 'leaveElement'); }} > { e.stopPropagation(); _click(e, item?.key, item, 'layerListClick'); }} onDoubleClick={(e) => { _dbClick(e, item?.key, item); }} onMouseDown={(e) => { e.stopPropagation(); !item?.selected && !(e.metaKey || e.ctrlKey) && !e.shiftKey && _click( e, item?.key, item, 'layerListClick', 'singleSortClick' ); }} onContextMenu={(e) => { _contextMenu(e, item?.key, item); }} > {Array.from({ length: item?.parentGroupIndex ? item?.parentGroupIndex?.split('-').length : 0}, (_, index) => (
    ))} {item?.children ? : ''} {/* 如果是地图,使用svg图片:因为iconfont不允许上传地图了,而原有地图图标不完整,所以使用svg图片 */} {item?.icon === 'icon-_map_off' || item?.icon === 'icon-_scattermap_off' || item?.icon === 'icon-_piecewisemap_off' ? ( {item?.icon} ) : ( item?.lastGroupElementIndex ? { e.stopPropagation(); return false; }} click={(value, e) => { e.stopPropagation(); _click( e, item?.key, item, 'layerListGroupClick' ); }} style={{ marginLeft: item?.children ? '5px' : '0' }} /> : )} {item?.laryerType === 'search' ? ( { _changeValue(type, value, item?.key, item); }} /> ) : ( {item?.title} )} {item?.statusIcon ? ( { e.preventDefault(); e.stopPropagation(); _click(value, item?.key, item, 'layerListIconClick'); }} /> ) : null} {item?.gisIcon ? ( { e.preventDefault(); e.stopPropagation(); if (item?.selected) { _click(value, item?.key, item, 'layerListIconClick'); } }} /> ) : null}
    {item?.children ? showChildren(item?.children, item?.key + 'ul') : ''}
  • ); })} ); const showChildren = (list, key) => ( ); return (
    {/* { // // 控制selecto框选插件是否启用 // return !isSelectoDisabled; // }} // hitRate={40} selectByClick={true} selectFromInside={true} onSelectStart={(e) => { e.added.forEach((el) => { el.classList.add('selected'); }); e.removed.forEach((el) => { el.classList.remove('selected'); }); }} onSelectEnd={(e) => { selectEnd(e); }} /> */} {content?.length === 0 ? (
    暂无图层 暂无图层~
    ) : (
      { e.stopPropagation(); wrapClick(e); }} ref={listRef} > {liChild(content)}
    )}
    ); }; export default LargeScreenElementCards;