Browse Source

Merge branch 'dev'

Denis K 8 years ago
parent
commit
bf922900ab
89 changed files with 308 additions and 913 deletions
  1. 23 1
      CHANGELOG.rst
  2. 1 0
      MANIFEST.in
  3. 18 0
      docs/config_file.rst
  4. 12 0
      docs/contribution.rst
  5. 1 1
      docs/dashboard.rst
  6. 4 4
      docs/dashboard_custom.rst
  7. 1 1
      docs/dashboard_custom_module.rst
  8. 27 5
      gulpfile.js
  9. 1 1
      jet/__init__.py
  10. 6 4
      jet/dashboard/modules.py
  11. 8 8
      jet/dashboard/templates/jet.dashboard/module.html
  12. 0 7
      jet/dashboard/templates/jet.dashboard/update_module.html
  13. 9 4
      jet/static/jet/css/_changeform.scss
  14. 51 37
      jet/static/jet/css/_changelist.scss
  15. 18 1
      jet/static/jet/css/_dashboard.scss
  16. 1 1
      jet/static/jet/css/_forms.scss
  17. 4 0
      jet/static/jet/css/_header.scss
  18. 28 11
      jet/static/jet/css/_messages.scss
  19. 7 1
      jet/static/jet/css/_sidebar.scss
  20. 1 0
      jet/static/jet/css/_variables.scss
  21. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png
  22. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png
  23. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png
  24. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_flat_10_000000_40x100.png
  25. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png
  26. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png
  27. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png
  28. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png
  29. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png
  30. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png
  31. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png
  32. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png
  33. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png
  34. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
  35. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png
  36. BIN
      jet/static/jet/css/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
  37. BIN
      jet/static/jet/css/jquery-ui/images/ui-icons_222222_256x240.png
  38. BIN
      jet/static/jet/css/jquery-ui/images/ui-icons_228ef1_256x240.png
  39. BIN
      jet/static/jet/css/jquery-ui/images/ui-icons_2e83ff_256x240.png
  40. BIN
      jet/static/jet/css/jquery-ui/images/ui-icons_454545_256x240.png
  41. BIN
      jet/static/jet/css/jquery-ui/images/ui-icons_888888_256x240.png
  42. BIN
      jet/static/jet/css/jquery-ui/images/ui-icons_cd0a0a_256x240.png
  43. BIN
      jet/static/jet/css/jquery-ui/images/ui-icons_ef8c08_256x240.png
  44. BIN
      jet/static/jet/css/jquery-ui/images/ui-icons_ffd27a_256x240.png
  45. BIN
      jet/static/jet/css/jquery-ui/images/ui-icons_ffffff_256x240.png
  46. 0 3
      jet/static/jet/css/select2/_layout.scss
  47. 6 3
      jet/static/jet/css/select2/_multiple.scss
  48. 6 2
      jet/static/jet/css/select2/_single.scss
  49. 0 0
      jet/static/jet/css/themes/default/base.css
  50. 0 0
      jet/static/jet/css/themes/default/base.css.map
  51. 0 0
      jet/static/jet/css/themes/default/jquery-ui.theme.css.map
  52. 0 0
      jet/static/jet/css/themes/default/select2.theme.css
  53. 0 0
      jet/static/jet/css/themes/default/select2.theme.css.map
  54. 0 0
      jet/static/jet/css/themes/green/base.css
  55. 0 0
      jet/static/jet/css/themes/green/base.css.map
  56. 0 0
      jet/static/jet/css/themes/green/select2.theme.css
  57. 0 0
      jet/static/jet/css/themes/green/select2.theme.css.map
  58. 0 0
      jet/static/jet/css/themes/light-blue/base.css
  59. 0 0
      jet/static/jet/css/themes/light-blue/base.css.map
  60. 0 0
      jet/static/jet/css/themes/light-blue/select2.theme.css
  61. 0 0
      jet/static/jet/css/themes/light-blue/select2.theme.css.map
  62. 0 0
      jet/static/jet/css/themes/light-gray/base.css
  63. 0 0
      jet/static/jet/css/themes/light-gray/base.css.map
  64. 0 0
      jet/static/jet/css/themes/light-gray/select2.theme.css
  65. 0 0
      jet/static/jet/css/themes/light-gray/select2.theme.css.map
  66. 0 0
      jet/static/jet/css/themes/light-green/base.css
  67. 0 0
      jet/static/jet/css/themes/light-green/base.css.map
  68. 0 0
      jet/static/jet/css/themes/light-green/select2.theme.css
  69. 0 0
      jet/static/jet/css/themes/light-green/select2.theme.css.map
  70. 0 0
      jet/static/jet/css/themes/light-violet/base.css
  71. 0 0
      jet/static/jet/css/themes/light-violet/base.css.map
  72. 0 0
      jet/static/jet/css/themes/light-violet/select2.theme.css
  73. 0 0
      jet/static/jet/css/themes/light-violet/select2.theme.css.map
  74. 0 780
      jet/static/jet/css/vendor.css
  75. 0 0
      jet/static/jet/js/build/bundle.min.js
  76. 8 7
      jet/static/jet/js/src/features/checkboxes.js
  77. 3 1
      jet/static/jet/js/src/features/dashboard.js
  78. 2 1
      jet/static/jet/js/src/features/selects.js
  79. 13 0
      jet/static/jet/js/src/features/sidebar/popup.js
  80. 4 2
      jet/static/jet/js/src/layout-updaters/actions.js
  81. 3 1
      jet/static/jet/js/src/layout-updaters/branding.js
  82. 5 7
      jet/static/jet/js/src/layout-updaters/paginator.js
  83. 6 1
      jet/static/jet/js/src/layout-updaters/toolbar.js
  84. 1 3
      jet/templates/admin/base.html
  85. 13 5
      jet/templatetags/jet_tags.py
  86. 1 1
      jet/tests/test_utils.py
  87. 13 7
      jet/utils.py
  88. 2 1
      package.json
  89. 1 1
      setup.py

