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/13 18:43:20 UTC

[airflow] 02/02: move convertSecsToHumanReadable to datetime_utils

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

bbovenzi pushed a commit to branch consistent-duration-format
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 6b69b4b09f024199113e620177496464c87de98a
Author: Brent Bovenzi <br...@gmail.com>
AuthorDate: Wed Apr 13 14:41:29 2022 -0400

    move convertSecsToHumanReadable to datetime_utils
---
 airflow/www/static/js/datetime_utils.js           | 35 ++++++++++++-
 airflow/www/static/js/graph.js                    |  3 +-
 airflow/www/static/js/main.js                     | 35 +------------
 airflow/www/static/js/task_instances.js           |  4 +-
 airflow/www/static/js/tree/dagRuns/index.test.jsx | 60 ++++++++++++-----------
 5 files changed, 71 insertions(+), 66 deletions(-)

diff --git a/airflow/www/static/js/datetime_utils.js b/airflow/www/static/js/datetime_utils.js
index 729bb89e15..bfb716c5c6 100644
--- a/airflow/www/static/js/datetime_utils.js
+++ b/airflow/www/static/js/datetime_utils.js
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-/* global moment, $, document, convertSecsToHumanReadable */
+/* global moment, $, document */
 export const defaultFormat = 'YYYY-MM-DD, HH:mm:ss';
 export const defaultFormatWithTZ = 'YYYY-MM-DD, HH:mm:ss z';
 export const defaultTZFormat = 'z (Z)';
@@ -25,6 +25,39 @@ export const dateTimeAttrFormat = 'YYYY-MM-DDThh:mm:ssTZD';
 
 export const TimezoneEvent = 'timezone';
 
