diff options
| author | zephyr <[email protected]> | 2023-05-26 11:42:43 +0800 |
|---|---|---|
| committer | Larvan2 <[email protected]> | 2023-06-20 22:10:39 +0800 |
| commit | d2203727898dec31c290ff38e5d375670be36bb0 (patch) | |
| tree | 6197e706b6fcf14c00afcf459ad903ce43c93953 /src/components/ConnectionTable.tsx | |
| parent | e3bba3b401383a207da875b279d2e713048782ab (diff) | |
feat: dnd column
Diffstat (limited to 'src/components/ConnectionTable.tsx')
| -rw-r--r-- | src/components/ConnectionTable.tsx | 156 |
1 files changed, 99 insertions, 57 deletions
diff --git a/src/components/ConnectionTable.tsx b/src/components/ConnectionTable.tsx index 5e99a2d..d7336fd 100644 --- a/src/components/ConnectionTable.tsx +++ b/src/components/ConnectionTable.tsx @@ -1,7 +1,8 @@ import cx from 'clsx'; import { formatDistance, Locale } from 'date-fns'; import { enUS, zhCN, zhTW } from 'date-fns/locale'; -import React from 'react'; +import React, { useState } from 'react'; +import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; import { ChevronDown } from 'react-feather'; import { useTranslation } from 'react-i18next'; import { useSortBy, useTable } from 'react-table'; @@ -11,22 +12,32 @@ import s from './ConnectionTable.module.scss'; const sortDescFirst = true; -const columns = [ - { accessor: 'id', show: false }, - { Header: 'c_type', accessor: 'type' }, - { Header: 'c_process', accessor: 'process' }, - { Header: 'c_host', accessor: 'host' }, - { Header: 'c_rule', accessor: 'rule' }, - { Header: 'c_chains', accessor: 'chains' }, - { Header: 'c_time', accessor: 'start' }, - { Header: 'c_dl_speed', accessor: 'downloadSpeedCurr', sortDescFirst }, - { Header: 'c_ul_speed', accessor: 'uploadSpeedCurr', sortDescFirst }, - { Header: 'c_dl', accessor: 'download', sortDescFirst }, - { Header: 'c_ul', accessor: 'upload', sortDescFirst }, - { Header: 'c_source', accessor: 'source' }, - { Header: 'c_destination_ip', accessor: 'destinationIP' }, - { Header: 'c_sni', accessor: 'sniffHost' }, -]; +const getItemStyle = (isDragging, draggableStyle) => { + return { + ...draggableStyle, + ...(isDragging && { background: 'transparent' }), + }; +}; + +const savedColumns = localStorage.getItem('columns'); +const columnsInit = savedColumns + ? JSON.parse(savedColumns) + : [ + { accessor: 'id', show: false }, + { Header: 'c_type', accessor: 'type' }, + { Header: 'c_process', accessor: 'process' }, + { Header: 'c_host', accessor: 'host' }, + { Header: 'c_rule', accessor: 'rule' }, + { Header: 'c_chains', accessor: 'chains' }, + { Header: 'c_time', accessor: 'start' }, + { Header: 'c_dl_speed', accessor: 'downloadSpeedCurr', sortDescFirst }, + { Header: 'c_ul_speed', accessor: 'uploadSpeedCurr', sortDescFirst }, + { Header: 'c_dl', accessor: 'download', sortDescFirst }, + { Header: 'c_ul', accessor: 'upload', sortDescFirst }, + { Header: 'c_source', accessor: 'source' }, + { Header: 'c_destination_ip', accessor: 'destinationIP' }, + { Header: 'c_sni', accessor: 'sniffHost' }, + ]; function renderCell(cell: { column: { id: string }; value: number }, locale: Locale) { switch (cell.column.id) { @@ -53,6 +64,7 @@ const tableState = { }; function Table({ data }) { + const [columns, setColumns] = useState(columnsInit); const { getTableProps, headerGroups, rows, prepareRow } = useTable( { columns, @@ -75,49 +87,79 @@ function Table({ data }) { locale = enUS; } - return ( - <div {...getTableProps()}> - {headerGroups.map((headerGroup) => { - return ( - <div {...headerGroup.getHeaderGroupProps()} className={s.tr}> - {headerGroup.headers.map((column, index) => ( - <div - {...column.getHeaderProps(column.getSortByToggleProps())} - className={index == 0 || (index >= 5 && index < 10) ? s.thdu : s.th} - > - <span>{t(column.render('Header'))}</span> - <span className={s.sortIconContainer}> - {column.isSorted ? ( - <span className={column.isSortedDesc ? '' : s.rotate180}> - <ChevronDown size={16} /> - </span> - ) : null} - </span> - </div> - ))} + const onDragEnd = (result) => { + if (!result.destination) { + return; + } - {rows.map((row, i) => { - prepareRow(row); - return row.cells.map((cell, j) => { - return ( - <div - {...cell.getCellProps()} - className={cx( - s.td, - i % 2 === 0 ? s.odd : false, - j == 0 || (j >= 5 && j < 10) ? s.center : true - // j ==1 ? s.break : true - )} - > - {renderCell(cell, locale)} - </div> - ); - }); + const items = Array.from(columns); + const [removed] = items.splice(result.source.index, 1); + items.splice(result.destination.index, 0, removed); + setColumns(items); + localStorage.setItem('columns', JSON.stringify(items)); + }; + + return ( + <DragDropContext onDragEnd={onDragEnd}> + <Droppable droppableId="droppable" direction="horizontal"> + {(provided) => ( + <div {...getTableProps()} {...provided.droppableProps} ref={provided.innerRef}> + {headerGroups.map((headerGroup) => { + return ( + <div {...headerGroup.getHeaderGroupProps()} className={s.tr}> + {headerGroup.headers.map((column, index) => ( + <Draggable + key={column.render('Header')} + draggableId={column.render('Header')} + index={columns.findIndex((i) => i.Header === column.render('Header'))} + > + {(provided, snapshot) => ( + <div + ref={provided.innerRef} + {...column.getHeaderProps(column.getSortByToggleProps())} + {...provided.draggableProps} + {...provided.dragHandleProps} + style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)} + className={index == 0 || (index >= 5 && index < 10) ? s.thdu : s.th} + > + <span>{t(column.render('Header'))}</span> + <span className={s.sortIconContainer}> + {column.isSorted ? ( + <span className={column.isSortedDesc ? '' : s.rotate180}> + <ChevronDown size={16} /> + </span> + ) : null} + </span> + </div> + )} + </Draggable> + ))} + {rows.map((row, i) => { + prepareRow(row); + return row.cells.map((cell, j) => { + return ( + <div + {...cell.getCellProps()} + className={cx( + s.td, + i % 2 === 0 ? s.odd : false, + j == 0 || (j >= 5 && j < 10) ? s.center : true + // j ==1 ? s.break : true + )} + > + {renderCell(cell, locale)} + </div> + ); + }); + })} + </div> + ); })} + {provided.placeholder} </div> - ); - })} - </div> + )} + </Droppable> + </DragDropContext> ); } |
