From f7cd23b313beba50fc67b70469e3fa392d4e67b5 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Wed, 28 Aug 2024 14:26:06 +0300 Subject: [PATCH] Fix Bug 69870 - Recovery progress is shown with jumps. --- .../PreparationPortal.utils.ts | 201 ++---------------- .../shared/pages/PreparationPortal/index.tsx | 105 ++++++--- 2 files changed, 90 insertions(+), 216 deletions(-) diff --git a/packages/shared/pages/PreparationPortal/PreparationPortal.utils.ts b/packages/shared/pages/PreparationPortal/PreparationPortal.utils.ts index 7eafa05ba6..3b6d13ac38 100644 --- a/packages/shared/pages/PreparationPortal/PreparationPortal.utils.ts +++ b/packages/shared/pages/PreparationPortal/PreparationPortal.utils.ts @@ -26,14 +26,7 @@ import { getRestoreProgress } from "../../api/portal"; -const baseSecondMultiplicationFactor = 400; -const baseThirdMultiplicationFactor = 180; -const baseFirstMultiplicationFactor = 700; -const unSizeMultiplicationFactor = 3; -const thirdBound = 98; - let prevProgress: number = 0; -let requestsCount: number = 0; export const clearLocalStorage = () => { [ @@ -44,208 +37,48 @@ export const clearLocalStorage = () => { "LocalCopyThirdPartyStorageValues", ].forEach((k) => localStorage.removeItem(k)); }; -export const reachingSecondBoundary = ( - percentage: number, - secondBound: number, - progressTimerId: ReturnType | null, - setPercent: (progress: number) => void, -) => { - let progress = percentage; - - const delay = baseSecondMultiplicationFactor * unSizeMultiplicationFactor; - - if (progressTimerId) return; - - progressTimerId = setInterval(() => { - progress += 1; - - if (progress !== secondBound) setPercent(progress); - else { - if (progressTimerId) clearInterval(progressTimerId); - progressTimerId = null; - } - }, delay); -}; -export const reachingThirdBoundary = ( - percentage: number, - progressTimerId: ReturnType | null, - setPercent: (progress: number) => void, -) => { - let progress = percentage; - const delay = baseThirdMultiplicationFactor * unSizeMultiplicationFactor; - if (progressTimerId) return; - - progressTimerId = setInterval(() => { - progress += 1; - - if (progress < thirdBound) setPercent(progress); - else { - if (progressTimerId) clearInterval(progressTimerId); - progressTimerId = null; - } - }, delay); -}; - -export const reachingFirstBoundary = ( - percentage: number, - firstBound: number, - progressTimerId: ReturnType | null, - setPercent: (progress: number) => void, -) => { - let progress = percentage; - const delay = baseFirstMultiplicationFactor * unSizeMultiplicationFactor; - - if (progressTimerId) return; - - progressTimerId = setInterval(() => { - progress += 1; - - if (progress !== firstBound) setPercent(progress); - else { - if (progressTimerId) clearInterval(progressTimerId); - progressTimerId = null; - } - }, delay); -}; export const returnToPortal = () => { setTimeout(() => { window.location.replace("/"); }, 5000); }; - -export const getIntervalProgress = async ( - setErrorMessage: (err: any) => void, - clearAllIntervals: VoidFunction, +export const clearAllIntervals = ( timerId: ReturnType | null, - progressTimerId: ReturnType | null, +) => { + if (timerId) clearInterval(timerId); + + timerId = null; +}; +export const getIntervalProgress = async ( + setMessage: (err?: unknown) => void, setPercent: (progress: number) => void, - errorInternalServer: string, + timerId: ReturnType | null, ) => { try { const response = await getRestoreProgress(); - if (!response) { - setErrorMessage(errorInternalServer); - clearAllIntervals(); - return; - } - - if (response.error) { - if (timerId) clearInterval(timerId); - if (progressTimerId) clearInterval(progressTimerId); - - progressTimerId = null; - timerId = null; - setErrorMessage(response.error); + if (!response || response.error) { + if (response?.error) setMessage(response.error); + else setMessage(); + clearAllIntervals(timerId); return; } const currProgress = response.progress; - console.log("prevProgress", prevProgress); - if (currProgress > 0 && prevProgress !== currProgress) { - setPercent(currProgress); - if (progressTimerId) clearInterval(progressTimerId); - progressTimerId = null; - } + if (prevProgress !== currProgress) setPercent(currProgress); prevProgress = currProgress; if (currProgress === 100) { - clearAllIntervals(); + clearAllIntervals(timerId); clearLocalStorage(); returnToPortal(); } - } catch (error: any) { - clearAllIntervals(); - setErrorMessage(error); - } -}; - -export const getRecoveryProgress = async ( - setErrorMessage: (err: any) => void, - errorInternalServer: string, - timerId: ReturnType | null, - progressTimerId: ReturnType | null, - firstBound: number, - setPercent: (progress: number) => void, - clearAllIntervals: VoidFunction, -) => { - const getMessage = (error: any) => { - if (typeof error !== "object") return error; - - return ( - error?.response?.data?.error?.message || - error?.statusText || - error?.message || - t("Common:ErrorInternalServer") - ); - }; - - try { - const response = await getRestoreProgress(); - - if (!response) { - setErrorMessage(errorInternalServer); - return; - } - - const { progress, error } = response; - - if (error) { - setErrorMessage(error); - - return; - } - - if (progress === 100) { - returnToPortal(); - clearLocalStorage(); - } else { - timerId = setInterval( - () => - getIntervalProgress( - setErrorMessage, - clearAllIntervals, - timerId, - progressTimerId, - setPercent, - errorInternalServer, - ), - 1000, - ); - if (progress < firstBound) - reachingFirstBoundary( - progress, - firstBound, - progressTimerId, - setPercent, - ); - } - - setPercent(progress); } catch (err: unknown) { - const knownError = err as { response: { status: number } }; - - const status = knownError?.response?.status; - const needCreationTableTime = status === 404; - - if (needCreationTableTime && requestsCount < 3) { - requestsCount += 1; - getRecoveryProgress( - setErrorMessage, - errorInternalServer, - timerId, - progressTimerId, - firstBound, - setPercent, - clearAllIntervals, - ); - return; - } - - setErrorMessage(getMessage(err)); + clearAllIntervals(timerId); + setMessage(err); } }; diff --git a/packages/shared/pages/PreparationPortal/index.tsx b/packages/shared/pages/PreparationPortal/index.tsx index d7d786c7fe..89aad244ef 100644 --- a/packages/shared/pages/PreparationPortal/index.tsx +++ b/packages/shared/pages/PreparationPortal/index.tsx @@ -23,7 +23,7 @@ // All the Product's GUI elements, including illustrations and icon sets, as well as technical writing // 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 React, { useEffect, useState } from "react"; +import React, { useEffect, useState, useCallback } from "react"; import { useTranslation } from "react-i18next"; import ErrorContainer from "@docspace/shared/components/error-container/ErrorContainer"; @@ -33,17 +33,17 @@ import { Text } from "../../components/text"; import { ColorTheme, ThemeId } from "../../components/color-theme"; import { IPreparationPortal } from "./PreparationPortal.types"; +import { getRestoreProgress } from "../../api/portal"; import { - getRecoveryProgress, - reachingSecondBoundary, - reachingThirdBoundary, + clearAllIntervals, + clearLocalStorage, + getIntervalProgress, + returnToPortal, } from "./PreparationPortal.utils"; -const firstBound = 10; -const secondBound = 63; +let requestsCount = 0; let timerId: ReturnType | null; -let progressTimerId: ReturnType | null; const PreparationPortal = (props: IPreparationPortal) => { const { withoutHeader, style, isDialog } = props; @@ -55,42 +55,83 @@ const PreparationPortal = (props: IPreparationPortal) => { const [percent, setPercent] = useState(0); const [errorMessage, setErrorMessage] = useState(""); - const clearAllIntervals = () => { - if (timerId) clearInterval(timerId); - if (progressTimerId) clearInterval(progressTimerId); + const setMessage = useCallback( + (error?: unknown) => { + const errorText = error ?? errorInternalServer; - progressTimerId = null; - timerId = null; - }; + setErrorMessage(errorText); + }, + [errorInternalServer], + ); useEffect(() => { - if (percent < firstBound) return; + const getRecoveryProgress = async () => { + try { + const response = await getRestoreProgress(); - if (percent < secondBound) { - reachingSecondBoundary(percent, secondBound, progressTimerId, setPercent); - return; - } + if (!response) { + setMessage(); + return; + } - reachingThirdBoundary(percent, progressTimerId, setPercent); - }, [percent]); + const { progress, error } = response; + + if (error) { + setMessage(error); + return; + } + + setPercent(progress); + + if (progress === 100) { + returnToPortal(); + clearLocalStorage(); + + return; + } + + timerId = setInterval( + () => getIntervalProgress(setMessage, setPercent, timerId), + 1000, + ); + } catch (err: unknown) { + const knownError = err as { + response?: { status: number; data: { error: { message: string } } }; + statusText?: string; + message?: string; + }; + + const status = knownError?.response?.status; + const needCreationTableTime = status === 404; + + if (needCreationTableTime && requestsCount < 3) { + requestsCount += 1; + + getRecoveryProgress(); + + return; + } + + const message = + typeof err !== "object" + ? err + : knownError?.response?.data?.error?.message || + knownError?.statusText || + knownError?.message || + errorInternalServer; + + setMessage(message); + } + }; - useEffect(() => { setTimeout(() => { - getRecoveryProgress( - setErrorMessage, - errorInternalServer, - timerId, - progressTimerId, - firstBound, - setPercent, - clearAllIntervals, - ); + getRecoveryProgress(); }, 6000); return () => { - clearAllIntervals(); + clearAllIntervals(timerId); }; - }, [errorInternalServer]); + }, [errorInternalServer, setMessage]); const headerText = errorMessage ? t("Common:Error")