#361 hubs.static: Initial fixes to migrate the JS code to their own files
Closed 6 years ago by ryanlerch. Opened 6 years ago by sayanchowdhury.
sayanchowdhury/fedora-hubs hotfix/fix-js-pages  into  develop

file modified
+2
@@ -1,5 +1,7 @@ 

  *.pyc

  *.egg*

+ *.vscode*

+ *.swp

  fedmsg.d/fas_credentials.py

  fedmsg.d/credentials.py

  node*

@@ -0,0 +1,100 @@ 

+ $(document).ready(function() {

+ 

+   // Intialize Sortable to sort the left & the right widgets

+   Sortable.create(document.getElementById('left-widgets'), {

+     animation: 150,

+     draggable: '.widget',

+     handle: '.card',

+   });

+ 

+   Sortable.create(document.getElementById('right-widgets'), {

+     animation: 150,

+     draggable: '.widget',

+     handle: '.card',

+   });

+ 

+   $('#save-edits-btn').click(function(e) {

+     e.preventDefault();

+ 

+     $this = $(this);

+     var requestUrl = $this.data('request-url');

+     var redirectUrl = $this.data('redirect-url');

+ 

+     var _r_indexes = [];

+     var _r_widgets = [];

+     $.each($('#right-widgets .widget'), function(i, el) {

+       _r_indexes.push(i);

+       _r_widgets.push($(el).attr('id').split('widget-')[1])

+     });

+ 

+     var _l_indexes = [];

+     var _l_widgets = [];

+     $.each($('#left-widgets .widget'), function(i, el) {

+       _l_indexes.push(i);

+       _l_widgets.push($(el).attr('id').split('widget-')[1])

+     });

+ 

+     $.post(

+       url: url,

+       data: {

+         'right_indexes': _r_indexes,

+         'right_widgets': _r_widgets,

+         'left_indexes': _l_indexes,

+         'left_widgets': _l_widgets,

+         'js': true

+       },

+       function(){

+         window.location = redirectUrl;

+       }

+     );

+   });

+ 

+   // Setup events for the "add widget" button.

+   $(".modal-widget").click(function(e) {

+     e.preventDefault();

+     $.ajax({

+       url: $(this).data('url'),

+       dataType: 'html',

+       success: function(html) {

+         $('#edit-modal-content').html(html);

+       },

+       error: function(html) {

+         $('#edit-modal-content .modal-body').html('An error occured when trying to add a new widget');

+       },

+       complete: function() {

+         $('#edit-modal').modal();

+       }

+     });

+     return false;

+   });

+ 

+   // Setup events for the "add widget" form using delegated events because it's

+   // not in the DOM yet.

+   $("body").on("submit", "#widget-add-form form", function(e) {

+     var form = $(this);

+     var error_msg = "An error occured when trying to add a new widget.";

+     e.preventDefault();

+ 

+     $.ajax({

+       type: "POST",

+       url: form.attr("action"),

+       dataType: "json",

+       data: form.serialize(),

+       success: function(data) {

+         if (data.status === "CONFIGURE") {

+           $("#widget-add-form").load(data.url);

+         } else if (data.status === "ADDED") {

+           // no config necessary, reload the page

+           window.location = window.location;

+         } else {

+           $('#widget-add-form .modal-body').html(error_msg);

+           $('#widget-add-form .modal-footer button[type="submit"]').remove();        

+         }

+       },

+       error: function(html) {

+         $('#widget-add-form .modal-body').html(error_msg);

+         $('#adding_form .modal-footer button[type="submit"]').remove();

+       }

+     });

+   });

+ });

@@ -0,0 +1,72 @@ 

+ function visitCounter() {

+   if (window.performance.navigation.type != 0) {

+     return null;

+   }

+ 

+   if(userName != null && userName != '' && userName != visitedHub) {

+     var url = [urlPrefix, visitedHub].join("");

+ 

+     $.ajax({

+       method: "POST",

+       url: url,

+       dataType: 'html',

+       success: function(html) {

+         console.log('Success: incrementing counter')

+       },

+       error: function() {

+         console.log('Error: incrementing counter');

+       },

+     });

+   }

+ }

+ 

