From 2ac5aaadd73aa5c82028d9ae400fac9582606fa4 Mon Sep 17 00:00:00 2001 From: Prasad Pawar Date: Sun, 26 Apr 2026 14:01:29 +0530 Subject: [PATCH 1/2] ATLAS-5275, ATLAS-5273, ATLAS-5272:Atlas React UI redirects to Home page during tag/term assignment after Ranger policy change. REACT UI Uploaded file name is truncated in Business Metadata import modal in React UI. React UI incorrectly allows/removes Applicable Type chips in Business Metadata edit flow --- dashboard/src/api/apiMethods/fetchApi.ts | 11 ++++-- dashboard/src/utils/Utils.ts | 4 +++ .../BusinessMetadataAtrributeForm.tsx | 36 +++++++++++++++++++ .../src/views/SideBar/Import/ImportLayout.tsx | 28 ++++++++------- 4 files changed, 65 insertions(+), 14 deletions(-) diff --git a/dashboard/src/api/apiMethods/fetchApi.ts b/dashboard/src/api/apiMethods/fetchApi.ts index 8ea64d7c968..a73127141ec 100644 --- a/dashboard/src/api/apiMethods/fetchApi.ts +++ b/dashboard/src/api/apiMethods/fetchApi.ts @@ -61,11 +61,12 @@ const fetchApi = async (url: string, config: AxiosRequestConfig) => { window.location.replace("login.jsp"); break; case 403: + // Match classic UI (Utils.defaultErrorHandler): show API message via + // notify/toast only; do not redirect — user stays on current screen. serverErrorHandler( { responseJSON: error.response?.data }, "You are not authorized" ); - window.location.replace("login.jsp"); break; case 404: serverErrorHandler( @@ -99,7 +100,13 @@ const fetchApi = async (url: string, config: AxiosRequestConfig) => { break; } } - if (error.response?.statusText != "abort") { + // Only treat as offline / connection failure when there is no HTTP + // response (or status 0). Do not run this for 403/404/5xx — those are + // handled above and would wrongly show a network toast. + const res = error.response; + const isAbort = + error.code === "ERR_CANCELED" || res?.statusText === "abort"; + if (!isAbort && (!res || Number(res.status) === 0)) { errorHandelingForAbortAndStatus0(); } } diff --git a/dashboard/src/utils/Utils.ts b/dashboard/src/utils/Utils.ts index 93b878186cf..b404c9d040f 100644 --- a/dashboard/src/utils/Utils.ts +++ b/dashboard/src/utils/Utils.ts @@ -340,6 +340,10 @@ const getEntityIconPath = (options: any) => { }; const serverError = (error: any, toastId: any) => { + // fetchApi already surfaces 403 via serverErrorHandler (toast); avoid duplicate. + if (error?.response?.status === 403) { + return; + } if ( error.response !== undefined && error.response.data.errorMessage !== undefined diff --git a/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx b/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx index 6c360731c33..6e161f68f04 100644 --- a/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx +++ b/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx @@ -33,6 +33,7 @@ import { FormControlLabel, Checkbox, Autocomplete, + Chip, Tooltip, tooltipClasses, TooltipProps, @@ -235,6 +236,18 @@ const BusinessMetadataAttributeForm = ({ : []; let enumTypeOptions = [...selectedEnumValues]; + const isBmAttributeEdit = !isEmpty(editbmAttribute); + const nonRemovableApplicableTypes = + isBmAttributeEdit && + Array.isArray(field?.options?.applicableEntityTypes) + ? new Set( + field.options.applicableEntityTypes.filter( + (t: unknown): t is string => + typeof t === "string" && t.length > 0 + ) + ) + : null; + return ( <>
+ tagValue.map((option: string, tagIndex) => { + const tagProps = getTagProps({ + index: tagIndex + }); + const stripDelete = + nonRemovableApplicableTypes.has(option); + return ( + + ); + }) + : undefined + } renderInput={(params) => ( - - {file.name} - + + + {file.name} + + Date: Tue, 28 Apr 2026 14:53:27 +0530 Subject: [PATCH 2/2] ATLAS-5275, ATLAS-5273, ATLAS-5272:Atlas React UI redirects to Home page during tag/term assignment after Ranger policy change. REACT UI Uploaded file name is truncated in Business Metadata import modal in React UI. React UI incorrectly allows/removes Applicable Type chips in Business Metadata edit flow --- dashboard/src/api/apiMethods/fetchApi.ts | 44 +++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/dashboard/src/api/apiMethods/fetchApi.ts b/dashboard/src/api/apiMethods/fetchApi.ts index a73127141ec..7f316a74672 100644 --- a/dashboard/src/api/apiMethods/fetchApi.ts +++ b/dashboard/src/api/apiMethods/fetchApi.ts @@ -20,6 +20,40 @@ import { globalSessionData } from "../../utils/Enum"; import { toast } from "react-toastify"; import { serverErrorHandler } from "@utils/Utils"; +/** Keep 403 toasts readable (Atlas authorization message). */ +const FORBIDDEN_ERROR_TOAST_MS = 5_000; +/** + * Callers often `toast.dismiss(ref.current)` in catch when `ref.current` is null; + * react-toastify then clears all toasts and removes the 403 toast we just showed. + * Queue the toast as a macrotask so it runs after that dismiss. + */ +const FETCH_API_FORBIDDEN_TOAST_ID = "fetch-api-http-403"; + +const showForbiddenToastLater = ( + responseData: unknown, + defaultMessage: string +) => { + setTimeout(() => { + let message = defaultMessage; + if (responseData && typeof responseData === "object") { + const d = responseData as { + errorMessage?: unknown; + message?: unknown; + error?: unknown; + }; + message = + (d.errorMessage as string | undefined) || + (d.message as string | undefined) || + (d.error as string | undefined) || + message; + } + toast.error(message, { + toastId: FETCH_API_FORBIDDEN_TOAST_ID, + autoClose: FORBIDDEN_ERROR_TOAST_MS + }); + }, 0); +}; + let prevNetworkErrorTime = 0; function errorHandelingForAbortAndStatus0() { @@ -61,10 +95,12 @@ const fetchApi = async (url: string, config: AxiosRequestConfig) => { window.location.replace("login.jsp"); break; case 403: - // Match classic UI (Utils.defaultErrorHandler): show API message via - // notify/toast only; do not redirect — user stays on current screen. - serverErrorHandler( - { responseJSON: error.response?.data }, + // Match classic UI: toast only, no redirect. Defer toast so callers + // that dismiss all toasts in catch (e.g. toast.dismiss(null ref)) do + // not remove this notification before it is shown — see + // showForbiddenToastLater. + showForbiddenToastLater( + error.response?.data, "You are not authorized" ); break;