+export function convertSecsToHumanReadable(seconds) {
+  const oriSeconds = seconds;
+  const floatingPart = oriSeconds - Math.floor(oriSeconds);
+
+  seconds = Math.floor(seconds);
+
+  const secondsPerHour = 60 * 60;
+  const secondsPerMinute = 60;
+
+  const hours = Math.floor(seconds / secondsPerHour);
+  seconds -= hours * secondsPerHour;
+
+  const minutes = Math.floor(seconds / secondsPerMinute);
+  seconds -= minutes * secondsPerMinute;
+
+  let readableFormat = '';
+  if (hours > 0) {
+    readableFormat += `${hours}Hours `;
+  }
+  if (minutes > 0) {
+    readableFormat += `${minutes}Min `;
+  }
+  if (seconds + floatingPart > 0) {
+    if (Math.floor(oriSeconds) === oriSeconds) {
+      readableFormat += `${seconds}Sec`;
+    } else {
+      seconds += floatingPart;
+      readableFormat += `${seconds.toFixed(3)}Sec`;
+    }
+  }
+  return readableFormat;
+}
+
 export function formatTimezone(what) {
   if (what instanceof moment) {
     return what.isUTC() ? 'UTC' : what.format(defaultTZFormat);
diff --git a/airflow/www/static/js/graph.js b/airflow/www/static/js/graph.js
index ea7fc10cb7..cd41bed5ae 100644
--- a/airflow/www/static/js/graph.js
+++ b/airflow/www/static/js/graph.js
@@ -21,13 +21,14 @@
 
 /*
   global d3, document, nodes, taskInstances, tasks, edges, dagreD3, localStorage, $,
-  autoRefreshInterval, moment, convertSecsToHumanReadable
+  autoRefreshInterval, moment,
 */
 
 import { getMetaValue, finalStatesMap } from './utils';
 import { escapeHtml } from './main';
 import tiTooltip, { taskNoInstanceTooltip } from './task_instances';
 import { callModal } from './dag';
+import { convertSecsToHumanReadable } from './datetime_utils';
 
 // dagId comes from dag.html
 const dagId = getMetaValue('dag_id');
diff --git a/airflow/www/static/js/main.js b/airflow/www/static/js/main.js
index 878a32bb66..6b63fabd56 100644
--- a/airflow/www/static/js/main.js
+++ b/airflow/www/static/js/main.js
@@ -61,6 +61,7 @@ function changeDisplayedTimezone(tz) {
 
 const el = document.createElement('span');
 
+// eslint-disable-next-line import/prefer-default-export
 export function escapeHtml(text) {
   el.textContent = text;
   return el.innerHTML;
@@ -68,40 +69,6 @@ export function escapeHtml(text) {
 
 window.escapeHtml = escapeHtml;
 
-export function convertSecsToHumanReadable(seconds) {
-  const oriSeconds = seconds;
-  const floatingPart = oriSeconds - Math.floor(oriSeconds);
-
-  seconds = Math.floor(seconds);
-
-  const secondsPerHour = 60 * 60;
-  const secondsPerMinute = 60;
-
-  const hours = Math.floor(seconds / secondsPerHour);
-  seconds -= hours * secondsPerHour;
-
-  const minutes = Math.floor(seconds / secondsPerMinute);
-  seconds -= minutes * secondsPerMinute;
-
-  let readableFormat = '';
-  if (hours > 0) {
-    readableFormat += `${hours}Hours `;
-  }
-  if (minutes > 0) {
-    readableFormat += `${minutes}Min `;
-  }
-  if (seconds + floatingPart > 0) {
-    if (Math.floor(oriSeconds) === oriSeconds) {
-      readableFormat += `${seconds}Sec`;
-    } else {
-      seconds += floatingPart;
-      readableFormat += `${seconds.toFixed(3)}Sec`;
-    }
-  }
-  return readableFormat;
-}
-window.convertSecsToHumanReadable = convertSecsToHumanReadable;
-
 function postAsForm(url, parameters) {
   const form = $('<form></form>');
 
diff --git a/airflow/www/static/js/task_instances.js b/airflow/www/static/js/task_instances.js
index 4b6482c5d7..bd43e410f8 100644
--- a/airflow/www/static/js/task_instances.js
+++ b/airflow/www/static/js/task_instances.js
@@ -17,11 +17,11 @@
  * under the License.
  */
 
-/* global window, moment, convertSecsToHumanReadable */
+/* global window, moment */
 
 // We don't re-import moment again, otherwise webpack will include it twice in the bundle!
 import { escapeHtml } from './main';
-import { defaultFormat, formatDateTime } from './datetime_utils';
+import { defaultFormat, formatDateTime, convertSecsToHumanReadable } from './datetime_utils';
 import { dagTZ } from './dag';
 import { finalStatesMap } from './utils';
 
diff --git a/airflow/www/static/js/tree/dagRuns/index.test.jsx b/airflow/www/static/js/tree/dagRuns/index.test.jsx
index 5faa8b6e95..5a4f94c2ea 100644
--- a/airflow/www/static/js/tree/dagRuns/index.test.jsx
+++ b/airflow/www/static/js/tree/dagRuns/index.test.jsx
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-/* global describe, test, expect */
+/* global describe, test, expect, beforeAll */
 
 import React from 'react';
 import { render } from '@testing-library/react';
@@ -30,8 +30,7 @@ import { ContainerRefProvider } from '../context/containerRef';
 import { SelectionProvider } from '../context/selection';
 import { TimezoneProvider } from '../context/timezone';
 import { AutoRefreshProvider } from '../context/autorefresh';
-
-global.moment = moment;
+import { convertSecsToHumanReadable } from '../../datetime_utils';
 
 const Wrapper = ({ children }) => {
   const queryClient = new QueryClient();
@@ -58,30 +57,35 @@ const Wrapper = ({ children }) => {
   );
 };
 
+const dagRuns = [
+  {
+    dagId: 'dagId',
+    runId: 'run1',
+    dataIntervalStart: new Date(),
+    dataIntervalEnd: new Date(),
+    startDate: '2021-11-08T21:14:19.704433+00:00',
+    endDate: '2021-11-08T21:17:13.206426+00:00',
+    state: 'failed',
+    runType: 'scheduled',
+    executionDate: '2021-11-08T21:14:19.704433+00:00',
+  },
+  {
+    dagId: 'dagId',
+    runId: 'run2',
+    dataIntervalStart: new Date(),
+    dataIntervalEnd: new Date(),
+    state: 'success',
+    runType: 'manual',
+    startDate: '2021-11-09T00:19:43.023200+00:00',
+    endDate: '2021-11-09T00:22:18.607167+00:00',
+  },
+];
+
 describe('Test DagRuns', () => {
-  const dagRuns = [
-    {
-      dagId: 'dagId',
-      runId: 'run1',
-      dataIntervalStart: new Date(),
-      dataIntervalEnd: new Date(),
-      startDate: '2021-11-08T21:14:19.704433+00:00',
-      endDate: '2021-11-08T21:17:13.206426+00:00',
-      state: 'failed',
-      runType: 'scheduled',
-      executionDate: '2021-11-08T21:14:19.704433+00:00',
-    },
-    {
-      dagId: 'dagId',
-      runId: 'run2',
-      dataIntervalStart: new Date(),
-      dataIntervalEnd: new Date(),
-      state: 'success',
-      runType: 'manual',
-      startDate: '2021-11-09T00:19:43.023200+00:00',
-      endDate: '2021-11-09T00:22:18.607167+00:00',
-    },
-  ];
+  beforeAll(() => {
+    global.moment = moment;
+    global.convertSecsToHumanReadable = convertSecsToHumanReadable;
+  });
 
   test('Durations and manual run arrow render correctly, but without any date ticks', () => {
     global.treeData = JSON.stringify({
@@ -94,8 +98,8 @@ describe('Test DagRuns', () => {
     expect(queryAllByTestId('run')).toHaveLength(2);
     expect(queryAllByTestId('manual-run')).toHaveLength(1);
 
-    expect(getByText('00:02:53')).toBeInTheDocument();
-    expect(getByText('00:01:26')).toBeInTheDocument();
+    expect(getByText('2Min 53.502Sec')).toBeInTheDocument();
+    expect(getByText('1Min 26.751Sec')).toBeInTheDocument();
     expect(queryByText(moment.utc(dagRuns[0].executionDate).format('MMM DD, HH:mm'))).toBeNull();
   });