+ function setupSettings() {

+   var settingsPanel = React.createElement(Hubs.HubConfig, {

+     urls: {

+       config: hubConfigURL,

+       suggestUsers: hubConfigSuggestUsers,

+     }

+   });

+   ReactDOM.render(settingsPanel, document.getElementById("settings-modal"));

+ }

+ 

+ $(document).ready(function() {

+   // Call the visit counter

+   visitCounter();

+ 

+   // Setup the widgets

+   setupWidgets();

+ 

+   // Setup the SSE URL

+   setupSSE(sseURL);

+ 

+   // Setup settings if allowed to setup settings

+   if (canSetupSettings) {

+     setupSettings();

+   }

+ 

+   // Send a AJAX request and fill the target with the response html.

+   $('ajax-hubs-modal').click(function(e) {

+     e.preventDefault();

+     $this = $(this);

+     var target = $this.attr('data-target');

+     var url = $this.attr('ajax');

+ 

+     $.ajax({

+       url: url,

+       dataType: 'html',

+       success: function(html) {

+         var target = document.getElementById(target);

+         target.html(html);

+       }

+     });

+   });

+ 

+   // This is how to activate and remove (here after 13 sec) the favicon

+   // notification

+   Notificon('#33ff00');

+   setTimeout(function(){Notificon()}, 13000)

+   setTimeout(function(){Notificon('#eb361e')}, 15000)

+   setTimeout(function(){Notificon()}, 18000)

+ 

+ }); 

\ No newline at end of file

file modified
+63 -63
@@ -1,77 +1,77 @@ 

  // These two functions are used by the feed widget to expand and collapse

  // entries.

  var expand_feed_entries = function(idx) {

-     $("#expand-" + idx).addClass('hidden');

-     $("#collapse-" + idx).removeClass('hidden');

-     $("#content-" + idx).removeClass('hidden');

+   $("#expand-" + idx).addClass('hidden');

+   $("#collapse-" + idx).removeClass('hidden');

+   $("#content-" + idx).removeClass('hidden');

  }

  var collapse_feed_entries = function(idx) {

-     $("#expand-" + idx).removeClass('hidden');

-     $("#collapse-" + idx).addClass('hidden');

-     $("#content-" + idx).addClass('hidden');

+   $("#expand-" + idx).removeClass('hidden');

+   $("#collapse-" + idx).addClass('hidden');

+   $("#content-" + idx).addClass('hidden');

  }

  

  // Load widgets

