UI : User profile page improvements (#9376)

* UI : User profile page improvements

* chore : remove owns and following fields from user api call

* chore: update effect logic to avoid unnecessary API calls
This commit is contained in:
Sachin Chaurasiya 2022-12-17 19:44:24 +05:30 committed by GitHub
parent 8e887d3506
commit 92bad23fcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 52 deletions

View File

@ -138,6 +138,8 @@ const Users = ({
const location = useLocation(); const location = useLocation();
const isTaskType = isEqual(threadType, ThreadType.Task); const isTaskType = isEqual(threadType, ThreadType.Task);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [isRolesLoading, setIsRolesLoading] = useState<boolean>(false);
const [isTeamsLoading, setIsTeamsLoading] = useState<boolean>(false);
const { authConfig } = useAuthContext(); const { authConfig } = useAuthContext();
const { t } = useTranslation(); const { t } = useTranslation();
@ -161,21 +163,23 @@ const Users = ({
[threadType, fetchFeedHandler] [threadType, fetchFeedHandler]
); );
const fetchTeams = () => { const fetchTeams = async () => {
getTeams(['users']) setIsTeamsLoading(true);
.then((res) => { try {
if (res.data) { const response = await getTeams(['users']);
setTeams(res.data); if (response.data) {
} else { setTeams(response.data);
throw jsonData['api-error-messages']['unexpected-server-response']; } else {
} throw jsonData['api-error-messages']['unexpected-server-response'];
}) }
.catch((err: AxiosError) => { } catch (error) {
showErrorToast( showErrorToast(
err, error as AxiosError,
jsonData['api-error-messages']['fetch-teams-error'] jsonData['api-error-messages']['fetch-teams-error']
); );
}); } finally {
setIsTeamsLoading(false);
}
}; };
const onDisplayNameChange = (e: React.ChangeEvent<HTMLInputElement>) => { const onDisplayNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@ -484,6 +488,7 @@ const Users = ({
isSearchable isSearchable
aria-label="Select teams" aria-label="Select teams"
className="tw-w-full" className="tw-w-full"
isLoading={isTeamsLoading}
options={teams?.map((team) => ({ options={teams?.map((team) => ({
label: getEntityName(team as unknown as EntityReference), label: getEntityName(team as unknown as EntityReference),
value: team.id, value: team.id,
@ -624,6 +629,7 @@ const Users = ({
aria-label="Select roles" aria-label="Select roles"
className="tw-w-full" className="tw-w-full"
id="select-role" id="select-role"
isLoading={isRolesLoading}
options={userRolesOption} options={userRolesOption}
placeholder="Roles..." placeholder="Roles..."
styles={reactSingleSelectCustomStyle} styles={reactSingleSelectCustomStyle}
@ -778,7 +784,7 @@ const Users = ({
<div className="tw--mt-4 tw-px-1.5 tw-flex tw-justify-between"> <div className="tw--mt-4 tw-px-1.5 tw-flex tw-justify-between">
<div className="tw-relative"> <div className="tw-relative">
<AntDButton <AntDButton
className="flex items-center" className="flex items-center p-0"
data-testid="feeds" data-testid="feeds"
icon={getFeedFilterDropdownIcon(feedFilter)} icon={getFeedFilterDropdownIcon(feedFilter)}
type="link" type="link"
@ -867,6 +873,7 @@ const Users = ({
}; };
const fetchRoles = async () => { const fetchRoles = async () => {
setIsRolesLoading(true);
try { try {
const response = await getRoles( const response = await getRoles(
'', '',
@ -882,6 +889,8 @@ const Users = ({
err as AxiosError, err as AxiosError,
jsonData['api-error-messages']['fetch-roles-error'] jsonData['api-error-messages']['fetch-roles-error']
); );
} finally {
setIsRolesLoading(false);
} }
}; };
@ -889,11 +898,6 @@ const Users = ({
fetchMoreFeed(isInView as boolean, paging, isFeedLoading); fetchMoreFeed(isInView as boolean, paging, isFeedLoading);
}, [isInView, paging, isFeedLoading]); }, [isInView, paging, isFeedLoading]);
useEffect(() => {
fetchTeams();
fetchRoles();
}, []);
useEffect(() => { useEffect(() => {
prepareSelectedRoles(); prepareSelectedRoles();
prepareSelectedTeams(); prepareSelectedTeams();
@ -905,6 +909,18 @@ const Users = ({
} }
}, [image]); }, [image]);
useEffect(() => {
if (isRolesEdit && isEmpty(roles)) {
fetchRoles();
}
}, [isRolesEdit, roles]);
useEffect(() => {
if (isTeamsEdit && isEmpty(teams)) {
fetchTeams();
}
}, [isTeamsEdit, teams]);
const getEntityData = useCallback( const getEntityData = useCallback(
(tabNumber: number) => { (tabNumber: number) => {
const entityData = tabNumber === 3 ? ownedEntities : followingEntities; const entityData = tabNumber === 3 ? ownedEntities : followingEntities;

View File

@ -26,3 +26,9 @@ export enum CreatePasswordGenerator {
AutomaticGenerate = 'AUTOMATIC_GENERATE', AutomaticGenerate = 'AUTOMATIC_GENERATE',
CreatePassword = 'CREATE_PASSWORD', CreatePassword = 'CREATE_PASSWORD',
} }
export enum UserProfileTab {
ACTIVITY = 'activity',
TASKS = 'tasks',
MY_DATA = 'mydata',
FOLLOWING = 'following',
}

View File

@ -39,6 +39,7 @@ import { PAGE_SIZE } from '../../constants/constants';
import { myDataSearchIndex } from '../../constants/Mydata.constants'; import { myDataSearchIndex } from '../../constants/Mydata.constants';
import { getUserCurrentTab } from '../../constants/usersprofile.constants'; import { getUserCurrentTab } from '../../constants/usersprofile.constants';
import { FeedFilter } from '../../enums/mydata.enum'; import { FeedFilter } from '../../enums/mydata.enum';
import { UserProfileTab } from '../../enums/user.enum';
import { import {
Post, Post,
Thread, Thread,
@ -54,7 +55,8 @@ import { showErrorToast } from '../../utils/ToastUtils';
const UserPage = () => { const UserPage = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { username, tab } = useParams<{ [key: string]: string }>(); const { username, tab = UserProfileTab.ACTIVITY } =
useParams<{ [key: string]: string }>();
const { search } = useLocation(); const { search } = useLocation();
const { isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext(); const { isAuthDisabled } = useAuthContext();
@ -93,7 +95,7 @@ const UserPage = () => {
const fetchUserData = () => { const fetchUserData = () => {
setUserData({} as User); setUserData({} as User);
getUserByName(username, 'profile,roles,teams,follows,owns') getUserByName(username, 'profile,roles,teams')
.then((res) => { .then((res) => {
if (res) { if (res) {
setUserData(res); setUserData(res);
@ -113,27 +115,29 @@ const UserPage = () => {
.finally(() => setIsLoading(false)); .finally(() => setIsLoading(false));
}; };
const fetchEntities = ( const fetchEntities = async (
fetchOwnedEntities = false, fetchOwnedEntities = false,
handleEntity: Dispatch<SetStateAction<AssetsDataType>> handleEntity: Dispatch<SetStateAction<AssetsDataType>>
) => { ) => {
const entity = fetchOwnedEntities ? ownedEntities : followingEntities; const entity = fetchOwnedEntities ? ownedEntities : followingEntities;
searchData( if (userData.id) {
fetchOwnedEntities try {
? `owner.id:${userData.id}` const response = await searchData(
: `followers:${userData.id}`, fetchOwnedEntities
entity.currPage, ? `owner.id:${userData.id}`
PAGE_SIZE, : `followers:${userData.id}`,
``, entity.currPage,
'', PAGE_SIZE,
'', ``,
myDataSearchIndex '',
) '',
.then((res) => { myDataSearchIndex
const hits = res?.data?.hits?.hits as SearchEntityHits; );
const hits = response.data.hits.hits as SearchEntityHits;
if (hits?.length > 0) { if (hits?.length > 0) {
const data = formatDataResponse(hits); const data = formatDataResponse(hits);
const total = res.data.hits.total.value; const total = response.data.hits.total.value;
handleEntity({ handleEntity({
data, data,
total, total,
@ -148,15 +152,15 @@ const UserPage = () => {
currPage: entity.currPage, currPage: entity.currPage,
}); });
} }
}) } catch (error) {
.catch((err: AxiosError) => {
showErrorToast( showErrorToast(
err, error as AxiosError,
t('server.entity-fetch-error', { t('server.entity-fetch-error', {
entity: `${fetchOwnedEntities ? 'Owned' : 'Follwing'} Entities`, entity: `${fetchOwnedEntities ? 'Owned' : 'Follwing'} Entities`,
}) })
); );
}); }
}
}; };
const handleFollowingEntityPaginate = (page: string | number) => { const handleFollowingEntityPaginate = (page: string | number) => {
@ -338,7 +342,13 @@ const UserPage = () => {
}, [username]); }, [username]);
useEffect(() => { useEffect(() => {
if (userData.id) { const isActivityTabs = [
UserProfileTab.ACTIVITY,
UserProfileTab.TASKS,
].includes(tab as UserProfileTab);
// only make feed api call if active tab is either activity or tasks
if (userData.id && isActivityTabs) {
const threadType = const threadType =
tab === 'tasks' ? ThreadType.Task : ThreadType.Conversation; tab === 'tasks' ? ThreadType.Task : ThreadType.Conversation;
@ -358,19 +368,16 @@ const UserPage = () => {
}, [tab]); }, [tab]);
useEffect(() => { useEffect(() => {
if (!isEmpty(userData)) { if (tab === UserProfileTab.FOLLOWING) {
fetchEntities(true, setOwnedEntities);
fetchEntities(false, setFollowingEntities); fetchEntities(false, setFollowingEntities);
} }
}, [userData]); }, [followingEntities.currPage, tab, userData]);
useEffect(() => { useEffect(() => {
fetchEntities(false, setFollowingEntities); if (tab === UserProfileTab.MY_DATA) {
}, [followingEntities.currPage]); fetchEntities(true, setOwnedEntities);
}
useEffect(() => { }, [ownedEntities.currPage, tab, userData]);
fetchEntities(true, setOwnedEntities);
}, [ownedEntities.currPage]);
useEffect(() => { useEffect(() => {
setCurrentLoggedInUser(AppState.getCurrentUserDetails()); setCurrentLoggedInUser(AppState.getCurrentUserDetails());