Compare commits

...

173 Commits

Author SHA1 Message Date
Fabio Caccamo d5c14ef3f4 Updated CHANGELOG and version. 2019-09-27 12:08:25 +02:00
Fabio Caccamo 93dfb07af9 Fixed select2 background color. 2019-09-27 11:59:29 +02:00
Fabio Caccamo 8e734864c2 Merge pull request #69 from lorenzomorandini/select2-theme-color
Autocomplete selected color:
2019-09-27 09:29:31 +02:00
Lorenzo Morandini d1cb3c11aa Autocomplete selected color:
set select2 selected color based on css_header_background_color
2019-09-25 15:00:16 +02:00
Fabio Caccamo 82923f9e98 Optimized language chooser template tag. 2019-09-05 10:15:29 +02:00
Fabio Caccamo 235d51ed9a Updated CHANGELOG. [ci skip] 2019-09-04 11:25:21 +02:00
Fabio Caccamo 1baebf9d62 Added language chooser display option. 2019-09-04 11:24:02 +02:00
Fabio Caccamo 56cdbe5d2f Updated README and CHANGELOG. [ci skip] 2019-09-03 18:58:17 +02:00
Fabio Caccamo 06de101ded Added language chooser. 2019-09-03 18:46:31 +02:00
Fabio Caccamo 59ab83538f Removed FUNDING.yml [ci skip] 2019-07-23 18:24:50 +02:00
Fabio Caccamo b04c17a4fd Updated FUNDING.yml [ci skip] 2019-07-23 18:22:47 +02:00
Fabio Caccamo 5b0490b352 Updated FUNDING.yml [ci skip] 2019-07-23 18:19:27 +02:00
Fabio Caccamo 783464c065 Removed python 3.4 from travis. 2019-07-03 15:49:31 +02:00
Fabio Caccamo 6b3f59788b Updated .travis.yml 2019-07-03 15:18:14 +02:00
Fabio Caccamo 45ab7066cc Merge commit 'bb83f74fb4524b708e3f10f4a0b669b4e80fd70a' 2019-07-03 14:32:04 +02:00
Fabio Caccamo df013b9ba3 Removed README.rst 2019-07-03 14:31:57 +02:00
Fabio Caccamo bb83f74fb4 Create FUNDING.yml 2019-06-03 11:15:23 +02:00
Fabio Caccamo da044864d1 Added Codacy badge to README. [ci skip] 2019-05-20 10:44:31 +02:00
Fabio Caccamo db7c12fdb4 Added CHANGELOG and updated version. [ci skip] 2019-05-09 11:26:03 +02:00
Fabio Caccamo 5b0a5e4c46 Merge pull request #62 from pooyamb/master
Fix #52: Broken migration on postgres/windows
2019-05-09 10:41:27 +02:00
Pouya Mobasher Behrouz 0f1dde545e Fix #52: Broken migration on postgres/windows 2019-05-07 18:44:00 +04:30
Fabio Caccamo b45e357418 Updated .travis 2019-04-29 18:44:29 +02:00
Fabio Caccamo fa6c79c367 Updated .travis 2019-04-29 18:37:34 +02:00
Fabio Caccamo 760609cafd Updated .travis 2019-04-29 18:27:26 +02:00
Fabio Caccamo cb3443aa4c Added django 2.2 to tox and travis and updated README. 2019-04-29 17:51:51 +02:00
Fabio Caccamo 9384c6db79 Updated version. 2019-04-29 17:36:47 +02:00
Fabio Caccamo 1a800d7d6a Fixed admin duplicated count query. 2019-04-29 17:36:36 +02:00
Fabio Caccamo 352701ae7d Added admin theme caching to remove duplicated queries. Fixed #19 2019-04-29 17:35:24 +02:00
Fabio Caccamo b4d0b4c985 Added django-dynamic-raw-id support - #61 2019-04-29 16:38:28 +02:00
Fabio Caccamo 26e67dab66 Updated app title italian localization. 2019-04-29 16:37:56 +02:00
Fabio Caccamo e604dcdffa Updated version [ci skip] 2019-03-28 12:15:30 +01:00
Fabio Caccamo 9b56343a81 Added idempotent deploy support. 2019-03-28 12:08:17 +01:00
Fabio Caccamo aef2d56fba Updated version. 2019-03-22 11:41:40 +01:00
Fabio Caccamo cb7a358c6c Fixed raw-id-field whith django-admin-interface #58 2019-03-22 11:41:31 +01:00
Fabio Caccamo c8690b316b Updated version. [ci skip] 2019-03-21 10:27:49 +01:00
Fabio Caccamo 91bba7f522 Merge pull request #57 from merwok-forks/master
Update French localization
2019-03-21 10:16:46 +01:00
Éric Araujo 439902dce8 fix typo 2019-03-20 14:15:39 -04:00
Éric Araujo 19854f70a3 update french localization 2019-03-20 14:14:44 -04:00
Fabio Caccamo 8291a65a15 Updated version [ci skip] 2019-03-20 17:58:20 +01:00
Fabio Caccamo 9433287cee Updated messages. 2019-03-20 17:53:25 +01:00
Fabio Caccamo f0a046ff7f Added related modal close button #45 2019-03-20 17:53:03 +01:00
Fabio Caccamo 877c4da5bf Updated fields verbose names. 2019-03-20 12:42:10 +01:00
Fabio Caccamo 229a4ef573 Updated README. [ci skip] 2019-03-20 12:34:29 +01:00
Fabio Caccamo cf5e784550 Updated messages. 2019-03-20 12:34:17 +01:00
Fabio Caccamo e58bbbeacf Added environment options - Fixed #56 2019-03-20 12:33:53 +01:00
Fabio Caccamo 1c2ac2a308 Updated version. [ci skip] 2019-02-21 18:05:09 +01:00
Fabio Caccamo 3133beb82f Enabled travis pip cache. 2019-02-21 17:30:13 +01:00
Fabio Caccamo 18d2281011 Splitted tests to multiple files. 2019-02-21 17:17:59 +01:00
Fabio Caccamo 7d9edddf82 Added env badge to favicon. 2019-02-21 17:16:48 +01:00
Fabio Caccamo 1c335f83e9 Added PyPi downloads badge to README. [ci skip] 2019-02-08 12:01:33 +01:00
Fabio Caccamo 68a9974df8 Updated version. 2019-02-06 17:01:31 +01:00
Fabio Caccamo efb38d5825 Fixed #53 - Cancel button does not work 2019-02-06 17:01:17 +01:00
Fabio Caccamo a48d2175ba Removed django 2.2 from tox and travis. 2019-02-06 17:00:45 +01:00
Fabio Caccamo 8bffc8f82a Added postgres to tox and travis and included django 2.2. 2019-02-06 16:23:22 +01:00
Fabio Caccamo 1870635697 Removed extra white space. [ci skip] 2019-02-06 16:22:27 +01:00
Fabio Caccamo 4e0c4a00e2 Fixed IntegrityError on postgres 2019-02-06 16:21:50 +01:00
Fabio Caccamo 4b055f7ffa Added missing migration - fixed #51 2019-01-11 15:08:52 +01:00
Fabio Caccamo d6f0e5b0da Merge pull request #50 from merwok-forks/add-french-translation
French translation
2019-01-08 17:02:26 +01:00
Éric Araujo 4cf0d8f1b9 add French translation 2019-01-07 11:27:14 -05:00
Éric Araujo cc9b470bfe fix translations 2019-01-07 11:25:55 -05:00
Fabio Caccamo 01d995b031 Added .mo files. 2019-01-07 10:31:52 +01:00
Fabio Caccamo c383adb9a0 Updated version. 2019-01-04 11:56:24 +01:00
Fabio Caccamo 4ad2d87020 Fixed imports order. 2019-01-04 11:56:07 +01:00
Fabio Caccamo 9284594901 Added italian localization. 2019-01-04 11:55:48 +01:00
Fabio Caccamo a3c469f032 Removed useless comment from spanish localization. 2019-01-04 11:55:29 +01:00
Fabio Caccamo 17f71ad803 Merge pull request #48 from softbutterfly/master
Added internationalization and spanish localization
2019-01-04 11:03:52 +01:00
Martín Josemaría 1913af4b7d translatable default title, fix import style in admin.py 2019-01-03 16:01:14 -05:00
Martín Josemaría 8c382f97d1 Removed fuzzy and old msgid for 'Environment' 2019-01-02 16:42:20 -05:00
Martín Josemaría 89fda153de Fix typo in 'Enviroment' fieldset label, added localization for help text in icon field 2019-01-01 21:34:40 -05:00
Martín Josemaría 3fc3fe5912 Update metadata in spanish PO file 2018-12-30 19:23:58 -05:00
Martín Josemaría acdb755071 Added internationalization and spanish localization 2018-12-30 18:47:18 -05:00
Fabio Caccamo c680bb5461 Updated version 2018-11-13 10:19:35 +01:00
Fabio Caccamo ce32a56cdf Fixed #44 - raw_id_fields issue with django 2.1 2018-11-13 10:19:24 +01:00
Fabio Caccamo 7137cbab08 Updated version. 2018-10-24 17:27:55 +02:00
Fabio Caccamo 3f7b1e54e9 Fixed #42 - Related modal does not dismiss on popup response. 2018-10-24 17:27:42 +02:00
Fabio Caccamo cf76fd412e Updated version 2018-10-11 12:11:46 +02:00
Fabio Caccamo ab0afff087 Added automatic check of 3rd party installed apps according to django version. 2018-10-11 12:11:32 +02:00
Fabio Caccamo e3811e2609 Fixed delete modal not dismissed when clicking 'cancel' button. 2018-10-11 12:08:35 +02:00
Fabio Caccamo 47a3d66d5c Enforced django.jQuery usage in popup_response.js 2018-10-11 12:07:02 +02:00
Fabio Caccamo 2700b4ff12 Updated README [ci skip] 2018-10-10 15:51:06 +02:00
Fabio Caccamo 6a1897b95c Updated tests, tox and travis to support django 2.1 and python 3.7. 2018-10-10 15:48:43 +02:00
Fabio Caccamo e5768da21b Fixed tox and travis for django 2.1 testing. 2018-08-31 15:36:42 +02:00
Fabio Caccamo dc8efcbd6b Updated version. 2018-08-31 15:22:06 +02:00
Fabio Caccamo 01c4ad1f06 Added django 2.1 to tox and travis. 2018-08-31 15:21:54 +02:00
Fabio Caccamo 4a848948a0 Added modal to raw_id_fields #37 2018-08-31 15:21:30 +02:00
Fabio Caccamo a96a70400f Cleaned js code [ci skip] 2018-08-31 15:20:21 +02:00
Fabio Caccamo cc0d2a402b Update .gitattributes 2018-06-14 10:27:58 +02:00
Fabio Caccamo 415de9ca66 Update .gitattributes 2018-06-13 16:09:35 +02:00
Fabio Caccamo 7e57885988 Update .gitattributes 2018-06-13 16:04:18 +02:00
Fabio Caccamo 013dcedd37 Delete vendor.yml 2018-06-13 16:03:54 +02:00
Fabio Caccamo b011256370 Update vendor.yml 2018-06-13 15:59:07 +02:00
Fabio Caccamo 752ccbb603 Created vendor.yml 2018-06-13 12:39:14 +02:00
Fabio Caccamo 8612012783 Fixed README license link [ci skip] 2018-03-29 14:57:20 +02:00
Fabio Caccamo f78167b711 Fixed README license link [ci skip] 2018-03-29 14:55:47 +02:00
Fabio Caccamo ef9b7e6d1b Updated travis 2018-03-29 11:45:18 +02:00
Fabio Caccamo 748b95854e Updated tox 2018-03-29 11:38:04 +02:00
Fabio Caccamo 2f10c88375 AddAdded Django 1.11 to .travis 2018-03-07 10:22:20 +01:00
Fabio Caccamo 73c9a54d94 Updated version 2018-02-06 15:31:19 +01:00
Fabio Caccamo eff414b40c Removed old selector fixies 2018-02-06 15:31:09 +01:00
Fabio Caccamo ccbf76dc5a Improved jquery.ui.tabs compatibility 2018-02-06 15:30:29 +01:00
Fabio Caccamo 5b6e83751b Updated README [ci skip] 2018-02-05 12:37:02 +01:00
Fabio Caccamo 572294f646 Updated version 2018-02-05 12:24:54 +01:00
Fabio Caccamo 4e18d36c79 Added django-tabbed-admin style support 2018-02-05 12:24:42 +01:00
Fabio Caccamo ee9994231b Fixed selectors text overflow 2018-02-05 12:23:54 +01:00
Fabio Caccamo fb4cfdb772 Updated version 2018-02-01 14:52:56 +01:00
Fabio Caccamo 8535232598 Merge pull request #32 from founders4schools/django-20-simple-tag
Avoid deprecation warning about assignment_tag
2018-02-01 14:51:08 +01:00
Bruno Alla abbb666eae Avoid deprecation warning about assignment_tag
Even though the try/except is Django 2.0 compatible, it still
accesses the deprecated template tag, and therefore it emits a
warning in the console, whereas it's actually fixed.

I tried to swap the try and the catch, but it doesn't work:
`simple_tag` existed before 1.9 but in a non-compatible form.

I've changed the decorator name we use to match the new Django version,
it should make the codebase more future proof.
2018-02-01 13:35:54 +00:00
Fabio Caccamo d48fc882f1 Updated USWDS fixture [ci skip] 2018-01-31 16:38:08 +01:00
Fabio Caccamo f968bd9ffa Updated README [ci skip] 2018-01-31 16:37:36 +01:00
Fabio Caccamo c0592276de Updated README [ci skip] 2018-01-31 12:36:43 +01:00
Fabio Caccamo 451679d565 Updated version 2018-01-31 12:24:22 +01:00
Fabio Caccamo e579134152 Added enviroment display and customization 2018-01-31 12:24:08 +01:00
Fabio Caccamo 6e57cf558c Updated .gitignore [ci skip] 2018-01-31 12:12:01 +01:00
Fabio Caccamo d00428c30a Tested against django 2.0 2017-12-05 12:14:27 +01:00
Fabio Caccamo 9becccce39 Updated version 2017-11-23 12:10:32 +01:00
Fabio Caccamo 64a9e8371c Updated setup.py 2017-11-23 12:10:19 +01:00
Fabio Caccamo 8a85334f68 Changed related_modal_background_opacity field type from FloatField to CharField 2017-11-23 12:10:06 +01:00
Fabio Caccamo 41a5ba61c8 Fixed migrations pep8 compliance 2017-11-23 12:08:36 +01:00
Fabio Caccamo c780ccfbcf Added Requirements Status badge provided by https://requires.io/ [ci skip] 2017-10-18 15:52:42 +02:00
Fabio Caccamo 6091c886d7 Updated version 2017-10-04 12:10:24 +02:00
Fabio Caccamo d05009ce44 Fixed horizontal and vertical selector style in inlines 2017-10-04 12:09:48 +02:00
Fabio Caccamo ef1eefb084 Fixed ckeditor style in tabular inlines 2017-10-04 12:08:44 +02:00
Fabio Caccamo e57042b1b4 Fixed README.rst badges [ci skip] 2017-09-29 15:26:40 +02:00
Fabio Caccamo 0b0eff8653 Updated version 2017-09-29 15:11:32 +02:00
Fabio Caccamo f6cef18c6b Updated README.rst for pypi 2017-09-29 15:11:18 +02:00
Fabio Caccamo e8522fe3d7 Updated version 2017-09-29 12:25:29 +02:00
Fabio Caccamo fcb8a38e50 Generate long_description in rst (reStructured Text) format on the fly using pandoc. 2017-09-29 12:25:15 +02:00
Fabio Caccamo 6c3a645edd Replaced repeated strings with variables 2017-09-29 12:24:02 +02:00
Fabio Caccamo b9d0ac6dab Updated django-flat-responsive version range. 2017-09-29 12:22:16 +02:00
Fabio Caccamo 3f270b0b75 Removed README.rst 2017-09-29 12:19:43 +02:00
Fabio Caccamo 7bc15ba61e Removed unused context argument 2017-09-29 12:12:44 +02:00
Fabio Caccamo 37bb3ce0df Removed unused arguments and variables 2017-09-29 12:12:01 +02:00
Fabio Caccamo 66b0172195 Removed unused import 2017-09-29 12:11:40 +02:00
Fabio Caccamo ca2f5c549e Fixed inlines style 2017-09-29 12:11:02 +02:00
Fabio Caccamo 21b221f9e9 Removed unused templatetag 2017-09-27 14:58:42 +02:00
Fabio Caccamo 5fcbef3c5b Merge branch 'master' of https://github.com/fabiocaccamo/django-admin-interface 2017-09-27 14:50:41 +02:00
Fabio Caccamo bc9d200461 Added README.rst to MANIFEST.in 2017-09-27 14:47:42 +02:00
Fabio Caccamo 8c903d5f4c Updated version 2017-09-27 14:47:14 +02:00
Fabio Caccamo c253617346 Updated Python code to be PEP8 compliant 2017-09-27 14:47:03 +02:00
Fabio Caccamo ca2b405989 Updated README.rst 2017-09-27 14:37:18 +02:00
Fabio Caccamo 0fd8469d9a Updated version 2017-09-27 14:34:28 +02:00
Fabio Caccamo 5cce94eefc Added README.rst [ci skip] 2017-09-27 14:33:52 +02:00
Fabio Caccamo c4c6a2b0f2 Updated README.md [ci skip] 2017-09-11 11:48:57 +02:00
Fabio Caccamo 73a61080ae Added code-quality badge to README - [ci skip] 2017-09-04 17:19:12 +02:00
Fabio Caccamo 0164e5b791 Fixed fieldset collapse show/hide link style [ci skip] 2017-08-29 12:41:29 +02:00
Fabio Caccamo bb29c637ff Fixed tests error 2017-08-24 18:37:28 +02:00
Fabio Caccamo a8e9fffdac Increased coverage 2017-08-24 18:23:35 +02:00
Fabio Caccamo d81c7fcdd8 Updated version 2017-08-24 14:28:54 +02:00
Fabio Caccamo 4d07e9fec5 Added favicon support #28 2017-08-24 14:28:36 +02:00
Fabio Caccamo 3b982a84c3 Improved coverage 2017-08-24 14:27:34 +02:00
Fabio Caccamo 072fdcdc95 Fixed duplicated admin queries #19 2017-08-24 14:27:01 +02:00
Fabio Caccamo 07c38baa83 Updated version 2017-07-13 18:01:10 +02:00
Fabio Caccamo ed669a88be Fixed django 1.7 and django 1.9 compatibility 2017-07-13 18:00:56 +02:00
Fabio Caccamo 71ad991ba7 Fixed modals closing in older django versions. 2017-07-13 15:53:00 +02:00
Fabio Caccamo 05128a997e Added version parameter to prevent css/js caching. 2017-07-13 15:50:58 +02:00
Fabio Caccamo 92a816b9ae Updated README.md [ci skip] 2017-06-13 12:57:07 +02:00
Fabio Caccamo 4a9b6e5e5c Updated version 2017-06-13 11:45:28 +02:00
Fabio Caccamo 0e69ccdba6 Changed dependencies versions from strict to ranges 2017-06-13 11:45:17 +02:00
Fabio Caccamo 3f9dc0c58e Merge pull request #26 from 18F/uswds-theme
Add USWDS color scheme.
2017-06-13 10:38:12 +02:00
CM Lubinski cbd414485f Add USWDS color scheme.
As a first draft of a U.S. Web Design Standards theme, this selects uses
reasonable colors from its 508-compliant color pallet.
2017-06-12 17:48:42 -04:00
Fabio Caccamo ccb818043c Merge pull request #23 from 18F/bytes2unicode
Add migration to convert bytes to unicode.
2017-06-12 15:50:37 +02:00
Fabio Caccamo 07d4fd65ef Merge pull request #21 from 18F/future-safe
Specify a max_length on all ColorFields.
2017-06-12 15:49:44 +02:00
Fabio Caccamo 4dd7a9dd3d Merge pull request #20 from founders4schools/deprecation-warnings
Fix a Django deprecation warning
2017-06-12 11:42:05 +02:00
CM Lubinski 9ecaa3836c Add migration to convert bytes to unicode.
Python 2 and 3 treat strings differently; in 2 they are bytes and in 3 they
are unicode objects. The Theme fields' attributes were encoded as bytes in the
initial migration (0001) but should be unicode values, leading to a missing
migration whenever the code is ran on Python 3. This changeset "alters" all
the fields to set them to have unicode attributes rather than bytes.