+ 23 - 1
CHANGELOG.rst

@@ -1,6 +1,28 @@
 Changelog
 =========
 
+1.0.0
+-----
+* Fixed dashboard module buttons mobile layout misplacement
+* Fixed double tap menu issue for iOS devices
+* Fixed changelist footer from fixed position transition
+* Fixed system messages style
+* Fixed jQuery UI base styles broken image paths
+* Issue-69, 72: Updated checkboxes without label UI (thanks to h00p, JuniorLima for report)
+* Issue-89: Fixed multiple admin sites support (thanks to sysint64 for report)
+* Added missing locale files to PyPI package (thanks to SalahAdDin for report)
+* Issue-49: Fixed AppList and ModelList models/exclude parsers (thanks to eltismerino for report)
+* Issue-50: Fix pinned application user filtering (thanks to eltismerino for report)
+* Fixed empty branding visibility
+* Fixed IE dashboard list items wrapping
+* Fixed IE sidebar popup items spacing
+* Fixed dashboard module wrong height after animation
+* Fixed dashboard module change form breadcrumbs
+* Improved paginator 'show all' layout
+* Updated documentation
+* Added support for filters with multiple select
+
+
 0.9.1
 -----
 * Mobile UX improved
@@ -8,7 +30,7 @@ Changelog
 * More documentation added
 * Improved object tools and toolbar arrangement
 * Fixed change list footer misplacement
-* Fix chromium sidebar scrollbar misplacement
+* Fixed chromium sidebar scrollbar misplacement
 * Remove unused tags
 * Prefixed JET template tags
 * Fixed jet_custom_apps_example command

+ 1 - 0
MANIFEST.in

@@ -3,5 +3,6 @@ include LICENSE
 recursive-include jet/locale *
 recursive-include jet/static *
 recursive-include jet/templates *
+recursive-include jet/dashboard/locale *
 recursive-include jet/dashboard/static *
 recursive-include jet/dashboard/templates *

+ 18 - 0
docs/config_file.rst

@@ -124,6 +124,24 @@ If want to show all application's models use ``__all__`` keyword.
         ...
     ]
 
+If have multiple admin sites and you want to specify different menu applications for each admin site, wrap menu lists
+in dictionary with admin site names as keys:
+
+.. code:: python
+
+    JET_SIDE_MENU_CUSTOM_APPS = {
+        'admin': [
+            ('core', ['__all__']),
+            ...
+        ],
+        'custom_admin': [
+            ('custom_admin_app', [
+                'CustomAdminAppModel',
+            ]),
+            ...
+        ]
+    }
+
 .. note::
 
     You can use ``jet_custom_apps_example`` management command to generate example ``JET_SIDE_MENU_CUSTOM_APPS``

+ 12 - 0
docs/contribution.rst

@@ -64,6 +64,18 @@ In order to be merged into Django JET, contributions must have the following:
 If your contribution lacks any of these things, they will have to be added by a core contributor before
 being merged into Django JET proper, which may take time to get to.
 
+Contribution Translations
+-------------------------
+
+If you want to add new translations locale, please do not use automatic Django locale generation, because it will
+produce files with missing JS strings and duplicates. Instead copy the following well formatted "en" files to your
+new locale folder:
+
+* jet/locale/LOCALE/LC_MESSAGES/django.mo
+* jet/locale/LOCALE/LC_MESSAGES/djangojs.mo
+* jet/dashboard/locale/LOCALE/LC_MESSAGES/django.mo
+* jet/dashboard/locale/LOCALE/LC_MESSAGES/djangojs.mo
+
 Contribution Styles/Javascript/Translations
 -------------------------------------------
 

+ 1 - 1
docs/dashboard.rst

@@ -5,6 +5,6 @@ Dashboard
 .. toctree::
    :maxdepth: 2
 
-   dashboard_getting_started
+   dashboard_custom
    dashboard_modules
    dashboard_custom_module

+ 4 - 4
docs/dashboard_getting_started.rst → docs/dashboard_custom.rst

@@ -1,6 +1,6 @@
-===============
-Getting Started
-===============
+================
+Custom Dashboard
+================
 
 .. note::
    Django JET Dashboard tries to be as compatible as possible with django-admin-tools dashboard so that
@@ -63,4 +63,4 @@ Set Up Custom Dashboard
 
 That's all, now you have dashboard with only one widget - ``LinkList``. Dashboard reset may be needed
 if your had another dashboard already rendered for any user. Visit :doc:`dashboard_modules` to learn
