diff --git a/packages/console/src/components/CustomUiAssetsUploader/index.tsx b/packages/console/src/components/CustomUiAssetsUploader/index.tsx index 070cdbdc0..498721dd2 100644 --- a/packages/console/src/components/CustomUiAssetsUploader/index.tsx +++ b/packages/console/src/components/CustomUiAssetsUploader/index.tsx @@ -13,6 +13,8 @@ import FileIcon from '../FileIcon'; import styles from './index.module.scss'; +const requestTimeout = 300_000; // 5 minutes + type Props = { // eslint-disable-next-line react/boolean-prop-naming readonly disabled?: boolean; @@ -51,6 +53,7 @@ function CustomUiAssetsUploader({ disabled, value, onChange }: Props) { if (showUploader) { return ( + defaultApiInstanceTimeout={requestTimeout} disabled={disabled} allowedMimeTypes={allowedMimeTypes} maxSize={maxUploadFileSize} diff --git a/packages/console/src/ds-components/Uploader/FileUploader/index.tsx b/packages/console/src/ds-components/Uploader/FileUploader/index.tsx index 4110aee0a..7183266a6 100644 --- a/packages/console/src/ds-components/Uploader/FileUploader/index.tsx +++ b/packages/console/src/ds-components/Uploader/FileUploader/index.tsx @@ -18,6 +18,11 @@ export type Props = UserAssets> = { // eslint-disable-next-line react/boolean-prop-naming readonly disabled?: boolean; readonly maxSize: number; // In bytes + /** + * The timeout for the default api instance, in milliseconds. + * Will not be applied if a custom API instance is provided. + */ + readonly defaultApiInstanceTimeout?: number; readonly allowedMimeTypes: AllowedUploadMimeType[]; readonly actionDescription?: string; readonly onCompleted: (response: T) => void; @@ -25,6 +30,7 @@ export type Props = UserAssets> = { readonly className?: string; /** * Specify which API instance to use for the upload request. For example, you can use admin tenant API instead. + * The `timeout` prop will not be applied to this instance. * Defaults to the return value of `useApi()`. */ readonly apiInstance?: KyInstance; @@ -37,6 +43,7 @@ export type Props = UserAssets> = { function FileUploader = UserAssets>({ disabled, maxSize, + defaultApiInstanceTimeout, allowedMimeTypes, actionDescription, onCompleted, @@ -57,7 +64,7 @@ function FileUploader = UserAssets>({ }; }, [onUploadErrorChange, uploadError]); - const api = useApi(); + const api = useApi({ timeout: defaultApiInstanceTimeout }); const onDrop = useCallback( async (acceptedFiles: File[] = [], fileRejection: FileRejection[] = []) => { diff --git a/packages/console/src/hooks/use-api.ts b/packages/console/src/hooks/use-api.ts index 2bb144559..747fab8ff 100644 --- a/packages/console/src/hooks/use-api.ts +++ b/packages/console/src/hooks/use-api.ts @@ -40,6 +40,7 @@ export type StaticApiProps = { prefixUrl?: URL; hideErrorToast?: boolean | LogtoErrorCode[]; resourceIndicator: string; + timeout?: number; }; const useGlobalRequestErrorHandler = (toastDisabledErrorCodes?: LogtoErrorCode[]) => { @@ -110,6 +111,7 @@ export const useStaticApi = ({ prefixUrl, hideErrorToast, resourceIndicator, + timeout = requestTimeout, }: StaticApiProps): KyInstance => { const { isAuthenticated, getAccessToken, getOrganizationToken } = useLogto(); const { i18n } = useTranslation(undefined, { keyPrefix: 'admin_console' }); @@ -125,7 +127,7 @@ export const useStaticApi = ({ () => ky.create({ prefixUrl, - timeout: requestTimeout, + timeout, hooks: { beforeError: conditionalArray( !disableGlobalErrorHandling && @@ -156,6 +158,7 @@ export const useStaticApi = ({ getOrganizationToken, getAccessToken, i18n.language, + timeout, ] );