You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by ry...@apache.org on 2021/02/16 18:11:16 UTC

[airflow] branch master updated: Js linting and inline migration for simple scripts (#14215)

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

ryanahamilton pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/master by this push:
     new 9f14724  Js linting and inline migration for simple scripts (#14215)
9f14724 is described below

commit 9f14724d160f12a1315cfcd7e557eae820de8498
Author: Brent Bovenzi <br...@gmail.com>
AuthorDate: Tue Feb 16 12:10:58 2021 -0600

    Js linting and inline migration for simple scripts (#14215)
    
    * Js linting and inline migration for simple scripts
    
    - Linting for all the relatively simple JS in our html templates
    - Replaced jQuery .click() and .ready() functions
    - changed all js files to snake_case instead of kebab-case for consistency
    
    * add function to get metadata
    
    * fix meta_head and clean up js
    
    * remove extra <head> tag
    
    * snake case task instances file
---
 airflow/www/.eslintignore                          |   2 +-
 airflow/www/static/js/circles.js                   | 127 +++++++++++++++++++++
 airflow/www/static/js/dag_code.js                  |  38 ++++++
 .../js/{datetime-utils.js => datetime_utils.js}    |   0
 airflow/www/static/js/duration_chart.js            |  31 +++++
 .../{gantt-chart-d3v2.js => gantt_chart_d3v2.js}   |   0
 airflow/www/static/js/main.js                      |   2 +-
 airflow/www/static/js/meta_value.js                |  26 +++++
 airflow/www/static/js/task_instance.js             |  31 +++++
 .../js/{task-instances.js => task_instances.js}    |   2 +-
 airflow/www/static/js/trigger.js                   |  27 +++++
 airflow/www/static/js/variable_edit.js             |  22 ++++
 airflow/www/templates/airflow/circles.html         | 117 +------------------
 airflow/www/templates/airflow/dag.html             |   2 +-
 airflow/www/templates/airflow/dag_code.html        |  27 ++---
 airflow/www/templates/airflow/duration_chart.html  |  18 +--
 airflow/www/templates/airflow/main.html            |   5 +-
 airflow/www/templates/airflow/task_instance.html   |  15 +--
 airflow/www/templates/airflow/trigger.html         |  10 +-
 airflow/www/templates/airflow/variable_edit.html   |   6 +-
 airflow/www/webpack.config.js                      |  10 +-
 21 files changed, 329 insertions(+), 189 deletions(-)

diff --git a/airflow/www/.eslintignore b/airflow/www/.eslintignore
index 924c9fc..d764602 100644
--- a/airflow/www/.eslintignore
+++ b/airflow/www/.eslintignore
@@ -1,7 +1,7 @@
 **/*{.,-}min.js
 **/*.sh
 **/*.py
-gantt-chart-d3v2.js
+gantt_chart_d3v2.js
 jqClock.min.js
 coverage/**
 static/dist/*
diff --git a/airflow/www/static/js/circles.js b/airflow/www/static/js/circles.js
new file mode 100644
index 0000000..66cab98
--- /dev/null
+++ b/airflow/www/static/js/circles.js
@@ -0,0 +1,127 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import d3 from 'd3';
+
+const height = 700;
+const width = document.getElementById('div_svg').offsetWidth;
+const points = 20;
+const matrix = [];
+const duration = 2000;
+let i = 0;
+let flip = 0;
+const colors = [
+  '#FF5A5F', '#007A87', '#7B0051', '#00D1C1', '#8CE071', '#FFB400',
+  '#FFAA91', '#B4A76C', '#9CA299', '#565A5C',
+];
+
+function choose(choices) {
+  const index = Math.floor(Math.random() * choices.length);
+  return choices[index];
+}
+// Making a matrix
+for (let x = 0; x < points; x += 1) {
+  for (let y = 0; y < points; y += 1) {
+    matrix[i] = {
+      x,
+      y,
+    };
+    i += 1;
+  }
+}
+const sclx = d3.scale.linear().domain([-1, points]).range([0, width]);
+const scly = d3.scale.linear().domain([-1, points]).range([0, height]);
+
+const circles = d3.select('#circles-svg')
+  .attr('width', '100%')
+
+  .attr('height', height)
+  .selectAll('circle')
+  .data(matrix)
+  .enter()
+  .append('circle')
+  .attr('stroke', 'black')
+  .attr('fill', 'none')
+  .attr('cx', (d) => sclx(d.x))
+  .attr('cy', (d) => scly(d.y))
+  .attr('r', () => 0);
+
+function toggle() {
+  const size = 50 + (200 * Math.random());
+  let yDelay = 0;
+  let randomDelay = 0;
+  if (Math.random() > 0.7) {
+    yDelay = 50 + (Math.random() * 50);
+  }
+  let xDelay = 0;
+  if (Math.random() > 0.7) {
+    xDelay = 50 + (Math.random() * 50);
+  }
+  if (Math.random() > 0.7) {
+    randomDelay = 1;
+  }
+
+  const randomX = Math.random() * width;
+  const randomY = Math.random() * height;
+  let col;
+  if (Math.random() > 0.5) {
+    col = choose(colors);
+  } else {
+    col = 'black';
+  }
+  if (Math.random() > 0.8) {
+    col = choose(colors);
+  }
+
+  if (flip === 0) {
+    flip = 1;
+
+    circles.transition()
+      .duration(duration)
+      .attr('cx', (d) => sclx(d.x))
+      .attr('cy', (d) => scly(d.y))
+      .attr('stroke', col)
+      .delay((d) => (randomDelay * Math.random() * 1000) + (d.x * xDelay) + (d.y * yDelay))
+      .attr('r', () => size);
+  } else {
+    flip = 0;
+
+    if (Math.random() > 0.6) {
+      circles.transition()
+        .duration(duration)
+        .attr('r', () => 0)
+        .attr('cx', () => randomX)
+        .attr('stroke', col)
+        .delay((d, j) => (j / 2) * Math.random() * 5)
+        .attr('cy', () => randomY);
+    } else {
+      circles.transition()
+        .duration(duration)
+        .attr('cx', (d) => sclx(d.x))
+        .attr('cy', (d) => scly(d.y))
+        .attr('stroke', col)
+        .delay((d) => (randomDelay * Math.random() * 1000) + (d.x * xDelay) + (d.y * yDelay))
+        .attr('r', () => 0);
+    }
+  }
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+  setInterval(toggle, duration * 3);
+  toggle();
+});
diff --git a/airflow/www/static/js/dag_code.js b/airflow/www/static/js/dag_code.js
new file mode 100644
index 0000000..a3aab34
--- /dev/null
+++ b/airflow/www/static/js/dag_code.js
@@ -0,0 +1,38 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import getMetaValue from './meta_value';
+
+const isDemoMode = getMetaValue('demo_mode');
+const isWrapped = getMetaValue('wrapped');
+
+document.addEventListener('DOMContentLoaded', () => {
+  // We blur task_ids in demo mode
+  if (isDemoMode) {
+    $('pre span.s').css({
+      'text-shadow': '0 0 10px red',
+      color: 'transparent',
+    });
+  }
+});
+
+// pygments generates the HTML so set wrap toggle via js
+if (isWrapped) {
+  $('.code pre').toggleClass('wrap');
+}
diff --git a/airflow/www/static/js/datetime-utils.js b/airflow/www/static/js/datetime_utils.js
similarity index 100%
rename from airflow/www/static/js/datetime-utils.js
rename to airflow/www/static/js/datetime_utils.js
diff --git a/airflow/www/static/js/duration_chart.js b/airflow/www/static/js/duration_chart.js
new file mode 100644
index 0000000..3a18294
--- /dev/null
+++ b/airflow/www/static/js/duration_chart.js
@@ -0,0 +1,31 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+function handleCheck() {
+  if ($('#isCumulative').is(':checked')) {
+    $('#dur_chart').hide();
+    $('#cum_dur_chart').show();
+  } else {
+    $('#dur_chart').show();
+    $('#cum_dur_chart').hide();
+  }
+}
+$(document).on('chartload', handleCheck);
+
+$('#isCumulative').on('click', handleCheck);
diff --git a/airflow/www/static/js/gantt-chart-d3v2.js b/airflow/www/static/js/gantt_chart_d3v2.js
similarity index 100%
rename from airflow/www/static/js/gantt-chart-d3v2.js
rename to airflow/www/static/js/gantt_chart_d3v2.js
diff --git a/airflow/www/static/js/main.js b/airflow/www/static/js/main.js
index 8293eb4..2508a3b 100644
--- a/airflow/www/static/js/main.js
+++ b/airflow/www/static/js/main.js
@@ -23,7 +23,7 @@ import {
   formatTimezone,
   isoDateToTimeEl,
   setDisplayedTimezone,
-} from './datetime-utils';
+} from './datetime_utils';
 
 window.isoDateToTimeEl = isoDateToTimeEl;
 
diff --git a/airflow/www/static/js/meta_value.js b/airflow/www/static/js/meta_value.js
new file mode 100644
index 0000000..89c1753
--- /dev/null
+++ b/airflow/www/static/js/meta_value.js
@@ -0,0 +1,26 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export default function getMetaValue(name) {
+  const elem = document.querySelector(`meta[name="${name}"]`);
+  if (!elem) {
+    return null;
+  }
+  return elem.getAttribute('content');
+}
diff --git a/airflow/www/static/js/task_instance.js b/airflow/www/static/js/task_instance.js
new file mode 100644
index 0000000..d4253c5
--- /dev/null
+++ b/airflow/www/static/js/task_instance.js
@@ -0,0 +1,31 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+document.addEventListener('DOMContentLoaded', () => {
+  function dateChange() {
+    // We don't want to navigate away if the datetimepicker is still visible
+    if ($('.datetimepicker bootstrap-datetimepicker-widget :visible').length > 0) {
+      return;
+    }
+
+    $('input#execution_date').parents('form').submit();
+  }
+  $('input#execution_date').parents('.datetimepicker').on('dp.change', dateChange);
+  $('input#execution_date').parents('.datetimepicker').on('dp.hide', dateChange);
+});
diff --git a/airflow/www/static/js/task-instances.js b/airflow/www/static/js/task_instances.js
similarity index 98%
rename from airflow/www/static/js/task-instances.js
rename to airflow/www/static/js/task_instances.js
index 871f344..4e2e1e1 100644
--- a/airflow/www/static/js/task-instances.js
+++ b/airflow/www/static/js/task_instances.js
@@ -21,7 +21,7 @@
 
 // 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 } from './datetime_utils';
 
 function makeDateTimeHTML(start, end) {
   // check task ended or not
diff --git a/airflow/www/static/js/trigger.js b/airflow/www/static/js/trigger.js
new file mode 100644
index 0000000..0fdb2e6
--- /dev/null
+++ b/airflow/www/static/js/trigger.js
@@ -0,0 +1,27 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const textArea = document.getElementById('json');
+
+CodeMirror.fromTextArea(textArea, {
+  lineNumbers: true,
+  mode: { name: 'javascript', json: true },
+  gutters: ['CodeMirror-lint-markers'],
+  lint: true,
+});
diff --git a/airflow/www/static/js/variable_edit.js b/airflow/www/static/js/variable_edit.js
new file mode 100644
index 0000000..0433df0
--- /dev/null
+++ b/airflow/www/static/js/variable_edit.js
@@ -0,0 +1,22 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const val = document.getElementById('val');
+const height = Math.min(window.innerHeight * 0.5, val.scrollHeight);
+val.style.height = `${height}px`;
diff --git a/airflow/www/templates/airflow/circles.html b/airflow/www/templates/airflow/circles.html
index 21574c1..c21b76a 100644
--- a/airflow/www/templates/airflow/circles.html
+++ b/airflow/www/templates/airflow/circles.html
@@ -33,122 +33,7 @@
          class="centered text-center"
          style="border: 1px solid #ccc;padding:0;margin:0;">
         <svg id="circles-svg"></svg>
-
     </div>
-    <script src="{{ url_for_asset('d3.min.js') }}"></script>
-    <script>
-    var height =700;
-    var width = document.getElementById("div_svg").offsetWidth;
-    var points = 20;
-    var matrix = [];
-    var duration = 2000;
-    var i = 0;
-    var flip = 0;
-    var colors = [
-        "#FF5A5F", "#007A87", "#7B0051", "#00D1C1", "#8CE071", "#FFB400",
-        "#FFAA91", "#B4A76C", "#9CA299", "#565A5C"
-    ];
-
-
-    function choose(choices) {
-        var index = Math.floor(Math.random() * choices.length);
-        return choices[index];
-    }
-    // Making a matrix
-    for(var x=0; x<points; x++) {
-        for(var y=0; y<points; y++) {
-            matrix[i] = {
-                'x': x,
-                'y': y,
-            }
-            i += 1;
-        }
-    }
-    sclx = d3.scale.linear().domain([-1, points]).range([0, width]);
-    scly = d3.scale.linear().domain([-1, points]).range([0, height]);
-
-    circles = d3.select("#circles-svg")
-    .attr('width', "100%")
-
-    .attr('height', height)
-    .selectAll("circle").data(matrix).enter()
-    .append("circle")
-    .attr("stroke", 'black')
-    .attr("fill", 'none')
-    .attr("cx", function(d, i) {return sclx(d.x)})
-    .attr("cy", function(d, i) {return scly(d.y)})
-    .attr("r", function(d, i) {return 0});
-
-
-
-    function toggle(){
-        var size = 50 + (200* Math.random());
-        var y_delay = 0;
-        var random_delay = 0;
-        if(Math.random() > 0.7){
-            y_delay = 50+ (Math.random() * 50);
-        }
-        var x_delay = 0;
-        if(Math.random() > 0.7){
-            x_delay = 50+ (Math.random() * 50);
-        }
-        if(Math.random() > 0.7){
-            random_delay = 1;
-        }
-
-        var random_x = Math.random() * width;
-        var random_y = Math.random() * height;
-        if(Math.random() > 0.5){
-            col = choose(colors);
-        } else {
-            col = "black";
-        }
-        if(Math.random() > 0.8){
-            col = function() {return choose(colors)};
-        }
-
-
-
-        if (flip==0){
-
-            flip = 1;
-
-            circles.transition()
-            .duration(duration)
-            .attr("cx", function(d, i) {return sclx(d.x)})
-            .attr("cy", function(d, i) {return scly(d.y)})
-            .attr("stroke", col)
-            .delay(function(d, i) {return (random_delay * Math.random() * 1000) + (d.x*x_delay) + (d.y * y_delay)})
-            .attr("r", function(d, i) {return size});
-        }
-        else{
-            flip = 0;
-
-            if(Math.random() > 0.6){
-                circles.transition()
-                .duration(duration)
-                .attr("r", function(d, i) {return 0})
-                .attr("cx", function(d, i) {return random_x})
-                .attr("stroke", col)
-                .delay(function(d, i) {return (i/2) *  Math.random() * 5})
-                .attr("cy", function(d, i) {return random_y});
-            }
-            else{
-                circles.transition()
-                .duration(duration)
-                .attr("cx", function(d, i) {return sclx(d.x)})
-                .attr("cy", function(d, i) {return scly(d.y)})
-                .attr("stroke", col)
-                .delay(function(d, i) {return (random_delay * Math.random() * 1000) + (d.x*x_delay) + (d.y * y_delay)})
-                .attr("r", function(d, i) {return 0});
-            }
-        }
-
-    }
-
-    setInterval(toggle, duration*3);
-    toggle();
-
-    </script>
+    <script src="{{ url_for_asset('circles.js') }}"></script>
 </body>
 </html>
diff --git a/airflow/www/templates/airflow/dag.html b/airflow/www/templates/airflow/dag.html
index cc026a1..72c4378 100644
--- a/airflow/www/templates/airflow/dag.html
+++ b/airflow/www/templates/airflow/dag.html
@@ -393,7 +393,7 @@
 
     var id = '';
     var dag_id = '{{ dag.dag_id }}';
-    var dagTZ = '{{ dag.timezone.name }}'; // Being used in datetime-utils.js
+    var dagTZ = '{{ dag.timezone.name }}'; // Being used in datetime_utils.js
     var task_id = '';
     var execution_date = '';
     var subdag_id = '';
diff --git a/airflow/www/templates/airflow/dag_code.html b/airflow/www/templates/airflow/dag_code.html
index 3eff37f..1a5afc2 100644
--- a/airflow/www/templates/airflow/dag_code.html
+++ b/airflow/www/templates/airflow/dag_code.html
@@ -21,6 +21,12 @@
 
 {% block page_title %}{{ dag.dag_id }} - Code - Airflow{% endblock %}
 
+{% block head_meta %}
+  {{ super() }}
+  <meta name="demo_mode" content="{{ demo_mode }}">
+  <meta name="wrapped" content="{{ wrapped }}">
+{% endblock %}
+
 {% block content %}
   {{ super() }}
   <div class="code-wrap">
@@ -31,24 +37,5 @@
 
 {% block tail_js %}
   {{ super() }}
-  <script>
-    function toggleWrap() {
-      $('.code pre').toggleClass('wrap')
-    };
-
-    // We blur task_ids in demo mode
-    $(document).ready(function() {
-      if ("{{ demo_mode }}" == "True") {
-        $("pre span.s").css({
-          'text-shadow': '0 0 10px red',
-          'color': 'transparent',
-        });
-      }
-    });
-
-    // pygments generates the HTML so set wrap toggle via js
-    if ("{{ wrapped }}" == "True") {
-      toggleWrap();
-    };
-  </script>
+  <script src="{{ url_for_asset('dagCode.js') }}"></script>
 {% endblock %}
diff --git a/airflow/www/templates/airflow/duration_chart.html b/airflow/www/templates/airflow/duration_chart.html
index 2d11840..c41642b 100644
--- a/airflow/www/templates/airflow/duration_chart.html
+++ b/airflow/www/templates/airflow/duration_chart.html
@@ -66,22 +66,6 @@
 {% endblock %}
 
 {% block tail %}
-  <script>
-    function handleCheck() {
-      if ($('#isCumulative').is(':checked')) {
-        $('#dur_chart').hide();
-        $('#cum_dur_chart').show();
-      } else {
-        $('#dur_chart').show();
-        $('#cum_dur_chart').hide();
-      };
-    };
-    $( document ).on('chartload', function() {
-      handleCheck();
-    });
-    $('#isCumulative').click(function() {
-      handleCheck();
-    });
-  </script>
+  <script src="{{ url_for_asset('durationChart.js') }}"></script>
   {{ super() }}
 {% endblock %}
diff --git a/airflow/www/templates/airflow/main.html b/airflow/www/templates/airflow/main.html
index ca3655e..223ebe1 100644
--- a/airflow/www/templates/airflow/main.html
+++ b/airflow/www/templates/airflow/main.html
@@ -79,13 +79,14 @@
 
   <script>
     // below variables are used in main.js
+    // keep as var, changing to const or let breaks other code
     var Airflow = {
       serverTimezone: '{{ server_timezone }}',
-      defaultUITimezone: '{{ default_ui_timezone }}'
+      defaultUITimezone: '{{ default_ui_timezone }}',
     };
     var hostName = '{{ hostname }}';
     var csrfToken = '{{ csrf_token() }}';
-    $("time[title]").tooltip()
+    $('time[title]').tooltip();
   </script>
   <!--[if IE ]>
   <script src="{{ url_for_asset('ie.js') }}"></script>
diff --git a/airflow/www/templates/airflow/task_instance.html b/airflow/www/templates/airflow/task_instance.html
index 14dc7ff..c21613c 100644
--- a/airflow/www/templates/airflow/task_instance.html
+++ b/airflow/www/templates/airflow/task_instance.html
@@ -57,18 +57,5 @@
 {% endblock %}
 {% block tail %}
   {{ super() }}
-  <script>
-    $(document).ready(function () {
-      function date_change(e) {
-          // We don't want to navigate away if the datetimepicker is still visible
-          if ($('.datetimepicker bootstrap-datetimepicker-widget :visible').length > 0) {
-            return;
-          }
-
-          $('input#execution_date').parents('form').submit();
-      }
-      $('input#execution_date').parents('.datetimepicker').on('dp.change', date_change);
-      $('input#execution_date').parents('.datetimepicker').on('dp.hide', date_change);
-    });
-  </script>
+  <script src="{{ url_for_asset('taskInstance.js') }}"></script>
 {% endblock %}
diff --git a/airflow/www/templates/airflow/trigger.html b/airflow/www/templates/airflow/trigger.html
index f150f2f..c4187f1 100644
--- a/airflow/www/templates/airflow/trigger.html
+++ b/airflow/www/templates/airflow/trigger.html
@@ -52,14 +52,6 @@
   <script src="{{ url_for_asset('lint.js') }}"></script>
   <script src="{{ url_for_asset('javascript-lint.js') }}"></script>
   <script src="{{ url_for_asset('jshint.js') }}"></script>
-  <script>
-    const textArea = document.getElementById('json');
-    CodeMirror.fromTextArea(textArea, {
-      lineNumbers: true,
-      mode: { name: 'javascript', json: true },
-      gutters: ['CodeMirror-lint-markers'],
-      lint: true,
-    });
-  </script>
+  <script src="{{ url_for_asset('trigger.js') }}"></script>
   {{ super() }}
 {% endblock %}
diff --git a/airflow/www/templates/airflow/variable_edit.html b/airflow/www/templates/airflow/variable_edit.html
index 289c388..93a8d0f 100644
--- a/airflow/www/templates/airflow/variable_edit.html
+++ b/airflow/www/templates/airflow/variable_edit.html
@@ -24,9 +24,5 @@
   <style>
     #val { font-family: monospace; }
   </style>
-  <script>
-    const val = document.getElementById('val');
-    const height = Math.min(window.innerHeight * 0.5, val.scrollHeight);
-    val.style.height = `${height}px`;
-  </script>
+  <script src="{{ url_for_asset('variableEdit.js') }}"></script>
 {% endblock %}
diff --git a/airflow/www/webpack.config.js b/airflow/www/webpack.config.js
index 6d3a2cb..255444c 100644
--- a/airflow/www/webpack.config.js
+++ b/airflow/www/webpack.config.js
@@ -41,7 +41,7 @@ const config = {
     dags: `${STATIC_DIR}/css/dags.css`,
     flash: `${STATIC_DIR}/css/flash.css`,
     gantt: `${STATIC_DIR}/css/gantt.css`,
-    ganttChartD3v2: `${STATIC_DIR}/js/gantt-chart-d3v2.js`,
+    ganttChartD3v2: `${STATIC_DIR}/js/gantt_chart_d3v2.js`,
     graph: `${STATIC_DIR}/css/graph.css`,
     ie: `${STATIC_DIR}/js/ie.js`,
     loadingDots: `${STATIC_DIR}/css/loading-dots.css`,
@@ -49,8 +49,14 @@ const config = {
     materialIcons: `${STATIC_DIR}/css/material-icons.css`,
     moment: 'moment-timezone',
     switch: `${STATIC_DIR}/css/switch.css`,
-    taskInstances: `${STATIC_DIR}/js/task-instances.js`,
+    taskInstances: `${STATIC_DIR}/js/task_instances.js`,
+    taskInstance: `${STATIC_DIR}/js/task_instance.js`,
     tree: `${STATIC_DIR}/css/tree.css`,
+    circles: `${STATIC_DIR}/js/circles.js`,
+    durationChart: `${STATIC_DIR}/js/duration_chart.js`,
+    trigger: `${STATIC_DIR}/js/trigger.js`,
+    variableEdit: `${STATIC_DIR}/js/variable_edit.js`,
+    dagCode: `${STATIC_DIR}/js/dag_code.js`,
   },
   output: {
     path: BUILD_DIR,