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/04/01 14:09:24 UTC

[airflow] 01/01: Grid view responds to pausing a DAG

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

bbovenzi pushed a commit to branch track-is-paused
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit a88e5e98f530c4509fc6e52836c89f0cd3e752d8
Author: Brent Bovenzi <br...@gmail.com>
AuthorDate: Fri Apr 1 09:54:32 2022 -0400

    Grid view responds to pausing a DAG
---
 airflow/www/static/js/dag.js                       | 11 +++++++-
 airflow/www/static/js/tree/Tree.jsx                |  5 ++--
 airflow/www/static/js/tree/context/autorefresh.jsx | 31 +++++++++++++++++-----
 3 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/airflow/www/static/js/dag.js b/airflow/www/static/js/dag.js
index 87db8f1..1606737 100644
--- a/airflow/www/static/js/dag.js
+++ b/airflow/www/static/js/dag.js
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-/* global document, window, $ */
+/* global document, window, Event, $ */
 
 import { getMetaValue } from './utils';
 import { approxTimeFromNow, formatDateTime } from './datetime_utils';
@@ -368,10 +368,19 @@ $('#pause_resume').on('change', function onChange() {
   // Remove focus on element so the tooltip will go away
   $input.trigger('blur');
   $input.removeClass('switch-input--error');
+
+  // dispatch an event that React can listen for
+  const event = new Event('paused');
+  event.value = isPaused;
+  event.key = 'isPaused';
+  document.dispatchEvent(event);
+
   $.post(url).fail(() => {
     setTimeout(() => {
       $input.prop('checked', !isPaused);
       $input.addClass('switch-input--error');
+      event.value = !isPaused;
+      document.dispatchEvent(event);
     }, 500);
   });
 });
diff --git a/airflow/www/static/js/tree/Tree.jsx b/airflow/www/static/js/tree/Tree.jsx
index 6f8c284..6108293 100644
--- a/airflow/www/static/js/tree/Tree.jsx
+++ b/airflow/www/static/js/tree/Tree.jsx
@@ -34,7 +34,6 @@ import {
   Button,
 } from '@chakra-ui/react';
 
-import { getMetaValue } from '../utils';
 import { useTreeData } from './api';
 import renderTaskRows from './renderTaskRows';
 import ResetRoot from './ResetRoot';
@@ -43,7 +42,6 @@ import Details from './details';
 import { useSelection } from './context/selection';
 import { useAutoRefresh } from './context/autorefresh';
 
-const isPaused = getMetaValue('is_paused') === 'True';
 const sidePanelKey = 'showSidePanel';
 
 const Tree = () => {
@@ -51,7 +49,7 @@ const Tree = () => {
   const tableRef = useRef();
   const [tableWidth, setTableWidth] = useState('100%');
   const { data: { groups = {}, dagRuns = [] } } = useTreeData();
-  const { isRefreshOn, toggleRefresh } = useAutoRefresh();
+  const { isRefreshOn, toggleRefresh, isPaused } = useAutoRefresh();
   const isPanelOpen = JSON.parse(localStorage.getItem(sidePanelKey));
   const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: isPanelOpen });
 
@@ -94,6 +92,7 @@ const Tree = () => {
             isDisabled={isPaused}
             isChecked={isRefreshOn}
             size="lg"
+            title={isPaused ? 'Autorefresh is disabled while the DAG is paused' : ''}
           />
         </FormControl>
         <Button
diff --git a/airflow/www/static/js/tree/context/autorefresh.jsx b/airflow/www/static/js/tree/context/autorefresh.jsx
index 34dd986..48825bd 100644
--- a/airflow/www/static/js/tree/context/autorefresh.jsx
+++ b/airflow/www/static/js/tree/context/autorefresh.jsx
@@ -17,23 +17,26 @@
  * under the License.
  */
 
-/* global localStorage, treeData */
+/* global localStorage, treeData, document */
 
-import React, { useContext, useState } from 'react';
+import React, { useContext, useState, useEffect } from 'react';
 import { getMetaValue } from '../../utils';
 import { formatData, areActiveRuns } from '../treeDataUtils';
 
 const autoRefreshKey = 'disabledAutoRefresh';
 
-const isPaused = getMetaValue('is_paused') === 'True';
+const initialIsPaused = getMetaValue('is_paused') === 'True';
 const isRefreshDisabled = JSON.parse(localStorage.getItem(autoRefreshKey));
-const isRefreshAllowed = !(isPaused || isRefreshDisabled);
 
 const AutoRefreshContext = React.createContext(null);
 
 export const AutoRefreshProvider = ({ children }) => {
-  const dagRuns = treeData && treeData.dag_runs ? formatData(treeData.dag_runs, []) : [];
+  let dagRuns = [];
+  const data = JSON.parse(treeData);
+  if (data.dag_runs) dagRuns = formatData(data.dag_runs);
+  const [isPaused, setIsPaused] = useState(initialIsPaused);
   const isActive = areActiveRuns(dagRuns);
+  const isRefreshAllowed = !(isPaused || isRefreshDisabled);
   const initialState = isRefreshAllowed && isActive;
 
   const [isRefreshOn, setRefresh] = useState(initialState);
@@ -55,10 +58,26 @@ export const AutoRefreshProvider = ({ children }) => {
     }
   };
 
+  useEffect(() => {
+    const handleChange = (e) => {
+      setIsPaused(!e.value);
+      if (!e.value) {
+        stopRefresh();
+      } else if (isActive) {
+        setRefresh(true);
+      }
+    };
+
+    document.addEventListener('paused', handleChange);
+    return () => {
+      document.removeEventListener('paused', handleChange);
+    };
+  });
+
   return (
     <AutoRefreshContext.Provider
       value={{
-        isRefreshOn, toggleRefresh, stopRefresh, startRefresh,
+        isRefreshOn, toggleRefresh, stopRefresh, startRefresh, isPaused,
       }}
     >
       {children}