import { useCallback, useEffect, useMemo, useState } from "react" import { Button, Form, Modal, Input } from 'antd' import { CloseOutlined, PlusOutlined, RotateRightOutlined } from '@ant-design/icons' import style from './style.module.scss' import { title, compass } from './board' import ReactEditeTable, { InputEditor } from 'react-edit-table' import { alert } from 'utils' import type { Board, BoardShape, ShapeType, ExtractShape } from "./board" import type { ComponentType } from 'react' import { useSelector } from "store" import { usePathData } from "router" // import { Select } from 'antd' // import InputColor from 'react-input-color'; // const ColorInput = ({ shape }: { shape: BoardShape }) => ( // // shape.setColor(color.rgba)} // /> // // ) // const sizeOptions = [6,7,8,9,10,11,12,13,14,16,18,20,28,36,48,72] // .map(size => ({ label: `${size}px`, value: size })) // const FontSizeInput = ({ shape }: { shape: ExtractShape<'fontSize'> }) => ( // // { ev.key === 'Enter' && onChang() ev.stopPropagation() } } onBlur={onChang} onChange={ev => setText(ev.target.value)} /> ) } const ContentInput = ({ shape }: { shape: ExtractShape<'content'> }) => { const [edit, setEdit] = useState(false) const [content, setContent] = useState(shape.data.content) const refer = content.filter(item => item.rowIndex === 0) const tableAttrs = useMemo(() => { const dataSource: string[][] = [] content.forEach(item => { let columns = dataSource[item.rowIndex] if (!columns) { columns = dataSource[item.rowIndex] = [] } columns[item.colIndex] = item.value }) return { columns: refer.map((item, i) => ({ title: `列${i + 1}`, dataIndex: i, key: i, editor: { type: 'input', component: InputEditor } })), dataSource } }, [content, refer]) const sortContent = () => content.sort((a, b) => { const rowDiff: number = a.rowIndex - b.rowIndex if (rowDiff) { return rowDiff } else { return a.colIndex - b.colIndex } }) const onChange = (data: any) => { const newContent = [...content] const item = newContent.find(item => item.rowIndex === data.rowIndex && item.colIndex === data.key) item!.value = data.newValue setContent(newContent) } const onDelete = (data: any) => { if (content.length <= 2) { return alert("表格最少需要保留一行!") } const newContent = sortContent() const startIndex = newContent.findIndex(item => item.rowIndex === data.rowIndex) const endIndex = startIndex + refer.length setContent([ ...newContent.slice(0, startIndex), ...newContent.slice(endIndex).map(item => ({...item, rowIndex: --item.rowIndex})) ]) } const onInsert = () => { const maxRow = Math.max(...content.map(item => item.rowIndex)) setContent([ ...content, ...refer.map(item => ({ ...item, value: '', rowIndex: maxRow + 1 })) ]) } const onSubmit = useCallback(() => { const rowEls = Array.from(document.querySelectorAll('#edit-table .body-container .row-container')) as HTMLDivElement[] const bound = rowEls.map((row, rowIndex) => { const cells = Array.from(row.querySelectorAll('.cell')) as HTMLDivElement[] return cells.slice(0, -1).map((cell, colIndex) => ({ width: cell.offsetWidth, height: row.offsetHeight - 1, value: content.find(item => item.rowIndex === rowIndex && item.colIndex === colIndex)!.value, colIndex, rowIndex })) }).flat() setContent(bound) shape.setContent(bound) console.log(bound) setEdit(false) }, [content, shape]) useEffect(() => { if (!edit) { setContent(shape.data.content || [['', '']]) } }, [edit, shape.data.content]) useEffect(() => { if (shape.autoSet) { setEdit(true) setTimeout(onSubmit, 100) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return ( setEdit(false)} onOk={onSubmit} width="430px" className="edit-table-layout">
ev.stopPropagation()}> { tableAttrs.dataSource.length && }
) } const RotateInput = ({ shape }: { shape: ExtractShape<'rotate'> }) => ( ) const shapeCompontes: { [key in ShapeType]?: ComponentType<{ shape: any }> } = { Tag: TextInput, Table: ContentInput, Compass: RotateInput, Title: TextInput } export type EShapeProps = { board: Board } export const EShape = ({ board }: EShapeProps) => { const [shape, setShape] = useState(null) const Edit = shape && shapeCompontes[shape.data.type] const disabledDelete: boolean = ([title, compass] as any).includes(shape?.data.type) const renderDelete = !disabledDelete && ( ) useEffect(() => { board.bus.on('selectShape', setShape) return () => { board.bus.off('selectShape', setShape) } }, [board]) useEffect(() => { const keydownHandler = (ev: KeyboardEvent) => { if (['Backspace', 'Delete'].includes(ev.key) && shape && !disabledDelete) { shape.delete() } } window.addEventListener('keydown', keydownHandler) return () => { window.removeEventListener('keydown', keydownHandler) } }, [board, shape, disabledDelete]) const path = usePathData() const user = useSelector(store => store.user.value) useEffect(() => { if (board && path?.id === '-1') { board.calcTableShape([ ["案发时间", ""], ["案发地点", ""], ["绘图单位", ""], ["绘图人", ""], ["绘图时间", ""] ]).then(data => { board.setDefaultTable(data.content, null) board.initHistory() }) } else { board.initHistory() } }, [user, board, path?.id]) return shape ? (
{ Edit && } { renderDelete }
setShape(null)} > board.unSelectShape()} />
) : <> } export default EShape