- function setup_widgets() {

-     $("div.widget[data-url]").each(function() {

-         var element=$(this);

-         $.ajax({

-             url: element.attr("data-url"),

-             dataType: 'html',

-             success: function(html) {

-                 element.html(html);

-                 setTimeout(function() {

-                   element.find('.panel').toggleClass('panel-visible');

-                 }, 100);

-             },

-             error: function() {

-                 element.html('Got an error retrieving this widget.  Sorry :(');

-                 console.log('error');

-                 console.trace();

-             },

-         });

+ function setupWidgets() {

+   $("div.widget[data-url]").each(function() {

+     var element=$(this);

+     $.ajax({

+       url: element.attr("data-url"),

+       dataType: 'html',

+       success: function(html) {

+         element.html(html);

+         setTimeout(function() {

+           element.find('.panel').toggleClass('panel-visible');

+         }, 100);

+       },

+       error: function() {

+         element.html('Got an error retrieving this widget.  Sorry :(');

+         console.log('error');

+         console.trace();

+       },

      });

+   });

  }

  

- function setup_sse(url) {

-     if (!url || !window.EventSource) {

-       // Auto-update is disabled.

-       return;

-     }

-     var sseSource = new Hubs.ReconnectingEventSource(url),

-         notifTimeout = null;

-     sseSource.addEventListener("hubs:widget-updated", function(e) {

-         var widget = $("#widget-" + e.data);

-         if (widget.length === 0) { return; }

-         if (widget.find("div.card[data-disable-autoreload]").length !== 0) { return; }

-         $.ajax({

-             url: widget.attr("data-url"),

-             dataType: 'html',

-             success: function(html) {

-                 widget.css("opacity", "0.5");

-                 widget.html(html);

-                 widget.animate({opacity: 1}, 200);

-             },

-             error: function() {

-                 console.log('error updating the widget');

-                 console.trace();

-             },

-         });

+ function setupSSE(url) {

+   if (!url || !window.EventSource) {

+     // Auto-update is disabled.

+     return;

+   }

+   var sseSource = new Hubs.ReconnectingEventSource(url),

+     notifTimeout = null;

+   sseSource.addEventListener("hubs:widget-updated", function(e) {

+     var widget = $("#widget-" + e.data);

+     if (widget.length === 0) { return; }

+     if (widget.find("div.card[data-disable-autoreload]").length !== 0) { return; }

+     $.ajax({

+       url: widget.attr("data-url"),

+       dataType: 'html',

+       success: function(html) {

+         widget.css("opacity", "0.5");

+         widget.html(html);

+         widget.animate({opacity: 1}, 200);

+       },

+       error: function() {

+         console.log('error updating the widget');

+         console.trace();

+       },

      });

-     function change_notify_icon(color) {

-         // Set the notify icon for 5s

-         if (color == "green") {

-             color = "#33ff00";

-         } else if (color == "red") {

-             color = "#eb361e";

-         }

-         Notificon(color);

-         if (notifTimeout) { clearTimeout(notifTimeout); }

-         notifTimeout = setTimeout(function(){ Notificon(); }, 5000)

+   });

+   function change_notify_icon(color) {

+     // Set the notify icon for 5s

+     if (color == "green") {

+       color = "#33ff00";

+     } else if (color == "red") {

+       color = "#eb361e";

      }

-     // Icon to red on disconnect, icon to green on reconnect.

-     sseSource.addEventListener("error", function() { change_notify_icon("red"); });

-     sseSource.addEventListener("open", function() { change_notify_icon("green"); });

-     // Make it accessible by other components on the page.

-     document.sseSource = sseSource;

+     Notificon(color);

+     if (notifTimeout) { clearTimeout(notifTimeout); }

+     notifTimeout = setTimeout(function(){ Notificon(); }, 5000)

    }

+   // Icon to red on disconnect, icon to green on reconnect.

+   sseSource.addEventListener("error", function() { change_notify_icon("red"); });

+   sseSource.addEventListener("open", function() { change_notify_icon("green"); });

+   // Make it accessible by other components on the page.

+   document.sseSource = sseSource;

+ }

@@ -1,20 +1,16 @@ 

- 

- <div class="modal-dialog" id="adding_form">

-   <div class="modal-content">

+   <!-- Modal content-->

+   <div id="widget-add-form" >

      <form method="post" action="{{ url_for('hub_add_widget', name=hub.name) }}">

-     <input type="hidden" name="position" value="{{ position }}" />

-     <!-- Modal content-->

+       <input type="hidden" name="position" value="{{ position }}" />

        <div class="modal-header">

          <button type="button" class="close" data-dismiss="modal">&times;</button>

-         <h4 class="modal-title">

-           Adding a widget to hub: {{ hub.name }}

-         </h4>

+         <h4 class="modal-title">Adding a widget to hub: {{ hub.name }}</h4>

        </div>

        <div class="modal-body">

          <select id="widget" class="c-select" name="widget">

-             {% for widget in widgets %}

-             <option value="{{ widget.name }}">{{ widget.label }}</option>

-             {% endfor %}

+           {% for widget in widgets %}

+           <option value="{{ widget.name }}">{{ widget.label }}</option>

+           {% endfor %}

          </select>

        </div>

        <div class="modal-footer">
@@ -27,4 +23,3 @@ 

        </div>

      </form>

    </div>

- </div>

file modified
+40 -215
@@ -2,9 +2,7 @@ 

  

  {% block title %}{{ hub.name }}{% endblock %}

  

- 

  {% block header %}

-         

  <div class="row">

  

    <!-- Left side of header -->
@@ -19,7 +17,7 @@ 

        <h5 class="m-t-1 m-b-1">{{ hub.config.summary }}</h5>

      {% endif %}

    </div>

-           

+ 

    <!-- right side of header -->

    <div class="col-md-{{ hub.config.right_width }} text-center align-self-end">

      {% if hub.allows(g.user, "config") %}
@@ -33,22 +31,18 @@ 

            edit page layout

          </a>

        {% else %}

-         <button class="btn btn-sm btn-primary" href="#" id="save_edits_btn">

+         <button id="save-edits-btn" class="btn btn-sm btn-primary" data-request-url="{{ url_for('hub_edit', name=hub.name) }}" data-redirect-url="{{ url_for('hub', name=hub.name) }}">

            <i class="fa fa-download" aria-hidden="true"></i>

            Save changes

          </button>

        {% endif %}

      {% endif %}

    </div>

- 

  </div>

-         

  {% endblock header %}

  

  

- 

  {% block content %}

- 

  <div class="row">

    <div class="col-md-{{ hub.config.left_width }}">

      <!--
@@ -60,11 +54,9 @@ 

        <li class="media">

          <div class="media-left">

          {% if hub.archived %}

-           <img class="media-object square-32"

-             src="{{ url_for('static', filename='img/archived.png') }}"/>

+           <img class="media-object square-32" src="{{ url_for('static', filename='img/archived.png') }}"/>

          {% else %}

-           <img class="media-object square-32"

-             src="{{ url_for('static', filename='img/cobweb.png') }}"/>

+           <img class="media-object square-32" src="{{ url_for('static', filename='img/cobweb.png') }}"/>

          {% endif %}

          </div>

          <div class="media-body">
@@ -84,16 +76,16 @@ 

        <div class="card">

          <div class="card-block">

            <h4>

-           <a href="{{ url_for("hub_add_widget", name=hub.name) }}?position=left" class="add_widget">

-             <span><i class="fa fa-plus" aria-hidden="true"></i></span> Add a widget

-           </a>

+             <a href="{{ url_for("hub_add_widget", name=hub.name) }}?position=left" class="add-widget op-modal-widget">

+               <span><i class="fa fa-plus" aria-hidden="true"></i></span> Add a widget

+             </a>

            </h4>

          </div>

        </div>

      </div>

      {% endif %}

  

-     <div id="left_widgets">

+     <div id="left-widgets">

        {% for widget in widgets["left"] %}

        <div id="widget-{{ widget.idx }}" class="widget row"

             data-url="{{ url_for('%s_root' % widget.plugin, hub=hub.name, idx=widget.idx) }}{% if edit %}?editmode=1{% endif %}"
@@ -108,16 +100,16 @@ 

        <div class="card">

          <div class="card-block">

            <h4>

-           <a href="{{ url_for("hub_add_widget", name=hub.name) }}?position=right" class="add_widget">

-           <span><i class="fa fa-plus" aria-hidden="true"></i></span> Add a widget

-           </a>

+             <a href="{{ url_for("hub_add_widget", name=hub.name) }}?position=right" class="add-widget op-modal-widget">

+               <span><i class="fa fa-plus" aria-hidden="true"></i></span> Add a widget

+             </a>

            </h4>

          </div>

        </div>

      </div>

      {% endif %}

  

-     <div id="right_widgets">

+     <div id="right-widgets">

        {% for widget in widgets["right"] %}

        <div id="widget-{{ widget.idx }}" class="widget row"

             data-url="{{ url_for('%s_root' % widget.plugin, hub=hub.name, idx=widget.idx) }}{% if edit %}?editmode=1{% endif %}"
@@ -128,213 +120,46 @@ 

  

  </div>  <!-- /row -->

  

- <div id="settings-modal" class="modal fade" tabindex="-1" role="dialog">

- </div>

- 

+ <div id="settings-modal" class="modal fade" tabindex="-1" role="dialog"></div>

+ <div id="hubs-modal" class="modal fade" tabindex="-1" role="dialog"></div>

  

- <div id="edit_modal" class="modal fade" role="dialog">

-   <div class="modal-dialog" id="edit_modal_content">

+ <div id="edit-modal" class="modal fade" role="dialog">

+   <div class="modal-dialog">

+     <div id="edit-modal-content" class="modal-content">

+       <div class="modal-body"></div>

+     </div>

    </div>

  </div>

  

  {% endblock content %}

  

- 

- 

  {% block jscripts %}

  {{ super() }}

- 

- {% if edit %}

- <script src="{{ url_for('static', filename='js/Sortable.min.js') }}"></script>

- <script>

- 

- function make_widget_sortable() {

-   var byId = function (id) { return document.getElementById(id); }

- 

-   Sortable.create(byId('left_widgets'), {

-     animation: 150,

-     draggable: '.widget',

-     handle: '.card',

-   });

- 

-   Sortable.create(byId('right_widgets'), {

-     animation: 150,

-     draggable: '.widget',

-     handle: '.card',

-   });

- 

- };

- 

- function setup_add_btns() {

-   // Setup events for the "add widget" button.

-   $(".add_widget").click(function(e) {

-     e.preventDefault();

-     $.ajax({

-       url: $(this).attr('href'),

-       dataType: 'html',

-       success: function(html) {

-         $('#edit_modal_content').html(html);

-       },

-       error: function(html) {

-         $('#edit_modal_content').html(

-           '<div class="modal-dialog"><div class="modal-content"> \

-           <div class="modal-body"> \

-           An error occured when trying to add a new widget\

-           </div></div></div>'

-         );

-         console.log('error');

-         console.trace();

-         console.log(html);

-       },

-       complete: function() {

-         $('#edit_modal').modal();

-       }

-     });

-     return false;

-   });

-   // Setup events for the "add widget" form using delegated events because it's

-   // not in the DOM yet.

-   $("body").on("submit", "#adding_form form", function(e) {

-       var form = $(this);

-       e.preventDefault();

-       $.ajax({

-           type: "POST",

-           url: form.attr("action"),

-           dataType: "json",

-           data: form.serialize(),

-           success: function(data) {

-               if (data.status === "CONFIGURE") {

-                   $("#adding_form").load(data.url);

-               } else if (data.status === "ADDED") {

-                   // no config necessary, reload the page

-                   window.location = window.location;

-               } else {

-                 $('#adding_form .modal-body').html(

-                   "An error occured when trying to add a new widget."

-                 );

-                 $('#adding_form .modal-footer button[type="submit"]').remove();

-                 console.log('error');

-                 console.trace();

-                 console.log(data);

-               }

-           },

-           error: function(html) {

-             $('#adding_form .modal-body').html(

-               "An error occured when trying to add a new widget."

-             );

-             $('#adding_form .modal-footer button[type="submit"]').remove();

-             console.log('error');

-             console.trace();

-             console.log(html);

-           }

-         });

-   });

- }

- 

- $('#save_edits_btn').click(function(e) {

-   e.preventDefault();

-   var _r_indexes = [];

-   var _r_widgets = [];

-   $.each($('#right_widgets .widget'), function(i, el) {

-     _r_indexes.push(i);

-     _r_widgets.push($(el).attr('id').split('widget-')[1])

-   });

- 

-   var _l_indexes = [];

-   var _l_widgets = [];

-   $.each($('#left_widgets .widget'), function(i, el) {

-     _l_indexes.push(i);

-     _l_widgets.push($(el).attr('id').split('widget-')[1])

-   });

- 

-   $.post(

-     '{{ url_for("hub_edit", name=hub.name) }}',

-     {'right_indexes': _r_indexes, 'right_widgets': _r_widgets,

-      'left_indexes': _l_indexes, 'left_widgets': _l_widgets,

-      'js': true},

-     function(){ window.location = '{{ url_for("hub", name=hub.name) }}' }

-   );

- });

- </script>

- {% endif %}

- 

  <script type="text/javascript">

- function setup_edit_btns() {

-   $("body").on("click", ".edit_widget", function(e) {

-     e.preventDefault();

-     var url = $(this).attr('data-url');

- 

-     $.ajax({

-       url: url,

-       dataType: 'html',

-       success: function(html) {

-         $('#edit_modal_content').html(html);

-         $('#edit_modal').modal();

-       },

-       error: function() {

-         $('#edit_modal_content').html(

-           '<div class="modal-dialog"><div class="modal-content"> \

-           <div class="modal-body"> \

-           Nothing to configure for this widget\

-           </div></div></div>'

-         );

-         console.log('error');

-         console.trace();

-         $('#edit_modal').modal();

-       },

-     });

-     return false;

-   });

- }

- 

- function visit_counter() {

-   if (window.performance.navigation.type == 0) {

-     var username = '{{ g.auth.nickname }}'

-     var visited_hub = '{{ hub.name }}'

-     if(username != null && username != '' && username != visited_hub) {

-       url_str = '/visit/' + visited_hub;

- 

-       $.ajax({

-         method: "POST",

-         url: url_str,

-         dataType: 'html',

-         success: function(html) {

-           console.log('Success: incrementing counter')

-         },

-         error: function() {

-           console.log('Error: incrementing counter');

-         },

-       });

-     }

-   }

- }

+   var userName = '{{ g.auth.nickname }}';

+   var urlPrefix = '/visit/';

+   var visitedHub = '{{ hub.name }}';

+   var hubConfigURL = {{ url_for("hub_config", name=hub.name)|tojson }};

+   var hubConfigSuggestUsers = {{ url_for("hub_config_suggest_users", name=hub.name)|tojson }};

+   var sseURL = {{ sse_url | tojson }};

  

- function setup_settings() {

-   var settingsPanel = React.createElement(Hubs.HubConfig, {

-     urls: {

-       config: {{ url_for("hub_config", name=hub.name)|tojson }},

-       suggestUsers: {{ url_for("hub_config_suggest_users", name=hub.name)|tojson }},

-     }

-   });

-   ReactDOM.render(settingsPanel, document.getElementById("settings-modal"));

- }

- 

- $(function() {

-   visit_counter()

- 

-   setup_widgets();

-   setup_sse({{ sse_url | tojson }});

-   setup_edit_btns();

    {% if hub.allows(g.user, "config") %}

-   setup_settings();

+     var canSetupSettings = true;

+   {% else %}

+     var canSetupSettings = false;

    {% endif %}

  

-   {% if edit -%}

-   make_widget_sortable();

-   setup_add_btns();

-   {%- endif %}

- });

- 

+   {% if edit %}

+   var editMode = true;

+   {% else %}

+   var editMode = false;

+   {% endif %}

  </script>

- {% endblock %}

+ <script src="{{ url_for('static', filename='js/hubs.main.js') }}"></script>

+ 

+ {% if edit %}

+ <script src="{{ url_for('static', filename='js/Sortable.min.js') }}"></script>

+ <script src="{{ url_for('static', filename='js/widgets/hubs.edit.js') }}"></script>

+ {% endif %}

+ {% endblock jscripts%}

  {# vim: set ts=2 sw=2 et: #}

file modified
+20 -39
@@ -2,20 +2,18 @@ 

  <html lang='en'>

  <head>

    <title>{% block title %}{% endblock %}</title>

-   <link href="{{ url_for('static', filename='css/style-patternlab.css') }}" rel="stylesheet" />

-   <link href="{{ url_for('static', filename='fedora-bootstrap/fedora-bootstrap.min.css') }}" rel="stylesheet" />

-   <link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet" />

-   <link href="{{ url_for('static', filename='css/pace-theme-minimal.css') }}" rel="stylesheet" />

-   <script type="text/javascript"  src="{{ url_for('static', filename='js/pace.min.js') }}"></script>

-   <script type="text/javascript"  src="{{ url_for('static', filename='notificon.js') }}"></script>

-   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">

-   <link href="{{ url_for('static', filename='badges/b.css') }}"

-         type="text/css" rel="stylesheet" />

-   <link rel="icon" type="image/png"

-       href="{{ url_for('static', filename='img/favicon.png') }}">

+   <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='fedora-bootstrap/fedora-bootstrap.min.css') }}"/>

+   <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}"/>

+   <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/pace-theme-minimal.css') }}"/>

+   <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='badges/b.css') }}" />

+   <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">

+   <link rel="icon" type="image/png" href="{{ url_for('static', filename='img/favicon.png') }}">

+ 

+   <script type="text/javascript" src="{{ url_for('static', filename='js/pace.min.js') }}"></script>

+   <script type="text/javascript" src="{{ url_for('static', filename='notificon.js') }}"></script>

  </head>

- <body>

  

+ <body>

  <nav class="navbar navbar-toggleable-sm navbar-light" id="navbar-top">

    <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbar-top-menu" aria-controls="navbar-top" aria-expanded="false" aria-label="Toggle navigation">

      <span class="navbar-toggler-icon"></span>
@@ -62,33 +60,23 @@ 

        <a href="{{ url_for('login', next=request.url) }}">login</a>.

      </span>

      {% endif %}

- 

    </div>

- 

  </nav>

  

- 

  <header>

- 

    <!-- Flash messages -->

    {%- with messages = get_flashed_messages(with_categories=true) -%}

    {%- if category, messages -%}

-     <div class="row p-t-2">

-       <div class="col-md-6 offset-md-3">

+   <div class="row p-t-2">

+     <div class="col-md-6 offset-md-3">

        {%- for category, message in messages -%}

-         <div class="alert {%

-           if category == 'error' %}alert-warning{%

-           else %}alert-info{%

-           endif %} alert-dismissible" role="alert">