For more context, we've more or less followed the steps outlined here:
https://docs.djangoproject.com/en/1.11/topics/migrations/#supporting-python-2-and-3
2017-06-09 11:41:15 -04:00
Bruno Alla 511ad909bf Run tests on Python 3.6 for Django 1.11+ 2017-06-09 16:27:13 +01:00
CM Lubinski 8fe6ffd3b2 Specify a max_length on all ColorFields.
Django-colorfield bumped up its default max_length from 10 to 18 characters in
bfe421b8. Though we've pinned the version of colorfields we're depending on,
we can make the future version upgrade easier now by locking our fields to
having a max length of 10 chars.
2017-06-09 11:26:46 -04:00
Bruno Alla d0f8d7514a Fix allow_failures 2017-06-09 15:56:05 +01:00
Bruno Alla 78d80bc129 Run tests against Django master 2017-06-09 15:49:54 +01:00
Bruno Alla 09bd082759 Fix the error on older versions of Django 2017-06-09 15:44:23 +01:00
Bruno Alla 70b4be757d Fix a Django deprecation warning
Replace deprecated assignment_tag:

`python/lib/python3.5/site-packages/admin_interface/templatetags/admin_interface_tags.py:11: RemovedInDjango20Warning: assignment_tag() is deprecated. Use simple_tag() instead`
2017-06-09 15:12:00 +01:00
Fabio Caccamo 486bfa9aba Updated version 2017-06-09 11:58:26 +02:00
Fabio Caccamo e19cd51803 Added per-request cache to get_admin_interface_theme template tag #19 2017-06-09 11:58:10 +02:00
Fabio Caccamo 2d8eeee425 Updated README [ci skip] 2017-05-24 12:46:42 +02:00
62 changed files with 4014 additions and 498 deletions
+2 -1
View File
@@ -1 +1,2 @@
admin_interface/static/ckeditor/* linguist-vendored admin_interface/static/admin_interface/magnific-popup/* linguist-vendored=true
admin_interface/static/ckeditor/* linguist-vendored=true
+2 -1
View File
@@ -44,7 +44,6 @@ coverage.xml
*,cover *,cover
# Translations # Translations
*.mo
*.pot *.pot
# Django stuff: # Django stuff:
@@ -55,3 +54,5 @@ docs/_build/
# PyBuilder # PyBuilder
target/ target/
screenshots
TODO.txt
+93 -15
View File
@@ -1,22 +1,100 @@
sudo: required
language: python language: python
python: 3.5 python: 3.5
cache: pip
env: env:
- TOX_ENV=py27-17 - TOX_ENV=py27-dj17-sqlite
- TOX_ENV=py27-18 - TOX_ENV=py27-dj17-postgres
- TOX_ENV=py27-19 - TOX_ENV=py27-dj18-sqlite
- TOX_ENV=py27-110 - TOX_ENV=py27-dj18-postgres
- TOX_ENV=py34-17 - TOX_ENV=py27-dj19-sqlite
- TOX_ENV=py34-18 - TOX_ENV=py27-dj19-postgres
- TOX_ENV=py34-19 - TOX_ENV=py27-dj110-sqlite
- TOX_ENV=py34-110 - TOX_ENV=py27-dj110-postgres
- TOX_ENV=py35-18 - TOX_ENV=py27-dj111-sqlite
- TOX_ENV=py35-19 - TOX_ENV=py27-dj111-postgres
- TOX_ENV=py35-110 # - TOX_ENV=py34-dj17-sqlite
#- TOX_ENV=py36-18 # - TOX_ENV=py34-dj17-postgres
#- TOX_ENV=py36-19 # - TOX_ENV=py34-dj18-sqlite
#- TOX_ENV=py36-110 # - TOX_ENV=py34-dj18-postgres
# - TOX_ENV=py34-dj19-sqlite
# - TOX_ENV=py34-dj19-postgres
# - TOX_ENV=py34-dj110-sqlite
# - TOX_ENV=py34-dj110-postgres
# - TOX_ENV=py34-dj111-sqlite
# - TOX_ENV=py34-dj111-postgres
# - TOX_ENV=py34-dj20-sqlite
# - TOX_ENV=py34-dj20-postgres
- TOX_ENV=py35-dj18-sqlite
- TOX_ENV=py35-dj18-postgres
- TOX_ENV=py35-dj19-sqlite
- TOX_ENV=py35-dj19-postgres
- TOX_ENV=py35-dj110-sqlite
- TOX_ENV=py35-dj110-postgres
- TOX_ENV=py35-dj111-sqlite
- TOX_ENV=py35-dj111-postgres
- TOX_ENV=py35-dj20-sqlite
- TOX_ENV=py35-dj20-postgres
- TOX_ENV=py35-dj21-sqlite
- TOX_ENV=py35-dj21-postgres
# - TOX_ENV=py35-dj22-sqlite
- TOX_ENV=py35-dj22-postgres
matrix:
include:
- python: "3.6"
env: TOX_ENV=py36-dj111-sqlite
- python: "3.6"
env: TOX_ENV=py36-dj111-postgres
- python: "3.6"
env: TOX_ENV=py36-dj20-sqlite
- python: "3.6"
env: TOX_ENV=py36-dj20-postgres
- python: "3.6"
env: TOX_ENV=py36-dj21-sqlite
- python: "3.6"
env: TOX_ENV=py36-dj21-postgres
- python: "3.6"
env: TOX_ENV=py36-dj22-sqlite
- python: "3.6"
env: TOX_ENV=py36-dj22-postgres
- python: "3.6"
env: TOX_ENV=py36-djmaster-sqlite
- python: "3.6"
env: TOX_ENV=py36-djmaster-postgres
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj20-sqlite
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj20-postgres
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj21-sqlite
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj21-postgres
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj22-sqlite
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj22-postgres
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-djmaster-sqlite
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-djmaster-postgres
allow_failures:
- env: TOX_ENV=py36-djmaster-sqlite
- env: TOX_ENV=py36-djmaster-postgres
- env: TOX_ENV=py37-djmaster-sqlite
- env: TOX_ENV=py37-djmaster-postgres
install: install:
- pip install tox - pip install tox
services:
- postgresql
before_script:
- psql -c 'create database admin_interface;' -U postgres
script: script:
- tox -e $TOX_ENV - tox -e $TOX_ENV
sudo: false
+98
View File
@@ -0,0 +1,98 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.11.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.11.2) - 2019-09-27
- Fixed select2 background color.
## [0.11.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.11.1) - 2019-09-04
- Added language chooser display option.
## [0.11.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.11.0) - 2019-09-03
- Added language chooser.
## [0.10.5](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.10.5) - 2019-05-09
- Fixed broken migration on postgres/windows. #52
## [0.10.4](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.10.4) - 2019-03-29
- Added django 2.2 to tox and travis.
- Fixed admin duplicated count query.
- Added admin theme caching to remove duplicated queries. #19
- Added django-dynamic-raw-id support. #61
- Updated app title italian localization.
## [0.10.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.10.3) - 2019-03-28
- Fixed idempotent deploy support. #40
## [0.10.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.10.2) - 2019-03-22
- Fixed raw-id-field whith django-admin-interface. #58
## [0.10.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.10.1) - 2019-03-20
- Updated french localization.
## [0.10.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.10.0) - 2019-02-21
- Updated messages.
- Added related modal close button. #45
- Updated fields verbose names.
- Added environment options. #56
## [0.9.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.9.3) - 2019-02-06
- Enabled travis pip cache.
- Splitted tests to multiple files.
- Added env badge to favicon.
## [0.9.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.9.2) - 2019-01-11
- Fixed cancel button does not work. #53
- Fixed IntegrityError on postgres
## [0.9.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.9.1) - 2019-01-11
- Fixed missing migration. #51
## [0.9.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.9.0) - 2018-11-13
- Added French localization.
- Added Italian localization.
- Added Spanish localization.
- Added internationalization support.
## [0.8.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.8.2) - 2018-10-24
## [0.8.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.8.1) - 2018-10-11
## [0.8.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.8.0) - 2018-08-31
## [0.7.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.7.0) - 2018-02-06
## [0.6.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.6.3) - 2018-02-05
## [0.6.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.6.2) - 2018-02-01
## [0.6.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.6.1) - 2018-01-31
## [0.6.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.6.0) - 2017-11-23
## [0.5.9](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.5.9) - 2017-10-04
## [0.5.8](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.5.8) - 2017-09-29
## [0.5.7](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.5.7) - 2017-09-29
## [0.5.6](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.5.6) - 2017-09-29
## [0.5.5](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.5.5) - 2017-09-27
## [0.5.4](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.5.4) - 2017-09-27
## [0.5.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.5.3) - 2017-08-24
## [0.5.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.5.2) - 2017-07-13
## [0.5.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.5.1) - 2017-06-13
## [0.5.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.5.0) - 2017-06-09
## [0.4.6](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.4.6) - 2017-05-24
## [0.4.5](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.4.5) - 2017-05-19
## [0.4.4](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.4.4) - 2017-05-18
## [0.4.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.4.3) - 2017-05-16
## [0.4.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.4.2) - 2017-05-11
## [0.4.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.4.1) - 2017-05-04
## [0.4.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.4.0) - 2017-04-14
## [0.3.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.3.2) - 2017-03-29
## [0.3.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.3.1) - 2017-03-29
## [0.3.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.3.0) - 2017-02-09
## [0.2.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.2.1) - 2016-11-08
## [0.2.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.2.0) - 2016-09-10
## [0.1.9](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.1.9) - 2016-09-04
## [0.1.8](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.1.8) - 2016-08-05
## [0.1.7](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.1.7) - 2016-06-29
## [0.1.6](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.1.6) - 2016-04-13
## [0.1.5](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.1.5) - 2016-02-24
## [0.1.4](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.1.4) - 2016-02-15
## [0.1.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.1.3) - 2015-12-03
## [0.1.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.1.2) - 2015-11-25
## [0.1.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.1.1) - 2015-11-13
## [0.0.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.0.1) - 2015-11-13
+51 -12
View File
@@ -1,23 +1,34 @@
[![Build Status](https://travis-ci.org/fabiocaccamo/django-admin-interface.svg?branch=master)](https://travis-ci.org/fabiocaccamo/django-admin-interface) [![Build Status](https://travis-ci.org/fabiocaccamo/django-admin-interface.svg?branch=master)](https://travis-ci.org/fabiocaccamo/django-admin-interface)
[![codecov](https://codecov.io/gh/fabiocaccamo/django-admin-interface/branch/master/graph/badge.svg)](https://codecov.io/gh/fabiocaccamo/django-admin-interface) [![codecov](https://codecov.io/gh/fabiocaccamo/django-admin-interface/branch/master/graph/badge.svg)](https://codecov.io/gh/fabiocaccamo/django-admin-interface)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/21cb657283c04e70b56fb935277a1ad1)](https://www.codacy.com/app/fabiocaccamo/django-admin-interface)
[![PyPI version](https://badge.fury.io/py/django-admin-interface.svg)](https://badge.fury.io/py/django-admin-interface) [![PyPI version](https://badge.fury.io/py/django-admin-interface.svg)](https://badge.fury.io/py/django-admin-interface)
[![PyPI downloads](https://img.shields.io/pypi/dm/django-admin-interface.svg)](https://img.shields.io/pypi/dm/django-admin-interface.svg)
[![Py versions](https://img.shields.io/pypi/pyversions/django-admin-interface.svg)](https://img.shields.io/pypi/pyversions/django-admin-interface.svg) [![Py versions](https://img.shields.io/pypi/pyversions/django-admin-interface.svg)](https://img.shields.io/pypi/pyversions/django-admin-interface.svg)
[![License](https://img.shields.io/pypi/l/django-admin-interface.svg)](https://img.shields.io/pypi/l/django-admin-interface.svg) [![License](https://img.shields.io/pypi/l/django-admin-interface.svg)](https://img.shields.io/pypi/l/django-admin-interface.svg)
# django-admin-interface # django-admin-interface
django-admin-interface is a modern **responsive flat admin interface customizable by the admin itself**. django-admin-interface is a modern **responsive flat admin interface customizable by the admin itself**.
![django-admin-interface-preview](https://user-images.githubusercontent.com/1035294/35631521-64b0cab8-06a4-11e8-8f57-c04fdfbb7e8b.gif)
## Features ## Features
- Beautiful default **django-theme** - Beautiful default **django-theme**
- Themes management and customization *(you can **customize admin title, logo and colors**)* - Themes management and customization *(you can **customize admin title, logo and colors**)*
- Responsive - Responsive
- List filter dropdown *(optional)* - List filter dropdown *(optional)*
- **`NEW`** **Related modal** *(instead of the old popup window, optional)* - `NEW` **Related modal** *(instead of the old popup window, optional)*
- Style optimizations for: `django-ckeditor`, `django-modeltranslation`, `sorl-thumbnail` - `NEW` **Environment name/marker**
- `NEW` **Language chooser**
- Compatibility / Style optimizations for:
- `django-ckeditor`
- `django-dynamic-raw-id`
- `django-modeltranslation`
- `django-tabbed-admin`
- `sorl-thumbnail`
## Requirements ## Requirements
- Python 2.7, 3.4, 3.5, 3.6 - Python 2.7, 3.4, 3.5, 3.6, 3.7
- Django 1.7, 1.8, 1.9, 1.10, 1.11 - Django 1.7, 1.8, 1.9, 1.10, 1.11, 2.0, 2.1, 2.2
## Installation ## Installation
- Run `pip install django-admin-interface` - Run `pip install django-admin-interface`
@@ -26,8 +37,8 @@ django-admin-interface is a modern **responsive flat admin interface customizabl
INSTALLED_APPS = ( INSTALLED_APPS = (
#... #...
'admin_interface', 'admin_interface',
'flat_responsive', 'flat_responsive', # only if django version < 2.0
'flat', #if django version < 1.9 'flat', # only if django version < 1.9
'colorfield', 'colorfield',
#... #...
'django.contrib.admin', 'django.contrib.admin',
@@ -40,10 +51,36 @@ INSTALLED_APPS = (
#### Upgrade #### Upgrade
- Run `pip install django-admin-interface --upgrade` - Run `pip install django-admin-interface --upgrade`
- Run ``python manage.py migrate`` *(add ``--fake-initial`` if you are upgrading from 0.1.0 version)* - Run ``python manage.py migrate`` *(add* ``--fake-initial`` *if you are upgrading from 0.1.0 version)*
- Run ``python manage.py collectstatic --clear`` - Run ``python manage.py collectstatic --clear``
- Restart your application server - Restart your application server
## Optional themes
This package ships with optional themes as fixtures, they can be installed using the [loaddata admin command](https://docs.djangoproject.com/en/1.11/ref/django-admin/#django-admin-loaddata). Optional themes are activated on installation.
##### [Django](https://www.djangoproject.com/) theme (default):
Run ``python manage.py loaddata admin_interface_theme_django.json``
##### [Bootstrap](http://getbootstrap.com/) theme:
Run ``python manage.py loaddata admin_interface_theme_bootstrap.json``
##### [Foundation](http://foundation.zurb.com/) theme:
Run ``python manage.py loaddata admin_interface_theme_foundation.json``
##### [U.S. Web Design Standards](https://standards.usa.gov/) theme:
Run ``python manage.py loaddata admin_interface_theme_uswds.json``
### Add more themes
You can add a theme you've created through the admin to this repository by [sending us a PR](http://makeapullrequest.com/). Here are the steps to follow to add :
1. Export your exact theme as fixture using the `dumpdata` admin command:
``python manage.py dumpdata admin_interface.Theme --indent 4 -o admin_interface_theme_{{name}}.json --pks=N``
2. Copy the generated json file into the fixtures folder *(making sure its name starts with* `admin_interface_theme_` *to avoid clashes with fixtures that might be provided by other third party apps)*.
3. Remove the `"pk"` from the fixture and make sure the `active` field is set to `true` *(in this way a theme is automatically activated when installed)*.
4. Edit the section above to document your theme.
## Screenshots ## Screenshots
###### Admin login ###### Admin login
@@ -58,10 +95,12 @@ INSTALLED_APPS = (
###### Admin theme customization ###### Admin theme customization
![django-admin-interface_theme_customization](https://cloud.githubusercontent.com/assets/1035294/11240250/7350d942-8df1-11e5-9b28-f2f54c333cdc.gif) ![django-admin-interface_theme_customization](https://cloud.githubusercontent.com/assets/1035294/11240250/7350d942-8df1-11e5-9b28-f2f54c333cdc.gif)
#### Thanks ## FAQ
- [django-flat-theme](https://github.com/elky/django-flat-theme/) - #### I already have a custom `base_site.html`, how can I make it work?
- [django-flat-responsive](https://github.com/elky/django-flat-responsive)
- [django-colorfield](https://github.com/jaredly/django-colorfield/) You can use [django-apptemplates](https://github.com/bittner/django-apptemplates), then add `{% extends "admin_interface:admin/base_site.html" %}` to your `base_site.html`
---
## License ## License
Released under [MIT License](LICENSE). Released under [MIT License](LICENSE.txt).
-3
View File
@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from admin_interface.version import __version__
default_app_config = 'admin_interface.apps.AdminInterfaceConfig' default_app_config = 'admin_interface.apps.AdminInterfaceConfig'
+78 -19
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.contrib import admin from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from admin_interface.models import Theme from admin_interface.models import Theme
@@ -9,49 +10,107 @@ class ThemeAdmin(admin.ModelAdmin):
list_display = ('name', 'active', ) list_display = ('name', 'active', )
list_editable = ('active', ) list_editable = ('active', )
list_per_page = 100
show_full_result_count = False
fieldsets = ( fieldsets = (
(None, { (None, {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('name', 'active', ) 'fields': ('name', 'active', )
}), }),
('Logo', { (_('Environment'), {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('logo', 'logo_color', 'logo_visible', ) 'fields': (
'env_name',
'env_color',
'env_visible_in_header',
'env_visible_in_favicon',
)
}), }),
('Title', { (_('Language chooser'), {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('title', 'title_color', 'title_visible', ) 'fields': (
'language_chooser_active',
'language_chooser_display',
)
}), }),
('Header', { (_('Logo'), {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('css_header_background_color', 'css_header_text_color', 'css_header_link_color', 'css_header_link_hover_color', ) 'fields': (
'logo',
'logo_color',
'logo_visible',
)
}), }),
('Breadcrumbs / Module headers', { (_('Favicon'), {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('css_module_background_color', 'css_module_text_color', 'css_module_link_color', 'css_module_link_hover_color', 'css_module_rounded_corners', ) 'fields': ('favicon', )
}), }),
('Generic Links', { (_('Title'), {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('css_generic_link_color', 'css_generic_link_hover_color', ) 'fields': (
'title',
'title_color',
'title_visible',
)
}), }),
('Save Buttons', { (_('Header'), {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('css_save_button_background_color', 'css_save_button_background_hover_color', 'css_save_button_text_color', ) 'fields': (
'css_header_background_color',
'css_header_text_color',
'css_header_link_color',
'css_header_link_hover_color',
)
}), }),
('Delete Buttons', { (_('Breadcrumbs / Module headers'), {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('css_delete_button_background_color', 'css_delete_button_background_hover_color', 'css_delete_button_text_color', ) 'fields': (
'css_module_background_color',
'css_module_text_color',
'css_module_link_color',
'css_module_link_hover_color',
'css_module_rounded_corners',
)
}), }),
('Related Modal', { (_('Generic Links'), {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('related_modal_active', 'related_modal_background_color', 'related_modal_background_opacity', 'related_modal_rounded_corners', ) 'fields': (
'css_generic_link_color',
'css_generic_link_hover_color',
)
}), }),
('List Filter', { (_('Save Buttons'), {
'classes': ('wide', ),
'fields': (
'css_save_button_background_color',
'css_save_button_background_hover_color',
'css_save_button_text_color',
)
}),
(_('Delete Buttons'), {
'classes': ('wide', ),
'fields': (
'css_delete_button_background_color',
'css_delete_button_background_hover_color',
'css_delete_button_text_color',
)
}),
(_('Related Modal'), {
'classes': ('wide', ),
'fields': (
'related_modal_active',
'related_modal_background_color',
'related_modal_background_opacity',
'related_modal_rounded_corners',
'related_modal_close_button_visible',
)
}),
(_('List Filter'), {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('list_filter_dropdown', ) 'fields': ('list_filter_dropdown', )
}), }),
('Recent Actions', { (_('Recent Actions'), {
'classes': ('wide', ), 'classes': ('wide', ),
'fields': ('recent_actions_visible', ) 'fields': ('recent_actions_visible', )
}), }),
@@ -59,5 +118,5 @@ class ThemeAdmin(admin.ModelAdmin):
save_on_top = True save_on_top = True
admin.site.register(Theme, ThemeAdmin)
admin.site.register(Theme, ThemeAdmin)
+6 -2
View File
@@ -2,15 +2,19 @@
from django.apps import AppConfig from django.apps import AppConfig
from django.db.models.signals import post_migrate from django.db.models.signals import post_migrate
from django.utils.translation import ugettext_lazy as _
class AdminInterfaceConfig(AppConfig): class AdminInterfaceConfig(AppConfig):
name = 'admin_interface' name = 'admin_interface'
verbose_name = 'Admin Interface' verbose_name = _('Admin Interface')
def ready(self): def ready(self):
from admin_interface import settings
from admin_interface.models import Theme from admin_interface.models import Theme
post_migrate.connect(Theme.post_migrate_handler, sender = self)
settings.check_installed_apps()
post_migrate.connect(
Theme.post_migrate_handler, sender=self)
+20
View File
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.core.cache import cache, caches
def app_cache():
return caches['admin_interface'] if 'admin_interface' in settings.CACHES else cache
def del_cached_active_theme():
app_cache().delete('admin_interface_theme')
def get_cached_active_theme():
return app_cache().get('admin_interface_theme', None)
def set_cached_active_theme(theme):
app_cache().set('admin_interface_theme', theme)
@@ -0,0 +1,39 @@
[
{
"model": "admin_interface.theme",
"fields": {
"name": "USWDS",
"active": true,
"title": "Django administration",
"title_color": "#FFFFFF",
"title_visible": false,
"logo": "",
"logo_color": "#FFFFFF",
"logo_visible": true,
"css_header_background_color": "#112E51",
"css_header_text_color": "#FFFFFF",
"css_header_link_color": "#FFFFFF",
"css_header_link_hover_color": "#E1F3F8",
"css_module_background_color": "#205493",
"css_module_text_color": "#FFFFFF",
"css_module_link_color": "#FFFFFF",
"css_module_link_hover_color": "#E1F3F8",
"css_module_rounded_corners": true,
"css_generic_link_color": "#205493",
"css_generic_link_hover_color": "#0071BC",
"css_save_button_background_color": "#205493",
"css_save_button_background_hover_color": "#112E51",
"css_save_button_text_color": "#FFFFFF",
"css_delete_button_background_color": "#CD2026",
"css_delete_button_background_hover_color": "#981B1E",
"css_delete_button_text_color": "#FFFFFF",
"css": "",
"related_modal_active": true,
"related_modal_background_color": "#000000",
"related_modal_background_opacity": 0.8,
"related_modal_rounded_corners": true,
"list_filter_dropdown": false,
"recent_actions_visible": true
}
}
]
Binary file not shown.
@@ -0,0 +1,206 @@
# This file is distributed under the same license as the
# django-admin-interface package.
#
# Translators:
# Martin Vuelta <martin.vuelta@softbutterfly.io>, 2018
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: django-admin-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-04 09:18+0000\n"
"PO-Revision-Date: 2018-12-30 19:13-0500\n"
"Last-Translator: Martin Vuelta <martin.vuelta@softbutterfly.io>\n"
"Language-Team: Spanish <dev@softbutterfly.io>\n"
"Language: Spanish \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: admin_interface/admin.py:21
msgid "Environment"
msgstr "Ambiente"
#: admin_interface/admin.py:30
msgid "Language chooser"
msgstr ""
#: admin_interface/admin.py:37
msgid "Logo"
msgstr "Logo"
#: admin_interface/admin.py:45
msgid "Favicon"
msgstr "Favicon"
#: admin_interface/admin.py:49
msgid "Title"
msgstr "Título"
#: admin_interface/admin.py:57
msgid "Header"
msgstr "Encabezado"
#: admin_interface/admin.py:66
msgid "Breadcrumbs / Module headers"
msgstr "Breadcrumbs / Encabezados de módulos"
#: admin_interface/admin.py:76
msgid "Generic Links"
msgstr "Enlaces genéricos"
#: admin_interface/admin.py:83
msgid "Save Buttons"
msgstr "Botones de guardar"
#: admin_interface/admin.py:91
msgid "Delete Buttons"
msgstr "Botones de borrar"
#: admin_interface/admin.py:99
msgid "Related Modal"
msgstr "Modal para objetos relacionados"
#: admin_interface/admin.py:109
msgid "List Filter"
msgstr "Lista de filtros"
#: admin_interface/admin.py:113
msgid "Recent Actions"
msgstr "Acciones recientes"
#: admin_interface/apps.py:11
msgid "Admin Interface"
msgstr "Interfaz de administración"
#: admin_interface/models.py:72 admin_interface/models.py:116
#: admin_interface/models.py:135
msgid "name"
msgstr "Nombre"
#: admin_interface/models.py:75 admin_interface/models.py:132
#: admin_interface/models.py:253
msgid "active"
msgstr "Activo"
#: admin_interface/models.py:79
#: admin_interface/templates/admin/base_site.html:6
#: admin_interface/templates/admin/base_site.html:60
msgid "Django administration"
msgstr "Administración de Django"
#: admin_interface/models.py:81
msgid "title"
msgstr "Título"
#: admin_interface/models.py:87 admin_interface/models.py:102
#: admin_interface/models.py:122
#, fuzzy
#| msgid "logo color"
msgid "color"
msgstr "color de logo"
#: admin_interface/models.py:90 admin_interface/models.py:105
#: admin_interface/models.py:289
msgid "visible"
msgstr "Visible"
#: admin_interface/models.py:95
msgid "Leave blank to use the default Django logo"
msgstr "Dejar en blanco para usaer el logo por defecto de Django"
#: admin_interface/models.py:96
msgid "logo"
msgstr "logo"
#: admin_interface/models.py:110
msgid "(.ico|.png|.gif - 16x16|32x32 px)"
msgstr "Formatos ico, png o gif. Tamaños de 16x16 o 32x32 pixeles"
#: admin_interface/models.py:111
msgid "favicon"
msgstr "favicon"
#: admin_interface/models.py:120
msgid ""
"(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: "
"#3498DB)"
msgstr ""
#: admin_interface/models.py:125
msgid "visible in header (marker and name)"
msgstr ""
#: admin_interface/models.py:128
msgid "visible in favicon (marker)"
msgstr ""
#: admin_interface/models.py:134
msgid "code"
msgstr ""
#: admin_interface/models.py:141
msgid "display"
msgstr ""
#: admin_interface/models.py:148 admin_interface/models.py:173
#: admin_interface/models.py:214 admin_interface/models.py:233
#: admin_interface/models.py:259
msgid "background color"
msgstr "color de fondo"
#: admin_interface/models.py:154 admin_interface/models.py:179
#: admin_interface/models.py:226 admin_interface/models.py:245
#: admin_interface/models.py:249
msgid "text color"
msgstr "color de texto"
#: admin_interface/models.py:160 admin_interface/models.py:185
#: admin_interface/models.py:201
msgid "link color"
msgstr "color de enlace"
#: admin_interface/models.py:166 admin_interface/models.py:191
#: admin_interface/models.py:207
msgid "link hover color"
msgstr "color de enlace (hover)"
#: admin_interface/models.py:194 admin_interface/models.py:279
msgid "rounded corners"
msgstr "esquinas redondas"
#: admin_interface/models.py:220 admin_interface/models.py:239
msgid "background hover color"
msgstr "color de fondo (hover)"
#: admin_interface/models.py:276
msgid "background opacity"
msgstr "opacidad de fondo"
#: admin_interface/models.py:282
msgid "close button visible"
msgstr ""
#: admin_interface/models.py:286
msgid "use dropdown"
msgstr "Usar lista desplegable"
#: admin_interface/models.py:298
msgid "Theme"
msgstr "Tema"
#: admin_interface/models.py:299
msgid "Themes"
msgstr "Temas"
#: admin_interface/templates/admin/filter.html:13
#: admin_interface/templates/admin_interface/dropdown_filter.html:4
#, python-format
msgid " By %(filter_title)s "
msgstr " Por %(filter_title)s "
#: admin_interface/templates/admin/popup_response.html:3
msgid "Popup closing..."
msgstr "Cerando popup..."
Binary file not shown.
@@ -0,0 +1,205 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-04 09:18+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: admin_interface/admin.py:21
msgid "Environment"
msgstr "Environnment"
#: admin_interface/admin.py:30
msgid "Language chooser"
msgstr ""
#: admin_interface/admin.py:37
msgid "Logo"
msgstr "Logo"
#: admin_interface/admin.py:45
msgid "Favicon"
msgstr "Favicon"
#: admin_interface/admin.py:49
msgid "Title"
msgstr "Titre"
#: admin_interface/admin.py:57
msgid "Header"
msgstr "Bannière"
#: admin_interface/admin.py:66
msgid "Breadcrumbs / Module headers"
msgstr "Fil d'ariane / en-têtes de module"
#: admin_interface/admin.py:76
msgid "Generic Links"
msgstr "Liens génériques"
#: admin_interface/admin.py:83
msgid "Save Buttons"
msgstr "Boutons sauvegarder"
#: admin_interface/admin.py:91
msgid "Delete Buttons"
msgstr "Boutons supprimer"
#: admin_interface/admin.py:99
msgid "Related Modal"
msgstr "Modale pour objet reliés"
#: admin_interface/admin.py:109
msgid "List Filter"
msgstr "Filtre de liste"
#: admin_interface/admin.py:113
msgid "Recent Actions"
msgstr "Actions récentes"
#: admin_interface/apps.py:11
msgid "Admin Interface"
msgstr "Interface Admin"
#: admin_interface/models.py:72 admin_interface/models.py:116
#: admin_interface/models.py:135
msgid "name"
msgstr "nom"
#: admin_interface/models.py:75 admin_interface/models.py:132
#: admin_interface/models.py:253
msgid "active"
msgstr "actif"
#: admin_interface/models.py:79
#: admin_interface/templates/admin/base_site.html:6
#: admin_interface/templates/admin/base_site.html:60
msgid "Django administration"
msgstr "Administration Django"
#: admin_interface/models.py:81
msgid "title"
msgstr "titre"
#: admin_interface/models.py:87 admin_interface/models.py:102
#: admin_interface/models.py:122
msgid "color"
msgstr "couleur"
#: admin_interface/models.py:90 admin_interface/models.py:105
#: admin_interface/models.py:289
msgid "visible"
msgstr "visible"
#: admin_interface/models.py:95
msgid "Leave blank to use the default Django logo"
msgstr "Laisser vide pour utiliser le logo Django par défaut"
#: admin_interface/models.py:96
msgid "logo"
msgstr "logo"
#: admin_interface/models.py:110
msgid "(.ico|.png|.gif - 16x16|32x32 px)"
msgstr "(.ico|.png|.gif - 16x16|32x32 px)"
#: admin_interface/models.py:111
msgid "favicon"
msgstr "favicon"
#: admin_interface/models.py:120
msgid ""
"(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: "
"#3498DB)"
msgstr ""
"(rouge: #E74C3C, orange: #E67E22, jaune: #F1C40F, vert: #2ECC71, bleu: "
"#3498DB)"
#: admin_interface/models.py:125
msgid "visible in header (marker and name)"
msgstr "visible dans len-tête (marqueur et nom)"
#: admin_interface/models.py:128
msgid "visible in favicon (marker)"
msgstr "visible dans la favicon (marqueur)"
#: admin_interface/models.py:134
msgid "code"
msgstr ""
#: admin_interface/models.py:141
msgid "display"
msgstr ""
#: admin_interface/models.py:148 admin_interface/models.py:173
#: admin_interface/models.py:214 admin_interface/models.py:233
#: admin_interface/models.py:259
msgid "background color"
msgstr "couleur d'arrière-plan"
#: admin_interface/models.py:154 admin_interface/models.py:179
#: admin_interface/models.py:226 admin_interface/models.py:245
#: admin_interface/models.py:249
msgid "text color"
msgstr "couleur du texte"
#: admin_interface/models.py:160 admin_interface/models.py:185
#: admin_interface/models.py:201
msgid "link color"
msgstr "couleur de lien"
#: admin_interface/models.py:166 admin_interface/models.py:191
#: admin_interface/models.py:207
msgid "link hover color"
msgstr "couleur de lien au survol"
#: admin_interface/models.py:194 admin_interface/models.py:279
msgid "rounded corners"
msgstr "coins arrondis"
#: admin_interface/models.py:220 admin_interface/models.py:239
msgid "background hover color"
msgstr "couleur de fond au survol"
#: admin_interface/models.py:276
msgid "background opacity"
msgstr "opacité de l'arrière-plan"
#: admin_interface/models.py:282
msgid "close button visible"
msgstr "bouton fermer visible"
#: admin_interface/models.py:286
msgid "use dropdown"
msgstr "utiliser un menu déroulant"
#: admin_interface/models.py:298
msgid "Theme"
msgstr "Thème"
#: admin_interface/models.py:299
msgid "Themes"
msgstr "Thèmes"
#: admin_interface/templates/admin/filter.html:13
#: admin_interface/templates/admin_interface/dropdown_filter.html:4
#, python-format
msgid " By %(filter_title)s "
msgstr " Par %(filter_title)s "
#: admin_interface/templates/admin/popup_response.html:3
msgid "Popup closing..."
msgstr "Fermeture de la modale..."
Binary file not shown.
@@ -0,0 +1,206 @@
# This file is distributed under the same license as the
# django-admin-interface package.
#
# Translators:
# Fabio Caccamo <fabio.caccamo@gmail.com>, 2018
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: django-admin-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-04 09:19+0000\n"
"PO-Revision-Date: 2018-12-30 19:13-0500\n"
"Last-Translator: Fabio Caccamo <fabio.caccamo@gmail.com>\n"
"Language-Team: Italian <LL@li.org>\n"
"Language: Italian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: admin_interface/admin.py:21
msgid "Environment"
msgstr "Ambiente"
#: admin_interface/admin.py:30
msgid "Language chooser"
msgstr "Selettore di lingua"
#: admin_interface/admin.py:37
msgid "Logo"
msgstr "Logo"
#: admin_interface/admin.py:45
msgid "Favicon"
msgstr "Favicon"
#: admin_interface/admin.py:49
msgid "Title"
msgstr "Titolo"
#: admin_interface/admin.py:57
msgid "Header"
msgstr "Header"
#: admin_interface/admin.py:66
msgid "Breadcrumbs / Module headers"
msgstr "Breadcrumbs / Header dei moduli"
#: admin_interface/admin.py:76
msgid "Generic Links"
msgstr "Link generici"
#: admin_interface/admin.py:83
msgid "Save Buttons"
msgstr "Pulsanti per salvare"
#: admin_interface/admin.py:91
msgid "Delete Buttons"
msgstr "Pulsanti per eliminare"
#: admin_interface/admin.py:99
msgid "Related Modal"
msgstr "Modale per gli oggetti correlati"
#: admin_interface/admin.py:109
msgid "List Filter"
msgstr "Filtro listato"
#: admin_interface/admin.py:113
msgid "Recent Actions"
msgstr "Azioni recenti"
#: admin_interface/apps.py:11
msgid "Admin Interface"
msgstr "Interfaccia di amministrazione"
#: admin_interface/models.py:72 admin_interface/models.py:116
#: admin_interface/models.py:135
msgid "name"
msgstr "nome"
#: admin_interface/models.py:75 admin_interface/models.py:132
#: admin_interface/models.py:253
msgid "active"
msgstr "attivo"
#: admin_interface/models.py:79
#: admin_interface/templates/admin/base_site.html:6
#: admin_interface/templates/admin/base_site.html:60
msgid "Django administration"
msgstr "Amministrazione di Django"
#: admin_interface/models.py:81
msgid "title"
msgstr "titolo"
#: admin_interface/models.py:87 admin_interface/models.py:102
#: admin_interface/models.py:122
msgid "color"
msgstr "colore"
#: admin_interface/models.py:90 admin_interface/models.py:105
#: admin_interface/models.py:289
msgid "visible"
msgstr "visibile"
#: admin_interface/models.py:95
msgid "Leave blank to use the default Django logo"
msgstr "Lasciare vuoto per usare il logo Django di default"
#: admin_interface/models.py:96
msgid "logo"
msgstr "logo"
#: admin_interface/models.py:110
msgid "(.ico|.png|.gif - 16x16|32x32 px)"
msgstr "(formato ico, png o gif - dimensioni 16x16 o 32x32 px)"
#: admin_interface/models.py:111
msgid "favicon"
msgstr "favicon"
#: admin_interface/models.py:120
msgid ""
"(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: "
"#3498DB)"
msgstr ""
"(rosso: #E74C3C, arancione: #E67E22, giallo: #F1C40F, verde: #2ECC71, blu: "
"#3498DB)"
#: admin_interface/models.py:125
msgid "visible in header (marker and name)"
msgstr "visibile nell'header (marker e nome)"
#: admin_interface/models.py:128
msgid "visible in favicon (marker)"
msgstr "visibile nella favicon (marker)"
#: admin_interface/models.py:134
msgid "code"
msgstr "codice"
#: admin_interface/models.py:141
msgid "display"
msgstr "visualizzazione"
#: admin_interface/models.py:148 admin_interface/models.py:173
#: admin_interface/models.py:214 admin_interface/models.py:233
#: admin_interface/models.py:259
msgid "background color"
msgstr "colore di sfondo"
#: admin_interface/models.py:154 admin_interface/models.py:179
#: admin_interface/models.py:226 admin_interface/models.py:245
#: admin_interface/models.py:249
msgid "text color"
msgstr "colore del testo"
#: admin_interface/models.py:160 admin_interface/models.py:185
#: admin_interface/models.py:201
msgid "link color"
msgstr "colore dei link"
#: admin_interface/models.py:166 admin_interface/models.py:191
#: admin_interface/models.py:207
msgid "link hover color"
msgstr "colore dei link in hover"
#: admin_interface/models.py:194 admin_interface/models.py:279
msgid "rounded corners"
msgstr "bordi arrotondati"
#: admin_interface/models.py:220 admin_interface/models.py:239
msgid "background hover color"
msgstr "colore di sfondo in hover"
#: admin_interface/models.py:276
msgid "background opacity"
msgstr "opacità dello sfondo"
#: admin_interface/models.py:282
msgid "close button visible"
msgstr "pulsante chiudi visibile"
#: admin_interface/models.py:286
msgid "use dropdown"
msgstr "usa dropdown"
#: admin_interface/models.py:298
msgid "Theme"
msgstr "Tema"
#: admin_interface/models.py:299
msgid "Themes"
msgstr "Temi"
#: admin_interface/templates/admin/filter.html:13
#: admin_interface/templates/admin_interface/dropdown_filter.html:4
#, python-format
msgid " By %(filter_title)s "
msgstr " Per %(filter_title)s "
#: admin_interface/templates/admin/popup_response.html:3
msgid "Popup closing..."
msgstr "Chiusura popup..."
+161 -27
View File
@@ -1,7 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
import colorfield.fields import colorfield.fields
@@ -14,33 +16,165 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='Theme', name='Theme',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id',
('name', models.CharField(default=b'Django', max_length=50)), models.AutoField(
('active', models.BooleanField(default=True)), verbose_name='ID',
('title', models.CharField(default=b'Django administration', max_length=50, blank=True)), serialize=False,
('title_visible', models.BooleanField(default=True, verbose_name=b'visible')), auto_created=True,
('logo', models.FileField(upload_to=b'admin-interface/logo/', blank=True)), primary_key=True)),
('logo_visible', models.BooleanField(default=True, verbose_name=b'visible')), ('name',
('css_header_background_color', colorfield.fields.ColorField(default=b'#0C4B33', help_text=b'#0C4B33', max_length=10, verbose_name=b'background color', blank=True)), models.CharField(
('css_header_title_color', colorfield.fields.ColorField(default=b'#F5DD5D', help_text=b'#F5DD5D', max_length=10, verbose_name=b'title color', blank=True)), default=b'Django',
('css_header_text_color', colorfield.fields.ColorField(default=b'#44B78B', help_text=b'#44B78B', max_length=10, verbose_name=b'text color', blank=True)), max_length=50)),
('css_header_link_color', colorfield.fields.ColorField(default=b'#FFFFFF', help_text=b'#FFFFFF', max_length=10, verbose_name=b'link color', blank=True)), ('active',
('css_header_link_hover_color', colorfield.fields.ColorField(default=b'#C9F0DD', help_text=b'#C9F0DD', max_length=10, verbose_name=b'link hover color', blank=True)), models.BooleanField(
('css_module_background_color', colorfield.fields.ColorField(default=b'#44B78B', help_text=b'#44B78B', max_length=10, verbose_name=b'background color', blank=True)), default=True)),
('css_module_text_color', colorfield.fields.ColorField(default=b'#FFFFFF', help_text=b'#FFFFFF', max_length=10, verbose_name=b'text color', blank=True)), ('title',
('css_module_link_color', colorfield.fields.ColorField(default=b'#FFFFFF', help_text=b'#FFFFFF', max_length=10, verbose_name=b'link color', blank=True)), models.CharField(
('css_module_link_hover_color', colorfield.fields.ColorField(default=b'#C9F0DD', help_text=b'#C9F0DD', max_length=10, verbose_name=b'link hover color', blank=True)), default=b'Django administration',
('css_module_rounded_corners', models.BooleanField(default=True, verbose_name=b'rounded corners')), max_length=50,
('css_generic_link_color', colorfield.fields.ColorField(default=b'#0C3C26', help_text=b'#0C3C26', max_length=10, verbose_name=b'link color', blank=True)), blank=True)),
('css_generic_link_hover_color', colorfield.fields.ColorField(default=b'#156641', help_text=b'#156641', max_length=10, verbose_name=b'link hover color', blank=True)), ('title_visible',
('css_save_button_background_color', colorfield.fields.ColorField(default=b'#0C4B33', help_text=b'#0C4B33', max_length=10, verbose_name=b'background color', blank=True)), models.BooleanField(
('css_save_button_background_hover_color', colorfield.fields.ColorField(default=b'#0C3C26', help_text=b'#0C3C26', max_length=10, verbose_name=b'background hover color', blank=True)), default=True,
('css_save_button_text_color', colorfield.fields.ColorField(default=b'#FFFFFF', help_text=b'#FFFFFF', max_length=10, verbose_name=b'text color', blank=True)), verbose_name=b'visible')),
('css_delete_button_background_color', colorfield.fields.ColorField(default=b'#BA2121', help_text=b'#BA2121', max_length=10, verbose_name=b'background color', blank=True)), ('logo',
('css_delete_button_background_hover_color', colorfield.fields.ColorField(default=b'#A41515', help_text=b'#A41515', max_length=10, verbose_name=b'background hover color', blank=True)), models.FileField(
('css_delete_button_text_color', colorfield.fields.ColorField(default=b'#FFFFFF', help_text=b'#FFFFFF', max_length=10, verbose_name=b'text color', blank=True)), upload_to=b'admin-interface/logo/',
('css', models.TextField(blank=True)), blank=True)),
('list_filter_dropdown', models.BooleanField(default=False)), ('logo_visible',
models.BooleanField(
default=True,
verbose_name=b'visible')),
('css_header_background_color',
colorfield.fields.ColorField(
default=b'#0C4B33',
help_text=b'#0C4B33',
max_length=10,
verbose_name=b'background color',
blank=True)),
('css_header_title_color',
colorfield.fields.ColorField(
default=b'#F5DD5D',
help_text=b'#F5DD5D',
max_length=10,
verbose_name=b'title color',
blank=True)),
('css_header_text_color',
colorfield.fields.ColorField(
default=b'#44B78B',
help_text=b'#44B78B',
max_length=10,
verbose_name=b'text color',
blank=True)),
('css_header_link_color',
colorfield.fields.ColorField(
default=b'#FFFFFF',
help_text=b'#FFFFFF',
max_length=10,
verbose_name=b'link color',
blank=True)),
('css_header_link_hover_color',
colorfield.fields.ColorField(
default=b'#C9F0DD',
help_text=b'#C9F0DD',
max_length=10,
verbose_name=b'link hover color',
blank=True)),
('css_module_background_color',
colorfield.fields.ColorField(
default=b'#44B78B',
help_text=b'#44B78B',
max_length=10,
verbose_name=b'background color',
blank=True)),
('css_module_text_color',
colorfield.fields.ColorField(
default=b'#FFFFFF',
help_text=b'#FFFFFF',
max_length=10,
verbose_name=b'text color',
blank=True)),
('css_module_link_color',
colorfield.fields.ColorField(
default=b'#FFFFFF',
help_text=b'#FFFFFF',
max_length=10,
verbose_name=b'link color',
blank=True)),
('css_module_link_hover_color',
colorfield.fields.ColorField(
default=b'#C9F0DD',
help_text=b'#C9F0DD',
max_length=10,
verbose_name=b'link hover color',
blank=True)),
('css_module_rounded_corners',
models.BooleanField(
default=True,
verbose_name=b'rounded corners')),
('css_generic_link_color',
colorfield.fields.ColorField(
default=b'#0C3C26',
help_text=b'#0C3C26',
max_length=10,
verbose_name=b'link color',
blank=True)),
('css_generic_link_hover_color',
colorfield.fields.ColorField(
default=b'#156641',
help_text=b'#156641',
max_length=10,
verbose_name=b'link hover color',
blank=True)),
('css_save_button_background_color',
colorfield.fields.ColorField(
default=b'#0C4B33',
help_text=b'#0C4B33',
max_length=10,
verbose_name=b'background color',
blank=True)),
('css_save_button_background_hover_color',
colorfield.fields.ColorField(
default=b'#0C3C26',
help_text=b'#0C3C26',
max_length=10,
verbose_name=b'background hover color',
blank=True)),
('css_save_button_text_color',
colorfield.fields.ColorField(
default=b'#FFFFFF',
help_text=b'#FFFFFF',
max_length=10,
verbose_name=b'text color',
blank=True)),
('css_delete_button_background_color',
colorfield.fields.ColorField(
default=b'#BA2121',
help_text=b'#BA2121',
max_length=10,
verbose_name=b'background color',
blank=True)),
('css_delete_button_background_hover_color',
colorfield.fields.ColorField(
default=b'#A41515',
help_text=b'#A41515',
max_length=10,
verbose_name=b'background hover color',
blank=True)),
('css_delete_button_text_color',
colorfield.fields.ColorField(
default=b'#FFFFFF',
help_text=b'#FFFFFF',
max_length=10,
verbose_name=b'text color',
blank=True)),
('css',
models.TextField(
blank=True)),
('list_filter_dropdown',
models.BooleanField(
default=False)),
], ],
options={ options={
'verbose_name': 'Theme', 'verbose_name': 'Theme',
@@ -1,7 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import colorfield.fields import colorfield.fields
@@ -15,26 +17,44 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='theme', model_name='theme',
name='list_filter_dropdown', name='list_filter_dropdown',
field=models.BooleanField(default=False, verbose_name=b'use dropdown'), field=models.BooleanField(
default=False,
verbose_name=b'use dropdown'),
), ),
migrations.AddField( migrations.AddField(
model_name='theme', model_name='theme',
name='related_modal_active', name='related_modal_active',
field=models.BooleanField(default=True, verbose_name=b'active'), field=models.BooleanField(
default=True,
verbose_name=b'active'),
), ),
migrations.AddField( migrations.AddField(
model_name='theme', model_name='theme',
name='related_modal_background_color', name='related_modal_background_color',
field=colorfield.fields.ColorField(blank=True, default=b'#000000', help_text=b'#000000', max_length=10, verbose_name=b'background color'), field=colorfield.fields.ColorField(
blank=True,
default=b'#000000',
help_text=b'#000000',
max_length=10,
verbose_name=b'background color'),
), ),
migrations.AddField( migrations.AddField(
model_name='theme', model_name='theme',
name='related_modal_background_opacity', name='related_modal_background_opacity',
field=models.FloatField(choices=[(0.1, b'10%'), (0.2, b'20%'), (0.3, b'30%'), (0.4, b'40%'), (0.5, b'50%'), (0.6, b'60%'), (0.7, b'70%'), (0.8, b'80%'), (0.9, b'90%')], default=0.2, help_text=b'20%', verbose_name=b'background opacity'), field=models.FloatField(
choices=[
(0.1, b'10%'), (0.2, b'20%'), (0.3, b'30%'),
(0.4, b'40%'), (0.5, b'50%'), (0.6, b'60%'),
(0.7, b'70%'), (0.8, b'80%'), (0.9, b'90%')],
default=0.2,
help_text=b'20%',
verbose_name=b'background opacity'),
), ),
migrations.AddField( migrations.AddField(
model_name='theme', model_name='theme',
name='related_modal_rounded_corners', name='related_modal_rounded_corners',
field=models.BooleanField(default=True, verbose_name=b'rounded corners'), field=models.BooleanField(
default=True,
verbose_name=b'rounded corners'),
), ),
] ]
@@ -1,7 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
import colorfield.fields import colorfield.fields
from django.db import migrations, models from django.db import migrations, models
@@ -15,11 +17,19 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='theme', model_name='theme',
name='logo_color', name='logo_color',
field=colorfield.fields.ColorField(blank=True, default='#FFFFFF', help_text='#FFFFFF', max_length=10, verbose_name='logo color'), field=colorfield.fields.ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name='logo color'),
), ),
migrations.AlterField( migrations.AlterField(
model_name='theme', model_name='theme',
name='logo', name='logo',
field=models.FileField(blank=True, help_text='(leave blank to use the default Django logo)', upload_to='admin-interface/logo/'), field=models.FileField(
blank=True,
help_text='(leave blank to use the default Django logo)',
upload_to='admin-interface/logo/'),
), ),
] ]
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations from django.db import migrations
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.11.1 on 2017-05-23 15:37
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
@@ -15,6 +15,8 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='theme', model_name='theme',
name='recent_actions_visible', name='recent_actions_visible',
field=models.BooleanField(default=True, verbose_name='visible'), field=models.BooleanField(
default=True,
verbose_name='visible'),
), ),
] ]
@@ -0,0 +1,266 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import colorfield.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0005_add_recent_actions_visible'),
]
operations = [
migrations.AlterField(
model_name='theme',
name='css_delete_button_background_color',
field=colorfield.fields.ColorField(
blank=True,
default='#BA2121',
help_text='#BA2121',
max_length=10,
verbose_name='background color'),
),
migrations.AlterField(
model_name='theme',
name='css_delete_button_background_hover_color',
field=colorfield.fields.ColorField(
blank=True,
default='#A41515',
help_text='#A41515',
max_length=10,
verbose_name='background hover color'),
),
migrations.AlterField(
model_name='theme',
name='css_delete_button_text_color',
field=colorfield.fields.ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name='text color'),
),
migrations.AlterField(
model_name='theme',
name='css_generic_link_color',
field=colorfield.fields.ColorField(
blank=True,
default='#0C3C26',
help_text='#0C3C26',
max_length=10,
verbose_name='link color'),
),
migrations.AlterField(
model_name='theme',
name='css_generic_link_hover_color',
field=colorfield.fields.ColorField(
blank=True,
default='#156641',
help_text='#156641',
max_length=10,
verbose_name='link hover color'),
),
migrations.AlterField(
model_name='theme',
name='css_header_background_color',
field=colorfield.fields.ColorField(
blank=True,
default='#0C4B33',
help_text='#0C4B33',
max_length=10,
verbose_name='background color'),
),
migrations.AlterField(
model_name='theme',
name='css_header_link_color',
field=colorfield.fields.ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name='link color'),
),
migrations.AlterField(
model_name='theme',
name='css_header_link_hover_color',
field=colorfield.fields.ColorField(
blank=True,
default='#C9F0DD',
help_text='#C9F0DD',
max_length=10,
verbose_name='link hover color'),
),
migrations.AlterField(
model_name='theme',
name='css_header_text_color',
field=colorfield.fields.ColorField(
blank=True,
default='#44B78B',
help_text='#44B78B',
max_length=10,
verbose_name='text color'),
),
migrations.AlterField(
model_name='theme',
name='css_module_background_color',
field=colorfield.fields.ColorField(
blank=True,
default='#44B78B',
help_text='#44B78B',
max_length=10,
verbose_name='background color'),
),
migrations.AlterField(
model_name='theme',
name='css_module_link_color',
field=colorfield.fields.ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name='link color'),
),
migrations.AlterField(
model_name='theme',
name='css_module_link_hover_color',
field=colorfield.fields.ColorField(
blank=True,
default='#C9F0DD',
help_text='#C9F0DD',
max_length=10,
verbose_name='link hover color'),
),
migrations.AlterField(
model_name='theme',
name='css_module_rounded_corners',
field=models.BooleanField(
default=True,
verbose_name='rounded corners'),
),
migrations.AlterField(
model_name='theme',
name='css_module_text_color',
field=colorfield.fields.ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name='text color'),
),
migrations.AlterField(
model_name='theme',
name='css_save_button_background_color',
field=colorfield.fields.ColorField(
blank=True,
default='#0C4B33',
help_text='#0C4B33',
max_length=10,
verbose_name='background color'),
),
migrations.AlterField(
model_name='theme',
name='css_save_button_background_hover_color',
field=colorfield.fields.ColorField(
blank=True,
default='#0C3C26',
help_text='#0C3C26',
max_length=10,
verbose_name='background hover color'),
),
migrations.AlterField(
model_name='theme',
name='css_save_button_text_color',
field=colorfield.fields.ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name='text color'),
),
migrations.AlterField(
model_name='theme',
name='list_filter_dropdown',
field=models.BooleanField(
default=False,
verbose_name='use dropdown'),
),
migrations.AlterField(
model_name='theme',
name='logo_visible',
field=models.BooleanField(
default=True,
verbose_name='visible'),
),
migrations.AlterField(
model_name='theme',
name='name',
field=models.CharField(
default='Django',
max_length=50),
),
migrations.AlterField(
model_name='theme',
name='related_modal_active',
field=models.BooleanField(
default=True,
verbose_name='active'),
),
migrations.AlterField(
model_name='theme',
name='related_modal_background_color',
field=colorfield.fields.ColorField(
blank=True,
default='#000000',
help_text='#000000',
max_length=10,
verbose_name='background color'),
),
migrations.AlterField(
model_name='theme',
name='related_modal_background_opacity',
field=models.FloatField(
choices=[
(0.1, '10%'), (0.2, '20%'), (0.3, '30%'),
(0.4, '40%'), (0.5, '50%'), (0.6, '60%'),
(0.7, '70%'), (0.8, '80%'), (0.9, '90%')],
default=0.2,
help_text='20%',
verbose_name='background opacity'),
),
migrations.AlterField(
model_name='theme',
name='related_modal_rounded_corners',
field=models.BooleanField(
default=True,
verbose_name='rounded corners'),
),
migrations.AlterField(
model_name='theme',
name='title',
field=models.CharField(
blank=True,
default='Django administration',
max_length=50),
),
migrations.AlterField(
model_name='theme',
name='title_color',
field=colorfield.fields.ColorField(
blank=True,
default='#F5DD5D',
help_text='#F5DD5D',
max_length=10,
verbose_name='title color'),
),
migrations.AlterField(
model_name='theme',
name='title_visible',
field=models.BooleanField(
default=True,
verbose_name='visible'),
),
]
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0006_bytes_to_str'),
]
operations = [
migrations.AddField(
model_name='theme',
name='favicon',
field=models.FileField(
blank=True,
help_text='(.ico|.png|.gif - 16x16|32x32 px)',
upload_to='admin-interface/favicon/',
verbose_name='favicon'),
),
]
@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0007_add_favicon'),
]
operations = [
migrations.RemoveField(
model_name='theme',
name='related_modal_background_opacity'
),
migrations.AddField(
model_name='theme',
name='related_modal_background_opacity',
field=models.CharField(
choices=[
('0.1', '10%'), ('0.2', '20%'), ('0.3', '30%'),
('0.4', '40%'), ('0.5', '50%'), ('0.6', '60%'),
('0.7', '70%'), ('0.8', '80%'), ('0.9', '90%')],
default='0.3',
help_text='20%',
max_length=5,
verbose_name='background opacity'),
),
]
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0008_change_related_modal_background_opacity_type'),
]
operations = [
migrations.AddField(
model_name='theme',
name='env',
field=models.CharField(choices=[('development', 'Development'), ('testing', 'Testing'), ('staging', 'Staging'), ('production', 'Production')], default='development', max_length=50, verbose_name='enviroment'),
),
migrations.AddField(
model_name='theme',
name='env_visible',
field=models.BooleanField(default=True, verbose_name='visible'),
),
]
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0009_add_enviroment'),
]
operations = [
migrations.AlterField(
model_name='theme',
name='active',
field=models.BooleanField(default=True, verbose_name='active'),
),
migrations.AlterField(
model_name='theme',
name='css',
field=models.TextField(blank=True, verbose_name='text color'),
),
migrations.AlterField(
model_name='theme',
name='env',
field=models.CharField(choices=[('development', 'Development'), ('testing', 'Testing'), ('staging', 'Staging'), ('production', 'Production')], default='development', max_length=50, verbose_name='environment'),
),
migrations.AlterField(
model_name='theme',
name='logo',
field=models.FileField(blank=True, help_text='Leave blank to use the default Django logo', upload_to='admin-interface/logo/', verbose_name='logo'),
),
migrations.AlterField(
model_name='theme',
name='name',
field=models.CharField(default='Django', max_length=50, verbose_name='name'),
),
migrations.AlterField(
model_name='theme',
name='title',
field=models.CharField(blank=True, default='Django administration', max_length=50, verbose_name='title'),
),
]
@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import colorfield.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0010_add_localization'),
]
operations = [
migrations.RenameField(
model_name='theme',
old_name='env',
new_name='env_name',
),
migrations.AlterField(
model_name='theme',
name='env_name',
field=models.CharField(
blank=True,
max_length=50,
verbose_name='name'),
),
migrations.AddField(
model_name='theme',
name='env_color',
field=colorfield.fields.ColorField(
blank=True,
default='#E74C3C',
help_text='(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: #3498DB)',
max_length=10,
verbose_name='color'),
),
migrations.RenameField(
model_name='theme',
old_name='env_visible',
new_name='env_visible_in_header',
),
migrations.AlterField(
model_name='theme',
name='env_visible_in_header',
field=models.BooleanField(
default=True,
verbose_name='visible in header (marker and name)'),
),
migrations.AddField(
model_name='theme',
name='env_visible_in_favicon',
field=models.BooleanField(
default=True,
verbose_name='visible in favicon (marker)'),
),
]
@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import colorfield.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0011_add_environment_options'),
]
operations = [
migrations.AlterField(
model_name='theme',
name='logo_color',
field=colorfield.fields.ColorField(blank=True, default='#FFFFFF', help_text='#FFFFFF', max_length=10, verbose_name='color'),
),
migrations.AlterField(
model_name='theme',
name='title_color',
field=colorfield.fields.ColorField(blank=True, default='#F5DD5D', help_text='#F5DD5D', max_length=10, verbose_name='color'),
),
]
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0012_update_verbose_names'),
]
operations = [
migrations.AddField(
model_name='theme',
name='related_modal_close_button_visible',
field=models.BooleanField(default=True, verbose_name='close button visible'),
),
]
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0013_add_related_modal_close_button'),
]
operations = [
migrations.AlterField(
model_name='theme',
name='name',
field=models.CharField(default='Django', max_length=50, unique=True, verbose_name='name'),
),
]
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0014_name_unique'),
]
operations = [
migrations.AddField(
model_name='theme',
name='language_chooser_active',
field=models.BooleanField(default=True, verbose_name='active'),
),
]
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0015_add_language_chooser_active'),
]
operations = [
migrations.AddField(
model_name='theme',
name='language_chooser_display',
field=models.CharField(choices=[('code', 'code'), ('name', 'name')], default='code', max_length=10, verbose_name='display'),
),
]
+256 -71
View File
@@ -3,120 +3,305 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models from django.db import models
from django.db.models.signals import post_delete, post_save from django.db.models.signals import post_delete, post_save, pre_save
from django.utils.encoding import python_2_unicode_compatible, force_text from django.utils.encoding import python_2_unicode_compatible, force_text
from django.utils.translation import ugettext_lazy as _
from colorfield.fields import ColorField from colorfield.fields import ColorField
from admin_interface.cache import del_cached_active_theme
@python_2_unicode_compatible @python_2_unicode_compatible
class Theme(models.Model): class Theme(models.Model):
@staticmethod @staticmethod
def post_migrate_handler(sender, **kwargs): def post_migrate_handler(**kwargs):
del_cached_active_theme()
Theme.get_active_theme() Theme.get_active_theme()
@staticmethod @staticmethod
def post_delete_handler(instance, **kwargs): def post_delete_handler(**kwargs):
del_cached_active_theme()
Theme.get_active_theme() Theme.get_active_theme()
@staticmethod @staticmethod
def post_save_handler(instance, created, **kwargs): def post_save_handler(instance, **kwargs):
theme = instance del_cached_active_theme()
if theme.active: if instance.active:
Theme.objects.exclude( pk = theme.pk ).update( active = False ) Theme.objects.exclude(pk=instance.pk).update(active=False)
Theme.get_active_theme() Theme.get_active_theme()
@staticmethod
def pre_save_handler(instance, **kwargs):
if instance.pk is None:
try:
obj = Theme.objects.get(name=instance.name)
if obj:
instance.pk = obj.pk
except Theme.DoesNotExist:
pass
@staticmethod @staticmethod
def get_active_theme(): def get_active_theme():
objs_manager = Theme.objects
objs_active_qs = objs_manager.filter(active=True)
objs_active_ls = list(objs_active_qs)
objs_active_count = len(objs_active_ls)
objs_active_qs = Theme.objects.filter( active = True ) if objs_active_count == 0:
obj = objs_manager.all().first()
if obj:
obj.set_active()
else:
obj = objs_manager.create()
#get or create default theme and enforce default logo if deleted elif objs_active_count == 1:
default_obj_active = (objs_active_qs.count() == 0) obj = objs_active_ls[0]
default_obj, default_obj_created = Theme.objects.get_or_create(pk = '1', defaults = { 'active':default_obj_active })
if not default_obj_created and default_obj_active: elif objs_active_count > 1:
default_obj.set_active() obj = objs_active_ls[-1]
obj = objs_active_qs.last()
objs_active_count = objs_active_qs.count()
if objs_active_count > 1:
obj.set_active() obj.set_active()
return obj return obj
name = models.CharField( max_length = 50, default = 'Django' ) name = models.CharField(
active = models.BooleanField( default = True ) unique=True,
max_length=50,
default='Django',
verbose_name=_('name'))
active = models.BooleanField(
default=True,
verbose_name=_('active'))
title = models.CharField( max_length = 50, default = 'Django administration', blank = True ) title = models.CharField(
title_color = ColorField( blank = True, default = '#F5DD5D', help_text = '#F5DD5D', verbose_name = 'title color' ) max_length=50,
title_visible = models.BooleanField( default = True, verbose_name = 'visible' ) default=_('Django administration'),
blank=True,
verbose_name=_('title'))
title_color = ColorField(
blank=True,
default='#F5DD5D',
help_text='#F5DD5D',
max_length=10,
verbose_name=_('color'))
title_visible = models.BooleanField(
default=True,
verbose_name=_('visible'))
logo = models.FileField( upload_to = 'admin-interface/logo/', blank = True, help_text = '(leave blank to use the default Django logo)' ) logo = models.FileField(
logo_color = ColorField( blank = True, default = '#FFFFFF', help_text = '#FFFFFF', verbose_name = 'logo color' ) upload_to='admin-interface/logo/',
logo_visible = models.BooleanField( default = True, verbose_name = 'visible' ) blank=True,
help_text=_('Leave blank to use the default Django logo'),
verbose_name=_('logo'))
logo_color = ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name=_('color'))
logo_visible = models.BooleanField(
default=True,
verbose_name=_('visible'))
css_header_background_color = ColorField( blank = True, default = '#0C4B33', help_text = '#0C4B33', verbose_name = 'background color' ) favicon = models.FileField(
css_header_text_color = ColorField( blank = True, default = '#44B78B', help_text = '#44B78B', verbose_name = 'text color' ) upload_to='admin-interface/favicon/',
css_header_link_color = ColorField( blank = True, default = '#FFFFFF', help_text = '#FFFFFF', verbose_name = 'link color' ) blank=True,
css_header_link_hover_color = ColorField( blank = True, default = '#C9F0DD', help_text = '#C9F0DD', verbose_name = 'link hover color' ) help_text=_('(.ico|.png|.gif - 16x16|32x32 px)'),
verbose_name=_('favicon'))
css_module_background_color = ColorField( blank = True, default = '#44B78B', help_text = '#44B78B', verbose_name = 'background color' ) env_name = models.CharField(
css_module_text_color = ColorField( blank = True, default = '#FFFFFF', help_text = '#FFFFFF', verbose_name = 'text color' ) blank=True,
css_module_link_color = ColorField( blank = True, default = '#FFFFFF', help_text = '#FFFFFF', verbose_name = 'link color' ) max_length=50,
css_module_link_hover_color = ColorField( blank = True, default = '#C9F0DD', help_text = '#C9F0DD', verbose_name = 'link hover color' ) verbose_name=_('name'))
css_module_rounded_corners = models.BooleanField( default = True, verbose_name = 'rounded corners' ) env_color = ColorField(
blank=True,
default='#E74C3C',
help_text=_('(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: #3498DB)'),
max_length=10,
verbose_name=_('color'))
env_visible_in_header = models.BooleanField(
default=True,
verbose_name=_('visible in header (marker and name)'))
env_visible_in_favicon = models.BooleanField(
default=True,
verbose_name=_('visible in favicon (marker)'))
css_generic_link_color = ColorField( blank = True, default = '#0C3C26', help_text = '#0C3C26', verbose_name = 'link color' ) language_chooser_active = models.BooleanField(
css_generic_link_hover_color = ColorField( blank = True, default = '#156641', help_text = '#156641', verbose_name = 'link hover color' ) default=True,
verbose_name=_('active'))
css_save_button_background_color = ColorField( blank = True, default = '#0C4B33', help_text = '#0C4B33', verbose_name = 'background color' ) language_chooser_display_choices = (
css_save_button_background_hover_color = ColorField( blank = True, default = '#0C3C26', help_text = '#0C3C26', verbose_name = 'background hover color' ) ('code', _('code'), ),
css_save_button_text_color = ColorField( blank = True, default = '#FFFFFF', help_text = '#FFFFFF', verbose_name = 'text color' ) ('name', _('name'), ),
css_delete_button_background_color = ColorField( blank = True, default = '#BA2121', help_text = '#BA2121', verbose_name = 'background color' )
css_delete_button_background_hover_color = ColorField( blank = True, default = '#A41515', help_text = '#A41515', verbose_name = 'background hover color' )
css_delete_button_text_color = ColorField( blank = True, default = '#FFFFFF', help_text = '#FFFFFF', verbose_name = 'text color' )
css = models.TextField( blank = True )
related_modal_active = models.BooleanField( default = True, verbose_name = 'active' )
related_modal_background_color = ColorField( blank = True, default = '#000000', help_text = '#000000', verbose_name = 'background color' )
related_modal_background_opacity_choices = (
(0.1, '10%', ),
(0.2, '20%', ),
(0.3, '30%', ),
(0.4, '40%', ),
(0.5, '50%', ),
(0.6, '60%', ),
(0.7, '70%', ),
(0.8, '80%', ),
(0.9, '90%', ),
) )
related_modal_background_opacity = models.FloatField( choices = related_modal_background_opacity_choices, default = 0.2, help_text = '20%', verbose_name = 'background opacity' ) language_chooser_display = models.CharField(
related_modal_rounded_corners = models.BooleanField( default = True, verbose_name = 'rounded corners' ) max_length=10,
choices=language_chooser_display_choices,
default='code',
verbose_name=_('display'))
list_filter_dropdown = models.BooleanField( default = False, verbose_name = 'use dropdown' ) css_header_background_color = ColorField(
recent_actions_visible = models.BooleanField( default = True, verbose_name = 'visible' ) blank=True,
default='#0C4B33',
help_text='#0C4B33',
max_length=10,
verbose_name=_('background color'))
css_header_text_color = ColorField(
blank=True,
default='#44B78B',
help_text='#44B78B',
max_length=10,
verbose_name=_('text color'))
css_header_link_color = ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name=_('link color'))
css_header_link_hover_color = ColorField(
blank=True,
default='#C9F0DD',
help_text='#C9F0DD',
max_length=10,
verbose_name=_('link hover color'))
css_module_background_color = ColorField(
blank=True,
default='#44B78B',
help_text='#44B78B',
max_length=10,
verbose_name=_('background color'))
css_module_text_color = ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name=_('text color'))
css_module_link_color = ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name=_('link color'))
css_module_link_hover_color = ColorField(
blank=True,
default='#C9F0DD',
help_text='#C9F0DD',
max_length=10,
verbose_name=_('link hover color'))
css_module_rounded_corners = models.BooleanField(
default=True,
verbose_name=_('rounded corners'))
css_generic_link_color = ColorField(
blank=True,
default='#0C3C26',
help_text='#0C3C26',
max_length=10,
verbose_name=_('link color'))
css_generic_link_hover_color = ColorField(
blank=True,
default='#156641',
help_text='#156641',
max_length=10,
verbose_name=_('link hover color'))
css_save_button_background_color = ColorField(
blank=True,
default='#0C4B33',
help_text='#0C4B33',
max_length=10,
verbose_name=_('background color'))
css_save_button_background_hover_color = ColorField(
blank=True,
default='#0C3C26',
help_text='#0C3C26',
max_length=10,
verbose_name=_('background hover color'))
css_save_button_text_color = ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name=_('text color'))
css_delete_button_background_color = ColorField(
blank=True,
default='#BA2121',
help_text='#BA2121',
max_length=10,
verbose_name=_('background color'))
css_delete_button_background_hover_color = ColorField(
blank=True,
default='#A41515',
help_text='#A41515',
max_length=10,
verbose_name=_('background hover color'))
css_delete_button_text_color = ColorField(
blank=True,
default='#FFFFFF',
help_text='#FFFFFF',
max_length=10,
verbose_name=_('text color'))
css = models.TextField(
blank=True,
verbose_name=_('text color'))
related_modal_active = models.BooleanField(
default=True,
verbose_name=_('active'))
related_modal_background_color = ColorField(
blank=True,
default='#000000',
help_text='#000000',
max_length=10,
verbose_name=_('background color'))
related_modal_background_opacity_choices = (
('0.1', '10%', ),
('0.2', '20%', ),
('0.3', '30%', ),
('0.4', '40%', ),
('0.5', '50%', ),
('0.6', '60%', ),
('0.7', '70%', ),
('0.8', '80%', ),
('0.9', '90%', ),
)
related_modal_background_opacity = models.CharField(
max_length=5,
choices=related_modal_background_opacity_choices,
default='0.3',
help_text='20%',
verbose_name=_('background opacity'))
related_modal_rounded_corners = models.BooleanField(
default=True,
verbose_name=_('rounded corners'))
related_modal_close_button_visible = models.BooleanField(
default=True,
verbose_name=_('close button visible'))
list_filter_dropdown = models.BooleanField(
default=False,
verbose_name=_('use dropdown'))
recent_actions_visible = models.BooleanField(
default=True,
verbose_name=_('visible'))
def set_active(self): def set_active(self):
self.active = True self.active = True
self.save() self.save()
class Meta: class Meta:
app_label = 'admin_interface' app_label = 'admin_interface'
verbose_name = 'Theme' verbose_name = _('Theme')
verbose_name_plural = 'Themes' verbose_name_plural = _('Themes')
def __str__(self): def __str__(self):
return force_text(self.name) return force_text(self.name)
post_delete.connect(Theme.post_delete_handler, sender = Theme) post_delete.connect(Theme.post_delete_handler, sender=Theme)
post_save.connect(Theme.post_save_handler, sender = Theme) post_save.connect(Theme.post_save_handler, sender=Theme)
pre_save.connect(Theme.pre_save_handler, sender=Theme)
+37
View File
@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
import django
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
def check_installed_apps():
dj_version = django.VERSION
installed_apps = settings.INSTALLED_APPS
if 'colorfield' not in installed_apps:
raise ImproperlyConfigured(
'\'colorfield\' needed, '
'add it to settings.INSTALLED_APPS.')
if dj_version < (1, 9):
if 'flat' not in installed_apps:
raise ImproperlyConfigured(
'\'flat\' needed before django 1.9, '
'add it to settings.INSTALLED_APPS.')
else:
if 'flat' in installed_apps:
raise ImproperlyConfigured(
'\'flat\' not needed since django 1.9, '
'remove it from settings.INSTALLED_APPS.')
if dj_version < (2, 0):
if 'flat_responsive' not in installed_apps:
raise ImproperlyConfigured(
'\'flat_responsive\' needed before django 2.0, '
'add it to settings.INSTALLED_APPS.')
else:
if 'flat_responsive' in installed_apps:
raise ImproperlyConfigured(
'\'flat_responsive\' not needed since django 2.0, '
'remove it from settings.INSTALLED_APPS.')
+18
View File
@@ -0,0 +1,18 @@
if (typeof(django) !== 'undefined' && typeof(django.jQuery) !== 'undefined') {
(function($) {
'use strict';
$(document).ready(function() {
$('.cancel-link').click(function(e) {
e.preventDefault();
var parentWindow = window.parent;
if (parentWindow && typeof(parentWindow.dismissRelatedObjectModal) === 'function' && parentWindow !== window) {
parentWindow.dismissRelatedObjectModal();
} else {
// fallback to default behavior
window.history.back();
}
return false;
});
});
})(django.jQuery);
}
@@ -1,35 +1,52 @@
/*global opener */
(function() { (function() {
'use strict'; 'use strict';
var windowRef = window;
var windowName = windowRef.name; function getModalWindowData()
var widgetName = windowName.replace(/^(change|add|delete|lookup)_/, ''); {
//var windowNames = windowName.split('____'); var windowRef = window;
//var widgetName = windowNames[(windowNames.length - 1)]; var windowName = windowRef.name;
//widgetName = widgetName.replace(/^(change|add|delete|lookup)_/, ''); var widgetName = windowName.replace(/^(change|add|delete|lookup)_/, '');
//console.log('dismiss modal and update widget with id: "' + widgetName + '"'); var modalRef = {};
var modalRef = {}; var openerRef = windowRef.opener;
var openerRef = windowRef.opener; if (!openerRef) {
if(!openerRef){ openerRef = windowRef.parent;
openerRef = windowRef.parent; modalRef = {
modalRef = { name: openerRef.id_to_windowname(widgetName),
name: openerRef.id_to_windowname(widgetName), close: function(){
close: function(){ openerRef.dismissRelatedObjectModal();
openerRef.dismissRelatedObjectModal(); }
} };
}; }
return { opener:openerRef, modal:modalRef };
} }
var modalData = getModalWindowData();
var modalRef = modalData['modal'];
var openerRef = modalData['opener'];
var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse); var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse);
switch(initData.action){ // console.log(initData);
switch (initData.action) {
case 'change': case 'change':
openerRef.dismissChangeRelatedObjectPopup(modalRef, initData.value, initData.obj, initData.new_value); if (typeof(openerRef.dismissChangeRelatedObjectPopup) === 'function') {
openerRef.dismissChangeRelatedObjectPopup(modalRef, initData.value, initData.obj, initData.new_value);
}
break; break;
case 'delete': case 'delete':
openerRef.dismissDeleteRelatedObjectPopup(modalRef, initData.value); if (typeof(openerRef.dismissDeleteRelatedObjectPopup) === 'function') {
openerRef.dismissDeleteRelatedObjectPopup(modalRef, initData.value);
}
break; break;
default: default:
openerRef.dismissAddRelatedObjectPopup(modalRef, initData.value, initData.obj); if (typeof(openerRef.dismissAddRelatedObjectPopup) === 'function') {
openerRef.dismissAddRelatedObjectPopup(modalRef, initData.value, initData.obj);
}
else if (typeof(openerRef.dismissAddAnotherPopup) === 'function') {
// django 1.7 compatibility
openerRef.dismissAddAnotherPopup(modalRef, initData.value, initData.obj);
}
break; break;
} }
})();
})();
@@ -0,0 +1,913 @@
/**
* @license MIT or GPL-2.0
* @fileOverview Favico animations
* @author Miroslav Magda, http://blog.ejci.net
* @source: https://github.com/ejci/favico.js
* @version 0.3.10
*/
/**
* Create new favico instance
* @param {Object} Options
* @return {Object} Favico object
* @example
* var favico = new Favico({
* bgColor : '#d00',
* textColor : '#fff',
* fontFamily : 'sans-serif',
* fontStyle : 'bold',
* type : 'circle',
* position : 'down',
* animation : 'slide',
* elementId: false,
* element: null,
* dataUrl: function(url){},
* win: window
* });
*/
(function () {
var Favico = (function (opt) {
'use strict';
opt = (opt) ? opt : {};
var _def = {
bgColor: '#d00',
textColor: '#fff',
fontFamily: 'sans-serif', //Arial,Verdana,Times New Roman,serif,sans-serif,...
fontStyle: 'bold', //normal,italic,oblique,bold,bolder,lighter,100,200,300,400,500,600,700,800,900
type: 'circle',
position: 'down', // down, up, left, leftup (upleft)
animation: 'slide',
elementId: false,
element: null,
dataUrl: false,
win: window
};
var _opt, _orig, _h, _w, _canvas, _context, _img, _ready, _lastBadge, _running, _readyCb, _stop, _browser, _animTimeout, _drawTimeout, _doc;
_browser = {};
_browser.ff = typeof InstallTrigger != 'undefined';
_browser.chrome = !!window.chrome;
_browser.opera = !!window.opera || navigator.userAgent.indexOf('Opera') >= 0;
_browser.ie = /*@cc_on!@*/false;
_browser.safari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
_browser.supported = (_browser.chrome || _browser.ff || _browser.opera);
var _queue = [];
_readyCb = function () {
};
_ready = _stop = false;
/**
* Initialize favico
*/
var init = function () {
//merge initial options
_opt = merge(_def, opt);
_opt.bgColor = hexToRgb(_opt.bgColor);
_opt.textColor = hexToRgb(_opt.textColor);
_opt.position = _opt.position.toLowerCase();
_opt.animation = (animation.types['' + _opt.animation]) ? _opt.animation : _def.animation;
_doc = _opt.win.document;
var isUp = _opt.position.indexOf('up') > -1;
var isLeft = _opt.position.indexOf('left') > -1;
//transform the animations
if (isUp || isLeft) {
for (var a in animation.types) {
for (var i = 0; i < animation.types[a].length; i++) {
var step = animation.types[a][i];
if (isUp) {
if (step.y < 0.6) {
step.y = step.y - 0.4;
} else {
step.y = step.y - 2 * step.y + (1 - step.w);
}
}
if (isLeft) {
if (step.x < 0.6) {
step.x = step.x - 0.4;
} else {
step.x = step.x - 2 * step.x + (1 - step.h);
}
}
animation.types[a][i] = step;
}
}
}
_opt.type = (type['' + _opt.type]) ? _opt.type : _def.type;
_orig = link. getIcons();
//create temp canvas
_canvas = document.createElement('canvas');
//create temp image
_img = document.createElement('img');
var lastIcon = _orig[_orig.length - 1];
if (lastIcon.hasAttribute('href')) {
_img.setAttribute('crossOrigin', 'anonymous');
//get width/height
_img.onload = function () {
_h = (_img.height > 0) ? _img.height : 32;
_w = (_img.width > 0) ? _img.width : 32;
_canvas.height = _h;
_canvas.width = _w;
_context = _canvas.getContext('2d');
icon.ready();
};
_img.setAttribute('src', lastIcon.getAttribute('href'));
} else {
_h = 32;
_w = 32;
_img.height = _h;
_img.width = _w;
_canvas.height = _h;
_canvas.width = _w;
_context = _canvas.getContext('2d');
icon.ready();
}
};
/**
* Icon namespace
*/
var icon = {};
/**
* Icon is ready (reset icon) and start animation (if ther is any)
*/
icon.ready = function () {
_ready = true;
icon.reset();
_readyCb();
};
/**
* Reset icon to default state
*/
icon.reset = function () {
//reset
if (!_ready) {
return;
}
_queue = [];
_lastBadge = false;
_running = false;
_context.clearRect(0, 0, _w, _h);
_context.drawImage(_img, 0, 0, _w, _h);
//_stop=true;
link.setIcon(_canvas);
//webcam('stop');
//video('stop');
window.clearTimeout(_animTimeout);
window.clearTimeout(_drawTimeout);
};
/**
* Start animation
*/
icon.start = function () {
if (!_ready || _running) {
return;
}
var finished = function () {
_lastBadge = _queue[0];
_running = false;
if (_queue.length > 0) {
_queue.shift();
icon.start();
} else {
}
};
if (_queue.length > 0) {
_running = true;
var run = function () {
// apply options for this animation
['type', 'animation', 'bgColor', 'textColor', 'fontFamily', 'fontStyle'].forEach(function (a) {
if (a in _queue[0].options) {
_opt[a] = _queue[0].options[a];
}
});
animation.run(_queue[0].options, function () {
finished();
}, false);
};
if (_lastBadge) {
animation.run(_lastBadge.options, function () {
run();
}, true);
} else {
run();
}
}
};
/**
* Badge types
*/
var type = {};
var options = function (opt) {
opt.n = ((typeof opt.n) === 'number') ? Math.abs(opt.n | 0) : opt.n;
opt.x = _w * opt.x;
opt.y = _h * opt.y;
opt.w = _w * opt.w;
opt.h = _h * opt.h;
opt.len = ("" + opt.n).length;
return opt;
};
/**
* Generate circle
* @param {Object} opt Badge options
*/
type.circle = function (opt) {
opt = options(opt);
var more = false;
if (opt.len === 2) {
opt.x = opt.x - opt.w * 0.4;
opt.w = opt.w * 1.4;
more = true;
} else if (opt.len >= 3) {
opt.x = opt.x - opt.w * 0.65;
opt.w = opt.w * 1.65;
more = true;
}
// begin patch
// draw a smaller badge without text
opt.w = 14;
opt.h = 14;
opt.x = (_w - opt.w);
opt.y = (_h - opt.h);
// end patch
_context.clearRect(0, 0, _w, _h);
_context.drawImage(_img, 0, 0, _w, _h);
_context.beginPath();
_context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.85 : 1)) + "px " + _opt.fontFamily;
_context.textAlign = 'center';
if (more) {
_context.moveTo(opt.x + opt.w / 2, opt.y);
_context.lineTo(opt.x + opt.w - opt.h / 2, opt.y);
_context.quadraticCurveTo(opt.x + opt.w, opt.y, opt.x + opt.w, opt.y + opt.h / 2);
_context.lineTo(opt.x + opt.w, opt.y + opt.h - opt.h / 2);
_context.quadraticCurveTo(opt.x + opt.w, opt.y + opt.h, opt.x + opt.w - opt.h / 2, opt.y + opt.h);
_context.lineTo(opt.x + opt.h / 2, opt.y + opt.h);
_context.quadraticCurveTo(opt.x, opt.y + opt.h, opt.x, opt.y + opt.h - opt.h / 2);
_context.lineTo(opt.x, opt.y + opt.h / 2);
_context.quadraticCurveTo(opt.x, opt.y, opt.x + opt.h / 2, opt.y);
} else {
_context.arc(opt.x + opt.w / 2, opt.y + opt.h / 2, opt.h / 2, 0, 2 * Math.PI);
}
_context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')';
_context.fill();
_context.closePath();
_context.beginPath();
_context.stroke();
_context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')';
//_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
if ((typeof opt.n) === 'number' && opt.n > 999) {
_context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000)) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
} else {
_context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
}
_context.closePath();
};
/**
* Generate rectangle
* @param {Object} opt Badge options
*/
type.rectangle = function (opt) {
opt = options(opt);
var more = false;
if (opt.len === 2) {
opt.x = opt.x - opt.w * 0.4;
opt.w = opt.w * 1.4;
more = true;
} else if (opt.len >= 3) {
opt.x = opt.x - opt.w * 0.65;
opt.w = opt.w * 1.65;
more = true;
}
_context.clearRect(0, 0, _w, _h);
_context.drawImage(_img, 0, 0, _w, _h);
_context.beginPath();
_context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.9 : 1)) + "px " + _opt.fontFamily;
_context.textAlign = 'center';
_context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')';
_context.fillRect(opt.x, opt.y, opt.w, opt.h);
_context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')';
//_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
if ((typeof opt.n) === 'number' && opt.n > 999) {
_context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000)) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
} else {
_context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
}
_context.closePath();
};
/**
* Set badge
*/
var badge = function (number, opts) {
opts = ((typeof opts) === 'string' ? {
animation: opts
} : opts) || {};
_readyCb = function () {
try {
if (typeof (number) === 'number' ? (number > 0) : (number !== '')) {
var q = {
type: 'badge',
options: {
n: number
}
};
if ('animation' in opts && animation.types['' + opts.animation]) {
q.options.animation = '' + opts.animation;
}
if ('type' in opts && type['' + opts.type]) {
q.options.type = '' + opts.type;
}
['bgColor', 'textColor'].forEach(function (o) {
if (o in opts) {
q.options[o] = hexToRgb(opts[o]);
}
});
['fontStyle', 'fontFamily'].forEach(function (o) {
if (o in opts) {
q.options[o] = opts[o];
}
});
_queue.push(q);
if (_queue.length > 100) {
throw new Error('Too many badges requests in queue.');
}
icon.start();
} else {
icon.reset();
}
} catch (e) {
throw new Error('Error setting badge. Message: ' + e.message);
}
};
if (_ready) {
_readyCb();
}
};
/**
* Set image as icon
*/
var image = function (imageElement) {
_readyCb = function () {
try {
var w = imageElement.width;
var h = imageElement.height;
var newImg = document.createElement('img');
var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h);
newImg.setAttribute('crossOrigin', 'anonymous');
newImg.onload=function(){
_context.clearRect(0, 0, _w, _h);
_context.drawImage(newImg, 0, 0, _w, _h);
link.setIcon(_canvas);
};
newImg.setAttribute('src', imageElement.getAttribute('src'));
newImg.height = (h / ratio);
newImg.width = (w / ratio);
} catch (e) {
throw new Error('Error setting image. Message: ' + e.message);
}
};
if (_ready) {
_readyCb();
}
};
/**
* Set the icon from a source url. Won't work with badges.
*/
var rawImageSrc = function (url) {
_readyCb = function() {
link.setIconSrc(url);
};
if (_ready) {
_readyCb();
}
};
/**
* Set video as icon
*/
var video = function (videoElement) {
_readyCb = function () {
try {
if (videoElement === 'stop') {
_stop = true;
icon.reset();
_stop = false;
return;
}
//var w = videoElement.width;
//var h = videoElement.height;
//var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h);
videoElement.addEventListener('play', function () {
drawVideo(this);
}, false);
} catch (e) {
throw new Error('Error setting video. Message: ' + e.message);
}
};
if (_ready) {
_readyCb();
}
};
/**
* Set video as icon
*/
var webcam = function (action) {
//UR
if (!window.URL || !window.URL.createObjectURL) {
window.URL = window.URL || {};
window.URL.createObjectURL = function (obj) {
return obj;
};
}
if (_browser.supported) {
var newVideo = false;
navigator.getUserMedia = navigator.getUserMedia || navigator.oGetUserMedia || navigator.msGetUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
_readyCb = function () {
try {
if (action === 'stop') {
_stop = true;
icon.reset();
_stop = false;
return;
}
newVideo = document.createElement('video');
newVideo.width = _w;
newVideo.height = _h;
navigator.getUserMedia({
video: true,
audio: false
}, function (stream) {
newVideo.src = URL.createObjectURL(stream);
newVideo.play();
drawVideo(newVideo);
}, function () {
});
} catch (e) {
throw new Error('Error setting webcam. Message: ' + e.message);
}
};
if (_ready) {
_readyCb();
}
}
};
var setOpt = function (key, value) {
var opts = key;
if (!(value == null && Object.prototype.toString.call(key) == '[object Object]')) {
opts = {};
opts[key] = value;
}
var keys = Object.keys(opts);
for (var i = 0; i < keys.length; i++) {
if (keys[i] == 'bgColor' || keys[i] == 'textColor') {
_opt[keys[i]] = hexToRgb(opts[keys[i]]);
} else {
_opt[keys[i]] = opts[keys[i]];
}
}
_queue.push(_lastBadge);
icon.start();
};
/**
* Draw video to context and repeat :)
*/
function drawVideo(video) {
if (video.paused || video.ended || _stop) {
return false;
}
//nasty hack for FF webcam (Thanks to Julian Ćwirko, kontakt@redsunmedia.pl)
try {
_context.clearRect(0, 0, _w, _h);
_context.drawImage(video, 0, 0, _w, _h);
} catch (e) {
}
_drawTimeout = setTimeout(function () {
drawVideo(video);
}, animation.duration);
link.setIcon(_canvas);
}
var link = {};
/**
* Get icons from HEAD tag or create a new <link> element
*/
link.getIcons = function () {
var elms = [];
//get link element
var getLinks = function () {
var icons = [];
var links = _doc.getElementsByTagName('head')[0].getElementsByTagName('link');
for (var i = 0; i < links.length; i++) {
if ((/(^|\s)icon(\s|$)/i).test(links[i].getAttribute('rel'))) {
icons.push(links[i]);
}
}
return icons;
};
if (_opt.element) {
elms = [_opt.element];
} else if (_opt.elementId) {
//if img element identified by elementId
elms = [_doc.getElementById(_opt.elementId)];
elms[0].setAttribute('href', elms[0].getAttribute('src'));
} else {
//if link element
elms = getLinks();
if (elms.length === 0) {
elms = [_doc.createElement('link')];
elms[0].setAttribute('rel', 'icon');
_doc.getElementsByTagName('head')[0].appendChild(elms[0]);
}
}
elms.forEach(function(item) {
item.setAttribute('type', 'image/png');
});
return elms;
};
link.setIcon = function (canvas) {
var url = canvas.toDataURL('image/png');
link.setIconSrc(url);
};
link.setIconSrc = function (url) {
if (_opt.dataUrl) {
//if using custom exporter
_opt.dataUrl(url);
}
if (_opt.element) {
_opt.element.setAttribute('href', url);
_opt.element.setAttribute('src', url);
} else if (_opt.elementId) {
//if is attached to element (image)
var elm = _doc.getElementById(_opt.elementId);
elm.setAttribute('href', url);
elm.setAttribute('src', url);
} else {
//if is attached to fav icon
if (_browser.ff || _browser.opera) {
//for FF we need to "recreate" element, atach to dom and remove old <link>
//var originalType = _orig.getAttribute('rel');
var old = _orig[_orig.length - 1];
var newIcon = _doc.createElement('link');
_orig = [newIcon];
//_orig.setAttribute('rel', originalType);
if (_browser.opera) {
newIcon.setAttribute('rel', 'icon');
}
newIcon.setAttribute('rel', 'icon');
newIcon.setAttribute('type', 'image/png');
_doc.getElementsByTagName('head')[0].appendChild(newIcon);
newIcon.setAttribute('href', url);
if (old.parentNode) {
old.parentNode.removeChild(old);
}
} else {
_orig.forEach(function(icon) {
icon.setAttribute('href', url);
});
}
}
};
//http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb#answer-5624139
//HEX to RGB convertor
function hexToRgb(hex) {
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function (m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : false;
}
/**
* Merge options
*/
function merge(def, opt) {
var mergedOpt = {};
var attrname;
for (attrname in def) {
mergedOpt[attrname] = def[attrname];
}
for (attrname in opt) {
mergedOpt[attrname] = opt[attrname];
}
return mergedOpt;
}
/**
* Cross-browser page visibility shim
* http://stackoverflow.com/questions/12536562/detect-whether-a-window-is-visible
*/
function isPageHidden() {
return _doc.hidden || _doc.msHidden || _doc.webkitHidden || _doc.mozHidden;
}
/**
* @namespace animation
*/
var animation = {};
/**
* Animation "frame" duration
*/
animation.duration = 40;
/**
* Animation types (none,fade,pop,slide)
*/
animation.types = {};
animation.types.fade = [{
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 0.0
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 0.1
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 0.2
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 0.3
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 0.4
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 0.5
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 0.6
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 0.7
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 0.8
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 0.9
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 1.0
}];
animation.types.none = [{
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 1
}];
animation.types.pop = [{
x: 1,
y: 1,
w: 0,
h: 0,
o: 1
}, {
x: 0.9,
y: 0.9,
w: 0.1,
h: 0.1,
o: 1
}, {
x: 0.8,
y: 0.8,
w: 0.2,
h: 0.2,
o: 1
}, {
x: 0.7,
y: 0.7,
w: 0.3,
h: 0.3,
o: 1
}, {
x: 0.6,
y: 0.6,
w: 0.4,
h: 0.4,
o: 1
}, {
x: 0.5,
y: 0.5,
w: 0.5,
h: 0.5,
o: 1
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 1
}];
animation.types.popFade = [{
x: 0.75,
y: 0.75,
w: 0,
h: 0,
o: 0
}, {
x: 0.65,
y: 0.65,
w: 0.1,
h: 0.1,
o: 0.2
}, {
x: 0.6,
y: 0.6,
w: 0.2,
h: 0.2,
o: 0.4
}, {
x: 0.55,
y: 0.55,
w: 0.3,
h: 0.3,
o: 0.6
}, {
x: 0.50,
y: 0.50,
w: 0.4,
h: 0.4,
o: 0.8
}, {
x: 0.45,
y: 0.45,
w: 0.5,
h: 0.5,
o: 0.9
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 1
}];
animation.types.slide = [{
x: 0.4,
y: 1,
w: 0.6,
h: 0.6,
o: 1
}, {
x: 0.4,
y: 0.9,
w: 0.6,
h: 0.6,
o: 1
}, {
x: 0.4,
y: 0.9,
w: 0.6,
h: 0.6,
o: 1
}, {
x: 0.4,
y: 0.8,
w: 0.6,
h: 0.6,
o: 1
}, {
x: 0.4,
y: 0.7,
w: 0.6,
h: 0.6,
o: 1
}, {
x: 0.4,
y: 0.6,
w: 0.6,
h: 0.6,
o: 1
}, {
x: 0.4,
y: 0.5,
w: 0.6,
h: 0.6,
o: 1
}, {
x: 0.4,
y: 0.4,
w: 0.6,
h: 0.6,
o: 1
}];
/**
* Run animation
* @param {Object} opt Animation options
* @param {Object} cb Callabak after all steps are done
* @param {Object} revert Reverse order? true|false
* @param {Object} step Optional step number (frame bumber)
*/
animation.run = function (opt, cb, revert, step) {
var animationType = animation.types[isPageHidden() ? 'none' : _opt.animation];
if (revert === true) {
step = (typeof step !== 'undefined') ? step : animationType.length - 1;
} else {
step = (typeof step !== 'undefined') ? step : 0;
}
cb = (cb) ? cb : function () {
};
if ((step < animationType.length) && (step >= 0)) {
type[_opt.type](merge(opt, animationType[step]));
_animTimeout = setTimeout(function () {
if (revert) {
step = step - 1;
} else {
step = step + 1;
}
animation.run(opt, cb, revert, step);
}, animation.duration);
link.setIcon(_canvas);
} else {
cb();
return;
}
};
//auto init
init();
return {
badge: badge,
video: video,
image: image,
rawImageSrc: rawImageSrc,
webcam: webcam,
setOpt: setOpt,
reset: icon.reset,
browser: {
supported: _browser.supported
}
};
});
// AMD / RequireJS
if (typeof define !== 'undefined' && define.amd) {
define([], function () {
return Favico;
});
}
// CommonJS
else if (typeof module !== 'undefined' && module.exports) {
module.exports = Favico;
}
// included directly via <script> tag
else {
this.Favico = Favico;
}
})();
File diff suppressed because one or more lines are too long
@@ -1,69 +1,149 @@
if(typeof django !== 'undefined' && typeof django.jQuery !== 'undefined' ) if (typeof(django) !== 'undefined' && typeof(django.jQuery) !== 'undefined')
{ {
(function($) { (function($) {
$(document).ready(function(){ $(document).ready(function(){
// create the function that will close the modal function dismissModal()
function dismissRelatedObjectModal()
{ {
// close the popup
$.magnificPopup.close(); $.magnificPopup.close();
} }
// assign the function to a global variable // create the function that will close the modal
function dismissRelatedObjectModal()
{
dismissModal();
}
function dismissRelatedLookupModal(win, chosenId)
{
var windowRef = win;
var windowName = windowRef.name;
var widgetName = windowName.replace(/^(change|add|delete|lookup)_/, '');
var widgetEl = $('#' + widgetName);
var widgetVal = widgetEl.val();
if (widgetEl.hasClass('vManyToManyRawIdAdminField') && Boolean(widgetVal)) {
widgetEl.val(widgetVal + ', ' + chosenId);
} else {
widgetEl.val(chosenId);
}
dismissModal();
}
// assign functions to global variables
window.dismissRelatedObjectModal = dismissRelatedObjectModal; window.dismissRelatedObjectModal = dismissRelatedObjectModal;
window.dismissRelatedLookupPopup = dismissRelatedLookupModal;
// listen click events on related links function presentRelatedObjectModal(e)
// (:link prevents to listen click event if href is not defined) {
$('a.related-widget-wrapper-link:link').click(function(e){ var linkEl = $(this);
var href = (linkEl.attr('href') || '');
if (href == '') {
return;
}
// open the popup as modal
e.preventDefault(); e.preventDefault();
e.stopImmediatePropagation();
// remove focus from clicked link // remove focus from clicked link
$(this).blur(); linkEl.blur();
// use the clicked link id as iframe name // use the clicked link id as iframe name
// it will be available as window.name in the loaded iframe // it will be available as window.name in the loaded iframe
var iframeName = $(this).attr('id'); var iframeName = linkEl.attr('id');
//var iframeName = String(window.name + '____' + $(this).attr('id')); var iframeSrc = href;
//console.log('open modal with name: "' + iframeName + '"');
// browsers stop loading nested iframes having the same src url if (e.data.lookup !== true)
// create a random parameter and append it to the src url to prevent it {
var iframeSrcRandom = String(Math.round(Math.random() * 999999)); // browsers stop loading nested iframes having the same src url
var iframeSrc = $(this).attr('href') + '&_modal=' + iframeSrcRandom; // create a random parameter and append it to the src url to prevent it
// this workaround doesn't work with related lookup url
var iframeSrcRandom = String(Math.round(Math.random() * 999999));
if (iframeSrc.indexOf('?') === -1) {
iframeSrc += '?_modal=' + iframeSrcRandom;
} else {
iframeSrc += '&_modal=' + iframeSrcRandom;
}
}
// fix for django 1.7
if (iframeSrc.indexOf('_popup=1') === -1) {
if (iframeSrc.indexOf('?') === -1) {
iframeSrc += '?_popup=1';
} else {
iframeSrc += '&_popup=1';
}
}
// build the iframe html // build the iframe html
//var iframeHTML = '<iframe id="related-modal" name="' + iframeName + '" src="' + iframeSrc + '"></iframe>';
var iframeHTML = '<iframe id="related-modal-iframe" name="' + iframeName + '" src="' + iframeSrc + '"></iframe>'; var iframeHTML = '<iframe id="related-modal-iframe" name="' + iframeName + '" src="' + iframeSrc + '"></iframe>';
var modalHTML = '<div class="related-modal-iframe-container">' + iframeHTML + '</div>';
var modalEl = $(modalHTML);
var iframeEl = modalEl.find('#related-modal-iframe');
// create the iframe jquery element if (e.data.lookup === true)
var iframeEl = $(iframeHTML); {
// set current window as iframe opener because
// the callback is called on the opener window
iframeEl.on('load', function() {
var iframeObj = $(this).get(0);
var iframeWindow = iframeObj.contentWindow;
iframeWindow.opener = window;
});
}
// the modal css class // the modal css class
var iframeInternalModalClass = 'related-modal'; var iframeInternalModalClass = 'related-modal';
// if the current window is inside an iframe, it means that it is already in a modal, // if the current window is inside an iframe, it means that it is already in a modal,
// append an additional css class to the modal to offer more customization // append an additional css class to the modal to offer more customization
if( window.top != window.self ) if (window.top != window.self) {
{
iframeInternalModalClass += ' related-modal__nested'; iframeInternalModalClass += ' related-modal__nested';
} }
// open the popup using magnific popup // open the popup using magnific popup
$.magnificPopup.open({ $.magnificPopup.open({
mainClass: iframeInternalModalClass, mainClass: iframeInternalModalClass,
showCloseBtn: true,
closeBtnInside: true,
items: { items: {
src: iframeEl, src: modalEl,
type: 'inline' type: 'inline'
} }
}); });
return false; return false;
}); }
// listen click events on related links
function presentRelatedObjectModalOnClickOn(selector, lookup) {
var data = {
lookup:(lookup === true ? true : false)
};
var el = $(selector);
el.removeAttr('onclick');
el.unbind('click');
el.click(data, presentRelatedObjectModal);
}
// django 1.7 compatibility
// $('a.add-another').removeAttr('onclick').click({ lookup:false }, presentRelatedObjectModal);
presentRelatedObjectModalOnClickOn('a.add-another');
// django 1.8 and above
// $('a.related-widget-wrapper-link').click({ lookup:false }, presentRelatedObjectModal);
presentRelatedObjectModalOnClickOn('a.related-widget-wrapper-link');
// raw_id_fields support
// $('a.related-lookup').unbind('click').click({ lookup:true }, presentRelatedObjectModal);
presentRelatedObjectModalOnClickOn('a.related-lookup', true);
// django-dynamic-raw-id support - #61
// https://github.com/lincolnloop/django-dynamic-raw-id
presentRelatedObjectModalOnClickOn('a.dynamic_raw_id-related-lookup', true);
}); });
})(django.jQuery); })(django.jQuery);
} }
+21 -8
View File
@@ -8,15 +8,21 @@
{% block extrastyle %} {% block extrastyle %}
{% get_admin_interface_theme as theme %} {% get_admin_interface_theme as theme %}
{% get_admin_interface_version as version %}
<style type="text/css"> <style type="text/css">
/*
django-admin-interface {{ version }}
https://github.com/fabiocaccamo/django-admin-interface
*/
{% include "admin_interface/css/admin-interface.css" %} {% include "admin_interface/css/admin-interface.css" %}
{% include "admin_interface/css/admin-interface-fix.css" %} {% include "admin_interface/css/admin-interface-fix.css" %}
{% include "admin_interface/css/list-filter-dropdown.css" %} {% include "admin_interface/css/list-filter-dropdown.css" %}
{% include "admin_interface/css/recent-actions.css" %} {% include "admin_interface/css/recent-actions.css" %}
{% include "admin_interface/css/related-modal.css" %} {% include "admin_interface/css/related-modal.css" %}
{% include "admin_interface/css/jquery.ui.tabs.css" %}
{% include "admin_interface/css/modeltranslation.css" %} {% include "admin_interface/css/modeltranslation.css" %}
{% include "admin_interface/css/sorl-thumbnail.css" %} {% include "admin_interface/css/sorl-thumbnail.css" %}
{% include "admin_interface/css/tabbed-admin.css" %}
{% include "admin_interface/css/ckeditor.css" %} {% include "admin_interface/css/ckeditor.css" %}
{% include "admin_interface/css/tinymce.css" %} {% include "admin_interface/css/tinymce.css" %}
@@ -29,15 +35,13 @@
{% block blockbots %} {% block blockbots %}
{{ block.super }} {{ block.super }}
{% get_admin_interface_theme as theme %}
{% get_admin_interface_version as version %}
{# https://github.com/elky/django-flat-responsive#important-note #} {# https://github.com/elky/django-flat-responsive#important-note #}
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/responsive.css' %}" /> <link rel="stylesheet" type="text/css" href="{% static 'admin/css/responsive.css' %}?v={{ version }}" />
{% get_admin_interface_theme as theme %} {% include "admin_interface/favicon.html" %}
{% if theme.related_modal_active %} {% include "admin_interface/related-modal.html" %}
<link rel="stylesheet" type="text/css" href="{% static 'admin_interface/magnific-popup/magnific-popup.css' %}" />
<script type="text/javascript" src="{% static 'admin_interface/magnific-popup/jquery.magnific-popup.js' %}"></script>
<script type="text/javascript" src="{% static 'admin_interface/related-modal/related-modal.js' %}"></script>
{% endif %}
{% endblock %} {% endblock %}
{% block bodyclass %}admin-interface flat-theme {% get_admin_interface_theme as theme %}{% if theme.name %}{{ theme.name|slugify }}-theme{% endif %}{% endblock %} {% block bodyclass %}admin-interface flat-theme {% get_admin_interface_theme as theme %}{% if theme.name %}{{ theme.name|slugify }}-theme{% endif %}{% endblock %}
@@ -57,3 +61,12 @@
{% endif %} {% endif %}
</h1> </h1>
{% endblock %} {% endblock %}
{% block welcome-msg %}
{% get_admin_interface_theme as theme %}
{% if theme.language_chooser_active %}
{% get_admin_interface_languages as languages %}
{% include "admin_interface/language_chooser.html" %}
{% endif %}
{% if theme.env_visible_in_header %}<span class="environment-label {{ theme.env_name }}"></span> - {% endif %}{{ block.super }}<br>
{% endblock %}
@@ -0,0 +1,15 @@
{% load i18n static %}<!DOCTYPE html>
<html>
<head><title>{% trans 'Popup closing...' %}</title></head>
<body>
<script type="text/javascript"
id="django-admin-popup-response-constants"
src="{% static "admin/js/popup_response.js" %}"
{% if popup_response_data %}
data-popup-response="{{ popup_response_data }}"
{% else %}
data-popup-response='{"action":"{{ action|escape }}","value":"{{ value|escape }}","obj":"{{ obj|escape }}","new_value":"{{ new_value|escape }}"}'
{% endif %}>
</script>
</body>
</html>
@@ -78,14 +78,13 @@
border: 1px solid transparent; border: 1px solid transparent;
} }
.admin-interface fieldset.collapse.collapsed a.collapse-toggle { .admin-interface fieldset.collapse.collapsed a.collapse-toggle,
font-weight: bold;
text-transform: lowercase;
}
.admin-interface fieldset.collapse a.collapse-toggle { .admin-interface fieldset.collapse a.collapse-toggle {
font-weight: bold; font-weight: normal;
text-transform: lowercase; text-transform: lowercase;
font-size: 12px;
text-decoration: underline;
padding: 0 1px;
} }
/* /*
@@ -182,6 +181,11 @@ body.admin-interface .paginator a.showall:visited {
width: auto; width: auto;
padding: 0px; padding: 0px;
} }
/* fix inline horizontal scroll caused by checkbox-row */
.admin-interface form .form-row > div.checkbox-row {
width: 100%;
}
} }
@@ -239,9 +243,17 @@ body.admin-interface .paginator a.showall:visited {
} }
/* end fix */ /* end fix */
.admin-interface .inline-group { /* begin fix restrict tabular-inline horizontal-scroll to inline-group instead of whole page */
.admin-interface .inline-group[data-inline-type="tabular"] {
overflow-x:auto; overflow-x:auto;
} }
/* end fix */
/* begin fix stacked-inline margin-bottom in responsive small viewport */
.admin-interface .inline-group[data-inline-type="stacked"] .module {
margin-bottom:0px;
}
/* end fix */
/* begin fix issue #10 - Related widget broken in long tabular inline */ /* begin fix issue #10 - Related widget broken in long tabular inline */
.admin-interface .inline-group .tabular .related-widget-wrapper { .admin-interface .inline-group .tabular .related-widget-wrapper {
@@ -258,13 +270,22 @@ body.admin-interface .paginator a.showall:visited {
text-align:right; text-align:right;
} }
.admin-interface .inline-group .tabular tr td {
vertical-align: top;
}
.admin-interface .inline-group .tabular tr td.delete { .admin-interface .inline-group .tabular tr td.delete {
text-align:right; text-align:right;
padding-right:15px; padding-right:15px;
vertical-align: top;
}
.admin-interface .inline-group .tabular tr td input[type="checkbox"] {
margin: 7px 0px;
} }
.admin-interface .inline-group .tabular tr td.delete a.inline-deletelink { .admin-interface .inline-group .tabular tr td.delete a.inline-deletelink {
margin-top:2px; margin-top:4px;
overflow:hidden; overflow:hidden;
text-indent:9999px; text-indent:9999px;
} }
@@ -287,60 +308,28 @@ body.admin-interface .paginator a.showall:visited {
width: 100% !important; width: 100% !important;
flex: 0 1 auto; flex: 0 1 auto;
} }
.admin-interface .aligned .form-row input[type="file"] {
width: 100% !important;
}
} }
/* improve responsive selector */ /* improve responsive selector */
.admin-interface .selector.stacked {
width: 480px;
margin-right: 10px;
}
.admin-interface .selector.stacked .selector-chooser { /* fix [stacked, not-stacked] equalize horizontal and vertical select padding for selector */
margin-left: calc(50% - 25px);
}
@media (min-width: 767px) and (max-width: 1124px){
.admin-interface .selector {
width: 610px;
display: block;
}
.admin-interface .selector .selector-available,
.admin-interface .selector .selector-chosen {
width: 285px;
flex: 0 1 auto;
}
.admin-interface .selector .selector-filter {
display: flex;
align-items: center;
}
.admin-interface .selector .selector-filter label {
margin: 0;
}
.admin-interface .selector .selector-available input {
width: auto;
flex: 1 1;
}
.admin-interface .selector select {
width: 100%;
}
}
@media (max-width: 767px){
.admin-interface .selector.stacked {
margin-right: 0px;
}
.admin-interface .selector.stacked .selector-available select {
margin-bottom: 0px;
}
}
/* equalize selectors height by adding the height of the .selector-available filter-bar */
.admin-interface .selector:not(.stacked) .selector-chosen select {
height: calc(46px + 17.2em) !important;
}
/* equalize horizontal and vertical select padding */
.admin-interface .selector .selector-available select, .admin-interface .selector .selector-available select,
.admin-interface .selector .selector-chosen select { .admin-interface .selector .selector-chosen select {
padding: 7px 10px; padding: 7px 10px;
display: block;
}
/* fix [stacked, not-stacked] select options text overflow */
.admin-interface .selector .selector-available select option,
.admin-interface .selector .selector-chosen select option {
overflow: hidden;
text-overflow: ellipsis;
}
/* fix [not-stacked] equalize selectors height by adding the height of the .selector-available filter-bar */
.admin-interface .selector:not(.stacked) .selector-chosen select {
height: calc(46px + 17.2em) !important;
} }
File diff suppressed because one or more lines are too long
@@ -97,10 +97,7 @@ https://github.com/Ikimea/ckeditor-light-theme
@media (max-width: 767px){ @media (max-width: 767px){
.django-ckeditor-widget { .admin-interface .django-ckeditor-widget,
width: 100% !important;
}
.admin-interface .cke { .admin-interface .cke {
width: 100% !important; width: 100% !important;
} }
@@ -117,4 +114,13 @@ https://github.com/Ikimea/ckeditor-light-theme
.admin-interface .cke_contents { .admin-interface .cke_contents {
height: auto; height: auto;
} }
.admin-interface .tabular .django-ckeditor-widget,
.admin-interface .tabular .cke {
width: 400px !important;
}
.admin-interface .tabular .cke_contents {
height: 90px !important;
}
} }
@@ -0,0 +1,144 @@
/*
* jQuery UI CSS Framework
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
* http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/base/jquery.ui.core.css
*/
/*
backward compatibility:
.ui-tabs-selected: jquery ui < 1.10
.ui-tabs-active classes jquery ui >= 1.10
*/
/* Layout helpers
----------------------------------*/
.ui-helper-hidden { display: none; }
.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
.ui-helper-clearfix { display: inline-block; }
/* required comment for clearfix to work in Opera \*/
* html .ui-helper-clearfix { height:1%; }
.ui-helper-clearfix { display:block; }
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
.ui-state-disabled { cursor: default !important; }
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
/* http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/base/jquery.ui.tabs.css */
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
.ui-tabs .ui-tabs-nav li.ui-tabs-active, .ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
.ui-tabs .ui-tabs-hide {
position: absolute;
display: none;
}
/* Custom tabs theme */
.admin-interface .ui-tabs {
padding: 0;
}
.admin-interface .ui-tabs,
.admin-interface .ui-tabs .ui-widget-header,
.admin-interface .ui-tabs .ui-widget-header .ui-state-default {
border: none;
background: transparent;
}
.admin-interface .ui-tabs .ui-tabs-nav {
padding: 10px 0 0 10px;
border-bottom: none;
}
.admin-interface .ui-tabs .ui-tabs-nav li {
margin: 0 0 0 -1px;
}
.admin-interface .ui-tabs .ui-tabs-nav li.required {
font-weight: bold;
}
.admin-interface .ui-tabs .ui-tabs-nav li a {
border: 1px solid #eeeeee;
background-color: #f8f8f8;
border-bottom: none;
color: #666666;
padding: 7px 14px 8px 14px;
margin-top: 1px;
-moz-border-radius-topright: 4px;
-webkit-border-top-right-radius: 4px;
-moz-border-radius-topleft: 4px;
-webkit-border-top-left-radius: 4px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
font-size: 12px;
text-transform: uppercase;
outline: none;
}
.admin-interface .ui-tabs .ui-tabs-nav li.ui-tabs-active a,
.admin-interface .ui-tabs .ui-tabs-nav li.ui-tabs-selected a {
padding: 8px 14px 8px 14px;
margin-top: 0px;
margin-bottom: -1px;
font-weight: bold;
background-color: #FFFFFF;
color: {{ theme.css_module_background_color }};
border-bottom: 1px solid #FFFFFF;
}
.admin-interface .ui-tabs .ui-tabs-panel {
border: 1px solid #eeeeee;
border-radius: 4px;
padding: 10px;
margin-bottom: 30px;
overflow: hidden;
}
.admin-interface .inline-group .tabular .ui-tabs .ui-tabs-panel {
padding: 8px;
}
.admin-interface .inline-group .tabular .ui-tabs .ui-tabs-nav {
padding-left: 4px;
}
.admin-interface .inline-group .tabular tr td {
vertical-align: bottom;
}
.admin-interface .inline-group .tabular tr.has_original td.original,
.admin-interface .inline-group .tabular tr td.delete {
vertical-align: top;
}
.admin-interface .inline-group .tabular .datetime > input {
margin-right: 5px;
}
.admin-interface .inline-group .tabular .datetime br {
display: none;
}
.admin-interface #changelist .row1:not(.selected):hover,
.admin-interface #changelist .row2:not(.selected):hover {
background: #f9f9f9;
}
.admin-interface .row2 {
background: #fcfcfc;
}
.admin-interface .row2 .ui-tabs .ui-tabs-nav li a {
background-color: #f5f5f5;
border: 1px solid #ebebeb;
}
.admin-interface .row2 .ui-tabs .ui-tabs-nav li.ui-tabs-active a,
.admin-interface .row2 .ui-tabs .ui-tabs-nav li.ui-tabs-selected a {
background-color: #fcfcfc;
border-bottom: 1px solid #fcfcfc;
}
@@ -1,65 +1,17 @@
/* /*
django-modeltranslation support django-modeltranslation support
https://github.com/deschler/django-modeltranslation/pull/313/commits https://github.com/deschler/django-modeltranslation
*/ */
.admin-interface #content h1 select { .admin-interface #content h1 select {
text-transform:uppercase; text-transform: uppercase;
margin-left:15px; margin-left: 15px;
min-width: 50px;
} }
.admin-interface .ui-tabs .ui-tabs-nav { .admin-interface .ui-tabs .ui-tabs-panel[id^=tab_id_] {
padding:10px 0 0 10px; border: none;
} border-top: 1px solid #eeeeee;
padding: 0;
.admin-interface .ui-tabs .ui-tabs-nav li { margin-bottom: 0;
margin-left:-1px;
}
.admin-interface .ui-tabs .ui-tabs-nav li a {
outline:none;
background-color:#f8f8f8;
border:1px solid #eeeeee;
border-bottom:none;
text-transform:uppercase;
padding:7px 14px 8px 14px;
margin-top:1px;
}
.admin-interface .ui-tabs .ui-tabs-nav li.ui-tabs-active a,
.admin-interface .ui-tabs .ui-tabs-nav li.ui-tabs-selected a {
padding:8px 14px 8px 14px;
margin-top:0px;
margin-bottom:-1px;
font-weight: bold;
background-color:#FFFFFF;
color:{{ theme.css_module_background_color }};
border-bottom:1px solid #FFFFFF;
}
.admin-interface .inline-group .tabular .ui-tabs .ui-tabs-panel {
padding:8px;
}
.admin-interface #changelist .row1:not(.selected):hover,
.admin-interface #changelist .row2:not(.selected):hover {
background:#f9f9f9;
}
.admin-interface .row2 {
background:#fcfcfc;
}
.admin-interface .row2 .ui-tabs .ui-tabs-nav li a {
background-color:#f5f5f5;
border:1px solid #ebebeb;
}
.admin-interface .row2 .ui-tabs .ui-tabs-nav li.ui-tabs-active a,
.admin-interface .row2 .ui-tabs .ui-tabs-nav li.ui-tabs-selected a {
background-color:#fcfcfc;
border-bottom:1px solid #fcfcfc;
} }
@@ -3,38 +3,56 @@ related modal + magnific popup customization
https://github.com/dimsemenov/Magnific-Popup https://github.com/dimsemenov/Magnific-Popup
*/ */
.admin-interface .related-modal.mfp-bg { .admin-interface .related-modal.mfp-bg {
background-color:{{ theme.related_modal_background_color }}; background-color: {{ theme.related_modal_background_color }};
opacity: {{ theme.related_modal_background_opacity }}; opacity: {{ theme.related_modal_background_opacity }};
} }
.admin-interface .related-modal .mfp-content { .admin-interface .related-modal .mfp-content {
height: 100%; height: 100%;
overflow: hidden;
{% if theme.related_modal_rounded_corners %}
border-radius: 4px;
{% endif %}
-webkit-box-shadow: 0px 5px 30px 0px rgba(0,0,0,0.2); -webkit-box-shadow: 0px 5px 30px 0px rgba(0,0,0,0.2);
-moz-box-shadow: 0px 5px 30px 0px rgba(0,0,0,0.2); -moz-box-shadow: 0px 5px 30px 0px rgba(0,0,0,0.2);
box-shadow: 0px 5px 30px 0px rgba(0,0,0,0.2); box-shadow: 0px 5px 30px 0px rgba(0,0,0,0.2);
} }
.admin-interface .related-modal .mfp-container { .admin-interface .related-modal .mfp-container {
padding: 90px 90px 90px 90px; padding: 80px 80px 80px 80px;
} }
.admin-interface .related-modal__nested .mfp-container { .admin-interface .related-modal__nested .mfp-container {
padding: 30px 60px 30px 60px; padding: 40px 80px 40px 80px;
} }
@media (max-width:640px){ @media (max-width:640px){
.admin-interface .related-modal .mfp-container { .admin-interface .related-modal .mfp-container {
padding: 60px 15px 60px 15px; padding: 80px 20px 80px 20px;
} }
.admin-interface .related-modal__nested .mfp-container { .admin-interface .related-modal__nested .mfp-container {
padding: 30px 30px 30px 30px; padding: 40px 40px 40px 40px;
} }
} }
@media (max-height:640px){
.admin-interface .related-modal .mfp-container {
padding-top: 20px;
padding-bottom: 20px;
}
.admin-interface .related-modal__nested .mfp-container {
padding: 40px 40px 40px 40px;
}
}
.admin-interface .related-modal .related-modal-iframe-container {
display: block;
width: 100%;
height: 100%;
position: relative;
z-index: 100;
overflow: hidden;
{% if theme.related_modal_rounded_corners %}
border-radius: 4px;
{% endif %}
}
.admin-interface .related-modal #related-modal-iframe { .admin-interface .related-modal #related-modal-iframe {
width: 100%; width: 100%;
height: 100%; height: 100%;
@@ -48,3 +66,19 @@ https://github.com/dimsemenov/Magnific-Popup
padding: 0; padding: 0;
display: block; display: block;
} }
.admin-interface .related-modal .mfp-close {
width: 40px;
height: 40px;
opacity: 1.0;
color: rgba(0, 0, 0, 0.4);
{% if not theme.related_modal_close_button_visible %}
display: none;
{% endif %}
}
.admin-interface .related-modal .mfp-close:hover,
.admin-interface .related-modal .mfp-close:active {
color: rgba(0, 0, 0, 0.6);
top: 0;
}
@@ -0,0 +1,37 @@
/*
django-tabbed-admin support
https://github.com/omji/django-tabbed-admin
*/
/* Hide tabs until ready */
/*
.admin-interface #tabs ul {
display: none;
}
.admin-interface #tabs ul.ui-tabs-nav {
display: block;
}
*/
.admin-interface .ui-tabs .ui-tabs-panel[id^=tabs] .module.aligned:last-child {
margin-bottom: 0;
}
.admin-interface .ui-tabs .ui-tabs-panel[id^=tabs] .module.aligned:last-child .form-row:last-child {
border-bottom: none;
}
@media (max-width: 350px){
.admin-interface .ui-tabs .ui-tabs-panel[id^=tabs] .vTextField,
.admin-interface .inline-related .vTextField {
width: 17em;
}
}
@media (max-width: 767px){
/* fix horizontal overflow - responsive.css:563 */
.admin-interface .ui-tabs .ui-tabs-panel[id^=tabs] .aligned .form-row > div:not([class]) {
width: 100% !important;
}
}
@@ -1,4 +1,4 @@
{% load i18n admin_interface_tags %} {% load i18n %}
<div class="list-filter-dropdown"> <div class="list-filter-dropdown">
<h3>{% blocktrans with title as filter_title %} By {{ filter_title }} {% endblocktrans %}</h3> <h3>{% blocktrans with title as filter_title %} By {{ filter_title }} {% endblocktrans %}</h3>
@@ -10,4 +10,3 @@
</select> </select>
</div> </div>
</div> </div>
@@ -0,0 +1,17 @@
{% load static %}
{% if theme.favicon %}
<link rel="icon" type="image/x-icon" href="{{ theme.favicon.url }}?v={{ version }}" />
{% if theme.env_visible_in_favicon %}
<script type="text/javascript" src="{% static 'admin_interface/favico/favico-0.3.10-patched.min.js' %}?v={{ version }}"></script>
<script type="text/javascript">
var favicon = new Favico({
type: 'circle',
bgColor: '{{ theme.env_color }}',
textColor: '#FFFFFF',
animation: 'none'
});
favicon.badge(' ');
</script>
{% endif %}
{% endif %}
@@ -0,0 +1,20 @@
{% load admin_interface_tags %}
{% if languages %}
<div class="language-chooser">
{% for language in languages %}
<form class="language-chooser-hidden-form" id="language-chooser-hidden-form-{{ language.code }}" action="{{ language.activation_url }}" method="POST">
{% csrf_token %}
<input name="language" type="hidden" value="{{ language.code }}" />
</form>
{% endfor %}
<form class="language-chooser-select-form">
{% csrf_token %}
<select name="language" onchange="document.getElementById(String('language-chooser-hidden-form-' + this.value)).submit();">
{% for language in languages %}
<option value="{{ language.code }}" {% if language.active %}selected{% endif %}>{% if theme.language_chooser_display == 'code' %}{{ language.code|upper }}{% elif theme.language_chooser_display == 'name' %}{{ language.name }}{% endif %}</option>
{% endfor %}
</select>
</form>
</div>
{% endif %}
@@ -0,0 +1,7 @@
{% load static %}
{% if theme.related_modal_active %}
<link rel="stylesheet" type="text/css" href="{% static 'admin_interface/magnific-popup/magnific-popup.css' %}?v={{ version }}" />
<script type="text/javascript" src="{% static 'admin_interface/magnific-popup/jquery.magnific-popup.js' %}?v={{ version }}"></script>
<script type="text/javascript" src="{% static 'admin_interface/related-modal/related-modal.js' %}?v={{ version }}"></script>
{% endif %}
@@ -1,15 +1,80 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django import template import django
from django import template, VERSION
from django.conf import settings
if django.VERSION < (1, 10):
from django.core.urlresolvers import NoReverseMatch, reverse
else:
from django.urls import NoReverseMatch, reverse
from django.utils import translation
from admin_interface.cache import get_cached_active_theme, set_cached_active_theme
from admin_interface.models import Theme from admin_interface.models import Theme
from admin_interface.version import __version__
import re
register = template.Library() register = template.Library()
if VERSION < (1, 9):
simple_tag = register.assignment_tag
else:
simple_tag = register.simple_tag
@register.assignment_tag(takes_context = True)
@simple_tag(takes_context=True)
def get_admin_interface_languages(context):
if not settings.USE_I18N:
# i18n disabled
return None
if len(settings.LANGUAGES) < 2:
# less than 2 languages
return None
try:
set_language_url = reverse('set_language')
except NoReverseMatch:
# ImproperlyConfigured - must include i18n urls:
# urlpatterns += [url(r'^i18n/', include('django.conf.urls.i18n')),]
return None
request = context.get('request', None)
if not request:
return None
full_path = request.get_full_path()
admin_nolang_url = re.sub(r'^\/([\w]{2})([\-\_]{1}[\w]{2})?\/', '/', full_path)
if admin_nolang_url == full_path:
# ImproperlyConfigured - must include admin urls using i18n_patterns:
# from django.conf.urls.i18n import i18n_patterns
# urlpatterns += i18n_patterns(url(r'^admin/', admin.site.urls))
return None
langs_data = []
default_lang_code = settings.LANGUAGE_CODE
current_lang_code = translation.get_language() or default_lang_code
for language in settings.LANGUAGES:
lang_code = language[0].lower()
lang_name = language[1].title()
lang_data = {
'code': lang_code,
'name': lang_name,
'default': lang_code == default_lang_code,
'active': lang_code == current_lang_code,
'activation_url': '{}?next=/{}{}'.format(
set_language_url, lang_code, admin_nolang_url)
}
langs_data.append(lang_data)
return langs_data
@simple_tag(takes_context=True)
def get_admin_interface_theme(context): def get_admin_interface_theme(context):
theme = get_cached_active_theme()
if not theme:
theme = Theme.get_active_theme()
set_cached_active_theme(theme)
return theme
return Theme.get_active_theme()
@simple_tag(takes_context=False)
def get_admin_interface_version():
return __version__
+1 -2
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
__version__ = '0.4.5' __version__ = '0.11.2'
+27 -7
View File
@@ -1,25 +1,42 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*-
from setuptools import find_packages, setup from setuptools import find_packages, setup
import os
exec(open('admin_interface/version.py').read()) exec(open('admin_interface/version.py').read())
github_url = 'https://github.com/fabiocaccamo'
package_name = 'django-admin-interface'
package_path = os.path.abspath(os.path.dirname(__file__))
long_description_file_path = os.path.join(package_path, 'README.md')
long_description_content_type = 'text/markdown'
long_description = ''
try:
with open(long_description_file_path) as f:
long_description = f.read()
except IOError:
pass
setup( setup(
name='django-admin-interface', name=package_name,
packages=find_packages(exclude=['contrib', 'docs', 'tests*']), packages=find_packages(exclude=['contrib', 'docs', 'tests*']),
include_package_data=True, include_package_data=True,
version=__version__, version=__version__,
description='django-admin-interface is a modern responsive flat admin interface customizable by the admin itself.', description='django-admin-interface is a modern responsive flat admin interface customizable by the admin itself.',
long_description=long_description,
long_description_content_type=long_description_content_type,
author='Fabio Caccamo', author='Fabio Caccamo',
author_email='fabio.caccamo@gmail.com', author_email='fabio.caccamo@gmail.com',
url='https://github.com/fabiocaccamo/django-admin-interface', url='%s/%s' % (github_url, package_name, ),
download_url='https://github.com/fabiocaccamo/django-admin-interface/archive/%s.tar.gz' % __version__, download_url='%s/%s/archive/%s.tar.gz' % (github_url, package_name, __version__, ),
keywords=['django', 'admin', 'interface', 'responsive', 'flat', 'theme', 'custom', 'ui'], keywords=['django', 'admin', 'interface', 'responsive', 'flat', 'theme', 'custom', 'ui'],
requires=['django(>=1.7)'], requires=['django(>=1.7)'],
install_requires=[ install_requires=[
'django-colorfield==0.1.12', 'django-colorfield >= 0.1, < 1.0',
'django-flat-theme==1.1.4', 'django-flat-theme >= 1.0, < 2.0',
'django-flat-responsive==1.3.0' 'django-flat-responsive >= 1.0, < 3.0',
], ],
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
@@ -30,6 +47,9 @@ setup(
'Framework :: Django :: 1.9', 'Framework :: Django :: 1.9',
'Framework :: Django :: 1.10', 'Framework :: Django :: 1.10',
'Framework :: Django :: 1.11', 'Framework :: Django :: 1.11',
'Framework :: Django :: 2.0',
'Framework :: Django :: 2.1',
'Framework :: Django :: 2.2',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License', 'License :: OSI Approved :: MIT License',
'Natural Language :: English', 'Natural Language :: English',
@@ -40,9 +60,9 @@ setup(
'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Topic :: Software Development :: Build Tools', 'Topic :: Software Development :: Build Tools',
], ],
license='MIT', license='MIT',
test_suite='runtests.runtests' test_suite='runtests.runtests'
) )
+55 -11
View File
@@ -9,24 +9,46 @@ SECRET_KEY = 'django-admin-interface'
ALLOWED_HOSTS = ['*'] ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
'admin_interface', 'admin_interface',
'flat_responsive',
'flat', #if django version < 1.9
'colorfield', 'colorfield',
]
if django.VERSION < (1, 9):
# ONLY if django version < 1.9
INSTALLED_APPS += [
'flat',
]
if django.VERSION < (2, 0):
# ONLY if django version < 2.0
INSTALLED_APPS += [
'flat_responsive',
]
INSTALLED_APPS += [
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.sessions', 'django.contrib.sessions',
] ]
MIDDLEWARE_CLASSES = [ if django.VERSION < (2, 0):
'django.contrib.sessions.middleware.SessionMiddleware', MIDDLEWARE_CLASSES = [
'django.middleware.common.CommonMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware'
] 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
]
else:
MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
]
TEMPLATES = [{ TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
@@ -35,17 +57,39 @@ TEMPLATES = [{
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
'django.contrib.auth.context_processors.auth', 'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
] ]
}, },
},] },]
DATABASES = { database_engine = os.environ.get('DATABASE_ENGINE', 'sqlite')
'default': { database_config = {
'sqlite': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 'NAME': ':memory:',
},
# 'mysql': {
# 'ENGINE': 'django.db.backends.mysql',
# 'NAME': 'admin_interface',
# 'USER': 'mysql',
# 'PASSWORD': 'mysql',
# 'HOST': '',
# 'PORT': '',
# },
'postgres': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'admin_interface',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': '',
'PORT': '',
} }
} }
DATABASES = {
'default': database_config.get(database_engine),
}
MEDIA_ROOT = os.path.join(BASE_DIR, 'admin_interface/public/media/') MEDIA_ROOT = os.path.join(BASE_DIR, 'admin_interface/public/media/')
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
+46
View File
@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
from django.core.management import call_command
from django.test import TestCase
from admin_interface.models import Theme
class AdminInterfaceFixturesTestCase(TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def __load_theme(self, theme_name):
call_command('loaddata', 'admin_interface_theme_%s.json' % (theme_name, ))
def test_import_all(self):
self.__load_theme('django')
self.__load_theme('bootstrap')
self.__load_theme('foundation')
self.__load_theme('uswds')
self.assertEqual(Theme.objects.count(), 4);
def test_import_idempotency(self):
self.__load_theme('django')
self.__load_theme('django')
self.__load_theme('django')
self.__load_theme('django')
self.__load_theme('django')
self.assertEqual(Theme.objects.count(), 1);
self.__load_theme('bootstrap')
self.__load_theme('bootstrap')
self.__load_theme('bootstrap')
self.assertEqual(Theme.objects.count(), 2);
def test_import_override(self):
obj1 = Theme.get_active_theme()
obj1.title = 'Custom 1'
obj1.save()
self.__load_theme('django')
obj2 = Theme.get_active_theme()
self.assertEqual(obj1.pk, obj2.pk)
self.assertTrue(obj1.title != obj2.title)
+89
View File
@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.test import TestCase
import random
import shutil
from admin_interface.models import Theme
class AdminInterfaceModelsTestCase(TestCase):
def setUp(self):
pass
def tearDown(self):
shutil.rmtree(settings.MEDIA_ROOT, ignore_errors=True)
def __test_active_theme(self):
theme = Theme.get_active_theme()
print(theme)
self.assertTrue(theme != None)
self.assertTrue(theme.active)
self.assertEqual(Theme.objects.filter(active=True).count(), 1);
def test_default_theme_created_if_no_themes(self):
Theme.objects.all().delete()
self.__test_active_theme()
def test_default_theme_created_if_all_themes_deleted(self):
Theme.objects.all().delete()
self.__test_active_theme()
def test_default_theme_activated_on_save_if_no_active_themes(self):
Theme.objects.all().delete()
theme = Theme.get_active_theme()
theme.active = False
theme.save()
self.__test_active_theme()
def test_default_theme_activated_after_update_if_no_active_themes(self):
Theme.objects.all().delete()
Theme.objects.all().update(active=False)
self.__test_active_theme()
def test_default_theme_activated_after_update_if_multiple_active_themes(self):
Theme.objects.all().delete()
theme_1 = Theme.objects.create(name='Custom 1', active=True)
theme_2 = Theme.objects.create(name='Custom 2', active=True)
theme_3 = Theme.objects.create(name='Custom 3', active=True)
Theme.objects.update(active=False)
Theme.objects.update(active=True)
self.__test_active_theme()
def test_default_theme_activated_on_active_theme_deleted(self):
Theme.objects.all().delete()
theme_1 = Theme.objects.create(name='Custom 1', active=True)
theme_2 = Theme.objects.create(name='Custom 2', active=True)
theme_3 = Theme.objects.create(name='Custom 3', active=True)
Theme.objects.filter(pk=Theme.get_active_theme().pk).delete()
self.__test_active_theme()
def test_last_theme_activated_on_multiple_themes_created(self):
Theme.objects.all().delete()
theme_1 = Theme.objects.create(name='Custom 1', active=True)
theme_2 = Theme.objects.create(name='Custom 2', active=True)
theme_3 = Theme.objects.create(name='Custom 3', active=True)
self.assertEqual(Theme.get_active_theme().pk, theme_3.pk)
self.__test_active_theme()
def test_last_theme_activated_on_multiple_themes_activated(self):
Theme.objects.all().delete()
theme_1 = Theme.objects.create(name='Custom 1', active=True)
theme_2 = Theme.objects.create(name='Custom 2', active=True)
theme_3 = Theme.objects.create(name='Custom 3', active=True)
theme_4 = Theme.objects.create(name='Custom 4', active=True)
theme_5 = Theme.objects.create(name='Custom 5', active=True)
themes = [theme_1, theme_2, theme_3, theme_4, theme_5]
for i in range(5):
random.shuffle(themes)
for theme in themes:
theme.set_active()
self.assertEqual(Theme.get_active_theme().pk, theme.pk)
self.__test_active_theme()
def test_repr(self):
theme = Theme.get_active_theme()
self.assertEqual('{0}'.format(theme), 'Django')
+92
View File
@@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
import django
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.test import override_settings, TestCase
from admin_interface.settings import check_installed_apps
class AdminInterfaceSettingsTestCase(TestCase):
DJANGO_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.sessions',
]
def setUp(self):
pass
def tearDown(self):
pass
def __test_installed_apps(self):
dj_version = django.VERSION
installed_apps = settings.INSTALLED_APPS
if 'colorfield' not in installed_apps:
self.assertRaises(ImproperlyConfigured, check_installed_apps)
elif 'flat' not in installed_apps and dj_version < (1, 9):
self.assertRaises(ImproperlyConfigured, check_installed_apps)
elif 'flat' in installed_apps and dj_version >= (1, 9):
self.assertRaises(ImproperlyConfigured, check_installed_apps)
elif 'flat_responsive' not in installed_apps and dj_version < (2, 0):
self.assertRaises(ImproperlyConfigured, check_installed_apps)
elif 'flat_responsive' in installed_apps and dj_version >= (2, 0):
self.assertRaises(ImproperlyConfigured, check_installed_apps)
else:
check_installed_apps()
@override_settings(
INSTALLED_APPS = [
'admin_interface',
'colorfield',
'flat',
'flat_responsive',
] + DJANGO_APPS
)
def test_installed_apps_all(self):
self.__test_installed_apps()
@override_settings(
INSTALLED_APPS = [
'admin_interface',
# 'colorfield',
'flat',
'flat_responsive',
] + DJANGO_APPS
)
def test_installed_apps_no_colorfield(self):
self.__test_installed_apps()
@override_settings(
INSTALLED_APPS = [
'admin_interface',
'colorfield',
# 'flat',
'flat_responsive',
] + DJANGO_APPS
)
def test_installed_apps_no_flat(self):
self.__test_installed_apps()
@override_settings(
INSTALLED_APPS = [
'admin_interface',
'colorfield',
'flat',
# 'flat_responsive',
] + DJANGO_APPS
)
def test_installed_apps_no_flat_responsive(self):
self.__test_installed_apps()
+54
View File
@@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
from django.test import TestCase
from django.test.client import RequestFactory
from django.template import Context, Template
from admin_interface.models import Theme
from admin_interface.templatetags import admin_interface_tags as templatetags
from admin_interface.version import __version__
class AdminInterfaceTemplateTagsTestCase(TestCase):
def setUp(self):
self.request_factory = RequestFactory()
def tearDown(self):
pass
def __render_template(self, string, context=None):
return Template(string).render(Context(context or {}))
def test_get_theme(self):
Theme.objects.all().delete()
context = Context({})
theme = templatetags.get_admin_interface_theme(context)
self.assertEqual(theme.name, 'Django')
rendered = self.__render_template(
'{% load admin_interface_tags %}'\
'{% get_admin_interface_theme as theme %}'\
'{{ theme.name }}', context)
self.assertEqual(rendered, 'Django')
def test_get_theme_with_request(self):
Theme.objects.all().delete()
context = Context({
'request': self.request_factory.get('/')
})
theme = templatetags.get_admin_interface_theme(context)
self.assertEqual(theme.name, 'Django')
rendered = self.__render_template(
'{% load admin_interface_tags %}'\
'{% get_admin_interface_theme as theme %}'\
'{{ theme.name }}', context)
self.assertEqual(rendered, 'Django')
def test_get_version(self):
version = templatetags.get_admin_interface_version()
self.assertEqual(version, __version__)
rendered = self.__render_template(
'{% load admin_interface_tags %}'\
'{% get_admin_interface_version as version %}'\
'{{ version }}')
self.assertEqual(rendered, __version__)
-113
View File
@@ -1,113 +0,0 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.test import TestCase
from django.template import Context, Template
import random
import shutil
from admin_interface.models import Theme
class AdminInterfaceTestCase(TestCase):
def setUp(self):
pass
def tearDown(self):
shutil.rmtree(settings.MEDIA_ROOT, ignore_errors=True)
pass
def __render_template(self, string, context=None):
context = context or {}
context = Context(context)
return Template(string).render(context)
def __test_active_theme(self):
theme = Theme.get_active_theme()
print( theme )
self.assertTrue(theme != None)
self.assertTrue(theme.active)
self.assertEqual(Theme.objects.filter( active = True ).count(), 1);
def test_default_theme_created_if_no_themes(self):
Theme.objects.all().delete()
self.__test_active_theme()
def test_default_theme_created_if_all_themes_deleted(self):
Theme.objects.all().delete()
self.__test_active_theme()
def test_default_theme_activated_on_save_if_no_active_themes(self):
Theme.objects.all().delete()
theme = Theme.get_active_theme()
theme.active = False
theme.save()
self.__test_active_theme()
def test_default_theme_activated_after_update_if_no_active_themes(self):
Theme.objects.all().delete()
Theme.objects.all().update( active = False )
self.__test_active_theme()
def test_default_theme_activated_after_update_if_multiple_active_themes(self):
Theme.objects.all().delete()
theme_1 = Theme.objects.create( name = 'Custom 1', active = True )
theme_2 = Theme.objects.create( name = 'Custom 2', active = True )
theme_3 = Theme.objects.create( name = 'Custom 3', active = True )
Theme.objects.update( active = False )
Theme.objects.update( active = True )
self.__test_active_theme()
def test_default_theme_activated_on_active_theme_deleted(self):
Theme.objects.all().delete()
theme_1 = Theme.objects.create( name = 'Custom 1', active = True )
theme_2 = Theme.objects.create( name = 'Custom 2', active = True )
theme_3 = Theme.objects.create( name = 'Custom 3', active = True )
Theme.objects.filter( pk = Theme.get_active_theme().pk ).delete()
self.__test_active_theme()
def test_last_theme_activated_on_multiple_themes_created(self):
Theme.objects.all().delete()
theme_1 = Theme.objects.create( name = 'Custom 1', active = True )
theme_2 = Theme.objects.create( name = 'Custom 2', active = True )
theme_3 = Theme.objects.create( name = 'Custom 3', active = True )
self.assertEqual( Theme.get_active_theme().pk, theme_3.pk )
self.__test_active_theme()
def test_last_theme_activated_on_multiple_themes_activated(self):
Theme.objects.all().delete()
theme_1 = Theme.objects.create( name = 'Custom 1', active = True )
theme_2 = Theme.objects.create( name = 'Custom 2', active = True )
theme_3 = Theme.objects.create( name = 'Custom 3', active = True )
theme_4 = Theme.objects.create( name = 'Custom 4', active = True )
theme_5 = Theme.objects.create( name = 'Custom 5', active = True )
themes = [ theme_1, theme_2, theme_3, theme_4, theme_5 ]
for i in range(5):
random.shuffle(themes)
for theme in themes:
theme.set_active()
self.assertEqual( Theme.get_active_theme().pk, theme.pk )
self.__test_active_theme()
def test_templatetags(self):
Theme.objects.all().delete()
rendered = self.__render_template('{% load admin_interface_tags %}{% get_admin_interface_theme as theme %}{{ theme.name }}')
self.assertEqual(rendered, 'Django')
def test_repr(self):
theme = Theme.get_active_theme()
self.assertEqual( "{0}".format(theme), 'Django' )
+20 -9
View File
@@ -1,19 +1,30 @@
[tox] [tox]
envlist = envlist =
py27-{17,18,19,110,111}, py27-{dj17,dj18,dj19,dj110,dj111}-{sqlite,postgres},
py34-{17,18,19,110,111}, py34-{dj17,dj18,dj19,dj110,dj111,dj20}-{sqlite,postgres},
py35-{18,19,110,111}, py35-{dj18,dj19,dj110,dj111,dj20,dj21,dj22}-{sqlite,postgres},
py36-{18,19,110,111}, py36-{dj18,dj19,dj110,dj111,dj20,dj21,dj22,djmaster}-{sqlite,postgres},
py37-{dj20,dj21,dj22,djmaster}-{sqlite,postgres},
[testenv] [testenv]
passenv = CI TRAVIS TRAVIS_* passenv = CI TRAVIS TRAVIS_*
deps = deps =
17: Django >= 1.7, < 1.8 dj17: Django >= 1.7, < 1.8
18: Django >= 1.8, < 1.9 dj18: Django >= 1.8, < 1.9
19: Django >= 1.9, < 1.10 dj19: Django >= 1.9, < 1.10
110: Django >= 1.10, < 1.11 dj110: Django >= 1.10, < 1.11
111: Django >= 1.11, < 1.12 dj111: Django >= 1.11, < 1.12
dj20: Django >= 2.0, < 2.1
dj21: Django >= 2.1, < 2.2
dj22: Django >= 2.2, < 2.3
djmaster: https://github.com/django/django/archive/master.tar.gz
# mysql: mysqlclient
postgres: psycopg2-binary
coverage coverage
codecov codecov
setenv =
sqlite: DATABASE_ENGINE=sqlite
# mysql: DATABASE_ENGINE=mysql
postgres: DATABASE_ENGINE=postgres
commands = commands =
coverage run --append --source=admin_interface setup.py test coverage run --append --source=admin_interface setup.py test
coverage report -m coverage report -m