Client: Groups: Fix loaders

This commit is contained in:
Aleksandr Lushkin 2024-08-08 15:11:17 +02:00
parent 844daabd2f
commit 3be9024555
2 changed files with 137 additions and 65 deletions

View File

@ -24,7 +24,7 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import { ChangeEvent, useEffect, useState } from "react";
import { ChangeEvent, useEffect, useRef, useState } from "react";
import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
@ -34,6 +34,10 @@ import {
ModalDialogType,
} from "@docspace/shared/components/modal-dialog";
import { TGroup } from "@docspace/shared/api/groups/types";
import {
MIN_LOADER_TIMER,
SHOW_LOADER_TIMER,
} from "@docspace/shared/selectors/Files/FilesSelector.constants";
import EditGroupStore from "SRC_DIR/store/EditGroupStore";
import { StyledModal } from "./CreateEditGroupDialog.styled";
@ -101,6 +105,10 @@ const EditGroupDialog = ({
useState<boolean>(false);
const [selectMembersPanelIsVisible, setSelectMembersPanelIsVisible] =
useState<boolean>(false);
const [showLoader, setShowLoader] = useState(false);
const loaderTimeout = useRef<NodeJS.Timeout | null>(null);
const startLoaderTime = useRef<Date | null>(null);
const onChangeGroupName = (e: ChangeEvent<HTMLInputElement>) => {
setTitle(e.target.value);
@ -136,6 +144,38 @@ const EditGroupDialog = ({
};
}, []);
useEffect(() => {
if (!isInit) {
loaderTimeout.current = setTimeout(() => {
startLoaderTime.current = new Date();
setShowLoader(true);
}, SHOW_LOADER_TIMER);
} else if (startLoaderTime.current) {
const currentDate = new Date();
const ms = Math.abs(
startLoaderTime.current.getTime() - currentDate.getTime(),
);
if (ms >= MIN_LOADER_TIMER) {
startLoaderTime.current = null;
return setShowLoader(false);
}
setTimeout(() => {
if (isInit) {
startLoaderTime.current = null;
setShowLoader(false);
}
}, MIN_LOADER_TIMER - ms);
loaderTimeout.current = null;
} else if (loaderTimeout.current) {
clearTimeout(loaderTimeout.current);
loaderTimeout.current = null;
}
}, [isInit]);
const notEnoughParamsToEdit = !title || (!manager && !members?.length);
return (
@ -152,31 +192,33 @@ const EditGroupDialog = ({
</ModalDialog.Header>
<ModalDialog.Body>
{isInit ? (
<>
<GroupNameParam
groupName={title}
onChangeGroupName={onChangeGroupName}
/>
<HeadOfGroup
groupManager={manager}
onShowSelectGroupManagerPanel={onShowSelectGroupManagerPanel}
removeManager={removeManager}
/>
<MembersParam
groupManager={manager}
groupMembers={members}
removeMember={removeMember}
onShowSelectMembersPanel={onShowSelectMembersPanel}
withInfiniteLoader
total={currentTotal}
loadNextPage={loadMembers}
hasNextPage={!!members && members.length < currentTotal}
/>
</>
) : (
{showLoader ? (
<BodyLoader />
) : (
isInit && (
<>
<GroupNameParam
groupName={title}
onChangeGroupName={onChangeGroupName}
/>
<HeadOfGroup
groupManager={manager}
onShowSelectGroupManagerPanel={onShowSelectGroupManagerPanel}
removeManager={removeManager}
/>
<MembersParam
groupManager={manager}
groupMembers={members}
removeMember={removeMember}
onShowSelectMembersPanel={onShowSelectMembersPanel}
withInfiniteLoader
total={currentTotal}
loadNextPage={loadMembers}
hasNextPage={!!members && members.length < currentTotal}
/>
</>
)
)}
</ModalDialog.Body>

View File

@ -27,13 +27,16 @@
import { inject, observer } from "mobx-react";
import { withTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
import { useState, useEffect } from "react";
import { useState, useEffect, useRef } from "react";
import withLoader from "@docspace/client/src/HOCs/withLoader";
import InfoPanelViewLoader from "@docspace/shared/skeletons/info-panel/body";
import api from "@docspace/shared/api";
import AccountsFilter from "@docspace/shared/api/people/filter";
import { MIN_LOADER_TIMER } from "@docspace/shared/selectors/Files/FilesSelector.constants";
import {
MIN_LOADER_TIMER,
SHOW_LOADER_TIMER,
} from "@docspace/shared/selectors/Files/FilesSelector.constants";
import GroupMember from "./GroupMember";
import * as Styled from "../../styles/groups.styled";
@ -47,11 +50,14 @@ const Groups = ({
infoPanelSelectedGroup,
setInfoPanelSelectedGroup,
}) => {
const [isShowLoader, setIsShowLoader] = useState(false);
const [areMembersLoading, setAreMembersLoading] = useState(false);
const [isFirstLoad, setIsFirstLoad] = useState(true);
const [showLoader, setShowLoader] = useState(false);
const [groupMembers, setGroupMembers] = useState(null);
const [total, setTotal] = useState(0);
const startLoader = useRef(null);
const loaderTimeout = useRef(null);
const { groupId: paramsGroupId } = useParams();
const isInsideGroup = !!paramsGroupId;
@ -63,13 +69,7 @@ const Groups = ({
const groupManager = group?.manager;
const loadNextPage = async (startIndex) => {
const startLoadingTime = new Date();
try {
if (startIndex === 0) {
setAreMembersLoading(true);
}
const pageCount = 100;
const filter = AccountsFilter.getDefault();
filter.group = groupId;
@ -91,21 +91,48 @@ const Groups = ({
} catch (e) {
console.log(e);
} finally {
const nowDate = new Date();
const diff = Math.abs(nowDate.getTime() - startLoadingTime.getTime());
if (diff < MIN_LOADER_TIMER) {
setTimeout(() => {
setAreMembersLoading(false);
}, MIN_LOADER_TIMER - diff);
} else {
setAreMembersLoading(false);
if (startIndex === 0) {
setIsFirstLoad(false);
}
}
};
const calculateLoader = () => {
if (isFirstLoad) {
loaderTimeout.current = setTimeout(() => {
startLoader.current = new Date();
setShowLoader(true);
}, SHOW_LOADER_TIMER);
} else if (startLoader.current) {
const currentDate = new Date();
const ms = Math.abs(
startLoader.current.getTime() - currentDate.getTime(),
);
if (ms >= MIN_LOADER_TIMER) {
startLoader.current = null;
return setShowLoader(false);
}
setTimeout(() => {
startLoader.current = null;
setShowLoader(false);
}, MIN_LOADER_TIMER - ms);
loaderTimeout.current = null;
} else if (loaderTimeout.current) {
clearTimeout(loaderTimeout.current);
loaderTimeout.current = null;
}
};
useFetchGroup(groupId, group?.id, setGroup);
useEffect(() => {
setIsFirstLoad(true);
}, [infoPanelSelection.id]);
useEffect(() => {
if (group) {
loadNextPage(0);
@ -113,35 +140,38 @@ const Groups = ({
}, [group]);
useEffect(() => {
const showLoaderTimer = setTimeout(() => setIsShowLoader(true), 500);
return () => clearTimeout(showLoaderTimer);
calculateLoader();
}, [isFirstLoad]);
useEffect(() => {
return () => {
loaderTimeout.current = null;
};
}, []);
if (!group) {
if (isShowLoader)
return (
<Styled.GroupsContent>
<InfoPanelViewLoader view="groups" />
</Styled.GroupsContent>
);
return null;
if (showLoader) {
return (
<Styled.GroupsContent>
<InfoPanelViewLoader view="groups" />
</Styled.GroupsContent>
);
}
const totalWithoutManager = groupManager ? total - 1 : total;
return (
<Styled.GroupsContent>
{groupManager && <GroupMember groupMember={groupManager} isManager />}
{!groupMembers || areMembersLoading ? (
<InfoPanelViewLoader view="groups" />
) : (
<GroupMembersList
members={groupMembers}
hasNextPage={groupMembers.length < totalWithoutManager}
loadNextPage={loadNextPage}
total={totalWithoutManager}
managerId={groupManager?.id}
/>
{isFirstLoad || !groupMembers ? null : (
<>
{groupManager && <GroupMember groupMember={groupManager} isManager />}
<GroupMembersList
members={groupMembers}
hasNextPage={groupMembers.length < totalWithoutManager}
loadNextPage={loadNextPage}
total={totalWithoutManager}
managerId={groupManager?.id}
/>
</>
)}
</Styled.GroupsContent>
);