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 <[email protected]> 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(); });