-           <button type="button" class="close" data-dismiss="alert"

-             aria-label="Close">

-             <span aria-hidden="true">&times;</span>

-           </button>

-           {{ message }}

-         </div>

-       {%- endfor -%}

+       <div class="alert {% if category == 'error' %}alert-warning{% else %}alert-info{%endif %} alert-dismissible" role="alert">

+         <button type="button" class="close" data-dismiss="alert"aria-label="Close"><span aria-hidden="true">&times;</span></button>

+         {{ message }}

        </div>

+       {%- endfor -%}

      </div>

+   </div>

    {%- endif -%}

    {%- endwith -%}

  
@@ -99,15 +87,12 @@ 

        {% endblock header %}

      </div>

    </div>

- 

  </header>

  

  

  <!-- main content -->

  <div class="container-fluid">

- 

    <div class="row">

- 

      <!-- Left vertical nav menu -->

      <div class="col-lg-2">

        <ul class="nav nav-pills flex-lg-column mb-3 rounded" id="vertical-navbar" role="navigation">
@@ -129,8 +114,7 @@ 

          {% for hub in g.user.bookmarks %}

            <li class='nav-item idle-{{hub.activity_class}}{% if request.path.endswith('/' + hub.name + '/') %} active{% endif %}'>

              <a class="nav-link" href="{{ url_for("hub", name=hub.name) }}">

