You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by bb...@apache.org on 2022/03/08 16:27:25 UTC

[airflow] 03/09: reformat grid background colors

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

bbovenzi pushed a commit to branch mapped-task-drawer
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 5390dbc75db3128c11a937ade63e19406e3caa6c
Author: Brent Bovenzi <br...@gmail.com>
AuthorDate: Fri Feb 25 11:58:23 2022 -0500

    reformat grid background colors
---
 airflow/www/static/js/tree/InstanceTooltip.jsx | 16 ++---
 airflow/www/static/js/tree/SidePanel.jsx       | 45 +++++++++++--
 airflow/www/static/js/tree/StatusBox.jsx       | 19 +++---
 airflow/www/static/js/tree/Tree.jsx            | 28 ++++----
 airflow/www/static/js/tree/dagRuns/Bar.jsx     |  9 ++-
 airflow/www/static/js/tree/dagRuns/index.jsx   |  3 +-
 airflow/www/static/js/tree/renderTaskRows.jsx  | 88 ++++++++++++++------------
 7 files changed, 128 insertions(+), 80 deletions(-)

diff --git a/airflow/www/static/js/tree/InstanceTooltip.jsx b/airflow/www/static/js/tree/InstanceTooltip.jsx
index bc0d58c..b0d0584 100644
--- a/airflow/www/static/js/tree/InstanceTooltip.jsx
+++ b/airflow/www/static/js/tree/InstanceTooltip.jsx
@@ -125,29 +125,29 @@ const InstanceTooltip = ({
         </>
       )}
       <br />
-      <Text>
+      {/* <Text>
         {taskIdTitle}
         {taskId}
-      </Text>
-      <Text whiteSpace="nowrap">
+      </Text> */}
+      {/* <Text whiteSpace="nowrap">
         Run Id:
         {' '}
         {runId}
-      </Text>
-      {operator && (
+      </Text> */}
+      {/* {operator && (
       <Text>
         Operator:
         {' '}
         {operator}
       </Text>
-      )}
+      )} */}
       <Text>
         Duration:
         {' '}
         {formatDuration(duration || getDuration(startDate, endDate))}
       </Text>
       <br />
-      <Text as="strong">UTC</Text>
+      {/* <Text as="strong">UTC</Text>
       <Text>
         Started:
         {' '}
@@ -173,7 +173,7 @@ const InstanceTooltip = ({
         Ended:
         {' '}
         {endDate && formatDateTime(endDate)}
-      </Text>
+      </Text> */}
     </Box>
   );
 };
diff --git a/airflow/www/static/js/tree/SidePanel.jsx b/airflow/www/static/js/tree/SidePanel.jsx
index 3515f1c..7a21eba 100644
--- a/airflow/www/static/js/tree/SidePanel.jsx
+++ b/airflow/www/static/js/tree/SidePanel.jsx
@@ -21,29 +21,60 @@
 
 import React from 'react';
 import {
-  Box,
   chakra,
   Flex,
   Text,
+  useDisclosure,
+  CloseButton,
+  Button,
+  IconButton,
 } from '@chakra-ui/react';
+import { MdKeyboardArrowLeft, MdKeyboardArrowRight } from 'react-icons/md';
 
 import { formatDateTime } from '../datetime_utils';
 
-const SidePanel = ({ instance: { runId, taskId, executionDate }, isOpen }) => (
-  <Box bg="gray.200" maxWidth={isOpen ? 300 : 0} minWidth={isOpen ? 300 : 0} transition="all 0.5s" position="relative" overflow="hidden">
-    <Flex right={isOpen ? 0 : -300} top={0} transition="right 0.5s, max-width 0.5s" width={300} flexDirection="column" m={2}>
-      <Text as="h4">
+const SidePanel = ({ instance: { runId, taskId, executionDate } }) => {
+  const { isOpen, onOpen, onClose } = useDisclosure();
+  if (!isOpen) {
+    return (
+      <IconButton
+        ml={2}
+        icon={<MdKeyboardArrowLeft size={18} />}
+        aria-label="Open Details Panel"
+        onClick={onOpen}
+      />
+    );
+  }
+  const title = runId && taskId
+    ? (
+      <>
         <chakra.span>Task Instance: </chakra.span>
         <chakra.b>{taskId}</chakra.b>
         <chakra.span> at </chakra.span>
         <chakra.b>{formatDateTime(moment.utc(executionDate))}</chakra.b>
+      </>
+    )
+    : (
+      <chakra.span>Dag Details: </chakra.span>
+    );
+
+  return (
+    <Flex bg="gray.200" maxWidth={300} minWidth={300} flexDirection="column" p={3}>
+      <IconButton
+        ml={2}
+        icon={<MdKeyboardArrowRight size={18} />}
+        aria-label="Close Details Panel"
+        onClick={onClose}
+      />
+      <Text as="h4">
+        {title}
       </Text>
       <Text>
         {/* eslint-disable-next-line max-len */}
         Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc vel risus commodo viverra maecenas accumsan. Ut porttitor leo a diam sollicitudin tempor id eu. Molestie at elementum eu facilisis sed odio morbi quis commodo. Facilisis leo vel fringilla est ullamcorper eget nulla facilisi etiam. Est sit amet facilisis magna etiam tempor orci eu. Id semper risus in hendrerit gravida rutrum. Ac odio tempor orci dapibus  [...]
       </Text>
     </Flex>
-  </Box>
-);
+  );
+};
 
 export default SidePanel;
