This is an automated email from the ASF dual-hosted git repository.
shahar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 7d02b852889 Fix alignment of arrows in RTL mode (#55619)
7d02b852889 is described below
commit 7d02b8528892533550d35e0e367f6101c81d9292
Author: Shahar Epstein <[email protected]>
AuthorDate: Sat Sep 13 11:29:06 2025 +0300
Fix alignment of arrows in RTL mode (#55619)
---
.../src/airflow/ui/src/components/NeedsReviewButton.tsx | 5 ++++-
airflow-core/src/airflow/ui/src/components/StatsCard.tsx | 6 ++++--
.../airflow/ui/src/layouts/Nav/UserSettingsButton.tsx | 16 +++++++++++++---
.../ui/src/pages/Dashboard/Stats/DAGImportErrors.tsx | 5 ++++-
.../src/airflow/ui/src/pages/Dashboard/Stats/Stats.tsx | 8 +++++++-
5 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/airflow-core/src/airflow/ui/src/components/NeedsReviewButton.tsx
b/airflow-core/src/airflow/ui/src/components/NeedsReviewButton.tsx
index 1c20e991a9c..fcec3a8fe1d 100644
--- a/airflow-core/src/airflow/ui/src/components/NeedsReviewButton.tsx
+++ b/airflow-core/src/airflow/ui/src/components/NeedsReviewButton.tsx
@@ -52,7 +52,9 @@ export const NeedsReviewButton = ({
);
const hitlTIsCount = hitlStatsData?.hitl_details.length ?? 0;
- const { t: translate } = useTranslation("hitl");
+ const { i18n, t: translate } = useTranslation("hitl");
+
+ const isRTL = i18n.dir() === "rtl";
return hitlTIsCount > 0 ? (
<Box maxW="250px">
@@ -61,6 +63,7 @@ export const NeedsReviewButton = ({
count={hitlTIsCount}
icon={<LuUserRoundPen />}
isLoading={isLoading}
+ isRTL={isRTL}
label={translate("requiredAction_other")}
link="required_actions?response_received=false"
/>
diff --git a/airflow-core/src/airflow/ui/src/components/StatsCard.tsx
b/airflow-core/src/airflow/ui/src/components/StatsCard.tsx
index 7d7bf9c14b4..cbade7d249d 100644
--- a/airflow-core/src/airflow/ui/src/components/StatsCard.tsx
+++ b/airflow-core/src/airflow/ui/src/components/StatsCard.tsx
@@ -17,7 +17,7 @@
* under the License.
*/
import { Box, HStack, Skeleton, Text } from "@chakra-ui/react";
-import { FiChevronRight } from "react-icons/fi";
+import { FiChevronRight, FiChevronLeft } from "react-icons/fi";
import { Link as RouterLink } from "react-router-dom";
import type { TaskInstanceState } from "openapi/requests/types.gen";
@@ -28,6 +28,7 @@ export const StatsCard = ({
count,
icon,
isLoading = false,
+ isRTL,
label,
link,
onClick,
@@ -37,6 +38,7 @@ export const StatsCard = ({
readonly count: number;
readonly icon?: React.ReactNode;
readonly isLoading?: boolean;
+ readonly isRTL: boolean;
readonly label: string;
readonly link?: string;
readonly onClick?: () => void;
@@ -63,7 +65,7 @@ export const StatsCard = ({
<Text color="fg" fontSize="sm" fontWeight="bold">
{label}
</Text>
- <FiChevronRight size={16} />
+ {isRTL ? <FiChevronLeft size={16} /> : <FiChevronRight size={16} />}
</HStack>
);
diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx
b/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx
index a2b99016d91..c8cc8108945 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx
@@ -27,6 +27,7 @@ import {
FiGlobe,
FiEye,
FiChevronRight,
+ FiChevronLeft,
FiMonitor,
} from "react-icons/fi";
import { MdOutlineAccountTree } from "react-icons/md";
@@ -52,7 +53,7 @@ const COLOR_MODES = {
type ColorMode = (typeof COLOR_MODES)[keyof typeof COLOR_MODES];
export const UserSettingsButton = ({ externalViews }: { readonly
externalViews: Array<NavItemResponse> }) => {
- const { t: translate } = useTranslation();
+ const { i18n, t: translate } = useTranslation();
const { selectedTheme, setColorMode } = useColorMode();
const { onClose: onCloseTimezone, onOpen: onOpenTimezone, open:
isOpenTimezone } = useDisclosure();
const { onClose: onCloseLogout, onOpen: onOpenLogout, open: isOpenLogout } =
useDisclosure();
@@ -61,6 +62,8 @@ export const UserSettingsButton = ({ externalViews }: {
readonly externalViews:
const theme = selectedTheme ?? COLOR_MODES.SYSTEM;
+ const isRTL = i18n.dir() === "rtl";
+
return (
<Menu.Root positioning={{ placement: "right" }}>
<Menu.Trigger asChild>
@@ -75,7 +78,11 @@ export const UserSettingsButton = ({ externalViews }: {
readonly externalViews:
<Menu.TriggerItem>
<FiEye size="1.25rem" style={{ marginRight: "8px" }} />
{translate("appearance.appearance")}
- <FiChevronRight size="1.25rem" style={{ marginLeft: "auto" }} />
+ {isRTL ? (
+ <FiChevronLeft size="1.25rem" style={{ marginRight: "auto" }} />
+ ) : (
+ <FiChevronRight size="1.25rem" style={{ marginLeft: "auto" }} />
+ )}
</Menu.TriggerItem>
<Menu.Content>
<Menu.RadioItemGroup
@@ -121,7 +128,10 @@ export const UserSettingsButton = ({ externalViews }: {
readonly externalViews:
<PluginMenuItem {...view} key={view.name} />
))}
<Menu.Item onClick={onOpenLogout} value="logout">
- <FiLogOut size="1.25rem" style={{ marginRight: "8px" }} />
+ <FiLogOut
+ size="1.25rem"
+ style={{ marginRight: "8px", transform: isRTL ? "rotate(180deg)" :
undefined }}
+ />
{translate("logout")}
</Menu.Item>
</Menu.Content>
diff --git
a/airflow-core/src/airflow/ui/src/pages/Dashboard/Stats/DAGImportErrors.tsx
b/airflow-core/src/airflow/ui/src/pages/Dashboard/Stats/DAGImportErrors.tsx
index 079472cf353..2966fee23cd 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dashboard/Stats/DAGImportErrors.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dashboard/Stats/DAGImportErrors.tsx
@@ -29,7 +29,9 @@ import { DAGImportErrorsModal } from "./DAGImportErrorsModal";
export const DAGImportErrors = ({ iconOnly = false }: { readonly iconOnly?:
boolean }) => {
const { onClose, onOpen, open } = useDisclosure();
- const { t: translate } = useTranslation("dashboard");
+ const { i18n, t: translate } = useTranslation("dashboard");
+
+ const isRTL = i18n.dir() === "rtl";
const { data, error, isLoading } = useImportErrorServiceGetImportErrors();
const importErrorsCount = data?.total_entries ?? 0;
@@ -63,6 +65,7 @@ export const DAGImportErrors = ({ iconOnly = false }: {
readonly iconOnly?: bool
count={importErrorsCount}
icon={<LuFileWarning />}
isLoading={isLoading}
+ isRTL={isRTL}
label={translate("importErrors.dagImportError", { count:
importErrorsCount })}
onClick={onOpen}
/>
diff --git a/airflow-core/src/airflow/ui/src/pages/Dashboard/Stats/Stats.tsx
b/airflow-core/src/airflow/ui/src/pages/Dashboard/Stats/Stats.tsx
index b766cd12b4f..5cfc7b2d7c2 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dashboard/Stats/Stats.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dashboard/Stats/Stats.tsx
@@ -38,7 +38,9 @@ export const Stats = () => {
const queuedDagsCount = statsData?.queued_dag_count ?? 0;
const runningDagsCount = statsData?.running_dag_count ?? 0;
const activeDagsCount = statsData?.active_dag_count ?? 0;
- const { t: translate } = useTranslation("dashboard");
+ const { i18n, t: translate } = useTranslation("dashboard");
+
+ const isRTL = i18n.dir() === "rtl";
return (
<Box>
@@ -56,6 +58,7 @@ export const Stats = () => {
colorScheme="failed"
count={failedDagsCount}
isLoading={isStatsLoading}
+ isRTL={isRTL}
label={translate("stats.failedDags")}
link="dags?last_dag_run_state=failed"
state="failed"
@@ -70,6 +73,7 @@ export const Stats = () => {
colorScheme="queued"
count={queuedDagsCount}
isLoading={isStatsLoading}
+ isRTL={isRTL}
label={translate("stats.queuedDags")}
link="dags?last_dag_run_state=queued"
state="queued"
@@ -80,6 +84,7 @@ export const Stats = () => {
colorScheme="running"
count={runningDagsCount}
isLoading={isStatsLoading}
+ isRTL={isRTL}
label={translate("stats.runningDags")}
link="dags?last_dag_run_state=running"
state="running"
@@ -90,6 +95,7 @@ export const Stats = () => {
count={activeDagsCount}
icon={<FiZap />}
isLoading={isStatsLoading}
+ isRTL={isRTL}
label={translate("stats.activeDags")}
link="dags?paused=false"
/>