diff --git a/webui/src/lib/components/auth/forms.jsx b/webui/src/lib/components/auth/forms.jsx index 8f2b087952b..12608461c78 100644 --- a/webui/src/lib/components/auth/forms.jsx +++ b/webui/src/lib/components/auth/forms.jsx @@ -10,7 +10,7 @@ import {useAPI} from "../../hooks/api"; import {Checkbox, DataTable, DebouncedFormControl, AlertError, Loading} from "../controls"; -export const AttachModal = ({ show, searchFn, onAttach, onHide, resolveEntityFN = (ent => ent.id), addText = "Add", +export const AttachModal = ({ show, searchFn, resolveEntityFn = (ent => ent.id), onAttach, onHide , addText = "Add", emptyState = 'No matches', modalTitle = 'Add', headers = ['Select', 'ID'], filterPlaceholder = 'Filter...'}) => { const search = useRef(null); @@ -42,7 +42,7 @@ export const AttachModal = ({ show, searchFn, onAttach, onHide, resolveEntityFN onAdd={() => setSelected([...selected, ent])} onRemove={() => setSelected(selected.filter(selectedEnt => selectedEnt.id !== ent.id))} name={'selected'}/>, - {resolveEntityFN(ent)} + {resolveEntityFn(ent)} ]}/>
@@ -51,7 +51,7 @@ export const AttachModal = ({ show, searchFn, onAttach, onHide, resolveEntityFN Selected: {(selected.map(item => ( - {resolveEntityFN(item)} + {resolveEntityFn(item)} )))}

diff --git a/webui/src/lib/components/auth/users.jsx b/webui/src/lib/components/auth/users.jsx new file mode 100644 index 00000000000..8f317148359 --- /dev/null +++ b/webui/src/lib/components/auth/users.jsx @@ -0,0 +1,20 @@ +import {auth, MAX_LISTING_AMOUNT} from "../../api"; + +export const allUsersFromLakeFS = async (resolveUserDisplayNameFN = (user => user.id)) => { + let after = "" + let hasMore = true + let usersList = [] + try { + do { + const results = await auth.listUsers("", after, MAX_LISTING_AMOUNT); + usersList = usersList.concat(results.results); + after = results.pagination.next_offset; + hasMore = results.pagination.has_more; + } while (hasMore); + usersList.sort((a, b) => resolveUserDisplayNameFN(a).localeCompare(resolveUserDisplayNameFN(b))); + return usersList; + } catch (error) { + console.error("Error fetching users:", error); + return []; + } +} \ No newline at end of file diff --git a/webui/src/pages/auth/groups/group/members.jsx b/webui/src/pages/auth/groups/group/members.jsx index c7c9fe9842c..3cdef8a439d 100644 --- a/webui/src/pages/auth/groups/group/members.jsx +++ b/webui/src/pages/auth/groups/group/members.jsx @@ -4,7 +4,7 @@ import Button from "react-bootstrap/Button"; import {GroupHeader} from "../../../../lib/components/auth/nav"; import {useAPIWithPagination} from "../../../../lib/hooks/api"; -import {auth, MAX_LISTING_AMOUNT} from "../../../../lib/api"; +import {auth} from "../../../../lib/api"; import {Paginator} from "../../../../lib/components/pagination"; import {AttachModal} from "../../../../lib/components/auth/forms"; import {ConfirmationButton} from "../../../../lib/components/modals"; @@ -20,6 +20,7 @@ import { import {useRouter} from "../../../../lib/hooks/router"; import {Link} from "../../../../lib/components/nav"; import {resolveUserDisplayName} from "../../../../lib/utils"; +import {allUsersFromLakeFS} from "../../../../lib/components/auth/users"; const GroupMemberList = ({ groupId, after, onPaginate }) => { @@ -34,30 +35,13 @@ const GroupMemberList = ({ groupId, after, onPaginate }) => { setAttachError(null); }, [refresh]); - const allUsersFromLakeFS = async (resolveUserDisplayNameFN = (user => user.id)) => { - if (allUsers.length > 0) { - return allUsers - } - after = "" - let hasMore = true - let usersList = [] - try { - do { - const results = await auth.listUsers("", after, MAX_LISTING_AMOUNT); - usersList = usersList.concat(results.results); - after = results.pagination.next_offset; - hasMore = results.pagination.has_more; - } while (hasMore); - usersList.sort((a, b) => resolveUserDisplayNameFN(a).localeCompare(resolveUserDisplayNameFN(b))); - setAllUsers(usersList); - return usersList; - } catch (error) { - console.error("Error fetching users:", error); - return []; - } - } + const searchUsers = async (prefix, maxResults, resolveUserDisplayNameFN = (user => user.id)) => { - let allUsersList = await allUsersFromLakeFS(resolveUserDisplayNameFN) + let allUsersList = allUsers; + if (allUsersList.length == 0) { + allUsersList = await allUsersFromLakeFS(resolveUserDisplayNameFN) + setAllUsers(allUsersList) + } let filteredUsers = allUsersList.filter(user => resolveUserDisplayNameFN(user).startsWith(prefix)); return filteredUsers.slice(0, maxResults); }; @@ -101,7 +85,7 @@ const GroupMemberList = ({ groupId, after, onPaginate }) => { filterPlaceholder={'Find User...'} modalTitle={'Add to Group'} addText={'Add to Group'} - resolveEntityFN={resolveUserDisplayName} + resolveEntityFn={resolveUserDisplayName} searchFn={prefix => searchUsers(prefix, 5, resolveUserDisplayName).then(res => res)} onHide={() => setShowAddModal(false)} onAttach={(selected) => { diff --git a/webui/src/pages/auth/users/user/groups.jsx b/webui/src/pages/auth/users/user/groups.jsx index ccf9b0dfac4..bb8b0adc540 100644 --- a/webui/src/pages/auth/users/user/groups.jsx +++ b/webui/src/pages/auth/users/user/groups.jsx @@ -103,7 +103,7 @@ const UserGroupsList = ({ userId, after, onPaginate }) => { searchFn={(prefix) => auth.listGroups(prefix, "", 5).then((res) => res.results) } - resolveEntityFN={resolveGroupDisplayName} + resolveEntityFn={resolveGroupDisplayName} onHide={() => setShowAddModal(false)} onAttach={(selected) => { Promise.all(