summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorzephyr <[email protected]>2023-05-26 11:42:43 +0800
committerLarvan2 <[email protected]>2023-06-20 22:10:39 +0800
commitd2203727898dec31c290ff38e5d375670be36bb0 (patch)
tree6197e706b6fcf14c00afcf459ad903ce43c93953 /src/components
parente3bba3b401383a207da875b279d2e713048782ab (diff)
feat: dnd column
Diffstat (limited to 'src/components')
-rw-r--r--src/components/ConnectionTable.tsx156
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>
);
}