-               <span><i class="fa fa-bookmark" aria-hidden="true"></i></span>

-               {{hub.name}}

+               <span><i class="fa fa-bookmark" aria-hidden="true"></i></span> {{ hub.name }}

              </a>

            </li>

          {% endfor %}
@@ -138,19 +122,15 @@ 

          <!-- At the end of the list, tack on a link to all groups -->

          <li class="nav-item">

            <a class="nav-link" href="{{ url_for("groups") }}">

-             <span><i class="fa fa-users" aria-hidden="true"></i></span>

-             All groups

+             <span><i class="fa fa-users" aria-hidden="true"></i></span> All groups

            </a>

          </li>

        </ul>

      </div>

- 

      <div class="col-lg-10 px-0">

- 

        <!-- Main content -->

        {% block content %}

        {% endblock content %}

- 

      </div>

    </div>

  </div> <!-- /.container-fluid -->
@@ -163,6 +143,7 @@ 

  <script src="{{ url_for('static', filename='js/utils.js') }}"></script>

  <script src="{{ url_for('static', filename='js/build/common.js') }}"></script>

  <script src="{{ url_for('static', filename='js/build/Hubs.js') }}"></script>

+ <script src="{{ url_for('static', filename='js/hubs.main.js') }}"></script>

  {% endblock %}

  

  </body>

@@ -5,7 +5,7 @@ 

      <!-- the AGPLv3 wrapper puts the source url in all responses -->

      <a href="{{ url_for('widget_source', name=widget.name) }}"><span><i class="fa fa-eye" aria-hidden="true"></i></span></a>

      <a href="{{ url_for('%s_root' % widget.name, hub=widget_instance.hub.name, idx=widget_instance.idx) }}">

-         <span><i class="fa fa-external-link" aria-hidden="true"></i></span>

+       <span><i class="fa fa-external-link" aria-hidden="true"></i></span>

      </a>

      {% if edit_mode and widget_instance.hub.allows(g.user, "config") %}

      <a data-target="#edit_modal" data-toggle="modal" type="button"
@@ -14,11 +14,13 @@ 

      </a>

      {% endif %}

    </div>

+ 

    {% if title %}

    <div class="card-header">

      {{title}}

    </div> <!-- end card-header -->

    {% endif %}

+   

    <div class="card-block">

      {% block content %}{% endblock %}

    </div> <!-- end card-block -->

file modified
-1
@@ -20,7 +20,6 @@ 

      help='A configuration file to load (allowing to override the default '

      'configuraton)')

  

- 

  args = parser.parse_args()

  

  if args.config: