mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-07-16 13:41:37 +00:00
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:
parent
8e887d3506
commit
92bad23fcf
@ -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;
|
||||||
|
@ -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',
|
||||||
|
}
|
||||||
|
@ -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());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user