This is an automated email from the ASF dual-hosted git repository.

vatsrahul1001 pushed a commit to branch v3-2-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/v3-2-test by this push:
     new 1cced913570 [v3-2-test] UI: Make DAG detail page scrollable on mobile 
viewports (#65899) (#66975)
1cced913570 is described below

commit 1cced913570b11a2b3d1fe9be8e245faa93269a0
Author: Dheeraj Turaga <[email protected]>
AuthorDate: Thu May 14 23:56:41 2026 -0500

    [v3-2-test] UI: Make DAG detail page scrollable on mobile viewports 
(#65899) (#66975)
    
    On phones the horizontal split between the Graph/Grid/Gantt pane and
      the Details pane was squeezed to ~200px each, and nested overflow:hidden
      containers hid the panes' internal scrollbars. The page was effectively
      unusable on mobile.
    
      Pin a 1280px min-width on the DAG page wrapper below Chakra's
      breakpoint and switch the main-content box to overflow=auto so the
      browser exposes horizontal and vertical scrollbars. Desktop layout
      (>=768px) is unchanged.
    (cherry picked from commit e6f5de4f5eda87c702a5a1c7625ba395221cce48)
---
 .../src/airflow/ui/src/layouts/BaseLayout.tsx      |   2 +-
 .../ui/src/layouts/Details/DetailsLayout.tsx       | 347 +++++++++++----------
 2 files changed, 178 insertions(+), 171 deletions(-)

diff --git a/airflow-core/src/airflow/ui/src/layouts/BaseLayout.tsx 
b/airflow-core/src/airflow/ui/src/layouts/BaseLayout.tsx
index 30023505e62..062caca76d3 100644
--- a/airflow-core/src/airflow/ui/src/layouts/BaseLayout.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/BaseLayout.tsx
@@ -113,7 +113,7 @@ export const BaseLayout = ({ children }: PropsWithChildren) 
=> {
           flex={1}
           flexDirection="column"
           minH={0}
-          overflowY="auto"
+          overflow="auto"
           p={3}
         >
           {baseReactPlugins.map((plugin) => (
diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/DetailsLayout.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/DetailsLayout.tsx
index dacd6171f5d..89f9507cdb5 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/DetailsLayout.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/DetailsLayout.tsx
@@ -110,191 +110,198 @@ export const DetailsLayout = ({ children, error, 
isLoading, tabs }: Props) => {
   return (
     <HoverProvider>
       <OpenGroupsProvider dagId={dagId}>
-        <HStack justifyContent="space-between" mb={2}>
-          <DagBreadcrumb />
-          <Flex gap={1}>
-            <SearchDagsButton />
-            {dag === undefined ? undefined : (
-              <TriggerDAGButton
-                allowedRunTypes={dag.allowed_run_types}
-                dagDisplayName={dag.dag_display_name}
-                dagId={dag.dag_id}
-                isPaused={dag.is_paused}
-                variant="outline"
-                withText
-              />
-            )}
-          </Flex>
-        </HStack>
-        <Toaster />
-        <BackfillBanner dagId={dagId} />
-        <Box flex={1} minH={0}>
-          {isRightPanelCollapsed ? (
-            <Tooltip content={translate("common:showDetailsPanel")}>
-              <IconButton
-                aria-label={translate("common:showDetailsPanel")}
-                bg="fg.subtle"
-                borderRadius={direction === "ltr" ? "100% 0 0 100%" : "0 100% 
100% 0"}
-                boxShadow="md"
-                left={direction === "rtl" ? "-5px" : undefined}
-                onClick={() => setIsRightPanelCollapsed(false)}
-                position="absolute"
-                right={direction === "ltr" ? "-5px" : undefined}
-                size="2xs"
-                top="50%"
-                zIndex={10}
-              >
-                {direction === "ltr" ? <FaChevronLeft /> : <FaChevronRight />}
-              </IconButton>
-            </Tooltip>
-          ) : undefined}
-          <PanelGroup
-            autoSaveId={`${dagView}-${direction}`}
-            dir={direction}
-            direction="horizontal"
-            key={`${dagView}-${direction}`}
-            ref={panelGroupRef}
-          >
-            <Panel
-              defaultSize={dagView === "graph" ? 70 : 20}
-              id="main-panel"
-              minSize={showGantt && dagView === "grid" && Boolean(runId) ? 35 
: 6}
-              order={1}
-            >
-              <Box height="100%" position="relative">
-                <PanelButtons
-                  dagRunStateFilter={dagRunStateFilter}
-                  dagView={dagView}
-                  limit={limit}
-                  panelGroupRef={panelGroupRef}
-                  runAfterGte={runAfterGte}
-                  runAfterLte={runAfterLte}
-                  runTypeFilter={runTypeFilter}
-                  setDagRunStateFilter={setDagRunStateFilter}
-                  setDagView={setDagView}
-                  setLimit={setLimit}
-                  setRunAfterGte={setRunAfterGte}
-                  setRunAfterLte={setRunAfterLte}
-                  setRunTypeFilter={setRunTypeFilter}
-                  setShowGantt={setShowGantt}
-                  setShowVersionIndicatorMode={setShowVersionIndicatorMode}
-                  setTriggeringUserFilter={setTriggeringUserFilter}
-                  showGantt={showGantt}
-                  showVersionIndicatorMode={showVersionIndicatorMode}
-                  triggeringUserFilter={triggeringUserFilter}
+        <Box display="flex" flex={1} flexDirection="column" minH={0} minW={{ 
base: "1280px", md: "auto" }}>
+          <HStack justifyContent="space-between" mb={2}>
+            <DagBreadcrumb />
+            <Flex gap={1}>
+              <SearchDagsButton />
+              {dag === undefined ? undefined : (
+                <TriggerDAGButton
+                  allowedRunTypes={dag.allowed_run_types}
+                  dagDisplayName={dag.dag_display_name}
+                  dagId={dag.dag_id}
+                  isPaused={dag.is_paused}
+                  variant="outline"
+                  withText
                 />
-                {dagView === "graph" ? (
-                  <Graph />
-                ) : (
-                  <HStack alignItems="flex-start" gap={0}>
-                    <Grid
-                      dagRunState={dagRunStateFilter}
-                      limit={limit}
-                      runAfterGte={runAfterGte}
-                      runAfterLte={runAfterLte}
-                      runType={runTypeFilter}
-                      showGantt={Boolean(runId) && showGantt}
-                      showVersionIndicatorMode={showVersionIndicatorMode}
-                      triggeringUser={triggeringUserFilter}
-                    />
-                    {showGantt ? (
-                      <Gantt
+              )}
+            </Flex>
+          </HStack>
+          <Toaster />
+          <BackfillBanner dagId={dagId} />
+          <Box flex={1} minH={0}>
+            {isRightPanelCollapsed ? (
+              <Tooltip content={translate("common:showDetailsPanel")}>
+                <IconButton
+                  aria-label={translate("common:showDetailsPanel")}
+                  bg="fg.subtle"
+                  borderRadius={direction === "ltr" ? "100% 0 0 100%" : "0 
100% 100% 0"}
+                  boxShadow="md"
+                  left={direction === "rtl" ? "-5px" : undefined}
+                  onClick={() => setIsRightPanelCollapsed(false)}
+                  position="absolute"
+                  right={direction === "ltr" ? "-5px" : undefined}
+                  size="2xs"
+                  top="50%"
+                  zIndex={10}
+                >
+                  {direction === "ltr" ? <FaChevronLeft /> : <FaChevronRight 
/>}
+                </IconButton>
+              </Tooltip>
+            ) : undefined}
+            <PanelGroup
+              autoSaveId={`${dagView}-${direction}`}
+              dir={direction}
+              direction="horizontal"
+              key={`${dagView}-${direction}`}
+              ref={panelGroupRef}
+            >
+              <Panel
+                defaultSize={dagView === "graph" ? 70 : 20}
+                id="main-panel"
+                minSize={showGantt && dagView === "grid" && Boolean(runId) ? 
35 : 6}
+                order={1}
+              >
+                <Box height="100%" position="relative">
+                  <PanelButtons
+                    dagRunStateFilter={dagRunStateFilter}
+                    dagView={dagView}
+                    limit={limit}
+                    panelGroupRef={panelGroupRef}
+                    runAfterGte={runAfterGte}
+                    runAfterLte={runAfterLte}
+                    runTypeFilter={runTypeFilter}
+                    setDagRunStateFilter={setDagRunStateFilter}
+                    setDagView={setDagView}
+                    setLimit={setLimit}
+                    setRunAfterGte={setRunAfterGte}
+                    setRunAfterLte={setRunAfterLte}
+                    setRunTypeFilter={setRunTypeFilter}
+                    setShowGantt={setShowGantt}
+                    setShowVersionIndicatorMode={setShowVersionIndicatorMode}
+                    setTriggeringUserFilter={setTriggeringUserFilter}
+                    showGantt={showGantt}
+                    showVersionIndicatorMode={showVersionIndicatorMode}
+                    triggeringUserFilter={triggeringUserFilter}
+                  />
+                  {dagView === "graph" ? (
+                    <Graph />
+                  ) : (
+                    <HStack alignItems="flex-start" gap={0}>
+                      <Grid
                         dagRunState={dagRunStateFilter}
                         limit={limit}
                         runAfterGte={runAfterGte}
                         runAfterLte={runAfterLte}
                         runType={runTypeFilter}
+                        showGantt={Boolean(runId) && showGantt}
+                        showVersionIndicatorMode={showVersionIndicatorMode}
                         triggeringUser={triggeringUserFilter}
                       />
-                    ) : undefined}
-                  </HStack>
-                )}
-              </Box>
-            </Panel>
-            {!isRightPanelCollapsed && (
-              <>
-                <PanelResizeHandle
-                  className="resize-handle"
-                  onDragging={(isDragging) => {
-                    if (!isDragging) {
-                      const zoom = getZoom();
+                      {showGantt ? (
+                        <Gantt
+                          dagRunState={dagRunStateFilter}
+                          limit={limit}
+                          runAfterGte={runAfterGte}
+                          runAfterLte={runAfterLte}
+                          runType={runTypeFilter}
+                          triggeringUser={triggeringUserFilter}
+                        />
+                      ) : undefined}
+                    </HStack>
+                  )}
+                </Box>
+              </Panel>
+              {!isRightPanelCollapsed && (
+                <>
+                  <PanelResizeHandle
+                    className="resize-handle"
+                    onDragging={(isDragging) => {
+                      if (!isDragging) {
+                        const zoom = getZoom();
 
-                      void fitView({ maxZoom: zoom, minZoom: zoom });
-                    }
-                  }}
-                >
-                  <Box
-                    alignItems="center"
-                    bg="border.emphasized"
-                    cursor="col-resize"
-                    display="flex"
-                    h="100%"
-                    justifyContent="center"
-                    position="relative"
-                    w={0.5}
-                    // onClick={(e) => console.log(e)}
-                  />
-                </PanelResizeHandle>
+                        void fitView({ maxZoom: zoom, minZoom: zoom });
+                      }
+                    }}
+                  >
+                    <Box
+                      alignItems="center"
+                      bg="border.emphasized"
+                      cursor="col-resize"
+                      display="flex"
+                      h="100%"
+                      justifyContent="center"
+                      position="relative"
+                      w={0.5}
+                      // onClick={(e) => console.log(e)}
+                    />
+                  </PanelResizeHandle>
 
-                {/* Collapse button positioned next to the resize handle */}
+                  {/* Collapse button positioned next to the resize handle */}
 
-                <Panel defaultSize={dagView === "graph" ? 30 : 80} 
id="details-panel" minSize={20} order={2}>
-                  <Box display="flex" flexDirection="column" h="100%" 
position="relative">
-                    <Tooltip 
content={translate("common:collapseDetailsPanel")}>
-                      <IconButton
-                        aria-label={translate("common:collapseDetailsPanel")}
-                        bg="fg.subtle"
-                        borderRadius={direction === "ltr" ? "0 100% 100% 0" : 
"100% 0 0 100%"}
-                        boxShadow="md"
-                        left={direction === "ltr" ? "-5px" : undefined}
-                        onClick={() => setIsRightPanelCollapsed(true)}
-                        position="absolute"
-                        right={direction === "rtl" ? "-5px" : undefined}
-                        size="2xs"
-                        top="50%"
-                        zIndex={2}
-                      >
-                        {direction === "ltr" ? <FaChevronRight /> : 
<FaChevronLeft />}
-                      </IconButton>
-                    </Tooltip>
-                    {children}
-                    {Boolean(error) || (warningData?.dag_warnings.length ?? 0) 
> 0 ? (
-                      <>
-                        <Tooltip
-                          content={`${translate("common:dagWarnings")} 
(${warningData?.total_entries ?? 0 + Number(error)})`}
+                  <Panel
+                    defaultSize={dagView === "graph" ? 30 : 80}
+                    id="details-panel"
+                    minSize={20}
+                    order={2}
+                  >
+                    <Box display="flex" flexDirection="column" h="100%" 
position="relative">
+                      <Tooltip 
content={translate("common:collapseDetailsPanel")}>
+                        <IconButton
+                          aria-label={translate("common:collapseDetailsPanel")}
+                          bg="fg.subtle"
+                          borderRadius={direction === "ltr" ? "0 100% 100% 0" 
: "100% 0 0 100%"}
+                          boxShadow="md"
+                          left={direction === "ltr" ? "-5px" : undefined}
+                          onClick={() => setIsRightPanelCollapsed(true)}
+                          position="absolute"
+                          right={direction === "rtl" ? "-5px" : undefined}
+                          size="2xs"
+                          top="50%"
+                          zIndex={2}
                         >
-                          <IconButton
-                            aria-label={`${translate("common:dagWarnings")} 
(${warningData?.total_entries ?? 0 + Number(error)})`}
-                            colorPalette={Boolean(error) ? "red" : "orange"}
-                            margin="2"
-                            marginBottom="-1"
-                            onClick={onOpen}
-                            rounded="full"
-                            size="md"
-                            variant="solid"
+                          {direction === "ltr" ? <FaChevronRight /> : 
<FaChevronLeft />}
+                        </IconButton>
+                      </Tooltip>
+                      {children}
+                      {Boolean(error) || (warningData?.dag_warnings.length ?? 
0) > 0 ? (
+                        <>
+                          <Tooltip
+                            content={`${translate("common:dagWarnings")} 
(${warningData?.total_entries ?? 0 + Number(error)})`}
                           >
-                            <LuFileWarning />
-                          </IconButton>
-                        </Tooltip>
+                            <IconButton
+                              aria-label={`${translate("common:dagWarnings")} 
(${warningData?.total_entries ?? 0 + Number(error)})`}
+                              colorPalette={Boolean(error) ? "red" : "orange"}
+                              margin="2"
+                              marginBottom="-1"
+                              onClick={onOpen}
+                              rounded="full"
+                              size="md"
+                              variant="solid"
+                            >
+                              <LuFileWarning />
+                            </IconButton>
+                          </Tooltip>
 
-                        <DAGWarningsModal
-                          error={error}
-                          onClose={onClose}
-                          open={open}
-                          warnings={warningData?.dag_warnings}
-                        />
-                      </>
-                    ) : undefined}
-                    <ProgressBar size="xs" visibility={isLoading ? "visible" : 
"hidden"} />
-                    <NavTabs tabs={tabs} />
-                    <Box flexGrow={1} overflow="auto" px={2}>
-                      <Outlet />
+                          <DAGWarningsModal
+                            error={error}
+                            onClose={onClose}
+                            open={open}
+                            warnings={warningData?.dag_warnings}
+                          />
+                        </>
+                      ) : undefined}
+                      <ProgressBar size="xs" visibility={isLoading ? "visible" 
: "hidden"} />
+                      <NavTabs tabs={tabs} />
+                      <Box flexGrow={1} overflow="auto" px={2}>
+                        <Outlet />
+                      </Box>
                     </Box>
-                  </Box>
-                </Panel>
-              </>
-            )}
-          </PanelGroup>
+                  </Panel>
+                </>
+              )}
+            </PanelGroup>
+          </Box>
         </Box>
       </OpenGroupsProvider>
     </HoverProvider>

Reply via email to