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

phanikumv 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 95ed08ef3b Made filters bar collapsible and add a full screen toggle 
(#38296)
95ed08ef3b is described below

commit 95ed08ef3bbd634f9bd06dcb619b476c7b4baa61
Author: Brent Bovenzi <[email protected]>
AuthorDate: Tue Mar 19 20:33:40 2024 -0700

    Made filters bar collapsible and add a full screen toggle (#38296)
---
 airflow/www/static/js/dag/Main.tsx                 | 65 ++++++++++++++++++++--
 airflow/www/static/js/dag/details/graph/index.tsx  | 34 +++++++----
 airflow/www/static/js/dag/details/index.tsx        |  8 +++
 .../js/dag/details/taskInstance/Logs/index.tsx     | 20 ++++++-
 airflow/www/static/js/dag/nav/FilterBar.tsx        |  9 +--
 5 files changed, 111 insertions(+), 25 deletions(-)

diff --git a/airflow/www/static/js/dag/Main.tsx 
b/airflow/www/static/js/dag/Main.tsx
index 9a4ace85eb..d64534113b 100644
--- a/airflow/www/static/js/dag/Main.tsx
+++ b/airflow/www/static/js/dag/Main.tsx
@@ -20,15 +20,27 @@
 /* global localStorage */
 
 import React, { useState, useRef, useEffect, useCallback } from "react";
-import { Box, Flex, Divider, Spinner, useDisclosure } from "@chakra-ui/react";
+import {
+  Box,
+  Flex,
+  Spinner,
+  useDisclosure,
+  IconButton,
+  Accordion,
+  AccordionItem,
+  AccordionButton,
+  AccordionPanel,
+} from "@chakra-ui/react";
 import { isEmpty, debounce } from "lodash";
+import { MdDoubleArrow } from "react-icons/md";
+import { useSearchParams } from "react-router-dom";
 
 import { useGridData } from "src/api";
 import { hoverDelay } from "src/utils";
 
 import ShortcutCheatSheet from "src/components/ShortcutCheatSheet";
 import { useKeysPress } from "src/utils/useKeysPress";
-import { useSearchParams } from "react-router-dom";
+
 import Details, { TAB_PARAM } from "./details";
 import Grid from "./grid";
 import FilterBar from "./nav/FilterBar";
@@ -68,11 +80,20 @@ const MainInContext = () => {
     isLoading,
   } = useGridData();
   const [isGridCollapsed, setIsGridCollapsed] = useState(false);
+
+  const [accordionIndexes, setAccordionIndexes] = useState<Array<number>>([0]);
+  const isFilterCollapsed = !accordionIndexes.length;
+  const toggleFilterCollapsed = () => {
+    if (isFilterCollapsed) setAccordionIndexes([0]);
+    else setAccordionIndexes([]);
+  };
+
   const [searchParams] = useSearchParams();
   const resizeRef = useRef<HTMLDivElement>(null);
   const gridRef = useRef<HTMLDivElement>(null);
   const gridScrollRef = useRef<HTMLDivElement>(null);
   const ganttScrollRef = useRef<HTMLDivElement>(null);
+
   const isPanelOpen =
     localStorage.getItem(detailsPanelKey) !== "true" ||
     !!searchParams.get(TAB_PARAM);
@@ -182,6 +203,17 @@ const MainInContext = () => {
     onToggleShortcut
   );
 
+  const isFullScreen = isFilterCollapsed && isGridCollapsed;
+  const toggleFullScreen = () => {
+    if (!isFullScreen) {
+      setAccordionIndexes([]);
+      setIsGridCollapsed(true);
+    } else {
+      setAccordionIndexes([0]);
+      setIsGridCollapsed(false);
+    }
+  };
+
   return (
     <Box
       flex={1}
@@ -191,9 +223,30 @@ const MainInContext = () => {
       overflow="hidden"
       position="relative"
     >
-      <FilterBar />
-      <LegendRow onStatusHover={onStatusHover} onStatusLeave={onStatusLeave} />
-      <Divider mb={5} borderBottomWidth={2} />
+      <IconButton
+        position="absolute"
+        variant="ghost"
+        color="gray.400"
+        top={0}
+        left={0}
+        onClick={toggleFilterCollapsed}
+        icon={<MdDoubleArrow />}
+        aria-label="Toggle filters bar"
+        transform={isFilterCollapsed ? "rotateZ(90deg)" : "rotateZ(270deg)"}
+        transition="all 0.2s"
+      />
+      <Accordion allowToggle index={accordionIndexes} borderTopWidth={0}>
+        <AccordionItem>
+          <AccordionButton display="none" />
+          <AccordionPanel p={0}>
+            <FilterBar />
+            <LegendRow
+              onStatusHover={onStatusHover}
+              onStatusLeave={onStatusLeave}
+            />
+          </AccordionPanel>
+        </AccordionItem>
+      </Accordion>
       <Flex height="100%">
         {isLoading || isEmpty(groups) ? (
           <Spinner />
@@ -240,6 +293,8 @@ const MainInContext = () => {
                     hoveredTaskState={hoveredTaskState}
                     gridScrollRef={gridScrollRef}
                     ganttScrollRef={ganttScrollRef}
+                    isFullScreen={isFullScreen}
+                    toggleFullScreen={toggleFullScreen}
                   />
                 </Box>
               </>
diff --git a/airflow/www/static/js/dag/details/graph/index.tsx 
b/airflow/www/static/js/dag/details/graph/index.tsx
index 84f71313a3..3f34b86c73 100644
--- a/airflow/www/static/js/dag/details/graph/index.tsx
+++ b/airflow/www/static/js/dag/details/graph/index.tsx
@@ -28,7 +28,9 @@ import ReactFlow, {
   Panel,
   useOnViewportChange,
   Viewport,
+  ControlButton,
 } from "reactflow";
+import { BiCollapse, BiExpand } from "react-icons/bi";
 
 import { useDatasets, useGraphData, useGridData } from "src/api";
 import useSelection from "src/dag/useSelection";
@@ -47,11 +49,19 @@ interface Props {
   openGroupIds: string[];
   onToggleGroups: (groupIds: string[]) => void;
   hoveredTaskState?: string | null;
+  isFullScreen?: boolean;
+  toggleFullScreen?: () => void;
 }
 
 const dagId = getMetaValue("dag_id");
 
-const Graph = ({ openGroupIds, onToggleGroups, hoveredTaskState }: Props) => {
+const Graph = ({
+  openGroupIds,
+  onToggleGroups,
+  hoveredTaskState,
+  isFullScreen,
+  toggleFullScreen,
+}: Props) => {
   const graphRef = useRef(null);
   const { data } = useGraphData();
   const [arrange, setArrange] = useState(data?.arrange || "LR");
@@ -224,7 +234,15 @@ const Graph = ({ openGroupIds, onToggleGroups, 
hoveredTaskState }: Props) => {
             </Box>
           </Panel>
           <Background />
-          <Controls showInteractive={false} />
+          <Controls showInteractive={false}>
+            <ControlButton
+              onClick={toggleFullScreen}
+              aria-label="Toggle full screen"
+              title="Toggle full screen"
+            >
+              {isFullScreen ? <BiCollapse /> : <BiExpand />}
+            </ControlButton>
+          </Controls>
           <MiniMap
             nodeStrokeWidth={15}
             nodeStrokeColor={(props) => nodeStrokeColor(props, colors)}
@@ -238,17 +256,9 @@ const Graph = ({ openGroupIds, onToggleGroups, 
hoveredTaskState }: Props) => {
   );
 };
 
-const GraphWrapper = ({
-  openGroupIds,
-  onToggleGroups,
-  hoveredTaskState,
-}: Props) => (
+const GraphWrapper = (props: Props) => (
   <ReactFlowProvider>
-    <Graph
-      openGroupIds={openGroupIds}
-      onToggleGroups={onToggleGroups}
-      hoveredTaskState={hoveredTaskState}
-    />
+    <Graph {...props} />
   </ReactFlowProvider>
 );
 
diff --git a/airflow/www/static/js/dag/details/index.tsx 
b/airflow/www/static/js/dag/details/index.tsx
index 6ef60e0120..0305fe0a2d 100644
--- a/airflow/www/static/js/dag/details/index.tsx
+++ b/airflow/www/static/js/dag/details/index.tsx
@@ -77,6 +77,8 @@ interface Props {
   hoveredTaskState?: string | null;
   gridScrollRef: React.RefObject<HTMLDivElement>;
   ganttScrollRef: React.RefObject<HTMLDivElement>;
+  isFullScreen?: boolean;
+  toggleFullScreen?: () => void;
 }
 
 const tabToIndex = (tab?: string) => {
@@ -148,6 +150,8 @@ const Details = ({
   hoveredTaskState,
   gridScrollRef,
   ganttScrollRef,
+  isFullScreen,
+  toggleFullScreen,
 }: Props) => {
   const {
     selected: { runId, taskId, mapIndex },
@@ -407,6 +411,8 @@ const Details = ({
               openGroupIds={openGroupIds}
               onToggleGroups={onToggleGroups}
               hoveredTaskState={hoveredTaskState}
+              isFullScreen={isFullScreen}
+              toggleFullScreen={toggleFullScreen}
             />
           </TabPanel>
           <TabPanel p={0} height="100%">
@@ -456,6 +462,8 @@ const Details = ({
                     ? undefined
                     : instance.state
                 }
+                isFullScreen={isFullScreen}
+                toggleFullScreen={toggleFullScreen}
               />
             </TabPanel>
           )}
diff --git a/airflow/www/static/js/dag/details/taskInstance/Logs/index.tsx 
b/airflow/www/static/js/dag/details/taskInstance/Logs/index.tsx
index 2b1035fb23..9e664fda20 100644
--- a/airflow/www/static/js/dag/details/taskInstance/Logs/index.tsx
+++ b/airflow/www/static/js/dag/details/taskInstance/Logs/index.tsx
@@ -27,8 +27,10 @@ import {
   Icon,
   Spinner,
   Select,
+  IconButton,
 } from "@chakra-ui/react";
 import { MdWarning } from "react-icons/md";
+import { BiCollapse, BiExpand } from "react-icons/bi";
 
 import { getMetaValue } from "src/utils";
 import useTaskLog from "src/api/useTaskLog";
@@ -36,7 +38,6 @@ import LinkButton from "src/components/LinkButton";
 import { useTimezone } from "src/context/timezone";
 import type { Dag, DagRun, TaskInstance } from "src/types";
 import MultiSelect from "src/components/MultiSelect";
-
 import URLSearchParamsWrapper from "src/utils/URLSearchParamWrapper";
 
 import LogLink from "./LogLink";
@@ -95,6 +96,8 @@ interface Props {
   executionDate: DagRun["executionDate"];
   tryNumber: TaskInstance["tryNumber"];
   state?: TaskInstance["state"];
+  isFullScreen?: boolean;
+  toggleFullScreen?: () => void;
 }
 
 const Logs = ({
@@ -105,6 +108,8 @@ const Logs = ({
   executionDate,
   tryNumber,
   state,
+  isFullScreen,
+  toggleFullScreen,
 }: Props) => {
   const [internalIndexes, externalIndexes] = getLinkIndexes(tryNumber);
   const [selectedTryNumber, setSelectedTryNumber] = useState<
@@ -294,6 +299,19 @@ const Logs = ({
                 <LinkButton href={`${logUrl}&${params.toString()}`}>
                   See More
                 </LinkButton>
+                <IconButton
+                  variant="ghost"
+                  aria-label="Toggle full screen"
+                  title="Toggle full screen"
+                  onClick={toggleFullScreen}
+                  icon={
+                    isFullScreen ? (
+                      <BiCollapse height="24px" />
+                    ) : (
+                      <BiExpand height="24px" />
+                    )
+                  }
+                />
               </Flex>
             </Flex>
           </Box>
diff --git a/airflow/www/static/js/dag/nav/FilterBar.tsx 
b/airflow/www/static/js/dag/nav/FilterBar.tsx
index 935ddac8d6..f03ea734b8 100644
--- a/airflow/www/static/js/dag/nav/FilterBar.tsx
+++ b/airflow/www/static/js/dag/nav/FilterBar.tsx
@@ -121,13 +121,8 @@ const FilterBar = () => {
   });
 
   return (
-    <Flex
-      backgroundColor="blackAlpha.200"
-      mt={4}
-      p={4}
-      justifyContent="space-between"
-    >
-      <Flex>
+    <Flex backgroundColor="blackAlpha.200" p={4} 
justifyContent="space-between">
+      <Flex ml={10}>
         <Box px={2}>
           <Input
             {...inputStyles}

Reply via email to