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/08/17 14:54:53 UTC
[airflow] branch main updated: Next run datasets tooltip preview (#25694)
This is an automated email from the ASF dual-hosted git repository.
bbovenzi 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 aac2b1f6b7 Next run datasets tooltip preview (#25694)
aac2b1f6b7 is described below
commit aac2b1f6b73f443e3cd8454e53d5e474396cbd64
Author: Brent Bovenzi <br...@gmail.com>
AuthorDate: Wed Aug 17 15:54:45 2022 +0100
Next run datasets tooltip preview (#25694)
* create dataset triggered preview tooltip
* share datasets data btwn tooltip+modal
* add backup tooltip message
---
airflow/www/static/js/dag.js | 25 ++++++---
airflow/www/static/js/dags.js | 19 ++++++-
.../js/{openDatasetModal.js => datasetUtils.js} | 65 ++++++++++++++--------
airflow/www/templates/airflow/dag.html | 5 +-
airflow/www/templates/airflow/dags.html | 6 +-
5 files changed, 83 insertions(+), 37 deletions(-)
diff --git a/airflow/www/static/js/dag.js b/airflow/www/static/js/dag.js
index d4e5dc2255..8bf69aa67f 100644
--- a/airflow/www/static/js/dag.js
+++ b/airflow/www/static/js/dag.js
@@ -21,7 +21,7 @@
import { getMetaValue } from './utils';
import { approxTimeFromNow, formatDateTime } from './datetime_utils';
-import openDatasetModal from './openDatasetModal';
+import { openDatasetModal, getDatasetTooltipInfo } from './datasetUtils';
function updateQueryStringParameter(uri, key, value) {
const re = new RegExp(`([?&])${key}=.*?(&|$)`, 'i');
@@ -33,12 +33,6 @@ function updateQueryStringParameter(uri, key, value) {
return `${uri}${separator}${key}=${value}`;
}
-// Pills highlighting
-$(window).on('load', function onLoad() {
- $(`a[href*="${this.location.pathname}"]`).parent().addClass('active');
- $('.never_active').removeClass('active');
-});
-
const dagId = getMetaValue('dag_id');
export const dagTZ = getMetaValue('dag_timezone');
const logsWithMetadataUrl = getMetaValue('logs_with_metadata_url');
@@ -58,6 +52,21 @@ let mapIndex;
let mapStates = [];
let extraLinks;
const showExternalLogRedirect = getMetaValue('show_external_log_redirect') === 'True';
+let nextDatasets = [];
+let nextDatasetsError;
+
+const setNextDatasets = (datasets, error) => {
+ nextDatasets = datasets;
+ nextDatasetsError = error;
+};
+
+// Pills highlighting
+$(window).on('load', function onLoad() {
+ $(`a[href*="${this.location.pathname}"]`).parent().addClass('active');
+ $('.never_active').removeClass('active');
+ const run = $('#next-dataset-tooltip');
+ getDatasetTooltipInfo(dagId, run, setNextDatasets);
+});
const buttons = Array.from(document.querySelectorAll('a[id^="btn_"][data-base-url]')).reduce((obj, elm) => {
obj[elm.id.replace('btn_', '')] = elm;
@@ -403,5 +412,5 @@ $('#next-run').on('mouseover', () => {
$('.next-dataset-triggered').on('click', (e) => {
const summary = $(e.target).data('summary');
- openDatasetModal(dagId, summary || '');
+ openDatasetModal(dagId, summary, nextDatasets, nextDatasetsError);
});
diff --git a/airflow/www/static/js/dags.js b/airflow/www/static/js/dags.js
index 85b5e435e7..db8f19b203 100644
--- a/airflow/www/static/js/dags.js
+++ b/airflow/www/static/js/dags.js
@@ -23,7 +23,7 @@
import { getMetaValue } from './utils';
import tiTooltip from './task_instances';
import { approxTimeFromNow, formatDateTime } from './datetime_utils';
-import openDatasetModal from './openDatasetModal';
+import { openDatasetModal, getDatasetTooltipInfo } from './datasetUtils';
const DAGS_INDEX = getMetaValue('dags_index');
const ENTER_KEY_CODE = 13;
@@ -40,6 +40,9 @@ const dagStatsUrl = getMetaValue('dag_stats_url');
const taskStatsUrl = getMetaValue('task_stats_url');
const gridUrl = getMetaValue('grid_url');
+const nextDatasets = {};
+let nextDatasetsError;
+
// auto refresh interval in milliseconds
// (x2 the interval in tree/graph view since this page can take longer to refresh )
const refreshIntervalMs = 2000;
@@ -542,5 +545,17 @@ $('#auto_refresh').change(() => {
$('.next-dataset-triggered').on('click', (e) => {
const dagId = $(e.target).data('dag-id');
const summary = $(e.target).data('summary');
- if (dagId) openDatasetModal(dagId, summary || '');
+ if (dagId) openDatasetModal(dagId, summary, nextDatasets[dagId], nextDatasetsError);
+});
+
+$('.js-dataset-triggered').each((i, cell) => {
+ $(cell).on('mouseover', () => {
+ const run = $(cell).children();
+ const dagId = $(run).data('dag-id');
+ const setNextDatasets = (datasets, error) => {
+ nextDatasets[dagId] = datasets;
+ nextDatasetsError = error;
+ };
+ getDatasetTooltipInfo(dagId, run, setNextDatasets);
+ });
});
diff --git a/airflow/www/static/js/openDatasetModal.js b/airflow/www/static/js/datasetUtils.js
similarity index 54%
rename from airflow/www/static/js/openDatasetModal.js
rename to airflow/www/static/js/datasetUtils.js
index 6e6c824e1d..82e9771ae4 100644
--- a/airflow/www/static/js/openDatasetModal.js
+++ b/airflow/www/static/js/datasetUtils.js
@@ -21,15 +21,38 @@
import { getMetaValue } from './utils';
-function openDatasetModal(dagId, summary) {
+export function openDatasetModal(dagId, summary = '', nextDatasets = [], error = null) {
const datasetsUrl = getMetaValue('datasets_url');
- let nextRunUrl = getMetaValue('next_run_datasets_url');
$('#datasets_tbody').empty();
$('#datasets_error').hide();
- $('#datasetNextRunModal').modal({});
$('#dag_id').text(dagId);
+ $('#datasetNextRunModal').modal({});
$('#next_run_summary').text(summary);
- $('#datasets-loading-dots').css('display', 'inline-block');
+ nextDatasets.forEach((d) => {
+ const row = document.createElement('tr');
+
+ const uriCell = document.createElement('td');
+ const datasetLink = document.createElement('a');
+ datasetLink.href = `${datasetsUrl}?dataset_id=${d.id}`;
+ datasetLink.innerText = d.uri;
+ uriCell.append(datasetLink);
+
+ const timeCell = document.createElement('td');
+ if (d.created_at) timeCell.append(isoDateToTimeEl(d.created_at));
+
+ row.append(uriCell);
+ row.append(timeCell);
+ $('#datasets_tbody').append(row);
+ });
+
+ if (error) {
+ $('#datasets_error_msg').text(error);
+ $('#datasets_error').show();
+ }
+}
+
+export function getDatasetTooltipInfo(dagId, run, setNextDatasets) {
+ let nextRunUrl = getMetaValue('next_run_datasets_url');
if (dagId) {
if (nextRunUrl.includes('__DAG_ID__')) {
nextRunUrl = nextRunUrl.replace('__DAG_ID__', dagId);
@@ -37,31 +60,25 @@ function openDatasetModal(dagId, summary) {
$.get(nextRunUrl)
.done(
(datasets) => {
+ let count = 0;
+ let title = '<strong>Pending datasets:</strong><br>';
+ setNextDatasets(datasets);
datasets.forEach((d) => {
- const row = document.createElement('tr');
-
- const uriCell = document.createElement('td');
- const datasetLink = document.createElement('a');
- datasetLink.href = `${datasetsUrl}?dataset_id=${d.id}`;
- datasetLink.innerText = d.uri;
- uriCell.append(datasetLink);
-
- const timeCell = document.createElement('td');
- if (d.created_at) timeCell.append(isoDateToTimeEl(d.created_at));
-
- row.append(uriCell);
- row.append(timeCell);
- $('#datasets-loading-dots').hide();
- $('#datasets_tbody').append(row);
+ if (!d.created_at) {
+ if (count < 4) title += `${d.uri}<br>`;
+ count += 1;
+ }
});
+ if (count > 4) {
+ title += `<br>And ${count - 4} more.`;
+ }
+ title += '<br>Click to see more details.';
+ $(run).attr('data-original-title', () => title);
},
).fail((response, textStatus, err) => {
- $('#datasets-loading-dots').hide();
const description = (response.responseJSON && response.responseJSON.error) || 'Something went wrong.';
- $('#datasets_error_msg').text(`${textStatus}: ${err} ${description}`);
- $('#datasets_error').show();
+ const error = `${textStatus}: ${err} ${description}`;
+ setNextDatasets([], error);
});
}
}
-
-export default openDatasetModal;
diff --git a/airflow/www/templates/airflow/dag.html b/airflow/www/templates/airflow/dag.html
index 848a9b8413..d55c5506f4 100644
--- a/airflow/www/templates/airflow/dag.html
+++ b/airflow/www/templates/airflow/dag.html
@@ -122,7 +122,7 @@
<span class="text-muted">ROOT:</span> {{ root }}
{% endif %}
</h3>
- <h4 class="pull-right" style="user-select: none;-moz-user-select: auto;">
+ <h4 class="pull-right js-dataset-triggered" style="user-select: none;-moz-user-select: auto;">
{% if state_token is defined and state_token %}
{{ state_token }}
{% endif %}
@@ -139,8 +139,11 @@
{% endif %}
{% if dag_model is defined and dag_model.schedule_interval is defined and dag_model.schedule_interval == 'Dataset' %}
<span
+ id="next-dataset-tooltip"
class="js-tooltip"
title="Click to see dataset details."
+ data-html="true"
+ data-placement="bottom"
>
<p
class="label label-default next-dataset-triggered"
diff --git a/airflow/www/templates/airflow/dags.html b/airflow/www/templates/airflow/dags.html
index 92132ab517..0884a06c17 100644
--- a/airflow/www/templates/airflow/dags.html
+++ b/airflow/www/templates/airflow/dags.html
@@ -295,11 +295,13 @@
info
</span>
</td>
- <td class="text-nowrap">
+ <td class="text-nowrap {{ 'js-dataset-triggered' if dag.dag_id in dataset_triggered_next_run_info }}">
{% if dag.dag_id in dataset_triggered_next_run_info %}
<span
- class="js-tooltip"
+ data-dag-id="{{ dag.dag_id }}"
+ class="js-tooltip js-next-dataset-run-tooltip"
title="Click to see dataset details."
+ data-html="true"
>
<div
class="label label-default next-dataset-triggered"