From d5fa59f4779990d6c68f278515fd40a5893b8a85 Mon Sep 17 00:00:00 2001 From: Dreamacro <8615343+Dreamacro@users.noreply.github.com> Date: Tue, 3 Nov 2020 21:51:03 +0800 Subject: [PATCH] Feature: add connections filter --- src/containers/Connections/Devices/index.tsx | 35 +++++++++++++++++++ src/containers/Connections/Devices/style.scss | 21 +++++++++++ src/containers/Connections/index.tsx | 32 ++++++++++++++--- src/containers/Connections/style.scss | 4 +-- src/containers/Logs/style.scss | 4 ++- src/styles/variables.scss | 1 + 6 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 src/containers/Connections/Devices/index.tsx create mode 100644 src/containers/Connections/Devices/style.scss diff --git a/src/containers/Connections/Devices/index.tsx b/src/containers/Connections/Devices/index.tsx new file mode 100644 index 0000000..d228676 --- /dev/null +++ b/src/containers/Connections/Devices/index.tsx @@ -0,0 +1,35 @@ +import React from 'react' +import classnames from 'classnames' +import { BaseComponentProps } from '@models' +import './style.scss' + +interface DevicesProps extends BaseComponentProps { + devices: Array<{ label: string, number: number }> + selected: string + onChange?: (label: string) => void +} + +export function Devices (props: DevicesProps) { + const { className, style } = props + const classname = classnames('connections-devices', className) + function handleSelected (label: string) { + props.onChange?.(label) + } + + return ( +
+
handleSelected('')}>全部
+ { + props.devices.map( + device => ( +
handleSelected(device.label)}> + { device.label } ({ device.number }) +
+ ) + ) + } +
+ ) +} diff --git a/src/containers/Connections/Devices/style.scss b/src/containers/Connections/Devices/style.scss new file mode 100644 index 0000000..8f24e05 --- /dev/null +++ b/src/containers/Connections/Devices/style.scss @@ -0,0 +1,21 @@ +@import '~@styles/variables'; + +.connections-devices { + display: flex; + padding: 12px 0; +} + +.connections-devices-item { + padding: 4px 10px; + margin-right: 12px; + font-size: 14px; + color: $color-gray-darken; + background-color: $color-gray-light; + border-radius: 3px; + cursor: pointer; + transition: color .3s ease; + + &.selected { + color: $color-primary-dark; + } +} diff --git a/src/containers/Connections/index.tsx b/src/containers/Connections/index.tsx index 0534ef5..6ed3f79 100644 --- a/src/containers/Connections/index.tsx +++ b/src/containers/Connections/index.tsx @@ -1,7 +1,8 @@ -import React, { useMemo, useLayoutEffect, useCallback, useRef } from 'react' -import { Cell, Column, ColumnInstance, TableOptions, useBlockLayout, useResizeColumns, UseResizeColumnsColumnProps, UseResizeColumnsOptions, useSortBy, UseSortByColumnOptions, UseSortByColumnProps, UseSortByOptions, useTable } from 'react-table' +import React, { useMemo, useLayoutEffect, useCallback, useRef, useState } from 'react' +import { Cell, Column, ColumnInstance, TableInstance, TableOptions, useBlockLayout, useFilters, UseFiltersInstanceProps, UseFiltersOptions, useResizeColumns, UseResizeColumnsColumnProps, UseResizeColumnsOptions, useSortBy, UseSortByColumnOptions, UseSortByColumnProps, UseSortByOptions, useTable } from 'react-table' import classnames from 'classnames' import { useScroll } from 'react-use' +import { groupBy } from 'lodash' import { Header, Card, Checkbox, Modal, Icon } from '@components' import { useI18n } from '@stores' import * as API from '@lib/request' @@ -9,6 +10,7 @@ import { StreamReader } from '@lib/streamer' import { useObject, useVisible } from '@lib/hook' import { fromNow } from '@lib/date' import { RuleType } from '@models' +import { Devices } from './Devices' import { useConnections } from './store' import './style.scss' @@ -39,7 +41,12 @@ type TableColumnOption = interface ITableOptions extends TableOptions, - UseSortByOptions {} + UseSortByOptions, + UseFiltersOptions {} + +interface ITableInstance extends + TableInstance, + UseFiltersInstanceProps {} function formatTraffic(num: number) { const s = ['B', 'KB', 'MB', 'GB', 'TB'] @@ -117,6 +124,10 @@ export default function Connections() { completed: !!c.completed }) ), [connections]) + const devices = useMemo(() => { + const gb = groupBy(connections, 'metadata.sourceIP') + return Object.keys(gb).map(key => ({ label: key, number: gb[key].length })) + }, [connections]) // table const tableRef = useRef(null) @@ -181,18 +192,21 @@ export default function Connections() { getTableBodyProps, headerGroups, rows, - prepareRow + prepareRow, + setFilter } = useTable( { columns, data, autoResetSortBy: false, + autoResetFilters: false, initialState: { sortBy: [{ id: Columns.Time, desc: false }] } } as ITableOptions, useResizeColumns, useBlockLayout, + useFilters, useSortBy - ) + ) as ITableInstance const headerGroup = useMemo(() => headerGroups[0], [headerGroups]) const renderCell = useCallback(function (cell: Cell) { switch (cell.column.id) { @@ -208,6 +222,13 @@ export default function Connections() { } }, [lang]) + // filter + const [device, setDevice] = useState('') + function handleDeviceSelected (label: string) { + setDevice(label) + setFilter?.(Columns.SourceIP, label) + } + return (
@@ -217,6 +238,7 @@ export default function Connections() { {t('keepClosed')}
+ { devices.length > 1 && }
diff --git a/src/containers/Connections/style.scss b/src/containers/Connections/style.scss index e16dfef..169df19 100644 --- a/src/containers/Connections/style.scss +++ b/src/containers/Connections/style.scss @@ -27,7 +27,7 @@ position: relative; text-align: center; color: $color-gray-darken; - background: #f3f6f9; + background: $color-gray-light; height: $height; line-height: $height; font-weight: 500; @@ -105,7 +105,7 @@ } &.completed { - background-color: darken(#f3f6f9, 3%); + background-color: darken($color-gray-light, 3%); color: rgba($color-primary-darken, 50%); } diff --git a/src/containers/Logs/style.scss b/src/containers/Logs/style.scss index b377ef5..db8570d 100644 --- a/src/containers/Logs/style.scss +++ b/src/containers/Logs/style.scss @@ -1,3 +1,5 @@ +@import '~@styles/variables'; + .logs-card { display: flex; flex-direction: column; @@ -13,7 +15,7 @@ list-style: none; padding: 10px; border-radius: 2px; - background-color: #f3f6f9; + background-color: $color-gray-light; font-size: 12px; color: #73808f; overflow-y: auto; diff --git a/src/styles/variables.scss b/src/styles/variables.scss index 2cd0873..b636b43 100644 --- a/src/styles/variables.scss +++ b/src/styles/variables.scss @@ -14,6 +14,7 @@ $color-primary-lightly: #e4eaef; // common colors $color-gray: #d8dee2; +$color-gray-light: #f3f6f9; $color-gray-dark: #b7c5d6; $color-gray-darken: #909399; $color-white: #fff;