antd/lib/table/interface#SorterResult TypeScript Examples

The following examples show how to use antd/lib/table/interface#SorterResult. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.tsx    From next-basics with GNU General Public License v3.0 6 votes vote down vote up
// istanbul ignore next
  private frontendSearch(
    pagination: TablePaginationConfig,
    filters: Record<string, string[]>,
    sorter: SorterResult<Record<string, any>>
  ): void {
    this.sort = isNil(sorter.order) ? null : (sorter.columnKey as string);
    this.order = isNil(sorter.order) ? null : this._fields[sorter.order];
  }
Example #2
Source File: index.tsx    From next-basics with GNU General Public License v3.0 6 votes vote down vote up
private _handleOnChange = (
    pagination: TablePaginationConfig,
    filters: Record<string, string[]>,
    sorter: SorterResult<Record<string, any>>
  ): void => {
    // 排序
    if (sorter.columnKey !== this.sort || sorter.order !== this.order) {
      if (sorter.columnKey && sorter.order) {
        this.sort = sorter.columnKey as string;
        this.order = sorter.order;
      } else {
        this.sort = null;
        this.order = null;
      }
      this.sortUpdate.emit({
        sort: this.sort,
        order: this.order,
      });
    }
  };
Example #3
Source File: index.tsx    From next-basics with GNU General Public License v3.0 5 votes vote down vote up
// 对前端搜索数据进行排序
  private handleFrontendSorter(
    dataSource: Record<string, any>[],
    sorter: Partial<SorterResult<Record<string, any>>>
  ): Record<string, any>[] {
    const tempDataSource: Record<string, any>[] = dataSource || [];
    const { columnKey, order } = sorter;

    if (!columnKey || !order) {
      return dataSource;
    }

    let direction: 1 | -1;

    if (order === "descend") {
      direction = -1;
    } else if (order === "ascend") {
      direction = 1;
    }

    if (direction !== undefined) {
      tempDataSource.sort((a, b) => {
        const aValue = get(a, columnKey);
        const bValue = get(b, columnKey);

        if (isNil(aValue)) {
          if (!isNil(bValue)) {
            return 1;
          }
        } else {
          if (isNil(bValue)) {
            return -1;
          }
        }

        if (aValue == bValue) {
          return 0;
        }

        if (aValue > bValue) {
          return direction;
        }

        return -direction;
      });
      tempDataSource.forEach((item) => {
        const children = item[this.childrenColumnName];

        if (children) {
          this.handleFrontendSorter(children, sorter);
        }
      });
    }

    return tempDataSource;
  }
Example #4
Source File: index.tsx    From next-basics with GNU General Public License v3.0 5 votes vote down vote up
private _handleOnChange = (
    pagination: TablePaginationConfig,
    filters: Record<string, string[]>,
    sorter: SorterResult<Record<string, any>>
  ): void => {
    const history = getHistory();
    const urlSearchParams = new URLSearchParams(history.location.search);
    // 分页
    if (!isEmpty(pagination)) {
      if (pagination.pageSize !== this.pageSize) {
        pagination.current = 1;
        urlSearchParams.set("page", "1");
        urlSearchParams.set("pageSize", pagination.pageSize.toString());
        this.filterUpdate.emit({
          [this._fields.pageSize]: pagination.pageSize,
          [this._fields.page]: 1,
        });
        this.page = 1;
        this.pageSize = pagination.pageSize;
      } else if (pagination.current !== this.page) {
        const newPage = pagination.current || 1;
        urlSearchParams.set("page", newPage.toString());
        this.pageUpdate.emit({
          [this._fields.page]: newPage, // 可配置的 path
        });
        this.page = newPage;
      }
    }
    this.filters = filters;
    // 过滤
    if (!isEmpty(filters)) {
      forEach(filters, (value: any, key) => {
        isNil(value) || value.length === 0
          ? urlSearchParams.delete(key)
          : urlSearchParams.set(key, value);
      });
    }
    // 排序
    if (
      sorter.columnKey !== this.sort ||
      this._fields[sorter.order] !== this.order
    ) {
      if (sorter.columnKey && sorter.order) {
        urlSearchParams.set("sort", sorter.columnKey as string);
        urlSearchParams.set("order", this._fields[sorter.order].toString());
        this.sort = sorter.columnKey as string;
        this.order = this._fields[sorter.order];
      } else {
        urlSearchParams.delete("sort");
        urlSearchParams.delete("order");
        this.sort = null;
        this.order = null;
      }
      this.sortUpdate.emit({
        sort: this.sort,
        order: this.order,
      });
    }
    if (this.frontSearch) {
      if (this.shouldUpdateUrlParams) {
        history.push(`?${urlSearchParams}`, { notify: false });
      }
      this.frontendSearch(pagination, filters, sorter);
    } else {
      if (this.shouldUpdateUrlParams) {
        history.push(`?${urlSearchParams}`, {
          notify: !!this.shouldRenderWhenUrlParamsUpdate,
        });
      }
    }
  };
