From 7cf13a8b3bfdf2d3877745b8700c8abf5b24156c Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Wed, 16 Apr 2025 23:49:34 +0100 Subject: [PATCH] Add user search and pagination --- packages/web_ui/src/components/UsersPage.tsx | 41 +++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/packages/web_ui/src/components/UsersPage.tsx b/packages/web_ui/src/components/UsersPage.tsx index 4a2acbfa..1cf27ff3 100644 --- a/packages/web_ui/src/components/UsersPage.tsx +++ b/packages/web_ui/src/components/UsersPage.tsx @@ -1,9 +1,16 @@ -import React, { useEffect, useContext, useState } from "react"; +import React, { useEffect, useContext, useState, useRef } from "react"; import { useNavigate } from "react-router-dom"; -import { Button, Form, FormInstance, GetProp, Input, Modal, Radio, Space, Table, Tag, Upload, UploadProps } from "antd"; -import { InboxOutlined } from "@ant-design/icons"; import { Static } from "@sinclair/typebox"; +import { + Button, Form, FormInstance, Input, InputRef, Modal, + Radio, Space, Table, Tag, Upload, UploadProps, +} from "antd"; + +import { + InboxOutlined, SearchOutlined, +} from "@ant-design/icons"; + import * as lib from "@clusterio/lib"; import { useAccount } from "../model/account"; @@ -370,7 +377,8 @@ export default function UsersPage() { let navigate = useNavigate(); let [users] = useUsers(); - let [roles, setRoles] = useState(new Map()); + const [roles, setRoles] = useState(new Map()); + const searchInput = useRef(null); useEffect(() => { control.send(new lib.RoleListRequest()).then(newRoles => { @@ -404,6 +412,24 @@ export default function UsersPage() { , defaultSortOrder: "ascend", sorter: (a, b) => strcmp(a.name, b.name), + filterIcon: (filtered) => , + onFilter: (value, record) => record.name.toLowerCase().includes((value as string).toLowerCase()), + filterDropdownProps: { + onOpenChange: open => open && setTimeout(() => searchInput.current?.select(), 100), + }, + filterDropdown: ({ selectedKeys, setSelectedKeys, confirm, clearFilters }) => ( +
e.stopPropagation()}> + setSelectedKeys([e.target.value])} + onClear={() => clearFilters && clearFilters({ confirm: true, closeDropdown: true })} + onSearch={() => confirm({ closeDropdown: true })} + /> +
+ ), }, { title: "Roles", @@ -439,7 +465,12 @@ export default function UsersPage() { }, ]} dataSource={[...users.values()]} - pagination={false} + pagination={{ + defaultPageSize: 50, + showSizeChanger: true, + pageSizeOptions: ["10", "20", "50", "100", "200"], + showTotal: total => `${total} Users`, + }} rowKey={user => user.name} onRow={(user, rowIndex) => ({ onClick: event => {