Files
mattermost-mobile/app/components/server_user_list/index.tsx
Javier Aguirre 655f55be20 Fix multiselect on users list integration selector (#6826)
* Moving selected ids to a parent

* typing selectedIds for user
2022-12-05 12:13:48 +01:00

138 lines
4.2 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {fetchProfiles, searchProfiles} from '@actions/remote/user';
import UserList from '@components/user_list';
import {General} from '@constants';
import {useServerUrl} from '@context/server';
import {debounce} from '@helpers/api/general';
import {filterProfilesMatchingTerm} from '@utils/user';
type Props = {
currentTeamId: string;
currentUserId: string;
teammateNameDisplay: string;
tutorialWatched: boolean;
handleSelectProfile: (user: UserProfile) => void;
term: string;
selectedIds: {[id: string]: UserProfile};
}
export default function ServerUserList({
currentTeamId,
currentUserId,
teammateNameDisplay,
tutorialWatched,
handleSelectProfile,
term,
selectedIds,
}: Props) {
const serverUrl = useServerUrl();
const next = useRef(true);
const page = useRef(-1);
const mounted = useRef(false);
const [profiles, setProfiles] = useState<UserProfile[]>([]);
const [searchResults, setSearchResults] = useState<UserProfile[]>([]);
const [loading, setLoading] = useState(false);
const selectedCount = Object.keys(selectedIds).length;
const isSearch = Boolean(term);
const loadedProfiles = ({users}: {users?: UserProfile[]}) => {
if (mounted.current) {
if (users && !users.length) {
next.current = false;
}
page.current += 1;
setLoading(false);
setProfiles((current) => {
if (users?.length) {
return [...current, ...users];
}
return current;
});
}
};
const getProfiles = useCallback(debounce(() => {
if (next.current && !loading && !term && mounted.current) {
setLoading(true);
fetchProfiles(serverUrl, page.current + 1, General.PROFILE_CHUNK_SIZE).then(loadedProfiles);
}
}, 100), [loading, isSearch, serverUrl, currentTeamId]);
const onHandleSelectProfile = useCallback((user: UserProfile) => {
handleSelectProfile(user);
}, [handleSelectProfile]);
const searchUsers = useCallback(async (searchTerm: string) => {
const lowerCasedTerm = searchTerm.toLowerCase();
setLoading(true);
const results = await searchProfiles(serverUrl, lowerCasedTerm, {allow_inactive: true});
let data: UserProfile[] = [];
if (results.data) {
data = results.data;
}
setSearchResults(data);
setLoading(false);
}, [serverUrl, currentTeamId]);
useEffect(() => {
searchUsers(term);
}, [term]);
useEffect(() => {
mounted.current = true;
getProfiles();
return () => {
mounted.current = false;
};
}, []);
const data = useMemo(() => {
if (term) {
const exactMatches: UserProfile[] = [];
const filterByTerm = (p: UserProfile) => {
if (selectedCount > 0 && p.id === currentUserId) {
return false;
}
if (p.username === term || p.username.startsWith(term)) {
exactMatches.push(p);
return false;
}
return true;
};
const results = filterProfilesMatchingTerm(searchResults, term).filter(filterByTerm);
return [...exactMatches, ...results];
}
return profiles;
}, [term, isSearch && selectedCount, isSearch && searchResults, profiles]);
return (
<UserList
currentUserId={currentUserId}
handleSelectProfile={onHandleSelectProfile}
loading={loading}
profiles={data}
selectedIds={selectedIds}
showNoResults={!loading && page.current !== -1}
teammateNameDisplay={teammateNameDisplay}
fetchMore={getProfiles}
term={term}
testID='create_direct_message.user_list'
tutorialWatched={tutorialWatched}
/>
);
}