diff --git a/airflow/www/static/js/tree/StatusBox.jsx b/airflow/www/static/js/tree/StatusBox.jsx
index dce0fda..b4abc93 100644
--- a/airflow/www/static/js/tree/StatusBox.jsx
+++ b/airflow/www/static/js/tree/StatusBox.jsx
@@ -24,9 +24,10 @@ import {
   Flex,
   Box,
   Tooltip,
+  useTheme,
 } from '@chakra-ui/react';
 
-import { callModal } from '../dag';
+// import { callModal } from '../dag';
 import InstanceTooltip from './InstanceTooltip';
 
 const StatusBox = ({
@@ -35,21 +36,19 @@ const StatusBox = ({
   const {
     executionDate, taskId, tryNumber = 0, operator, runId,
   } = instance;
+  const { colors } = useTheme();
+  const hoverBlue = `${colors.blue[100]}50`;
 
-  const onOpenModal = () => executionDate && callModal(taskId, executionDate, extraLinks, tryNumber, operator === 'SubDagOperator' || undefined, runId);
-  const onClick = () => {
-    if (group.isMapped) {
-      onSelectInstance(instance);
-    } else {
-      onSelectInstance({});
-      onOpenModal();
-    }
+  // const onOpenModal = () => executionDate && callModal(taskId, executionDate, extraLinks, tryNumber, operator === 'SubDagOperator' || undefined, runId);
+  const onClick = (e) => {
+    e.stopPropagation();
+    onSelectInstance(instance);
   };
 
   // Fetch the corresponding column element and set its background color when hovering
   const onMouseOver = () => {
     [...containerRef.current.getElementsByClassName(`js-${runId}`)]
-      .forEach((e) => { e.style.backgroundColor = 'rgba(113, 128, 150, 0.1)'; });
+      .forEach((e) => { e.style.backgroundColor = hoverBlue; });
   };
   const onMouseLeave = () => {
     [...containerRef.current.getElementsByClassName(`js-${runId}`)]
diff --git a/airflow/www/static/js/tree/Tree.jsx b/airflow/www/static/js/tree/Tree.jsx
index 095adbd..ff1402f 100644
--- a/airflow/www/static/js/tree/Tree.jsx
+++ b/airflow/www/static/js/tree/Tree.jsx
@@ -59,7 +59,7 @@ const Tree = () => {
 
   return (
     <Box position="relative" ref={containerRef}>
-      <FormControl display="flex" alignItems="center" justifyContent="flex-end" width="100%">
+      <FormControl display="flex" alignItems="center" justifyContent="flex-end" width="100%" mb={2}>
         {isRefreshOn && <Spinner color="blue.500" speed="1s" mr="4px" />}
         <FormLabel htmlFor="auto-refresh" mb={0} fontSize="12px" fontWeight="normal">
           Auto-refresh
@@ -68,19 +68,21 @@ const Tree = () => {
       </FormControl>
       <Text transform="rotate(-90deg)" position="absolute" left="-6px" top="130px">Runs</Text>
       <Text transform="rotate(-90deg)" position="absolute" left="-6px" top="190px">Tasks</Text>
-      <Box pl="24px">
+      <Box pl="24px" height="100%" onClick={() => setSelectedInstance({})}>
         <Flex position="relative" flexDirection="row" justifyContent="space-between" overflow="hidden">
-          <Table mr="24px" overflowX="auto" ref={scrollRef} height={0}>
-            <Thead>
-              <DagRuns containerRef={containerRef} />
-            </Thead>
-            <Tbody>
-              {renderTaskRows({
-                task: groups, containerRef, onSelectInstance,
-              })}
-            </Tbody>
-          </Table>
-          <SidePanel isOpen={!!runId} instance={selectedInstance} />
+          <Box mr="12px" pb="12px" overflowX="auto" ref={scrollRef} maxWidth="60vw">
+            <Table height={0}>
+              <Thead>
+                <DagRuns containerRef={containerRef} selectedInstance={selectedInstance} />
+              </Thead>
+              <Tbody>
+                {renderTaskRows({
+                  task: groups, containerRef, onSelectInstance, selectedInstance,
+                })}
+              </Tbody>
+            </Table>
+          </Box>
+          <SidePanel instance={selectedInstance} />
         </Flex>
       </Box>
     </Box>
diff --git a/airflow/www/static/js/tree/dagRuns/Bar.jsx b/airflow/www/static/js/tree/dagRuns/Bar.jsx
index a0fa5b1..4dbe20d 100644
--- a/airflow/www/static/js/tree/dagRuns/Bar.jsx
+++ b/airflow/www/static/js/tree/dagRuns/Bar.jsx
@@ -26,6 +26,7 @@ import {
   Tooltip,
   Text,
   VStack,
+  useTheme,
 } from '@chakra-ui/react';
 import { MdPlayArrow } from 'react-icons/md';
 
@@ -35,13 +36,16 @@ import { callModalDag } from '../../dag';
 const BAR_HEIGHT = 100;
 
 const DagRunBar = ({
-  run, max, index, totalRuns, containerRef,
+  run, max, index, totalRuns, containerRef, selectedInstance,
 }) => {
+  const { colors } = useTheme();
+  const hoverBlue = `${colors.blue[100]}50`;
   let highlightHeight = '100%';
   if (containerRef && containerRef.current) {
     const table = containerRef.current.getElementsByTagName('tbody')[0];
     highlightHeight = table.offsetHeight + BAR_HEIGHT;
   }
+  const isSelected = run.runId === selectedInstance.runId;
   return (
     <Box position="relative">
       <Flex
@@ -93,7 +97,8 @@ const DagRunBar = ({
         top="1px"
         height={highlightHeight}
         className={`js-${run.runId}`}
-        _peerHover={{ backgroundColor: 'rgba(113, 128, 150, 0.1)' }}
+        bg={isSelected ? 'blue.100' : undefined}
+        _peerHover={!isSelected && { backgroundColor: hoverBlue }}
         zIndex={0}
         transition="background-color 0.2s"
       />
diff --git a/airflow/www/static/js/tree/dagRuns/index.jsx b/airflow/www/static/js/tree/dagRuns/index.jsx
index a0a4931..7de949f 100644
--- a/airflow/www/static/js/tree/dagRuns/index.jsx
+++ b/airflow/www/static/js/tree/dagRuns/index.jsx
@@ -36,7 +36,7 @@ const DurationTick = ({ children, ...rest }) => (
   </Text>
 );
 
-const DagRuns = ({ containerRef }) => {
+const DagRuns = ({ containerRef, selectedInstance }) => {
   const { data: { dagRuns = [] } } = useTreeData();
   const durations = [];
   const runs = dagRuns.map((dagRun) => {
@@ -97,6 +97,7 @@ const DagRuns = ({ containerRef }) => {
               index={i}
               totalRuns={runs.length}
               containerRef={containerRef}
+              selectedInstance={selectedInstance}
             />
           ))}
         </Flex>
diff --git a/airflow/www/static/js/tree/renderTaskRows.jsx b/airflow/www/static/js/tree/renderTaskRows.jsx
index f5a7ba0..7eff252 100644
--- a/airflow/www/static/js/tree/renderTaskRows.jsx
+++ b/airflow/www/static/js/tree/renderTaskRows.jsx
@@ -28,6 +28,7 @@ import {
   Flex,
   useDisclosure,
   Collapse,
+  useTheme,
 } from '@chakra-ui/react';
 import { FiChevronUp, FiChevronDown } from 'react-icons/fi';
 
@@ -40,7 +41,7 @@ import { getMetaValue } from '../utils';
 const dagId = getMetaValue('dag_id');
 
 const renderTaskRows = ({
-  task, containerRef, level = 0, isParentOpen, onSelectInstance,
+  task, containerRef, level = 0, isParentOpen, onSelectInstance, selectedInstance,
 }) => task.children.map((t) => (
   <Row
     key={t.id}
@@ -50,40 +51,37 @@ const renderTaskRows = ({
     prevTaskId={task.id}
     isParentOpen={isParentOpen}
     onSelectInstance={onSelectInstance}
+    selectedInstance={selectedInstance}
   />
 ));
 
 const TaskName = ({
   isGroup = false, isMapped = false, onToggle, isOpen, level, taskName,
 }) => (
-  <Box _groupHover={{ backgroundColor: 'rgba(113, 128, 150, 0.1)' }} transition="background-color 0.2s">
-    <Flex
-      as={isGroup ? 'button' : 'div'}
-      onClick={() => isGroup && onToggle()}
-      color={level > 4 && 'white'}
-      aria-label={taskName}
-      title={taskName}
-      mr={4}
-      width="100%"
-      backgroundColor={`rgba(203, 213, 224, ${0.25 * level})`}
-      alignItems="center"
+  <Flex
+    as={isGroup ? 'button' : 'div'}
+    onClick={() => isGroup && onToggle()}
+    aria-label={taskName}
+    title={taskName}
+    mr={4}
+    width="100%"
+    alignItems="center"
+  >
+    <Text
+      display="inline"
+      fontSize="12px"
+      ml={level * 4 + 4}
+      isTruncated
     >
-      <Text
-        display="inline"
-        fontSize="12px"
-        ml={level * 4 + 4}
-        isTruncated
-      >
-        {taskName}
-        {isMapped && (
-          ' [ ]'
-        )}
-      </Text>
-      {isGroup && (
-        isOpen ? <FiChevronDown data-testid="open-group" /> : <FiChevronUp data-testid="closed-group" />
+      {taskName}
+      {isMapped && (
+        ' [ ]'
       )}
-    </Flex>
-  </Box>
+    </Text>
+    {isGroup && (
+      isOpen ? <FiChevronDown data-testid="open-group" /> : <FiChevronUp data-testid="closed-group" />
+    )}
+  </Flex>
 );
 
 const TaskInstances = ({
@@ -104,16 +102,20 @@ const TaskInstances = ({
             onSelectInstance={onSelectInstance}
           />
         )
-        : <Box key={`${run.runId}-${task.id}`} width="18px" data-testid="blank-task" />;
+        : <Box key={`${run.runId}-${task.id}`} width="16px" data-testid="blank-task" />;
     })}
   </Flex>
 );
 
-const Row = ({
-  task, containerRef, level, prevTaskId, isParentOpen = true, onSelectInstance,
-}) => {
+const Row = (props) => {
+  const {
+    task, containerRef, level, prevTaskId, isParentOpen = true, onSelectInstance, selectedInstance,
+  } = props;
   const { data: { dagRuns = [] } } = useTreeData();
+  const { colors } = useTheme();
+  const hoverBlue = `${colors.blue[100]}50`;
   const isGroup = !!task.children;
+  const isSelected = selectedInstance.taskId === task.id;
 
   const taskName = prevTaskId ? task.id.replace(`${prevTaskId}.`, '') : task.id;
 
@@ -136,21 +138,23 @@ const Row = ({
   return (
     <>
       <Tr
-        backgroundColor={`rgba(203, 213, 224, ${0.25 * level})`}
+        bg={isSelected ? 'blue.100' : undefined}
         borderBottomWidth={isFullyOpen ? 1 : 0}
-        borderBottomColor={level > 1 ? 'white' : 'gray.200'}
+        borderBottomColor="gray.200"
         role="group"
+        _hover={!isSelected && { bg: hoverBlue }}
+        transition="background-color 0.2s"
       >
         <Td
-          _groupHover={level > 3 && {
-            color: 'white',
-          }}
+          bg={isSelected ? 'blue.100' : 'white'}
+          _groupHover={!isSelected && ({ bg: 'blue.50' })}
           p={0}
+          transition="background-color 0.2s"
           lineHeight="18px"
           position="sticky"
           left={0}
-          backgroundColor="white"
           borderBottom={0}
+          zIndex={2}
         >
           <Collapse in={isFullyOpen}>
             <TaskName
@@ -164,7 +168,11 @@ const Row = ({
           </Collapse>
         </Td>
         <Td width={0} p={0} borderBottom={0} />
-        <Td p={0} align="right" _groupHover={{ backgroundColor: 'rgba(113, 128, 150, 0.1)' }} transition="background-color 0.2s" borderBottom={0}>
+        <Td
+          p={0}
+          align="right"
+          borderBottom={0}
+        >
           <Collapse in={isFullyOpen}>
             <TaskInstances
               dagRuns={dagRuns}
@@ -177,7 +185,9 @@ const Row = ({
       </Tr>
       {isGroup && (
         renderTaskRows({
-          task, containerRef, level: level + 1, isParentOpen: isOpen, onSelectInstance,
+          ...props,
+          level: level + 1,
+          isParentOpen: isOpen,
         })
       )}
     </>