-other widgets you can add to your custom dashboard or create your own.
+other widgets you can add to your custom dashboard or :doc:`dashboard_custom_module` to create your own.

+ 1 - 1
docs/dashboard_custom_module.rst

@@ -1,5 +1,5 @@
 =======================
-Custom Dashboard module
+Custom Dashboard Module
 =======================
 
 

+ 27 - 5
gulpfile.js

@@ -3,7 +3,7 @@ require('es6-promise').polyfill();
 var gulp = require('gulp'),
     browserify = require('browserify'),
     concatCss = require('gulp-concat-css'),
-    minifyCss = require('gulp-minify-css'),
+    cleanCSS = require('gulp-clean-css'),
     sass = require('gulp-sass'),
     uglify = require('gulp-uglify'),
     buffer = require('vinyl-buffer'),
@@ -13,7 +13,8 @@ var gulp = require('gulp'),
     postcss = require('gulp-postcss'),
     pxtorem = require('postcss-pxtorem'),
     autoprefixer = require('autoprefixer'),
-    shell = require('gulp-shell');
+    shell = require('gulp-shell'),
+    replace = require('gulp-replace');
 
 var cssProcessors = [
     autoprefixer(),
@@ -54,12 +55,31 @@ gulp.task('styles', function() {
 });
 
 gulp.task('vendor-styles', function() {
+    gulp.src('./node_modules/jquery-ui/themes/base/images/*')
+        .pipe(gulp.dest('./jet/static/jet/css/jquery-ui/images/'));
+
     merge(
         gulp.src([
             './node_modules/select2/dist/css/select2.css',
-            './node_modules/jquery-ui/themes/base/all.css',
             './node_modules/timepicker/jquery.ui.timepicker.css'
         ]),
+        gulp.src([
+            './node_modules/jquery-ui/themes/base/all.css'
+        ])
+            .pipe(cleanCSS()) // needed to remove jQuery UI comments breaking concatCss
+            .on('error', function(error) {
+                console.error(error);
+            })
+            .pipe(concatCss('jquery-ui.css', {
+                rebaseUrls: false
+            }))
+            .on('error', function(error) {
+                console.error(error);
+            })
+            .pipe(replace('images/', 'jquery-ui/images/'))
+            .on('error', function(error) {
+                console.error(error);
+            }),
         gulp.src([
             './node_modules/perfect-scrollbar/src/css/main.scss'
         ])
@@ -74,11 +94,13 @@ gulp.task('vendor-styles', function() {
         .on('error', function(error) {
             console.error(error);
         })
-        .pipe(minifyCss())
+        .pipe(concatCss('vendor.css', {
+            rebaseUrls: false
+        }))
         .on('error', function(error) {
             console.error(error);
         })
-        .pipe(concatCss('vendor.css'))
+        .pipe(cleanCSS())
         .on('error', function(error) {
             console.error(error);
         })

+ 1 - 1
jet/__init__.py

@@ -1 +1 @@
-VERSION = '0.9.1'
+VERSION = '1.0.0'

+ 6 - 4
jet/dashboard/modules.py

@@ -317,12 +317,13 @@ class AppList(DashboardModule):
         app_to_remove = []
 
         for app in app_list:
+            app_name = app.get('app_label', app.get('name', ''))
             app['models'] = filter(
-                lambda model: self.models is None or model['object_name'] in self.models or app.get('app_label', app.get('name')) + '.*' in self.models,
+                lambda model: self.models is None or ('%s.%s' % (app_name, model['object_name'])) in self.models or ('%s.*' % app_name) in self.models,
                 app['models']
             )
             app['models'] = filter(
-                lambda model: self.exclude is None or model['object_name'] not in self.exclude and app.get('app_label', app.get('name')) + '.*' not in self.exclude,
+                lambda model: self.exclude is None or (('%s.%s' % (app_name, model['object_name'])) not in self.exclude and ('%s.*' % app_name) not in self.exclude),
                 app['models']
             )
             app['models'] = list(app['models'])
@@ -389,12 +390,13 @@ class ModelList(DashboardModule):
         models = []
 
         for app in app_list:
+            app_name = app.get('app_label', app.get('name', ''))
             app['models'] = filter(
-                lambda model: self.models is None or model['object_name'] in self.models or app.get('app_label', app.get('name')) + '.*' in self.models,
+                lambda model: self.models is None or ('%s.%s' % (app_name, model['object_name'])) in self.models or ('%s.*' % app_name) in self.models,
                 app['models']
             )
             app['models'] = filter(
-                lambda model: self.exclude is None or model['object_name'] not in self.exclude and app.get('app_label', app.get('name')) + '.*' not in self.exclude,
+                lambda model: self.exclude is None or (('%s.%s' % (app_name, model['object_name'])) not in self.exclude and ('%s.*' % app_name) not in self.exclude),
                 app['models']
             )
             app['models'] = list(app['models'])

+ 8 - 8
jet/dashboard/templates/jet.dashboard/module.html

@@ -3,6 +3,13 @@
 <div class="dashboard-item{% if module.collapsible %} collapsible{% endif %}{% if module.model.collapsed %} collapsed{% endif %}{% if module.deletable %} deletable{% endif %}{% if module.ajax_load %} ajax{% endif %}"{% if module.ajax_load %} data-ajax-url="{% url "jet-dashboard:load_dashboard_module" pk=module.model.id %}"{% endif %} data-module-id="{{ module.model.id }}">
     <div class="dashboard-item-header">
         <span class="dashboard-item-header-drag icon-grid"></span>
+        <span class="dashboard-item-header-buttons">
+            <a href="{% url "jet-dashboard:update_module" pk=module.model.id %}" title="{% trans "Change" %}"><span class="icon-edit"></span></a>
+
+            {% if module.deletable %}
+                <a href="#" title="{% trans "Delete" %}" class="dashboard-item-remove"><span class="icon-cross"></span></a>
+            {% endif %}
+        </span>
         <span class="dashboard-item-header-title">
             {% if module.collapsible %}
                 <a href="#" class="dashboard-item-collapse"><span class="dashboard-item-header-collapse-button icon-arrow-down"></span></a>
@@ -14,15 +21,8 @@
             {% else %}
                 {{ module.title }}
             {% endif %}
-
-            <span class="dashboard-item-header-buttons">
-                <a href="{% url "jet-dashboard:update_module" pk=module.model.id %}" title="{% trans "Change" %}"><span class="icon-edit"></span></a>
-
-                {% if module.deletable %}
-                    <a href="#" title="{% trans "Delete" %}" class="dashboard-item-remove"><span class="icon-cross"></span></a>
-                {% endif %}
-            </span>
         </span>
+        <div class="cf"></div>
     </div>
 
     <div class="dashboard-item-content{% if module.contrast %} contrast{% endif %}"{% if module.style %} style="{{ module.style }}"{% endif %}>

+ 0 - 7
jet/dashboard/templates/jet.dashboard/update_module.html

@@ -1,13 +1,6 @@
 {% extends "admin/base_site.html" %}
 {% load i18n jet_tags static %}
 
-{% block extrahead %}
-    {{ block.super }}
-    <script type="text/javascript" src="{% static "admin/js/jquery.js" %}"></script>
-    <script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
-    <script type="text/javascript" src="{% static "admin/js/inlines.js" %}"></script>
-{% endblock %}
-
 {% if not is_popup %}
     {% block breadcrumbs %}
         <div class="breadcrumbs">

+ 9 - 4
jet/static/jet/css/_changeform.scss

@@ -402,11 +402,16 @@ body.popup .submit-row {
   margin-right: 2px;
   margin-bottom: 4px;
   border-radius: 4px 0 0 4px !important;
-  border-right: 0 !important;
+  border-right-width: 0 !important;
+
+  #changelist & {
+    border-radius: 4px !important;
+    border-right-width: 1px !important;
+  }
 
   @include for-width(374px) {
     border-radius: 4px !important;
-    border-right: 1px !important;
+    border-right-width: 1px !important;
   }
 
   &-link {
@@ -536,6 +541,7 @@ body.popup .submit-row {
       display: inline-block;
       background: $content-contrast2-background-color;
       color: $content-contrast2-text-color;
+      margin-right: 10px;
       padding: 4px 8px;
       border-radius: 5px;
       font-size: 10px;
@@ -548,13 +554,12 @@ body.popup .submit-row {
       vertical-align: middle;
 
       @include for-mobile {
-        margin-right: 10px;
         line-height: normal;
       }
 
       ~ .inlinechangelink, ~ .inlineviewlink {
         font-size: 18px;
-        margin-left: 10px;
+        margin-right: 10px;
         vertical-align: middle;
 
         &:before {

+ 51 - 37
jet/static/jet/css/_changelist.scss

@@ -162,6 +162,20 @@
       @include for-phone {
         width: 100% !important;
       }
+
+      &-selection--multiple {
+        overflow: auto;
+        height: $input-height !important;
+
+        .select2-selection__rendered {
+          padding: 0 2px !important;
+        }
+
+        .select2-selection__choice {
+          margin-top: 2px !important;
+          margin-right: 2px !important;
+        }
+      }
     }
   }
 }
@@ -215,44 +229,54 @@
     display: inherit;
   }
 
-  span:not(.pages-wrapper), a {
-    font-size: 14px;
-    padding: 6px 10px;
+  .pages-wrapper {
+    margin-left: 10px;
     display: inline-block;
+    margin-bottom: 5px;
 
-    &:first-child {
-      border-radius: 4px 0 0 4px;
+    @include for-mobile {
+      margin-left: 0;
     }
 
-    &:last-child {
-      border-radius: 0 4px 4px 0;
-    }
+    span, a {
+      font-size: 14px;
+      padding: 6px 10px;
+      display: inline-block;
 
-    &:first-child:last-child {
-      border-radius: 4px;
-    }
-  }
+      &:first-child {
+        border-radius: 4px 0 0 4px;
+      }
 
-  span:not(.pages-wrapper) {
-    background-color: $button-active-background-color;
-    color: $button-active-text-color;
+      &:last-child {
+        border-radius: 0 4px 4px 0;
+      }
 
-    &.disabled {
-      background-color: $button-background-color;
-      color: $button-text-color;
+      &:first-child:last-child {
+        border-radius: 4px;
+      }
     }
-  }
 
-  a:not(.showall) {
-    &:link, &:visited {
-      background-color: $button-background-color;
-      color: $button-text-color;
-      text-decoration: none;
+    span {
+      background-color: $button-active-background-color;
+      color: $button-active-text-color;
+
+      &.disabled {
+        background-color: $button-background-color;
+        color: $button-text-color;
+      }
     }
 
-    &:focus, &:hover {
-      background-color: $button-hover-background-color;
-      color: $button-hover-text-color;
+    a {
+      &:link, &:visited {
+        background-color: $button-background-color;
+        color: $button-text-color;
+        text-decoration: none;
+      }
+
+      &:focus, &:hover {
+        background-color: $button-hover-background-color;
+        color: $button-hover-text-color;
+      }
     }
   }
 
@@ -262,16 +286,6 @@
     }
   }
 
-  .pages-wrapper {
-    margin-left: 10px;
-    display: inline-block;
-    margin-bottom: 5px;
-
-    @include for-mobile {
-      margin-left: 0;
-    }
-  }
-
   .label  {
     padding: 8px 0;
   }

+ 18 - 1
jet/static/jet/css/_dashboard.scss

@@ -41,6 +41,12 @@
       display: none;
     }
   }
+
+  &.jet.change-form .breadcrumbs {
+    @include for-mobile {
+      display: block;
+    }
+  }
 }
 
 /* RECENT ACTIONS MODULE */
@@ -210,15 +216,20 @@ ul.actionlist li {
       padding: 0 10px 0 6px;
 
       &-title {
+        display: block;
         font-size: 11px;
         font-weight: bold;
         text-transform: uppercase;
         line-height: 30px;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
       }
 
       &-drag {
         float: right;
         line-height: 30px !important;
+        margin-left: 10px;
 
         html.touchevents & {
           display: none;
@@ -232,14 +243,19 @@ ul.actionlist li {
       }
 
       &-buttons {
+        float: right;
         margin-left: 10px;
         font-size: 13px;
+        line-height: 30px;
         vertical-align: middle;
         visibility: hidden;
 
+        a {
+          vertical-align: middle;
+        }
+
         html.touchevents & {
           visibility: visible;
-          float: right;
         }
       }
 
@@ -267,6 +283,7 @@ ul.actionlist li {
         @extend .clear-list;
 
         li {
+          display: block;
           border-bottom: 1px solid $content-border-color;
           font-size: 13px;
           padding: 8px;

+ 1 - 1
jet/static/jet/css/_forms.scss

@@ -56,7 +56,7 @@
 input[type="text"], input[type="email"], input[type="password"], input[type="url"], input[type="number"], textarea, select, .vTextField {
   border-radius: 4px;
   font-size: 13px;
-  height: 32px;
+  height: $input-height;
   white-space: nowrap;
   outline: 0;
   box-sizing: border-box;

+ 4 - 0
jet/static/jet/css/_header.scss

@@ -13,6 +13,10 @@
     display: block;
   }
 
+  &:empty {
+    display: none;
+  }
+
   h1, h2 {
     padding: 0;
     margin: 0;

+ 28 - 11
jet/static/jet/css/_messages.scss

@@ -12,6 +12,11 @@ ul.messagelist {
     border-radius: 6px;
     padding: 10px;
 
+    @include for-phone {
+      margin-left: 10px;
+      margin-right: 10px;
+    }
+
     &.success {
       background: $success-color;
       color: $success-text-color;
@@ -76,20 +81,32 @@ ul.errorlist {
 }
 
 div.system-message {
-    background: #ffc;
-    margin: 10px;
-    padding: 6px 8px;
-    font-size: .8em;
-}
+  margin: 0 20px 10px 20px;
+  border-radius: 6px;
+  padding: 10px;
+  background: $warning-color;
+  color: $warning-text-color;
 
-div.system-message p.system-message-title {
-    padding: 4px 5px 4px 25px;
+  @include for-phone {
+    margin-left: 10px;
+    margin-right: 10px;
+  }
+
+  p.system-message-title {
     margin: 0;
-    color: #c11;
-    background: #ffefef url(../img/icon-no.svg) 5px 5px no-repeat;
+
+    &:before {
+      @include font-icon;
+      content: $icon-cross;
+      vertical-align: middle;
+      margin-right: 4px;
+      color: $warning-text-color;
+    }
+  }
 }
 
 .description {
-    font-size: 12px;
-    padding: 5px 0 0 12px;
+  font-size: 12px;
+  margin: 0;
+  padding: 6px 0 0 0;
 }

+ 7 - 1
jet/static/jet/css/_sidebar.scss

@@ -285,8 +285,12 @@
         html.touchevents & {
           position: static;
           padding: 6px;
-          margin-top: 6px;
+          margin-top: 2px;
           font-size: 18px;
+
+          @include for-mobile {
+            margin-top: 6px;
+          }
         }
       }
 
@@ -493,6 +497,8 @@
       list-style: none;
 
       &-item {
+        display: block;
+
         a, a:visited, a:hover {
           color: $sidebar-popup-link-text-color;
           padding: 8px 20px;

+ 1 - 0
jet/static/jet/css/_variables.scss

@@ -126,6 +126,7 @@ $background-button-text-color: #6f7e95 !default;
  * Inputs
  */
 
+$input-height: 32px !default;
 $input-background-color: #fff !default;
 $input-contrast-background-color: #d0dbe6 !default;
 $input-border-color: #ecf2f6 !default;

BIN
jet/static/jet/css/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_flat_10_000000_40x100.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png


BIN
jet/static/jet/css/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png


BIN
jet/static/jet/css/jquery-ui/images/ui-icons_222222_256x240.png


BIN
jet/static/jet/css/jquery-ui/images/ui-icons_228ef1_256x240.png


BIN
jet/static/jet/css/jquery-ui/images/ui-icons_2e83ff_256x240.png


BIN
jet/static/jet/css/jquery-ui/images/ui-icons_454545_256x240.png


BIN
jet/static/jet/css/jquery-ui/images/ui-icons_888888_256x240.png


BIN
jet/static/jet/css/jquery-ui/images/ui-icons_cd0a0a_256x240.png


BIN
jet/static/jet/css/jquery-ui/images/ui-icons_ef8c08_256x240.png


BIN
jet/static/jet/css/jquery-ui/images/ui-icons_ffd27a_256x240.png


BIN
jet/static/jet/css/jquery-ui/images/ui-icons_ffffff_256x240.png


+ 0 - 3
jet/static/jet/css/select2/_layout.scss

@@ -1,7 +1,5 @@
 @import "../globals";
 
-$input-height: 32px;
-
 .select2-container--jet {
   @import "single";
   @import "multiple";
@@ -12,7 +10,6 @@ $input-height: 32px;
     border: 1px solid $input-border-color;
     border-radius: 4px;
     outline: 0;
-    height: $input-height;
 
     @include for-mobile {
       fieldset.module & {

+ 6 - 3
jet/static/jet/css/select2/_multiple.scss

@@ -1,12 +1,10 @@
 @import "../globals";
 
-$input-height: 0 !default;
-
 .select2-selection--multiple {
   background-color: $input-background-color !important;
   border: 1px solid $input-border-color;
   cursor: text;
-  height: auto !important;
+  height: auto;
   min-height: $input-height;
 
   .select2-selection__rendered {
@@ -15,6 +13,10 @@ $input-height: 0 !default;
     margin: 0;
     padding: 0 5px;
     width: 100%;
+
+    li {
+      list-style-type: none;
+    }
   }
 
   .select2-selection__clear {
@@ -36,6 +38,7 @@ $input-height: 0 !default;
     margin-top: 5px;
     padding: 5px 5px;
     line-height: normal;
+    list-style-type: none;
   }
 
   .select2-selection__choice__remove {

+ 6 - 2
jet/static/jet/css/select2/_single.scss

@@ -1,8 +1,12 @@
 @import "../globals";
 
-$input-height: 0 !default;
-
 .select2-selection--single {
+  height: $input-height;
+
+  .select2-selection__rendered {
+    padding-right: 24px;
+  }
+
   .select2-selection__clear {
     cursor: pointer;
     float: right;

File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/default/base.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/default/base.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/default/jquery-ui.theme.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/default/select2.theme.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/default/select2.theme.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/green/base.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/green/base.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/green/select2.theme.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/green/select2.theme.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-blue/base.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-blue/base.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-blue/select2.theme.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-blue/select2.theme.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-gray/base.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-gray/base.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-gray/select2.theme.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-gray/select2.theme.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-green/base.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-green/base.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-green/select2.theme.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-green/select2.theme.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-violet/base.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-violet/base.css.map


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-violet/select2.theme.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/css/themes/light-violet/select2.theme.css.map


File diff suppressed because it is too large
+ 0 - 780
jet/static/jet/css/vendor.css


File diff suppressed because it is too large
+ 0 - 0
jet/static/jet/js/build/bundle.min.js


+ 8 - 7
jet/static/jet/js/src/features/checkboxes.js

@@ -17,14 +17,15 @@ Checkboxes.prototype = {
     },
     addLabelToCheckboxes: function() {
         var self = this;
-        var $containers = $('.action-checkbox, .action-checkbox-column, .tabular.inline-related .form-row');
-        var $checkboxes = $containers
-            .find('input[type="checkbox"]')
-            .add('.checkbox-without-label')
-            .add('label > input[type="checkbox"]');
 
-        $checkboxes.each(function() {
-            self.addLabelToCheckbox($(this));
+        $('input[type="checkbox"]').each(function() {
+            var $checkbox = $(this);
+
+            if ($checkbox.attr('id') != undefined && $('label[for="' + $checkbox.attr('id') + '"]').length != 0) {
+                return;
+            }
+
+            self.addLabelToCheckbox($checkbox);
         });
     },
     run: function() {

+ 3 - 1
jet/static/jet/js/src/features/dashboard.js

@@ -239,7 +239,9 @@ Dashboard.prototype = {
                     $content.height(oldHeight);
                     $content.animate({
                         height: newHeight
-                    }, 250);
+                    }, 250, 'swing', function() {
+                        $content.height('auto');
+                    });
                 },
                 error: function () {
                     $content.empty();

+ 2 - 1
jet/static/jet/js/src/features/selects.js

@@ -147,7 +147,8 @@ Select2.prototype = {
     initSelect: function($select, DropdownAdapter) {
         var settings = {
             theme: 'jet',
-            dropdownAdapter: DropdownAdapter
+            dropdownAdapter: DropdownAdapter,
+            width: 'auto'
         };
 
         if ($select.hasClass('ajax')) {

+ 13 - 0
jet/static/jet/js/src/features/sidebar/popup.js

@@ -184,6 +184,19 @@ SideBarPopup.prototype = {
             self.$currentSectionListItem = $(this).closest('.sidebar-popup-list-item');
             self.resetCurrentSectionListItems();
             self.$currentSectionListItem.addClass('selected');
+        }).on('touchmove touchend', function(e) {
+            var $el = $(this);
+
+            if (e.type == 'touchmove') {
+                $el.data('element_swiped', true);
+                return;
+            }
+
+            if (e.type == 'touchend' && !$el.data('element_swiped')) {
+                window.location = $el.attr('href');
+            }
+
+            $el.data('element_swiped', false);
         });
 
         this.initSectionKeyboardControls();

+ 4 - 2
jet/static/jet/js/src/layout-updaters/actions.js

@@ -32,8 +32,10 @@ ActionsUpdater.prototype = {
         $actions.detach();
         $paginator.detach();
 
-        $wrapper.append($actions);
-        $wrapper.append($paginator);
+        $wrapper
+            .append($actions)
+            .append($paginator)
+            .append($('<div>').addClass('cf'));
     },
     run: function() {
         var $actions = this.$changelist.find('.actions');

+ 3 - 1
jet/static/jet/js/src/layout-updaters/branding.js

@@ -25,5 +25,7 @@ $(document).ready(function() {
     $('#branding').each(function() {
         new BrandingUpdater($(this)).run();
     });
-    $('<img>').attr('src', '//jet.geex-arts.com/ping.gif').hide().appendTo($('body.login'));
+    if ($('body.login').length != 0) {
+        $('<img>').attr('src', '//jet.geex-arts.com/ping.gif');
+    }
 });

+ 5 - 7
jet/static/jet/js/src/layout-updaters/paginator.js

@@ -18,7 +18,7 @@ PaginatorUpdater.prototype = {
 
                 if ($.trim($node.text()) == '...') {
                     $node.wrap($('<span>').addClass('disabled'));
-                } else {
+                } else if ($.trim($node.text()) == '') {
                     $node.remove();
                 }
             }
@@ -30,7 +30,8 @@ PaginatorUpdater.prototype = {
         var $pageNodes = $([]);
 
         this.$paginator.contents().each(function() {
-            var pageNode = this.tagName == 'A' || this.tagName == 'SPAN';
+            var $node = $(this);
+            var pageNode = (this.tagName == 'A' && !$node.hasClass('showall')) || this.tagName == 'SPAN';
 
             if (pageNode) {
                 foundPage = true;
@@ -41,8 +42,6 @@ PaginatorUpdater.prototype = {
             }
 
             if (pageNode && !pagesEnded) {
-                var $node = $(this);
-
                 $node.detach();
                 $pageNodes = $pageNodes.add($node);
             } else {
@@ -57,13 +56,12 @@ PaginatorUpdater.prototype = {
         var $nodes = $([]);
 
         this.$paginator.contents().each(function() {
-            var pageNode = this.tagName == 'A' || this.tagName == 'SPAN';
+            var $node = $(this);
+            var pageNode = (this.tagName == 'A' && !$node.hasClass('showall')) || this.tagName == 'SPAN';
 
             if (pageNode) {
                 foundPage = true;
             } else if (foundPage && !pageNode && this.tagName != 'INPUT') {
-                var $node = $(this);
-
                 $node.detach();
                 $nodes = $nodes.add($node);
             }

+ 6 - 1
jet/static/jet/js/src/layout-updaters/toolbar.js

@@ -30,8 +30,13 @@ ToolbarUpdater.prototype = {
                 filterName = $element.text();
             } else if ($element.prop('tagName') == 'UL') {
                 var $select = $('<select>').addClass('changelist-filter-select');
+                var $items = $element.find('li');
 
-                $element.find('li').each(function(i) {
+                if ($items.filter('.selected').length > 1) {
+                    $select.attr('multiple', true);
+                }
+
+                $items.each(function(i) {
                     var $item = $(this);
                     var $link = $item.find('a');
                     var $option = $('<option>')

+ 1 - 3
jet/templates/admin/base.html

@@ -45,9 +45,7 @@
     {% if not is_popup %}
     <!-- Header -->
     <div id="header">
-        <div id="branding">
-        {% block branding %}{% endblock %}
-        </div>
+        <div id="branding">{% block branding %}{% endblock %}</div>
         {% block usertools %}
         {% if user.is_active and user.is_staff or has_permission %}
         <div id="user-tools">

+ 13 - 5
jet/templatetags/jet_tags.py

@@ -9,7 +9,8 @@ from django.utils.formats import get_format
 from django.utils.safestring import mark_safe
 from jet import settings, VERSION
 from jet.models import Bookmark, PinnedApplication
-from jet.utils import get_app_list, get_model_instance_label, get_model_queryset, get_possible_language_codes
+from jet.utils import get_app_list, get_model_instance_label, get_model_queryset, get_possible_language_codes, \
+    get_admin_site
 
 try:
     from urllib.parse import parse_qsl
@@ -55,8 +56,13 @@ def jet_get_menu(context):
             app['models'] = []
 
         app_list = []
+        settings_app_list = settings.JET_SIDE_MENU_CUSTOM_APPS
 
-        for item in settings.JET_SIDE_MENU_CUSTOM_APPS:
+        if isinstance(settings_app_list, dict):
+            admin_site = get_admin_site(context)
+            settings_app_list = settings_app_list.get(admin_site.name, [])
+
+        for item in settings_app_list:
             app_label, models = item
 
             if app_label in app_dict:
@@ -76,7 +82,7 @@ def jet_get_menu(context):
 
     current_found = False
 
-    pinned = PinnedApplication.objects.values_list('app_label', flat=True)
+    pinned = PinnedApplication.objects.filter(user=context.get('user').pk).values_list('app_label', flat=True)
 
     all_aps = []
     apps = []
@@ -213,7 +219,8 @@ def jet_sibling_object_url(context, next):
     model = type(original)
     preserved_filters_plain = context.get('preserved_filters', '')
     preserved_filters = dict(parse_qsl(preserved_filters_plain))
-    queryset = get_model_queryset(model, preserved_filters=preserved_filters)
+    admin_site = get_admin_site(context)
+    queryset = get_model_queryset(admin_site, model, preserved_filters=preserved_filters)
 
     sibling_object = None
     object_pks = list(queryset.values_list('pk', flat=True))
@@ -229,7 +236,8 @@ def jet_sibling_object_url(context, next):
     if sibling_object is None:
         return
 
-    url = reverse('admin:%s_%s_change' % (
+    url = reverse('%s:%s_%s_change' % (
+        admin_site.name,
         model._meta.app_label,
         model._meta.model_name
     ), args=(sibling_object.pk,))

+ 1 - 1
jet/tests/test_utils.py

@@ -52,7 +52,7 @@ class UtilsTestCase(TestCase):
                 self.assertIsNotNone(app, model.get('name'))
 
     def test_get_admin_site(self):
-        admin_site = get_admin_site('')
+        admin_site = get_admin_site({})
         self.assertIsInstance(admin_site, AdminSite)
 
     def test_lazy_date_time_encoder_dates(self):

+ 13 - 7
jet/utils.py

@@ -46,7 +46,7 @@ class JsonResponse(HttpResponse):
 
 
 def get_app_list(context, order=True):
-    admin_site = get_admin_site(context.get('current_app', ''))
+    admin_site = get_admin_site(context)
     request = context['request']
 
     app_dict = {}
@@ -111,10 +111,15 @@ def get_app_list(context, order=True):
     return app_list
 
 
-def get_admin_site(current_app):
+def get_admin_site(context):
     try:
-        resolver_match = resolve(reverse('%s:index' % current_app))
-        for func_closure in resolver_match.func.func_closure:
+        current_resolver = resolve(context.get('request').path)
+        index_resolver = resolve(reverse('%s:index' % current_resolver.namespaces[0]))
+
+        if hasattr(index_resolver.func, 'admin_site'):
+            return index_resolver.func.admin_site
+
+        for func_closure in index_resolver.func.__closure__:
             if isinstance(func_closure.cell_contents, AdminSite):
                 return func_closure.cell_contents
     except:
@@ -159,10 +164,11 @@ class SuccessMessageMixin(object):
         return self.success_message % cleaned_data
 
 
-def get_model_queryset(model, preserved_filters=None):
-    model_admin = admin.site._registry.get(model)
+def get_model_queryset(admin_site, model, preserved_filters=None):
+    model_admin = admin_site._registry.get(model)
 
-    changelist_url = urlresolvers.reverse('admin:%s_%s_changelist' % (
+    changelist_url = urlresolvers.reverse('%s:%s_%s_changelist' % (
+        admin_site.name,
         model._meta.app_label,
         model._meta.model_name
     ))

+ 2 - 1
package.json

@@ -6,9 +6,10 @@
     "browsernizr": "2.1.0",
     "es6-promise": "3.2.1",
     "gulp": "3.9.1",
+    "gulp-clean-css": "2.0.12",
     "gulp-concat-css": "2.3.0",
-    "gulp-minify-css": "1.2.4",
     "gulp-postcss": "6.1.1",
+    "gulp-replace": "0.5.4",
     "gulp-sass": "2.3.2",
     "gulp-shell": "0.5.2",
     "gulp-sourcemaps": "1.6.0",

+ 1 - 1
setup.py

@@ -30,7 +30,7 @@ setup(
     packages=find_packages(),
     license='GPLv2',
     classifiers=[
-        'Development Status :: 4 - Beta',
+        'Development Status :: 5 - Production/Stable',
         'Framework :: Django',
         'License :: Free for non-commercial use',
         'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',

Some files were not shown because too many files changed in this diff