Example #5
Source File: sorter.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
useSorterMenu = <T extends object>(onTableSort: (params: SorterResult<T>) => void) => {
  const [sortConfig, setSortConfig] = React.useState<SorterResult<T>>({});
  const sortCompareRef = React.useRef<((a: T, b: T) => number) | null>(null);
  const [prefixCls] = usePrefixCls('table');
  const [locale] = useLocaleReceiver('Table');

  const alignMap = React.useMemo(
    () => ({
      center: `${prefixCls}-justify-center`,
      left: `${prefixCls}-justify-start`,
      right: `${prefixCls}-justify-end`,
    }),
    [prefixCls],
  );

  const onSort = React.useCallback(
    (column: ErdaColumnType<T>, order?: SortOrder) => {
      const sorter = {
        column,
        columnKey: column.dataIndex,
        field: column.dataIndex,
      } as SorterResult<T>;
      setSortConfig({ ...sorter, order });
      const { sorter: columnSorter } = column;

      if (order && typeof columnSorter === 'function') {
        // eslint-disable-next-line no-param-reassign
        sortCompareRef.current = (a: T, b: T) => {
          if (order === 'ascend') {
            return columnSorter(a, b);
          } else {
            return columnSorter(b, a);
          }
        };
      } else if (
        order &&
        columnSorter &&
        typeof columnSorter !== 'boolean' &&
        'compare' in columnSorter &&
        columnSorter.compare
      ) {
        // eslint-disable-next-line no-param-reassign
        sortCompareRef.current = (a: T, b: T) => {
          if (order === 'ascend') {
            return columnSorter.compare!(a, b);
          } else {
            return columnSorter.compare!(b, a);
          }
        };
      } else {
        // eslint-disable-next-line no-param-reassign
        sortCompareRef.current = null;
        onTableSort({ ...sorter, order });
      }
    },
    [onTableSort],
  );

  const menuRender = React.useCallback(
    (column: ErdaColumnType<T>) => {
      return (
        <Menu>
          <Menu.Item key={'0'} onClick={() => onSort(column)}>
            <span className={`${prefixCls}-menu-item`}>{locale.cancelSort}</span>
          </Menu.Item>
          <Menu.Item key={'ascend'} onClick={() => onSort(column, 'ascend')}>
            <span className={`${prefixCls}-menu-item`}>
              <ErdaIcon type="shengxu" className={`${prefixCls}-menu-icon`} />
              {locale.ascend}
            </span>
          </Menu.Item>
          <Menu.Item key={'descend'} onClick={() => onSort(column, 'descend')}>
            <span className={`${prefixCls}-menu-item`}>
              <ErdaIcon type="jiangxu" className={`${prefixCls}-menu-icon`} />
              {locale.descend}
            </span>
          </Menu.Item>
        </Menu>
      );
    },
    [locale, onSort, prefixCls],
  );

  const renderSortTitle = React.useCallback(
    (column: ErdaColumnType<T>) => {
      const { title, align, dataIndex } = column;

      return (
        <Dropdown
          trigger={['click']}
          overlay={menuRender(column)}
          align={{ offset: [0, 5] }}
          overlayClassName={`${prefixCls}-sorter-overlay`}
          placement={align === 'right' ? 'bottomRight' : 'bottomLeft'}
          getPopupContainer={() => document.body}
        >
          <span className={cn(`${prefixCls}-sorter`, align ? alignMap[align] : undefined)}>
            {typeof title === 'function' ? title({}) : title}
            <span className={cn(`${prefixCls}-sorter-icon`)}>
              {sortConfig.order && sortConfig.columnKey === dataIndex ? (
                sortIcon[sortConfig.order]
              ) : (
                <ErdaIcon type="caret-down" size={16} className={cn(`${prefixCls}-sorter-icon-content`)} />
              )}
            </span>
          </span>
        </Dropdown>
      );
    },
    [alignMap, menuRender, prefixCls, sortConfig.columnKey, sortConfig.order],
  );

  return [renderSortTitle, sortConfig, sortCompareRef] as [
    (column: ErdaColumnType<T>) => JSX.Element,
    SorterResult<T>,
    React.MutableRefObject<((a: T, b: T) => number) | null>,
  ];
}
Example #6
Source File: PortAssetPage.tsx    From yakit with GNU Affero General Public License v3.0 4 votes vote down vote up
PortAssetTable: React.FC<PortAssetTableProp> = (props) => {
    const [response, setResponse] = useState<QueryGeneralResponse<PortAsset>>({
        Data: [], Pagination: {
            Limit: 15, Page: 1, OrderBy: "desc", Order: "updated_at",
        } as PaginationSchema, Total: 0
    });
    const [params, setParams] = useState<QueryPortsRequest>({
        Hosts: "", Ports: "", Service: "", State: props.closed ? "closed" : "open", Pagination: {
            Limit: 15, Page: 1, OrderBy: "desc", Order: "updated_at",
        },
    });
    const [loading, setLoading] = useState(false);
    const [outputByNetwork, setOutputByNetwork] = useState("");
    const [checkedURL, setCheckedURL] = useState<string[]>([])
    const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([])

    const update = (current?: number, pageSize?: number, order?: string, orderBy?: string) => {
        setLoading(true)
        ipcRenderer.invoke("QueryPorts", {
            ...params,
            Pagination: {
                Limit: pageSize || response.Pagination.Limit,
                Page: current || response.Pagination.Page,
                Order: order || "desc",
                OrderBy: orderBy || "updated_at"
            }
        }).then(data => {
            setResponse(data)
        }).catch((e: any) => {
            failed("QueryPorts failed: " + `${e}`)
        }).finally(() => setTimeout(() => setLoading(false), 300))
    }

    useEffect(() => {
        update()
    }, [])

    return <Table<PortAsset>
        title={() => {
            return <Row>
                <Col span={12}>
                    <Space>
                        端口资产列表 <Button
                        icon={<ReloadOutlined/>} size={"small"} type={"link"}
                        onClick={() => {
                            update(1)
                            setSelectedRowKeys([])
                            setCheckedURL([])
                        }}
                    />
                    </Space>
                </Col>
                <Col span={12} style={{textAlign: "right"}}>
                    <Space>
                        <Popover title={"输入想要导出的端口的网段(支持C段等 CIDR 格式,逗号分隔)"}
                                 trigger={["click"]}
                                 content={<div>
                                     <Form layout={"inline"} size={"small"} onSubmitCapture={e => {
                                         e.preventDefault()

                                         startExecYakCode("Output Ports", {
                                             Script: OutputAsset.outputPortByNetwork, Params: [
                                                 {Key: "network", Value: outputByNetwork}
                                             ]
                                         })
                                     }}>
                                         <InputItem
                                             label={"网段"} value={outputByNetwork}
                                             setValue={setOutputByNetwork}
                                         />
                                         <Form.Item colon={false} label={" "}>
                                             <Button size={"small"} type="primary" htmlType="submit"> 导出 </Button>
                                         </Form.Item>
                                     </Form>
                                 </div>}
                        >
                            <Button
                                type={"primary"}
                                size={"small"}
                            >导出端口</Button>
                        </Popover>
                        <Popover
                            title={"选择性删除端口"}
                            content={<PortDeleteForm onFinished={() => {
                                update(1)
                                setSelectedRowKeys([])
                                setCheckedURL([])
                            }}/>}
                        >
                            <Button size={"small"} danger={true}>删除端口</Button>
                        </Popover>
                        <DropdownMenu 
                            menu={{data: [
                                {key:'bug-test',title:"发送到漏洞检测"},
                                {key:'scan-port',title:"发送到端口扫描"},
                                {key:'brute',title:"发送到爆破"}
                            ]}}
                            dropdown={{placement: "bottomRight"}}
                            onClick={(key) => {
                                if(checkedURL.length === 0){
                                    failed("请最少选择一个选项再进行操作")
                                    return
                                }

                                ipcRenderer.invoke("send-to-tab", {
                                    type: key,
                                    data:{URL: JSON.stringify(checkedURL)}
                                })
                            }}
                        >
                            <Button type="link" icon={<LineMenunIcon />}></Button>
                        </DropdownMenu>
                    </Space>
                </Col>
            </Row>
        }}
        scroll={{x: "auto"}}
        size={"small"}
        bordered={true}
        rowKey={(row) => row.Id}
        onRow={r => {
            return {
                onClick: e => {
                    // props.onClicked && props.onClicked(r)
                },
            }
        }}
        expandable={{
            expandedRowRender: record => <PortAssetDescription port={record}/>,
        }}
        loading={loading}
        columns={props.closed ? [
            {
                title: "网络地址",
                render: (i: PortAsset) => <CopyableField text={`${i.Host}:${i.Port}`}/>,
                filterDropdown: ({setSelectedKeys, selectedKeys, confirm}) => {
                    return params && setParams && <TableFilterDropdownForm
                        label={"搜索IP/网段"} params={params} setParams={setParams}
                        filterName={"Hosts"} pureString={true}
                        confirm={confirm} setSelectedKeys={setSelectedKeys}
                    />
                }, width: 200,
                filterIcon: filtered => {
                    return params && !!setParams && <SearchOutlined style={{color: filtered ? '#1890ff' : undefined}}/>
                },
            },
            {
                title: "端口", width: 70,
                render: (i: PortAsset) => <Tag color={"geekblue"}>{i.Port}</Tag>,
                filterDropdown: ({setSelectedKeys, selectedKeys, confirm}) => {
                    return params && setParams && <TableFilterDropdownForm
                        label={"搜索端口"} params={params} setParams={setParams}
                        filterName={"Ports"} autoCompletions={[]} pureString={true}
                        confirm={confirm} setSelectedKeys={setSelectedKeys}
                    />
                },
                filterIcon: filtered => {
                    return params && !!setParams && <SearchOutlined style={{color: filtered ? '#1890ff' : undefined}}/>
                },
            },
            {
                title: "关闭原因",
                render: (i: PortAsset) => i.ServiceType ? <div style={{width: 230, overflow: "auto"}}><CopyableField
                    text={i.Reason}/></div> : "", width: 250,
            },
        ] : [
            {
                title: "网络地址",
                render: (i: PortAsset) => <CopyableField text={`${i.Host}:${i.Port}`}/>,
                filterDropdown: ({setSelectedKeys, selectedKeys, confirm}) => {
                    return params && setParams && <TableFilterDropdownForm
                        label={"搜索IP/网段"} params={params} setParams={setParams}
                        filterName={"Hosts"} pureString={true}
                        confirm={confirm} setSelectedKeys={setSelectedKeys}
                    />
                }, width: 200,
                filterIcon: filtered => {
                    return params && !!setParams && <SearchOutlined style={{color: filtered ? '#1890ff' : undefined}}/>
                },
            },
            {
                title: "端口", width: 70,
                render: (i: PortAsset) => <Tag color={"geekblue"}>{i.Port}</Tag>,
                filterDropdown: ({setSelectedKeys, selectedKeys, confirm}) => {
                    return params && setParams && <TableFilterDropdownForm
                        label={"搜索端口"} params={params} setParams={setParams}
                        filterName={"Ports"} autoCompletions={[]} pureString={true}
                        confirm={confirm} setSelectedKeys={setSelectedKeys}
                    />
                },
                filterIcon: filtered => {
                    return params && !!setParams && <SearchOutlined style={{color: filtered ? '#1890ff' : undefined}}/>
                },
            },
            {
                title: "协议", width: 57,
                render: (i: PortAsset) => <Tag color={"green"}>{i.Proto}</Tag>,
            },
            {
                title: "服务指纹",
                render: (i: PortAsset) => i.ServiceType ? <div style={{width: 230, overflowX: 'hidden'}}><CopyableField
                    noCopy={true}
                    text={i.ServiceType}/></div> : "", width: 250,
                filterDropdown: ({setSelectedKeys, selectedKeys, confirm}) => {
                    return params && setParams && <TableFilterDropdownForm
                        label={"服务关键字"} params={params} setParams={setParams}
                        filterName={"Service"} autoCompletions={[]} pureString={true}
                        confirm={confirm} setSelectedKeys={setSelectedKeys}
                    />
                },
                filterIcon: filtered => {
                    return params && !!setParams && <SearchOutlined style={{color: filtered ? '#1890ff' : undefined}}/>
                },
            },
            {
                title: "Title",
                render: (i: PortAsset) => i.ServiceType ? <div style={{width: 150, overflow: "auto"}}><CopyableField
                    noCopy={true}
                    text={i.HtmlTitle}/></div> : "", width: 170,
                filterDropdown: ({setSelectedKeys, selectedKeys, confirm}) => {
                    return params && setParams && <TableFilterDropdownForm
                        label={"Html Title"} params={params} setParams={setParams}
                        filterName={"Title"} autoCompletions={[]} pureString={true}
                        confirm={confirm} setSelectedKeys={setSelectedKeys}
                    />
                },
                filterIcon: filtered => {
                    return params && !!setParams && <SearchOutlined style={{color: filtered ? '#1890ff' : undefined}}/>
                },
            },
            {title: "最近更新时间", render: (i: PortAsset) => <Tag color={"green"}>{formatTimestamp(i.UpdatedAt)}</Tag>},
            {
                title: "操作", render: (i: PortAsset) => <Button
                    size={"small"} type={"link"}
                    onClick={e => {
                        openExternalWebsite(`http://${i.Host}:${i.Port}`)
                    }}>浏览器打开</Button>, fixed: "right",
            },
        ]}
        dataSource={response.Data}
        pagination={{
            size: "small",
            pageSize: response.Pagination?.Limit || 10,
            total: response.Total, showTotal: (i) => <Tag>共{i}条记录</Tag>,
            showSizeChanger: true, showLessItems: true,
        }}
        // @ts-ignore*/
        onChange={(paging: any, _: any, sorter: SorterResult<HTTPFlow>) => {
            if (sorter.order && sorter.columnKey) {
                update(paging.current, paging.pageSize, sorter.order, `${sorter.columnKey}`)
            } else {
                update(paging.current, paging.pageSize)
                setSelectedRowKeys([])
                setCheckedURL([])
            }
        }}
        rowSelection={{
            onChange: (selectedRowKeys, selectedRows) => {
                setSelectedRowKeys(selectedRowKeys as string[])
                setCheckedURL(selectedRows.map(item => `${item.Host}:${item.Port}`))
            },
            selectedRowKeys
        }}
    >
    </Table>
}