Compare commits
41
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98eefe2877 | ||
|
|
a302ea49dc | ||
|
|
ae53c43b29 | ||
|
|
363bc310a1 | ||
|
|
2ee03fc2de | ||
|
|
74dacaba2c | ||
|
|
9272e6563b | ||
|
|
8d3d7c9648 | ||
|
|
668c8c806b | ||
|
|
8562c2dbfb | ||
|
|
585575dce7 | ||
|
|
990db6fdc8 | ||
|
|
5fb85d02a2 | ||
|
|
833acf49a1 | ||
|
|
a96cede14f | ||
|
|
903417ab79 | ||
|
|
d76c64c2d6 | ||
|
|
951c07b76d | ||
|
|
769fab5e84 | ||
|
|
6eebeb62c1 | ||
|
|
53e9b3f9f7 | ||
|
|
b90ed72ef6 | ||
|
|
11bde80a36 | ||
|
|
003b0f9892 | ||
|
|
3156882cba | ||
|
|
de09ffd7b1 | ||
|
|
ce552f9f0c | ||
|
|
502b1af775 | ||
|
|
4212a695f0 | ||
|
|
04632078d1 | ||
|
|
94c436b137 | ||
|
|
4244b0b3ae | ||
|
|
7baffaf490 | ||
|
|
b8a160f746 | ||
|
|
5e3e3a1480 | ||
|
|
1e3b71825b | ||
|
|
7d649185cb | ||
|
|
3ff4f05e51 | ||
|
|
d8cffd8c2c | ||
|
|
8fe7178a13 | ||
|
|
d2b680e477 |
No files matched your search
@@ -1,2 +1 @@
|
|||||||
github: [fabiocaccamo]
|
github: [fabiocaccamo]
|
||||||
custom: ['https://www.paypal.me/fabiocaccamo']
|
|
||||||
@@ -18,12 +18,7 @@ jobs:
|
|||||||
uses: ffurrer2/extract-release-notes@v1
|
uses: ffurrer2/extract-release-notes@v1
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
uses: actions/create-release@v1
|
uses: ncipollo/release-action@v1
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ github.ref }}
|
|
||||||
release_name: ${{ github.ref }}
|
|
||||||
draft: false
|
|
||||||
prerelease: false
|
|
||||||
body: ${{ steps.extract-release-notes.outputs.release_notes }}
|
body: ${{ steps.extract-release-notes.outputs.release_notes }}
|
||||||
|
token: ${{ secrets.WORKFLOWS_CREATE_RELEASE_TOKEN }}
|
||||||
@@ -6,12 +6,37 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
|
||||||
|
prepare:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Create matrix
|
||||||
|
uses: fabiocaccamo/create-matrix-action@v2
|
||||||
|
id: create_matrix
|
||||||
|
with:
|
||||||
|
matrix: |
|
||||||
|
python-version {2.7}, django-version {1.8,1.9,1.10,1.11}, database {sqlite,postgres}
|
||||||
|
python-version {3.6}, django-version {1.8,1.9,1.10,1.11,2.0,2.1,2.2,3.0,3.1,3.2}, database {sqlite,postgres}
|
||||||
|
python-version {3.7}, django-version {2.0,2.1,2.2,3.0,3.1,3.2}, database {sqlite,postgres}
|
||||||
|
python-version {3.8}, django-version {2.2,3.0,3.1,3.2}, database {sqlite,postgres}
|
||||||
|
python-version {3.9}, django-version {2.2,3.0,3.1,3.2}, database {sqlite,postgres}
|
||||||
|
python-version {3.10}, django-version {3.2,4.0}, database {sqlite,postgres}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
matrix: ${{ steps.create_matrix.outputs.matrix }}
|
||||||
|
|
||||||
|
test:
|
||||||
|
|
||||||
|
needs: prepare
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ['2.7', '3.6', '3.7', '3.8', '3.9', '3.10']
|
include: ${{fromJson(needs.prepare.outputs.matrix)}}
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
@@ -27,7 +52,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install psycopg2 prerequisites
|
||||||
|
run: sudo apt-get install libpq-dev
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
@@ -35,15 +63,31 @@ jobs:
|
|||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
cache: 'pip'
|
cache: 'pip'
|
||||||
|
|
||||||
- name: Install psycopg2 prerequisites
|
- name: Upgrade pip version
|
||||||
run: sudo apt-get install libpq-dev
|
run: |
|
||||||
|
pip install pip --upgrade
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install django
|
||||||
|
run: |
|
||||||
|
pip install "Django ~= ${{ matrix.django-version }}"
|
||||||
|
|
||||||
|
- name: Install requirements
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
pip install -r requirements-test.txt
|
pip install -r requirements-test.txt
|
||||||
pip install tox tox-gh-actions
|
|
||||||
|
|
||||||
- name: Test with tox
|
- name: Run tests
|
||||||
run: tox
|
env:
|
||||||
|
DATABASE_ENGINE: ${{ matrix.database }}
|
||||||
|
run: |
|
||||||
|
coverage run --append --source=admin_interface setup.py test
|
||||||
|
coverage xml -o ./coverage.xml
|
||||||
|
|
||||||
|
- name: Upload coverage to Codecov
|
||||||
|
uses: codecov/codecov-action@v2
|
||||||
|
with:
|
||||||
|
fail_ci_if_error: false
|
||||||
|
files: ./coverage.xml
|
||||||
|
flags: unittests
|
||||||
|
verbose: true
|
||||||
|
|
||||||
@@ -4,6 +4,18 @@ 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/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.20.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.20.0) - 2022-08-25
|
||||||
|
- Add `django-streamfield` compatibility.
|
||||||
|
|
||||||
|
## [0.19.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.19.2) - 2022-08-04
|
||||||
|
- Fix `hashlib` compatibility with `FIPS` enabled systems. #167 (by [@jonlev1n](https://github.com/jonlev1n) in #168)
|
||||||
|
|
||||||
|
## [0.19.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.19.1) - 2022-05-14
|
||||||
|
- [css] Fixed dashboard alignment when recent-actions are not visible.
|
||||||
|
|
||||||
|
## [0.19.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.19.0) - 2022-03-08
|
||||||
|
- Converted dynamic inline CSS to external static CSS using CSS variables. #157 #93 (thanks to [@Mustafa-Abu-Ghazy](https://github.com/Mustafa-Abu-Ghazy))
|
||||||
|
|
||||||
## [0.18.7](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.18.7) - 2022-02-24
|
## [0.18.7](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.18.7) - 2022-02-24
|
||||||
- Removed public disclosures of the lib's version. #154 (thanks to [@mintyPT](https://github.com/mintyPT))
|
- Removed public disclosures of the lib's version. #154 (thanks to [@mintyPT](https://github.com/mintyPT))
|
||||||
- Reformatted code with **Black**.
|
- Reformatted code with **Black**.
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ django-admin-interface is a modern **responsive flat admin interface customizabl
|
|||||||
- `django-json-widget`
|
- `django-json-widget`
|
||||||
- `django-modeltranslation`
|
- `django-modeltranslation`
|
||||||
- `django-tabbed-admin`
|
- `django-tabbed-admin`
|
||||||
|
- `django-streamfield`
|
||||||
- `sorl-thumbnail`
|
- `sorl-thumbnail`
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -100,31 +101,48 @@ You can add a theme you've created through the admin to this repository by [send
|
|||||||
4. Edit the section above to document your theme.
|
4. Edit the section above to document your theme.
|
||||||
|
|
||||||
### Add theme support to third-party libraries
|
### Add theme support to third-party libraries
|
||||||
You can add **theme support to existing third-party libraries** using the following **css variables**:
|
You can add **theme support to existing third-party libraries** using the following **CSS variables**:
|
||||||
|
|
||||||
- `--admin-interface-title-color`
|
#### Header
|
||||||
- `--admin-interface-logo-color`
|
|
||||||
- `--admin-interface-env-color`
|
- `--admin-interface-header-background-color`
|
||||||
- `--admin-interface-header-background-color:`
|
|
||||||
- `--admin-interface-header-text-color`
|
- `--admin-interface-header-text-color`
|
||||||
- `--admin-interface-header-link-color`
|
- `--admin-interface-header-link-color`
|
||||||
- `--admin-interface-header-link_hover-color`
|
- `--admin-interface-header-link_hover-color`
|
||||||
|
- `--admin-interface-title-color`
|
||||||
|
- `--admin-interface-env-color`
|
||||||
|
|
||||||
|
#### Logo
|
||||||
|
|
||||||
|
- `--admin-interface-logo-color`
|
||||||
|
- `--admin-interface-logo-default-background-image`
|
||||||
|
- `--admin-interface-logo-max-width`
|
||||||
|
- `--admin-interface-logo-max-height`
|
||||||
|
|
||||||
|
#### Modules / Links
|
||||||
- `--admin-interface-module-background-color`
|
- `--admin-interface-module-background-color`
|
||||||
- `--admin-interface-module-background-selected-color`
|
- `--admin-interface-module-background-selected-color`
|
||||||
|
- `--admin-interface-module-border-radius`
|
||||||
- `--admin-interface-module-text-color`
|
- `--admin-interface-module-text-color`
|
||||||
- `--admin-interface-module-link-color`
|
- `--admin-interface-module-link-color`
|
||||||
- `--admin-interface-module-link-selected-color`
|
- `--admin-interface-module-link-selected-color`
|
||||||
- `--admin-interface-module-link-hover-color`
|
- `--admin-interface-module-link-hover-color`
|
||||||
- `--admin-interface-generic-link-color`
|
- `--admin-interface-generic-link-color`
|
||||||
- `--admin-interface-generic-link-hover-color`
|
- `--admin-interface-generic-link-hover-color`
|
||||||
|
|
||||||
|
#### Buttons
|
||||||
- `--admin-interface-save-button-background-color`
|
- `--admin-interface-save-button-background-color`
|
||||||
- `--admin-interface-save-button-background-hover-color`
|
- `--admin-interface-save-button-background-hover-color`
|
||||||
- `--admin-interface-save-button-text-color`
|
- `--admin-interface-save-button-text-color`
|
||||||
- `--admin-interface-delete-button-background-color`
|
- `--admin-interface-delete-button-background-color`
|
||||||
- `--admin-interface-delete-button-background-hover-color`
|
- `--admin-interface-delete-button-background-hover-color`
|
||||||
- `--admin-interface-delete-button-text-color`
|
- `--admin-interface-delete-button-text-color`
|
||||||
|
|
||||||
|
#### Related Modal
|
||||||
- `--admin-interface-related-modal-background-color`
|
- `--admin-interface-related-modal-background-color`
|
||||||
- `--admin-interface-related-modal-background-opacity`
|
- `--admin-interface-related-modal-background-opacity`
|
||||||
|
- `--admin-interface-related-modal-border-radius`
|
||||||
|
- `--admin-interface-related-modal-close-button-display`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -158,7 +176,7 @@ You must configure multilanguage `settings` and `urls` correctly:
|
|||||||
LANGUAGES = (
|
LANGUAGES = (
|
||||||
("en", _("English")),
|
("en", _("English")),
|
||||||
("it", _("Italiano")),
|
("it", _("Italiano")),
|
||||||
("fr", _("Française")),
|
("fr", _("Français")),
|
||||||
# more than one language is expected here
|
# more than one language is expected here
|
||||||
)
|
)
|
||||||
LANGUAGE_CODE = "en"
|
LANGUAGE_CODE = "en"
|
||||||
@@ -187,18 +205,17 @@ urlpatterns += i18n_patterns(path("admin/", admin.site.urls))
|
|||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
```bash
|
```bash
|
||||||
# create python virtual environment
|
# clone repository
|
||||||
virtualenv testing_django_admin_interface
|
git clone https://github.com/fabiocaccamo/django-admin-interface.git && cd django-admin-interface
|
||||||
|
|
||||||
# activate virtualenv
|
# create virtualenv and activate it
|
||||||
cd testing_django_admin_interface && . bin/activate
|
python -m venv venv && . venv/bin/activate
|
||||||
|
|
||||||
# clone repo
|
# upgrade pip
|
||||||
git clone https://github.com/fabiocaccamo/django-admin-interface.git src && cd src
|
python -m pip install --upgrade pip
|
||||||
|
|
||||||
# install dependencies
|
# install requirements
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt -r requirements-test.txt
|
||||||
pip install -r requirements-test.txt
|
|
||||||
|
|
||||||
# run tests
|
# run tests
|
||||||
tox
|
tox
|
||||||
@@ -215,6 +232,13 @@ Released under [MIT License](LICENSE.txt).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Supporting
|
||||||
|
|
||||||
|
- :star: Star this project on [GitHub](https://github.com/fabiocaccamo/django-admin-interface)
|
||||||
|
- :octocat: Follow me on [GitHub](https://github.com/fabiocaccamo)
|
||||||
|
- :blue_heart: Follow me on [Twitter](https://twitter.com/fabiocaccamo)
|
||||||
|
- :moneybag: Sponsor me on [Github](https://github.com/sponsors/fabiocaccamo)
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|
||||||
- [`django-colorfield`](https://github.com/fabiocaccamo/django-colorfield) - simple color field for models with a nice color-picker in the admin. 🎨
|
- [`django-colorfield`](https://github.com/fabiocaccamo/django-colorfield) - simple color field for models with a nice color-picker in the admin. 🎨
|
||||||
|
|||||||
@@ -1,16 +1,25 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from admin_interface.compat import gettext_lazy as _
|
|
||||||
from admin_interface.models import Theme
|
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.contrib.auth import models as auth_models
|
||||||
|
|
||||||
|
from admin_interface.compat import gettext_lazy as _
|
||||||
|
from admin_interface.models import Theme, UserTheme
|
||||||
|
|
||||||
|
|
||||||
|
class UserInline(admin.TabularInline):
|
||||||
|
model = UserTheme
|
||||||
|
extra = 0
|
||||||
|
autocomplete_fields = ('user', )
|
||||||
|
|
||||||
|
|
||||||
class ThemeAdmin(admin.ModelAdmin):
|
class ThemeAdmin(admin.ModelAdmin):
|
||||||
|
inlines = [UserInline, ]
|
||||||
|
|
||||||
list_display = (
|
list_display = (
|
||||||
"name",
|
"name",
|
||||||
"active",
|
"active",
|
||||||
|
"demo",
|
||||||
)
|
)
|
||||||
list_editable = ("active",)
|
list_editable = ("active",)
|
||||||
list_per_page = 100
|
list_per_page = 100
|
||||||
@@ -24,6 +33,7 @@ class ThemeAdmin(admin.ModelAdmin):
|
|||||||
"fields": (
|
"fields": (
|
||||||
"name",
|
"name",
|
||||||
"active",
|
"active",
|
||||||
|
"demo",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -133,7 +143,8 @@ class ThemeAdmin(admin.ModelAdmin):
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(_("Navigation Bar"), {"classes": ("wide",), "fields": ("foldable_apps",)}),
|
(_("Navigation Bar"), {"classes": (
|
||||||
|
"wide",), "fields": ("foldable_apps",)}),
|
||||||
(
|
(
|
||||||
_("Related Modal"),
|
_("Related Modal"),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
from .models import Theme
|
||||||
|
|
||||||
|
def get_active_theme(request):
|
||||||
|
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)
|
||||||
|
|
||||||
|
if objs_active_count == 0:
|
||||||
|
obj = objs_manager.first()
|
||||||
|
if obj:
|
||||||
|
obj.set_active()
|
||||||
|
# else:
|
||||||
|
# obj = objs_manager.create()
|
||||||
|
|
||||||
|
elif objs_active_count == 1:
|
||||||
|
obj = objs_active_ls[0]
|
||||||
|
|
||||||
|
elif objs_active_count > 1:
|
||||||
|
# for frame_record in inspect.stack():
|
||||||
|
# if frame_record[3]=='get_response':
|
||||||
|
# request = frame_record[0].f_locals['request']
|
||||||
|
# user = request.user
|
||||||
|
# break
|
||||||
|
# else:
|
||||||
|
# request = None
|
||||||
|
user = request.user
|
||||||
|
try:
|
||||||
|
obj = objs_active_qs.filter(user=user).first()
|
||||||
|
except:
|
||||||
|
obj = objs_active_ls[-1]
|
||||||
|
obj.set_active()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'theme': obj,
|
||||||
|
}
|
||||||
Whitespace-only changes.
@@ -0,0 +1,156 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
import zipfile
|
||||||
|
|
||||||
|
import django
|
||||||
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib import admin, messages
|
||||||
|
from django.contrib.auth import get_permission_codename
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
|
from django.core.files.storage import default_storage
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.template.response import TemplateResponse
|
||||||
|
from django.urls import path, reverse
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from .. import models
|
||||||
|
from .forms import ImportForm
|
||||||
|
|
||||||
|
|
||||||
|
class ImportMixin(admin.ModelAdmin):
|
||||||
|
"""
|
||||||
|
Import mixin.
|
||||||
|
|
||||||
|
This is intended to be mixed with django.contrib.admin.ModelAdmin
|
||||||
|
https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#modeladmin-objects
|
||||||
|
"""
|
||||||
|
|
||||||
|
#: template for change_list view
|
||||||
|
change_list_template = 'admin/import_export/change_list_import.html'
|
||||||
|
#: template for import view
|
||||||
|
import_template_name = 'admin/import_export/import.html'
|
||||||
|
|
||||||
|
def get_model_info(self):
|
||||||
|
app_label = self.model._meta.app_label
|
||||||
|
return (self.model._meta.app_label, self.model._meta.model_name)
|
||||||
|
|
||||||
|
def has_import_permission(self, request):
|
||||||
|
"""
|
||||||
|
Returns whether a request has import permission.
|
||||||
|
"""
|
||||||
|
IMPORT_PERMISSION_CODE = getattr(settings, 'IMPORT_EXPORT_IMPORT_PERMISSION_CODE', None)
|
||||||
|
if IMPORT_PERMISSION_CODE is None:
|
||||||
|
return True
|
||||||
|
|
||||||
|
opts = self.opts
|
||||||
|
codename = get_permission_codename(IMPORT_PERMISSION_CODE, opts)
|
||||||
|
return request.user.has_perm("%s.%s" % (opts.app_label, codename))
|
||||||
|
|
||||||
|
def get_urls(self):
|
||||||
|
urls = super().get_urls()
|
||||||
|
info = self.get_model_info()
|
||||||
|
my_urls = [
|
||||||
|
path('import/',
|
||||||
|
self.admin_site.admin_view(self.import_action),
|
||||||
|
name='%s_%s_import' % info),
|
||||||
|
]
|
||||||
|
return my_urls + urls
|
||||||
|
|
||||||
|
def get_import_context_data(self, **kwargs):
|
||||||
|
return self.get_context_data(**kwargs)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def get_form_kwargs(self, form, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Prepare/returns kwargs for the import form.
|
||||||
|
|
||||||
|
To distinguish between import and confirm import forms,
|
||||||
|
the following approach may be used:
|
||||||
|
|
||||||
|
if isinstance(form, ImportForm):
|
||||||
|
# your code here for the import form kwargs
|
||||||
|
# e.g. update.kwargs({...})
|
||||||
|
elif isinstance(form, ConfirmImportForm):
|
||||||
|
# your code here for the confirm import form kwargs
|
||||||
|
# e.g. update.kwargs({...})
|
||||||
|
...
|
||||||
|
"""
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def import_action(self, request, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Perform a dry_run of the import to make sure the import will not
|
||||||
|
result in errors. If there where no error, save the user
|
||||||
|
uploaded file to a local temp file that will be used by
|
||||||
|
'process_import' for the actual import.
|
||||||
|
"""
|
||||||
|
if not self.has_import_permission(request):
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
context = self.get_import_context_data()
|
||||||
|
|
||||||
|
form_type = ImportForm
|
||||||
|
form_kwargs = self.get_form_kwargs(form_type, *args, **kwargs)
|
||||||
|
form = form_type(request.POST or None,
|
||||||
|
request.FILES or None,
|
||||||
|
**form_kwargs)
|
||||||
|
|
||||||
|
if request.POST and form.is_valid():
|
||||||
|
import_file_tema = form.cleaned_data['tema']
|
||||||
|
if zipfile.is_zipfile(import_file_tema):
|
||||||
|
with zipfile.ZipFile(import_file_tema, 'r') as zip_ref:
|
||||||
|
with tempfile.TemporaryDirectory() as tempdir:
|
||||||
|
zip_ref.extractall(tempdir)
|
||||||
|
lst = os.listdir(tempdir)
|
||||||
|
allowed_extensions=[".gif", ".jpg", ".jpeg", ".png", ".svg"]
|
||||||
|
try:
|
||||||
|
tema_json = [s for s in os.listdir(f'{tempdir}/{lst[0]}') if '.json' in s][0]
|
||||||
|
logo = [s for s in os.listdir(f'{tempdir}/{lst[0]}/logo') if any(ele in s for ele in allowed_extensions)][0]
|
||||||
|
favicon = [s for s in os.listdir(f'{tempdir}/{lst[0]}/favicon') if any(ele in s for ele in allowed_extensions)][0]
|
||||||
|
with open(f'{tempdir}/{lst[0]}/{tema_json}', 'r') as temporary_file:
|
||||||
|
result = json.loads(temporary_file.read())
|
||||||
|
with open(f'{tempdir}/{lst[0]}/logo/{logo}', 'rb') as temporary_file:
|
||||||
|
default_storage.save(f"admin-interface/logo/{temporary_file.name.split('/')[-1]}", temporary_file)
|
||||||
|
with open(f'{tempdir}/{lst[0]}/favicon/{favicon}', 'rb') as temporary_file:
|
||||||
|
default_storage.save(f"admin-interface/favicon/{temporary_file.name.split('/')[-1]}", temporary_file)
|
||||||
|
skip_result = False
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
messages.error(request, 'Struttura del file .zip errata.')
|
||||||
|
skip_result = True
|
||||||
|
if not skip_result:
|
||||||
|
try:
|
||||||
|
new_theme = models.Theme(
|
||||||
|
**result[0]['fields']
|
||||||
|
)
|
||||||
|
new_theme.save()
|
||||||
|
|
||||||
|
messages.success(request, _('Import finished'))
|
||||||
|
except:
|
||||||
|
messages.error(request, 'Struttura del file .json errata.')
|
||||||
|
else:
|
||||||
|
messages.error(request, 'È richiesto un file .zip')
|
||||||
|
|
||||||
|
url = reverse('admin:%s_%s_changelist' % self.get_model_info(),
|
||||||
|
current_app=self.admin_site.name)
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
else:
|
||||||
|
context.update(self.admin_site.each_context(request))
|
||||||
|
|
||||||
|
context['title'] = _("Import")
|
||||||
|
context['form'] = form
|
||||||
|
context['opts'] = self.model._meta
|
||||||
|
|
||||||
|
request.current_app = self.admin_site.name
|
||||||
|
return TemplateResponse(request, [self.import_template_name],
|
||||||
|
context)
|
||||||
|
|
||||||
|
def changelist_view(self, request, extra_context=None):
|
||||||
|
if extra_context is None:
|
||||||
|
extra_context = {}
|
||||||
|
extra_context['has_import_permission'] = self.has_import_permission(request)
|
||||||
|
return super().changelist_view(request, extra_context)
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import os.path
|
||||||
|
|
||||||
|
from django import forms
|
||||||
|
from django.contrib.admin.helpers import ActionForm
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
class ImportForm(forms.Form):
|
||||||
|
tema = forms.FileField(
|
||||||
|
label='Zip'
|
||||||
|
)
|
||||||
Binary file not shown.
@@ -0,0 +1,139 @@
|
|||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
#
|
||||||
|
# Christian Galeffi <chri@gallochri.com>, 2015.
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: \n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2020-06-04 09:27+0200\n"
|
||||||
|
"PO-Revision-Date: 2015-08-30 20:32+0100\n"
|
||||||
|
"Last-Translator: Christian Galeffi <chri@gallochri.com>\n"
|
||||||
|
"Language-Team: Italian <kde-i18n-it@kde.org>\n"
|
||||||
|
"Language: it\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"
|
||||||
|
"X-Generator: Poedit 1.5.4\n"
|
||||||
|
|
||||||
|
#: admin.py:194
|
||||||
|
#, python-format
|
||||||
|
msgid "%s through import_export"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: admin.py:200
|
||||||
|
msgid "Import finished, with {} new and {} updated {}."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: admin.py:298
|
||||||
|
#, python-format
|
||||||
|
msgid "<h1>Imported file has a wrong encoding: %s</h1>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: admin.py:300
|
||||||
|
#, python-format
|
||||||
|
msgid "<h1>%s encountered while trying to read file: %s</h1>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: admin.py:331 templates/admin/import_export/change_list_import_item.html:5
|
||||||
|
#: templates/admin/import_export/import.html:10
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Importare"
|
||||||
|
|
||||||
|
#: admin.py:496 templates/admin/import_export/change_list_export_item.html:5
|
||||||
|
#: templates/admin/import_export/export.html:7
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Esportare"
|
||||||
|
|
||||||
|
#: admin.py:554
|
||||||
|
msgid "You must select an export format."
|
||||||
|
msgstr "Devi selezionare un formato di esportazione."
|
||||||
|
|
||||||
|
#: admin.py:567
|
||||||
|
#, python-format
|
||||||
|
msgid "Export selected %(verbose_name_plural)s"
|
||||||
|
msgstr "Esporta selezionati %(verbose_name_plural)s"
|
||||||
|
|
||||||
|
#: forms.py:10
|
||||||
|
msgid "File to import"
|
||||||
|
msgstr "File da importare"
|
||||||
|
|
||||||
|
#: forms.py:13 forms.py:41 forms.py:66
|
||||||
|
msgid "Format"
|
||||||
|
msgstr "Formato"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/base.html:11
|
||||||
|
msgid "Home"
|
||||||
|
msgstr "Home"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/export.html:31
|
||||||
|
#: templates/admin/import_export/import.html:52
|
||||||
|
msgid "Submit"
|
||||||
|
msgstr "Inviare"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:20
|
||||||
|
msgid ""
|
||||||
|
"Below is a preview of data to be imported. If you are satisfied with the "
|
||||||
|
"results, click 'Confirm import'"
|
||||||
|
msgstr ""
|
||||||
|
"Questa è un'anteprima dei dati che saranno importati. Se il risultato è "
|
||||||
|
"soddisfacente, premi 'Conferma importazione'"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:23
|
||||||
|
msgid "Confirm import"
|
||||||
|
msgstr "Conferma importazione"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:31
|
||||||
|
msgid "This importer will import the following fields: "
|
||||||
|
msgstr "Verranno importati i seguenti campi:"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:61
|
||||||
|
#: templates/admin/import_export/import.html:90
|
||||||
|
msgid "Errors"
|
||||||
|
msgstr "Errori"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:72
|
||||||
|
msgid "Line number"
|
||||||
|
msgstr "Numero linea"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:82
|
||||||
|
msgid "Some rows failed to validate"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:84
|
||||||
|
msgid ""
|
||||||
|
"Please correct these errors in your data where possible, then reupload it "
|
||||||
|
"using the form above."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:89
|
||||||
|
msgid "Row"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:116
|
||||||
|
msgid "Non field specific"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:137
|
||||||
|
msgid "Preview"
|
||||||
|
msgstr "Anteprima"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:152
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Nuovo"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:154
|
||||||
|
msgid "Skipped"
|
||||||
|
msgstr "Salta"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:156
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Cancella"
|
||||||
|
|
||||||
|
#: templates/admin/import_export/import.html:158
|
||||||
|
msgid "Update"
|
||||||
|
msgstr "Aggiorna"
|
||||||
|
|
||||||
|
#~ msgid "Import finished"
|
||||||
|
#~ msgstr "Importazione terminata"
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
.import-preview .errors {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-error-count {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #e40000;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: white;
|
||||||
|
font-size: 0.9em;
|
||||||
|
position: relative;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: -2px;
|
||||||
|
padding: 0.2em 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-error-container {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
background-color: #ffc1c1;
|
||||||
|
padding: 14px 15px 10px;
|
||||||
|
top: 25px;
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
width: 200px;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.import-preview tr.skip {
|
||||||
|
background-color: #d2d2d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.import-preview tr.new {
|
||||||
|
background-color: #bdd8b2;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.import-preview tr.delete {
|
||||||
|
background-color: #f9bebf;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.import-preview tr.update {
|
||||||
|
background-color: #fdfdcf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.import-preview td:hover .validation-error-count {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
.import-preview td:hover .validation-error-container {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-error-list {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-error-list li {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-error-list > li > ul {
|
||||||
|
margin: 8px 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-error-list > li > ul > li {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
line-height: 1.28em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-error-field-label {
|
||||||
|
display: block;
|
||||||
|
border-bottom: 1px solid #e40000;
|
||||||
|
color: #e40000;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.85em;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{% extends "admin/base_site.html" %}
|
||||||
|
{% load i18n admin_modify %}
|
||||||
|
{% load admin_urls %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
|
||||||
|
{% block bodyclass %}{{ block.super }} {{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
|
||||||
|
{% if not is_popup %}
|
||||||
|
{% block breadcrumbs %}
|
||||||
|
<div class="breadcrumbs">
|
||||||
|
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
|
||||||
|
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
|
||||||
|
› <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
|
||||||
|
› {% block breadcrumbs_last %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{% extends "admin/change_list.html" %}
|
||||||
|
|
||||||
|
{# Original template renders object-tools only when has_add_permission is True. #}
|
||||||
|
{# This hack allows sub templates to add to object-tools #}
|
||||||
|
{% block object-tools %}
|
||||||
|
<ul class="object-tools">
|
||||||
|
{% block object-tools-items %}
|
||||||
|
{% if has_add_permission %}
|
||||||
|
{{ block.super }}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{% extends "admin/import_export/change_list.html" %}
|
||||||
|
|
||||||
|
{% block object-tools-items %}
|
||||||
|
{% include "admin/import_export/change_list_import_item.html" %}
|
||||||
|
{{ block.super }}
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
{% extends "admin/import_export/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load admin_urls %}
|
||||||
|
{% load import_export_tags %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "import_export/import.css" %}" />{% endblock %}
|
||||||
|
|
||||||
|
{% block breadcrumbs_last %}
|
||||||
|
{% trans "Import" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% if confirm_form %}
|
||||||
|
<form action="{% url opts|admin_urlname:"process_import" %}" method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ confirm_form.as_p }}
|
||||||
|
<p>
|
||||||
|
{% trans "Below is a preview of data to be imported. If you are satisfied with the results, click 'Confirm import'" %}
|
||||||
|
</p>
|
||||||
|
<div class="submit-row">
|
||||||
|
<input type="submit" class="default" name="confirm" value="{% trans "Confirm import" %}">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<form action="" method="post" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{% trans "This importer will import the following fields: " %}
|
||||||
|
<code>{{ fields|join:", " }}</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<fieldset class="module aligned">
|
||||||
|
{% for field in form %}
|
||||||
|
<div class="form-row">
|
||||||
|
{{ field.errors }}
|
||||||
|
|
||||||
|
{{ field.label_tag }}
|
||||||
|
|
||||||
|
{{ field }}
|
||||||
|
|
||||||
|
{% if field.field.help_text %}
|
||||||
|
<p class="help">{{ field.field.help_text|safe }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div class="submit-row">
|
||||||
|
<input type="submit" class="default" value="{% trans "Submit" %}">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if result %}
|
||||||
|
|
||||||
|
{% if result.has_errors %}
|
||||||
|
|
||||||
|
<h2>{% trans "Errors" %}</h2>
|
||||||
|
<ul>
|
||||||
|
{% for error in result.base_errors %}
|
||||||
|
<li>
|
||||||
|
{{ error.error }}
|
||||||
|
<div class="traceback">{{ error.traceback|linebreaks }}</div>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% for line, errors in result.row_errors %}
|
||||||
|
{% for error in errors %}
|
||||||
|
<li>
|
||||||
|
{% trans "Line number" %}: {{ line }} - {{ error.error }}
|
||||||
|
<div><code>{{ error.row.values|join:", " }}</code></div>
|
||||||
|
<div class="traceback">{{ error.traceback|linebreaks }}</div>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{% elif result.has_validation_errors %}
|
||||||
|
|
||||||
|
<h2>{% trans "Some rows failed to validate" %}</h2>
|
||||||
|
|
||||||
|
<p>{% trans "Please correct these errors in your data where possible, then reupload it using the form above." %}</p>
|
||||||
|
|
||||||
|
<table class="import-preview">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "Row" %}</th>
|
||||||
|
<th>{% trans "Errors" %}</th>
|
||||||
|
{% for field in result.diff_headers %}
|
||||||
|
<th>{{ field }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for row in result.invalid_rows %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ row.number }} </td>
|
||||||
|
<td class="errors">
|
||||||
|
<span class="validation-error-count">{{ row.error_count }}</span>
|
||||||
|
<div class="validation-error-container">
|
||||||
|
<ul class="validation-error-list">
|
||||||
|
{% for field_name, error_list in row.field_specific_errors.items %}
|
||||||
|
<li>
|
||||||
|
<span class="validation-error-field-label">{{ field_name }}</span>
|
||||||
|
<ul>
|
||||||
|
{% for error in error_list %}
|
||||||
|
<li>{{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% if row.non_field_specific_errors %}
|
||||||
|
<li>
|
||||||
|
<span class="validation-error-field-label">{% trans "Non field specific" %}</span>
|
||||||
|
<ul>
|
||||||
|
{% for error in row.non_field_specific_errors %}
|
||||||
|
<li>{{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{% for field in row.values %}
|
||||||
|
<td>{{ field }}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
<h2>{% trans "Preview" %}</h2>
|
||||||
|
|
||||||
|
<table class="import-preview">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
{% for field in result.diff_headers %}
|
||||||
|
<th>{{ field }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for row in result.valid_rows %}
|
||||||
|
<tr class="{{ row.import_type }}">
|
||||||
|
<td class="import-type">
|
||||||
|
{% if row.import_type == 'new' %}
|
||||||
|
{% trans "New" %}
|
||||||
|
{% elif row.import_type == 'skip' %}
|
||||||
|
{% trans "Skipped" %}
|
||||||
|
{% elif row.import_type == 'delete' %}
|
||||||
|
{% trans "Delete" %}
|
||||||
|
{% elif row.import_type == 'update' %}
|
||||||
|
{% trans "Update" %}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% for field in row.diff %}
|
||||||
|
<td>{{ field }}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
@@ -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", "0024_remove_theme_css"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="theme",
|
||||||
|
name="demo",
|
||||||
|
field=models.BooleanField(default=False, verbose_name="demo"),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -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", "0025_add_demo_option"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="theme",
|
||||||
|
name="user",
|
||||||
|
field=models.ForeignKey('auth.User', on_delete=models.CASCADE, null=True, blank=True, verbose_name="active for user"),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# Generated by Django 3.2.13 on 2022-04-28 16:03
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('admin_interface', '0026_add_user_option'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='theme',
|
||||||
|
name='user',
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserTheme',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('theme', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='admin_interface.theme')),
|
||||||
|
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, unique=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Users theme',
|
||||||
|
'verbose_name_plural': 'Users themes',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='theme',
|
||||||
|
name='users',
|
||||||
|
field=models.ManyToManyField(through='admin_interface.UserTheme', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.0.4 on 2022-08-25 14:44
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('admin_interface', '0027_usertheme_m2m'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='theme',
|
||||||
|
name='demo',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='is demo'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Generated by Django 4.0.3 on 2022-10-25 13:59
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import connection, migrations, models, transaction
|
||||||
|
|
||||||
|
|
||||||
|
def forward(apps, schema_editor):
|
||||||
|
Theme = apps.get_model("admin_interface", "Theme")
|
||||||
|
if len(Theme.objects.all()) == 1 and Theme.objects.first().name == 'Django':
|
||||||
|
with transaction.atomic():
|
||||||
|
cursor = connection.cursor()
|
||||||
|
cursor.execute("""truncate table "admin_interface_theme" restart identity;""")
|
||||||
|
|
||||||
|
def reverse(apps, schema_editor):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('admin_interface', '0028_alter_theme_demo'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(forward, reverse),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='usertheme',
|
||||||
|
name='user',
|
||||||
|
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
]
|
||||||
+68
-71
@@ -2,16 +2,28 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from admin_interface.cache import del_cached_active_theme
|
import inspect
|
||||||
from admin_interface.compat import FileExtensionValidator, force_str, gettext_lazy as _
|
|
||||||
|
|
||||||
from colorfield.fields import ColorField
|
from colorfield.fields import ColorField
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.signals import post_delete, post_save, pre_save
|
from django.db.models.signals import post_delete, post_save, pre_save
|
||||||
|
|
||||||
from six import python_2_unicode_compatible
|
from six import python_2_unicode_compatible
|
||||||
|
|
||||||
|
from admin_interface.cache import del_cached_active_theme
|
||||||
|
from admin_interface.compat import FileExtensionValidator, force_str
|
||||||
|
from admin_interface.compat import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
|
class UserTheme(models.Model):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'Users theme'
|
||||||
|
verbose_name_plural = 'Users themes'
|
||||||
|
|
||||||
|
user = models.OneToOneField(
|
||||||
|
'auth.User', on_delete=models.CASCADE, null=True)
|
||||||
|
theme = models.ForeignKey('Theme', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Theme(models.Model):
|
class Theme(models.Model):
|
||||||
@@ -25,22 +37,22 @@ class Theme(models.Model):
|
|||||||
del_cached_active_theme()
|
del_cached_active_theme()
|
||||||
Theme.get_active_theme()
|
Theme.get_active_theme()
|
||||||
|
|
||||||
@staticmethod
|
# @staticmethod
|
||||||
def post_save_handler(instance, **kwargs):
|
# def post_save_handler(instance, **kwargs):
|
||||||
del_cached_active_theme()
|
# del_cached_active_theme()
|
||||||
if instance.active:
|
# if instance.active:
|
||||||
Theme.objects.exclude(pk=instance.pk).update(active=False)
|
# Theme.objects.exclude(pk=instance.pk).update(active=False)
|
||||||
Theme.get_active_theme()
|
# Theme.get_active_theme()
|
||||||
|
|
||||||
@staticmethod
|
# @staticmethod
|
||||||
def pre_save_handler(instance, **kwargs):
|
# def pre_save_handler(instance, **kwargs):
|
||||||
if instance.pk is None:
|
# if instance.pk is None:
|
||||||
try:
|
# try:
|
||||||
obj = Theme.objects.get(name=instance.name)
|
# obj = Theme.objects.get(name=instance.name)
|
||||||
if obj:
|
# if obj:
|
||||||
instance.pk = obj.pk
|
# instance.pk = obj.pk
|
||||||
except Theme.DoesNotExist:
|
# except Theme.DoesNotExist:
|
||||||
pass
|
# pass
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_active_theme():
|
def get_active_theme():
|
||||||
@@ -53,13 +65,24 @@ class Theme(models.Model):
|
|||||||
obj = objs_manager.all().first()
|
obj = objs_manager.all().first()
|
||||||
if obj:
|
if obj:
|
||||||
obj.set_active()
|
obj.set_active()
|
||||||
else:
|
# else:
|
||||||
obj = objs_manager.create()
|
# obj = objs_manager.create()
|
||||||
|
|
||||||
elif objs_active_count == 1:
|
elif objs_active_count == 1:
|
||||||
obj = objs_active_ls[0]
|
obj = objs_active_ls[0]
|
||||||
|
|
||||||
elif objs_active_count > 1:
|
elif objs_active_count > 1:
|
||||||
|
for frame_record in inspect.stack():
|
||||||
|
if frame_record[3] == 'get_response':
|
||||||
|
request = frame_record[0].f_locals['request']
|
||||||
|
user = request.user
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
request = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
return objs_active_qs.filter(user=user).first()
|
||||||
|
except:
|
||||||
obj = objs_active_ls[-1]
|
obj = objs_active_ls[-1]
|
||||||
obj.set_active()
|
obj.set_active()
|
||||||
|
|
||||||
@@ -70,6 +93,9 @@ class Theme(models.Model):
|
|||||||
)
|
)
|
||||||
active = models.BooleanField(default=True, verbose_name=_("active"))
|
active = models.BooleanField(default=True, verbose_name=_("active"))
|
||||||
|
|
||||||
|
demo = models.BooleanField(default=False, verbose_name=_("is demo"))
|
||||||
|
users = models.ManyToManyField('auth.User', through=UserTheme)
|
||||||
|
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
default=_("Django administration"),
|
default=_("Django administration"),
|
||||||
@@ -83,7 +109,8 @@ class Theme(models.Model):
|
|||||||
max_length=10,
|
max_length=10,
|
||||||
verbose_name=_("color"),
|
verbose_name=_("color"),
|
||||||
)
|
)
|
||||||
title_visible = models.BooleanField(default=True, verbose_name=_("visible"))
|
title_visible = models.BooleanField(
|
||||||
|
default=True, verbose_name=_("visible"))
|
||||||
|
|
||||||
logo = models.FileField(
|
logo = models.FileField(
|
||||||
upload_to="admin-interface/logo/",
|
upload_to="admin-interface/logo/",
|
||||||
@@ -123,7 +150,8 @@ class Theme(models.Model):
|
|||||||
verbose_name=_("favicon"),
|
verbose_name=_("favicon"),
|
||||||
)
|
)
|
||||||
|
|
||||||
env_name = models.CharField(blank=True, max_length=50, verbose_name=_("name"))
|
env_name = models.CharField(
|
||||||
|
blank=True, max_length=50, verbose_name=_("name"))
|
||||||
env_color = ColorField(
|
env_color = ColorField(
|
||||||
blank=True,
|
blank=True,
|
||||||
default="#E74C3C",
|
default="#E74C3C",
|
||||||
@@ -144,14 +172,8 @@ class Theme(models.Model):
|
|||||||
default=True, verbose_name=_("active")
|
default=True, verbose_name=_("active")
|
||||||
)
|
)
|
||||||
language_chooser_display_choices = (
|
language_chooser_display_choices = (
|
||||||
(
|
("code", _("code")),
|
||||||
"code",
|
("name", _("name")),
|
||||||
_("code"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"name",
|
|
||||||
_("name"),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
language_chooser_display = models.CharField(
|
language_chooser_display = models.CharField(
|
||||||
max_length=10,
|
max_length=10,
|
||||||
@@ -294,7 +316,8 @@ class Theme(models.Model):
|
|||||||
verbose_name=_("text color"),
|
verbose_name=_("text color"),
|
||||||
)
|
)
|
||||||
|
|
||||||
related_modal_active = models.BooleanField(default=True, verbose_name=_("active"))
|
related_modal_active = models.BooleanField(
|
||||||
|
default=True, verbose_name=_("active"))
|
||||||
related_modal_background_color = ColorField(
|
related_modal_background_color = ColorField(
|
||||||
blank=True,
|
blank=True,
|
||||||
default="#000000",
|
default="#000000",
|
||||||
@@ -303,42 +326,15 @@ class Theme(models.Model):
|
|||||||
verbose_name=_("background color"),
|
verbose_name=_("background color"),
|
||||||
)
|
)
|
||||||
related_modal_background_opacity_choices = (
|
related_modal_background_opacity_choices = (
|
||||||
(
|
("0.1", "10%"),
|
||||||
"0.1",
|
("0.2", "20%"),
|
||||||
"10%",
|
("0.3", "30%"),
|
||||||
),
|
("0.4", "40%"),
|
||||||
(
|
("0.5", "50%"),
|
||||||
"0.2",
|
("0.6", "60%"),
|
||||||
"20%",
|
("0.7", "70%"),
|
||||||
),
|
("0.8", "80%"),
|
||||||
(
|
("0.9", "90%"),
|
||||||
"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(
|
related_modal_background_opacity = models.CharField(
|
||||||
max_length=5,
|
max_length=5,
|
||||||
@@ -361,7 +357,8 @@ class Theme(models.Model):
|
|||||||
default=True, verbose_name=_("sticky position")
|
default=True, verbose_name=_("sticky position")
|
||||||
)
|
)
|
||||||
|
|
||||||
foldable_apps = models.BooleanField(default=True, verbose_name=_("foldable apps"))
|
foldable_apps = models.BooleanField(
|
||||||
|
default=True, verbose_name=_("foldable apps"))
|
||||||
|
|
||||||
recent_actions_visible = models.BooleanField(
|
recent_actions_visible = models.BooleanField(
|
||||||
default=True, verbose_name=_("visible")
|
default=True, verbose_name=_("visible")
|
||||||
@@ -389,5 +386,5 @@ class Theme(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
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)
|
# pre_save.connect(Theme.pre_save_handler, sender=Theme)
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var windowRef = window;
|
var windowRef = window;
|
||||||
|
var windowRefProxy;
|
||||||
var windowName, widgetName;
|
var windowName, widgetName;
|
||||||
var openerRef = windowRef.opener;
|
var openerRef = windowRef.opener;
|
||||||
if (!openerRef) {
|
if (!openerRef) {
|
||||||
@@ -14,12 +15,14 @@
|
|||||||
// django < 3.1 compatibility
|
// django < 3.1 compatibility
|
||||||
widgetName = openerRef.id_to_windowname(widgetName);
|
widgetName = openerRef.id_to_windowname(widgetName);
|
||||||
}
|
}
|
||||||
windowRef = {
|
windowRefProxy = {
|
||||||
name: widgetName,
|
name: widgetName,
|
||||||
|
location: windowRef.location,
|
||||||
close: function() {
|
close: function() {
|
||||||
openerRef.dismissRelatedObjectModal();
|
openerRef.dismissRelatedObjectModal();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
windowRef = windowRefProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// default django popup_response.js
|
// default django popup_response.js
|
||||||
|
|||||||
+1
-1
@@ -1507,7 +1507,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Get element postion relative to viewport
|
// Get element position relative to viewport
|
||||||
_getOffset: function(isLarge) {
|
_getOffset: function(isLarge) {
|
||||||
var el;
|
var el;
|
||||||
if(isLarge) {
|
if(isLarge) {
|
||||||
|
|||||||
@@ -136,23 +136,30 @@ if (typeof(django) !== 'undefined' && typeof(django.jQuery) !== 'undefined')
|
|||||||
window.presentRelatedObjectModalOnClickOn = presentRelatedObjectModalOnClickOn;
|
window.presentRelatedObjectModalOnClickOn = presentRelatedObjectModalOnClickOn;
|
||||||
|
|
||||||
// django 1.7 compatibility
|
// django 1.7 compatibility
|
||||||
// $('a.add-another').removeAttr('onclick').click({ lookup:false }, presentRelatedObjectModal);
|
|
||||||
presentRelatedObjectModalOnClickOn('a.add-another');
|
presentRelatedObjectModalOnClickOn('a.add-another');
|
||||||
|
|
||||||
// django 1.8 and above
|
// django 1.8 and above
|
||||||
// $('a.related-widget-wrapper-link').click({ lookup:false }, presentRelatedObjectModal);
|
|
||||||
presentRelatedObjectModalOnClickOn('a.related-widget-wrapper-link');
|
presentRelatedObjectModalOnClickOn('a.related-widget-wrapper-link');
|
||||||
|
|
||||||
// raw_id_fields support
|
// raw_id_fields support
|
||||||
// $('a.related-lookup').unbind('click').click({ lookup:true }, presentRelatedObjectModal);
|
|
||||||
presentRelatedObjectModalOnClickOn('a.related-lookup', true);
|
presentRelatedObjectModalOnClickOn('a.related-lookup', true);
|
||||||
|
|
||||||
// django-dynamic-raw-id support - #61
|
// django-dynamic-raw-id support - #61
|
||||||
// https://github.com/lincolnloop/django-dynamic-raw-id
|
// https://github.com/lincolnloop/django-dynamic-raw-id
|
||||||
presentRelatedObjectModalOnClickOn('a.dynamic_raw_id-related-lookup', true);
|
presentRelatedObjectModalOnClickOn('a.dynamic_raw_id-related-lookup', true);
|
||||||
|
|
||||||
// show_change_link=True support
|
// django-streamfield support
|
||||||
presentRelatedObjectModalOnClickOn('a.inlinechangelink');
|
// https://github.com/raagin/django-streamfield/
|
||||||
|
presentRelatedObjectModalOnClickOn('.streamfield_app a.stream-btn[href*="_popup=1"]');
|
||||||
|
// Vanilla js for catching the click during capture phase for anticipating Vue.js listener.
|
||||||
|
document.addEventListener('click', function(event) {
|
||||||
|
// console.log('click intercepted before Vue.');
|
||||||
|
if (event.target.matches('.streamfield_app a.stream-btn[href*="_popup=1"]')) {
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
$(event.target).trigger('click');
|
||||||
|
}
|
||||||
|
}, { capture: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
})(django.jQuery);
|
})(django.jQuery);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ CKEDITOR.skin.name = 'husky';
|
|||||||
// the complete list:
|
// the complete list:
|
||||||
// http://docs.ckeditor.com/#!/api/CKEDITOR.env
|
// http://docs.ckeditor.com/#!/api/CKEDITOR.env
|
||||||
//
|
//
|
||||||
// Internet explorer is an expection and the browser version is also accepted
|
// Internet explorer is an exception and the browser version is also accepted
|
||||||
// (ie7, ie8, ie9, ie10), as well as a special name for IE in Quirks mode (iequirks).
|
// (ie7, ie8, ie9, ie10), as well as a special name for IE in Quirks mode (iequirks).
|
||||||
//
|
//
|
||||||
// The available browser specific files must be set separately for editor.css
|
// The available browser specific files must be set separately for editor.css
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var windowRef = window;
|
||||||
|
var openerRef = windowRef.parent;
|
||||||
|
|
||||||
|
var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse);
|
||||||
|
switch (initData.action) {
|
||||||
|
case 'change':
|
||||||
|
openerRef.streamapps[initData.app_id].updateBlock(initData.block_id, initData.instance_id);
|
||||||
|
openerRef.dismissRelatedObjectModal();
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
openerRef.streamapps[initData.app_id].updateBlock(initData.block_id, initData.instance_id);
|
||||||
|
openerRef.dismissRelatedObjectModal();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -10,13 +10,81 @@
|
|||||||
{% get_admin_interface_theme as theme %}
|
{% get_admin_interface_theme as theme %}
|
||||||
{% get_admin_interface_nocache as version_md5_cache %}
|
{% get_admin_interface_nocache as version_md5_cache %}
|
||||||
{% get_current_language as current_lang %}
|
{% get_current_language as current_lang %}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
:root .admin-interface {
|
||||||
|
--admin-interface-title-color: {{ theme.title_color }};
|
||||||
|
--admin-interface-logo-color: {{ theme.logo_color }};
|
||||||
|
--admin-interface-logo-default-background-image: url("data:image/svg+xml;utf8,<?xml version='1.0' encoding='utf-8'?><svg width='104px' height='36px' viewBox='0 0 104 36' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:sketch='http://www.bohemiancoding.com/sketch/ns'><g id='Page-1' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' sketch:type='MSPage'><g id='logo-django' sketch:type='MSArtboardGroup' transform='translate(-8.000000, -5.000000)' fill='{{ theme.logo_color|urlencode }}'><path d='M20.2602817,5 L25.9509859,5 L25.9509859,31.0824248 C23.0360563,31.6338042 20.8901408,31.8507285 18.5684507,31.8507285 C11.6180282,31.8434735 8,28.7383366 8,22.7747325 C8,17.0287781 11.8377465,13.2997118 17.7847887,13.2997118 C18.7076056,13.2997118 19.4107042,13.3722617 20.2602817,13.5899115 L20.2602817,5 L20.2602817,5 Z M20.2602817,18.1242821 C19.5938028,17.9066323 19.044507,17.8340823 18.3414085,17.8340823 C15.4630986,17.8340823 13.8005634,19.5897906 13.8005634,22.6666331 C13.8005634,25.6622196 15.3898592,27.316358 18.3047887,27.316358 C18.9346479,27.316358 19.4473239,27.2808085 20.2602817,27.1719836 L20.2602817,18.1242821 L20.2602817,18.1242821 Z M34.9960563,13.6987364 L34.9960563,26.7577235 C34.9960563,31.2550936 34.6591549,33.417807 33.6704225,35.2823401 C32.7476056,37.0750489 31.531831,38.2053768 29.0197183,39.453961 L23.7391549,36.9654985 C26.2512676,35.7981701 27.4670423,34.7665101 28.2433803,33.1921767 C29.056338,31.5822938 29.3126761,29.7177606 29.3126761,24.8133855 L29.3126761,13.6987364 L34.9960563,13.6987364 Z M29.3126761,5.02901997 L35.0033803,5.02901997 L35.0033803,10.8112493 L29.3126761,10.8112493 L29.3126761,5.02901997 Z M38.4302535,14.9828702 C40.9430986,13.8148163 43.3453521,13.2997118 45.9673239,13.2997118 C48.8895775,13.2997118 50.8077183,14.0687411 51.6580282,15.5705246 C52.1340845,16.4121037 52.2878873,17.5076077 52.2878873,19.8509704 L52.2878873,31.2993491 C49.7398873,31.6620987 46.5239437,31.922553 44.1649014,31.922553 C39.3970141,31.922553 37.2584225,30.2756696 37.2584225,26.6198787 C37.2584225,22.6659076 40.1008451,20.8376494 47.079831,20.2565245 L47.079831,19.0159207 C47.079831,17.9929667 46.559831,17.6229621 45.124338,17.6229621 C43.0223662,17.6229621 40.6567324,18.2106165 38.4375775,19.3423954 L38.4302535,14.9828702 Z M47.336169,23.9420608 C43.571662,24.3048105 42.3485634,24.8931904 42.3485634,26.3579734 C42.3485634,27.4549284 43.051662,27.9693073 44.604338,27.9693073 C45.4539155,27.9693073 46.2302535,27.8967574 47.3354366,27.7153826 L47.3354366,23.9420608 L47.336169,23.9420608 Z M55.056338,14.5765906 C58.4180282,13.6987364 61.1857465,13.2997118 63.9908169,13.2997118 C66.9057465,13.2997118 69.0157746,13.9599162 70.2674366,15.2367949 C71.4458592,16.4411237 71.8208451,17.7615324 71.8208451,20.5764696 L71.8208451,31.6258237 L66.1294085,31.6258237 L66.1294085,20.8013744 C66.1294085,18.6393866 65.3896901,17.8340823 63.3616901,17.8340823 C62.5846197,17.8340823 61.8822535,17.9066323 60.7397183,18.2403619 L60.7397183,31.6265492 L55.056338,31.6265492 L55.056338,14.5765906 Z M74.0326761,34.7012152 C76.0240563,35.7241692 78.0169014,36.1964692 80.1261972,36.1964692 C83.8540845,36.1964692 85.4433803,34.6946857 85.4433803,31.1107193 L85.4433803,31.0018944 C84.3374648,31.5460188 83.223493,31.7716491 81.7513803,31.7716491 C76.764507,31.7716491 73.5932394,28.5141573 73.5932394,23.3558574 C73.5932394,16.9496987 78.2878873,13.3294573 86.5932394,13.3294573 C89.0321127,13.3294573 91.2878873,13.583382 94.0189859,14.1347615 L92.0708169,18.1975575 C90.5562254,17.9073578 91.9463099,18.1540275 90.804507,18.0452026 L90.804507,18.6328571 L90.8777465,21.0124947 L90.9136338,24.0886117 C90.9509859,24.8583664 90.9509859,25.6259447 90.988338,26.3956994 L90.988338,27.9330324 C90.988338,32.7648576 90.5774648,35.0291409 89.3616901,36.900929 C87.5892958,39.6425908 84.5212958,41 80.1620845,41 C77.943662,41 76.0240563,40.6727998 74.0326761,39.9030451 L74.0326761,34.7012152 L74.0326761,34.7012152 Z M85.3335211,17.8703573 L85.1504225,17.8703573 L84.7395493,17.8703573 C83.6336338,17.8340823 82.3380282,18.1242821 81.4510986,18.6756615 C80.0895775,19.4446908 79.3872113,20.8376494 79.3872113,22.8110074 C79.3872113,25.6252192 80.7934085,27.2365531 83.3055211,27.2365531 C84.0811268,27.2365531 84.7117183,27.0921787 85.4441127,26.8738034 L85.4441127,26.4667983 L85.4441127,24.9294653 C85.4441127,24.269261 85.4067606,23.5365067 85.4067606,22.7674775 L85.3708732,20.17019 L85.3335211,18.3056569 L85.3335211,17.8703573 Z M102.84507,13.2271619 C108.528451,13.2271619 112,16.7748534 112,22.5208077 C112,28.4118619 108.382704,32.1039278 102.617296,32.1039278 C96.9265915,32.1039278 93.4176901,28.5569618 93.4176901,22.8480079 C93.4272113,16.9199532 97.044507,13.2271619 102.84507,13.2271619 Z M102.727887,27.5623023 C104.910423,27.5623023 106.199437,25.7710445 106.199437,22.6586526 C106.199437,19.5825356 104.94631,17.7542774 102.765239,17.7542774 C100.509465,17.7542774 99.2189859,Line truncated
|
||||||
|
--admin-interface-env-color: {{ theme.env_color }};
|
||||||
|
--admin-interface-header-background-color: {{ theme.css_header_background_color }};
|
||||||
|
--admin-interface-header-text-color: {{ theme.css_header_text_color }};
|
||||||
|
--admin-interface-header-link-color: {{ theme.css_header_link_color }};
|
||||||
|
--admin-interface-header-link-hover-color: {{ theme.css_header_link_hover_color }};
|
||||||
|
--admin-interface-module-background-color: {{ theme.css_module_background_color }};
|
||||||
|
--admin-interface-module-background-selected-color: {{ theme.css_module_background_selected_color }};
|
||||||
|
--admin-interface-module-text-color: {{ theme.css_module_text_color }};
|
||||||
|
--admin-interface-module-link-color: {{ theme.css_module_link_color }};
|
||||||
|
--admin-interface-module-link-selected-color: {{ theme.css_module_link_selected_color }};
|
||||||
|
--admin-interface-module-link-hover-color: {{ theme.css_module_link_hover_color }};
|
||||||
|
--admin-interface-generic-link-color: {{ theme.css_generic_link_color }};
|
||||||
|
--admin-interface-generic-link-hover-color: {{ theme.css_generic_link_hover_color }};
|
||||||
|
--admin-interface-save-button-background-color: {{ theme.css_save_button_background_color }};
|
||||||
|
--admin-interface-save-button-background-hover-color: {{ theme.css_save_button_background_hover_color }};
|
||||||
|
--admin-interface-save-button-text-color: {{ theme.css_save_button_text_color }};
|
||||||
|
--admin-interface-delete-button-background-color: {{ theme.css_delete_button_background_color }};
|
||||||
|
--admin-interface-delete-button-background-hover-color: {{ theme.css_delete_button_background_hover_color }};
|
||||||
|
--admin-interface-delete-button-text-color: {{ theme.css_delete_button_text_color }};
|
||||||
|
--admin-interface-related-modal-background-color: {{ theme.related_modal_background_color }};
|
||||||
|
--admin-interface-related-modal-background-opacity: {{ theme.related_modal_background_opacity }};
|
||||||
|
|
||||||
|
{% if theme.css_header_background_color != theme.css_module_background_color %}
|
||||||
|
--admin-interface-main-border-top: 10px solid var(--admin-interface-module-background-color);
|
||||||
|
{% else %}
|
||||||
|
--admin-interface-main-border-top: 0px;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if theme.logo_max_width > 0 %}
|
||||||
|
--admin-interface-logo-max-width: min({{ theme.logo_max_width }}px, 100%);
|
||||||
|
{% else %}
|
||||||
|
--admin-interface-logo-max-width: 100%;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if theme.logo_max_height > 0 %}
|
||||||
|
--admin-interface-logo-max-height: {{ theme.logo_max_height }}px;
|
||||||
|
{% else %}
|
||||||
|
--admin-interface-logo-max-height: unset;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if theme.related_modal_rounded_corners %}
|
||||||
|
--admin-interface-related-modal-border-radius: 4px;
|
||||||
|
{% else %}
|
||||||
|
--admin-interface-related-modal-border-radius: 0px;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if theme.css_module_rounded_corners %}
|
||||||
|
--admin-interface-module-border-radius: 4px;
|
||||||
|
--admin-interface-jsoneditor-border-radius: var(--admin-interface-module-border-radius);
|
||||||
|
--admin-interface-jsoneditor-overflow: hidden;
|
||||||
|
{% else %}
|
||||||
|
--admin-interface-module-border-radius: 0px;
|
||||||
|
--admin-interface-jsoneditor-border-radius: var(--admin-interface-module-border-radius);
|
||||||
|
--admin-interface-jsoneditor-overflow: unset;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not theme.related_modal_close_button_visible %}
|
||||||
|
--admin-interface-related-modal-close-button-display: none;
|
||||||
|
{% else %}
|
||||||
|
--admin-interface-related-modal-close-button-display: unset;
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
{% 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/form-controls.css" %}
|
{% include "admin_interface/css/form-controls.css" %}
|
||||||
|
{% include "admin_interface/css/language-chooser.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/streamfield.css" %}
|
||||||
{% include "admin_interface/css/jquery.ui.tabs.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" %}
|
||||||
@@ -57,6 +125,7 @@ flat-theme admin-interface
|
|||||||
{% if theme.foldable_apps %} foldable-apps {% endif %}
|
{% if theme.foldable_apps %} foldable-apps {% endif %}
|
||||||
{% if theme.form_submit_sticky %} sticky-submit {% endif %}
|
{% if theme.form_submit_sticky %} sticky-submit {% endif %}
|
||||||
{% if theme.form_pagination_sticky %} sticky-pagination {% endif %}
|
{% if theme.form_pagination_sticky %} sticky-pagination {% endif %}
|
||||||
|
{% if theme.list_filter_sticky %} list-filter-sticky {% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block branding %}
|
{% block branding %}
|
||||||
@@ -83,5 +152,5 @@ flat-theme admin-interface
|
|||||||
{% get_admin_interface_languages as languages %}
|
{% get_admin_interface_languages as languages %}
|
||||||
{% include "admin_interface/language_chooser.html" %}
|
{% include "admin_interface/language_chooser.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if theme.env_visible_in_header %}<span class="environment-label {{ theme.env_name }}"></span><br>{% endif %}{{ block.super }}<br>
|
{% if theme.env_visible_in_header %}<span class="environment-label"></span><br>{% endif %}{{ block.super }}<br>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
.admin-interface #user-tools {
|
.admin-interface #user-tools {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
white-space: nowrap;
|
white-space: normal;
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,41 +42,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .admin-interface {
|
|
||||||
--admin-interface-title-color: {{ theme.title_color }};
|
|
||||||
--admin-interface-logo-color: {{ theme.logo_color }};
|
|
||||||
--admin-interface-env-color: {{ theme.env_color }};
|
|
||||||
--admin-interface-header-background-color: {{ theme.css_header_background_color }};
|
|
||||||
--admin-interface-header-text-color: {{ theme.css_header_text_color }};
|
|
||||||
--admin-interface-header-link-color: {{ theme.css_header_link_color }};
|
|
||||||
--admin-interface-header-link_hover-color: {{ theme.css_header_link_hover_color }};
|
|
||||||
--admin-interface-module-background-color: {{ theme.css_module_background_color }};
|
|
||||||
--admin-interface-module-background-selected-color: {{ theme.css_module_background_selected_color }};
|
|
||||||
--admin-interface-module-text-color: {{ theme.css_module_text_color }};
|
|
||||||
--admin-interface-module-link-color: {{ theme.css_module_link_color }};
|
|
||||||
--admin-interface-module-link-selected-color: {{ theme.css_module_link_selected_color }};
|
|
||||||
--admin-interface-module-link-hover-color: {{ theme.css_module_link_hover_color }};
|
|
||||||
--admin-interface-generic-link-color: {{ theme.css_generic_link_color }};
|
|
||||||
--admin-interface-generic-link-hover-color: {{ theme.css_generic_link_hover_color }};
|
|
||||||
--admin-interface-save-button-background-color: {{ theme.css_save_button_background_color }};
|
|
||||||
--admin-interface-save-button-background-hover-color: {{ theme.css_save_button_background_hover_color }};
|
|
||||||
--admin-interface-save-button-text-color: {{ theme.css_save_button_text_color }};
|
|
||||||
--admin-interface-delete-button-background-color: {{ theme.css_delete_button_background_color }};
|
|
||||||
--admin-interface-delete-button-background-hover-color: {{ theme.css_delete_button_background_hover_color }};
|
|
||||||
--admin-interface-delete-button-text-color: {{ theme.css_delete_button_text_color }};
|
|
||||||
--admin-interface-related-modal-background-color: {{ theme.related_modal_background_color }};
|
|
||||||
--admin-interface-related-modal-background-opacity: {{ theme.related_modal_background_opacity }};
|
|
||||||
}
|
|
||||||
|
|
||||||
.admin-interface #header {
|
.admin-interface #header {
|
||||||
background: {{ theme.css_header_background_color }};
|
background: var(--admin-interface-header-background-color);
|
||||||
color: {{ theme.css_header_text_color }};
|
color: var(--admin-interface-header-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #header + #main {
|
.admin-interface #header + #main {
|
||||||
{% if theme.css_header_background_color != theme.css_module_background_color %}
|
border-top: var(--admin-interface-main-border-top);
|
||||||
border-top: 10px solid {{ theme.css_module_background_color }};
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .environment-label {
|
.admin-interface .environment-label {
|
||||||
@@ -87,7 +59,7 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
background-color: {{ theme.env_color }};
|
background-color: var(--admin-interface-env-color);
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -99,7 +71,7 @@
|
|||||||
content: "{{ theme.env_name }} - ";
|
content: "{{ theme.env_name }} - ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width:1024px) {
|
@media (max-width: 1024px) {
|
||||||
.admin-interface .environment-label::after {
|
.admin-interface .environment-label::after {
|
||||||
content: "{{ theme.env_name }}";
|
content: "{{ theme.env_name }}";
|
||||||
}
|
}
|
||||||
@@ -112,12 +84,14 @@
|
|||||||
right: 15px;
|
right: 15px;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
@media (min-width:768px) {
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
.admin-interface .language-chooser {
|
.admin-interface .language-chooser {
|
||||||
right: 30px;
|
right: 30px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media (min-width:1024px) {
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
.admin-interface .language-chooser {
|
.admin-interface .language-chooser {
|
||||||
position: static;
|
position: static;
|
||||||
float: right;
|
float: right;
|
||||||
@@ -136,7 +110,7 @@
|
|||||||
.admin-interface #branding h1,
|
.admin-interface #branding h1,
|
||||||
.admin-interface.login #header h1,
|
.admin-interface.login #header h1,
|
||||||
.admin-interface.login #header h1 a {
|
.admin-interface.login #header h1 a {
|
||||||
color: {{ theme.title_color }};
|
color: var(--admin-interface-title-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #branding h1 a {
|
.admin-interface #branding h1 a {
|
||||||
@@ -148,134 +122,125 @@
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
background-size: 104px 36px;
|
background-size: 104px 36px;
|
||||||
background-image: url("data:image/svg+xml;utf8,<?xml version='1.0' encoding='utf-8'?><svg width='104px' height='36px' viewBox='0 0 104 36' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:sketch='http://www.bohemiancoding.com/sketch/ns'><g id='Page-1' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' sketch:type='MSPage'><g id='logo-django' sketch:type='MSArtboardGroup' transform='translate(-8.000000, -5.000000)' fill='{{ theme.logo_color|urlencode }}'><path d='M20.2602817,5 L25.9509859,5 L25.9509859,31.0824248 C23.0360563,31.6338042 20.8901408,31.8507285 18.5684507,31.8507285 C11.6180282,31.8434735 8,28.7383366 8,22.7747325 C8,17.0287781 11.8377465,13.2997118 17.7847887,13.2997118 C18.7076056,13.2997118 19.4107042,13.3722617 20.2602817,13.5899115 L20.2602817,5 L20.2602817,5 Z M20.2602817,18.1242821 C19.5938028,17.9066323 19.044507,17.8340823 18.3414085,17.8340823 C15.4630986,17.8340823 13.8005634,19.5897906 13.8005634,22.6666331 C13.8005634,25.6622196 15.3898592,27.316358 18.3047887,27.316358 C18.9346479,27.316358 19.4473239,27.2808085 20.2602817,27.1719836 L20.2602817,18.1242821 L20.2602817,18.1242821 Z M34.9960563,13.6987364 L34.9960563,26.7577235 C34.9960563,31.2550936 34.6591549,33.417807 33.6704225,35.2823401 C32.7476056,37.0750489 31.531831,38.2053768 29.0197183,39.453961 L23.7391549,36.9654985 C26.2512676,35.7981701 27.4670423,34.7665101 28.2433803,33.1921767 C29.056338,31.5822938 29.3126761,29.7177606 29.3126761,24.8133855 L29.3126761,13.6987364 L34.9960563,13.6987364 Z M29.3126761,5.02901997 L35.0033803,5.02901997 L35.0033803,10.8112493 L29.3126761,10.8112493 L29.3126761,5.02901997 Z M38.4302535,14.9828702 C40.9430986,13.8148163 43.3453521,13.2997118 45.9673239,13.2997118 C48.8895775,13.2997118 50.8077183,14.0687411 51.6580282,15.5705246 C52.1340845,16.4121037 52.2878873,17.5076077 52.2878873,19.8509704 L52.2878873,31.2993491 C49.7398873,31.6620987 46.5239437,31.922553 44.1649014,31.922553 C39.3970141,31.922553 37.2584225,30.2756696 37.2584225,26.6198787 C37.2584225,22.6659076 40.1008451,20.8376494 47.079831,20.2565245 L47.079831,19.0159207 C47.079831,17.9929667 46.559831,17.6229621 45.124338,17.6229621 C43.0223662,17.6229621 40.6567324,18.2106165 38.4375775,19.3423954 L38.4302535,14.9828702 Z M47.336169,23.9420608 C43.571662,24.3048105 42.3485634,24.8931904 42.3485634,26.3579734 C42.3485634,27.4549284 43.051662,27.9693073 44.604338,27.9693073 C45.4539155,27.9693073 46.2302535,27.8967574 47.3354366,27.7153826 L47.3354366,23.9420608 L47.336169,23.9420608 Z M55.056338,14.5765906 C58.4180282,13.6987364 61.1857465,13.2997118 63.9908169,13.2997118 C66.9057465,13.2997118 69.0157746,13.9599162 70.2674366,15.2367949 C71.4458592,16.4411237 71.8208451,17.7615324 71.8208451,20.5764696 L71.8208451,31.6258237 L66.1294085,31.6258237 L66.1294085,20.8013744 C66.1294085,18.6393866 65.3896901,17.8340823 63.3616901,17.8340823 C62.5846197,17.8340823 61.8822535,17.9066323 60.7397183,18.2403619 L60.7397183,31.6265492 L55.056338,31.6265492 L55.056338,14.5765906 Z M74.0326761,34.7012152 C76.0240563,35.7241692 78.0169014,36.1964692 80.1261972,36.1964692 C83.8540845,36.1964692 85.4433803,34.6946857 85.4433803,31.1107193 L85.4433803,31.0018944 C84.3374648,31.5460188 83.223493,31.7716491 81.7513803,31.7716491 C76.764507,31.7716491 73.5932394,28.5141573 73.5932394,23.3558574 C73.5932394,16.9496987 78.2878873,13.3294573 86.5932394,13.3294573 C89.0321127,13.3294573 91.2878873,13.583382 94.0189859,14.1347615 L92.0708169,18.1975575 C90.5562254,17.9073578 91.9463099,18.1540275 90.804507,18.0452026 L90.804507,18.6328571 L90.8777465,21.0124947 L90.9136338,24.0886117 C90.9509859,24.8583664 90.9509859,25.6259447 90.988338,26.3956994 L90.988338,27.9330324 C90.988338,32.7648576 90.5774648,35.0291409 89.3616901,36.900929 C87.5892958,39.6425908 84.5212958,41 80.1620845,41 C77.943662,41 76.0240563,40.6727998 74.0326761,39.9030451 L74.0326761,34.7012152 L74.0326761,34.7012152 Z M85.3335211,17.8703573 L85.1504225,17.8703573 L84.7395493,17.8703573 C83.6336338,17.8340823 82.3380282,18.1242821 81.4510986,18.6756615 C80.0895775,19.4446908 79.3872113,20.8376494 79.3872113,22.8110074 C79.3872113,25.6252192 80.7934085,27.2365531 83.3055211,27.2365531 C84.0811268,27.2365531 84.7117183,27.0921787 85.4441127,26.8738034 L85.4441127,26.4667983 L85.4441127,24.9294653 C85.4441127,24.269261 85.4067606,23.5365067 85.4067606,22.7674775 L85.3708732,20.17019 L85.3335211,18.3056569 L85.3335211,17.8703573 Z M102.84507,13.2271619 C108.528451,13.2271619 112,16.7748534 112,22.5208077 C112,28.4118619 108.382704,32.1039278 102.617296,32.1039278 C96.9265915,32.1039278 93.4176901,28.5569618 93.4176901,22.8480079 C93.4272113,16.9199532 97.044507,13.2271619 102.84507,13.2271619 Z M102.727887,27.5623023 C104.910423,27.5623023 106.199437,25.7710445 106.199437,22.6586526 C106.199437,19.5825356 104.94631,17.7542774 102.765239,17.7542774 C100.509465,17.7542774 99.2189859,19.5462607 99.2189859,22.6586526 C99.21Line truncated
|
background-image: var(--admin-interface-logo-default-background-image);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #branding h1 img.logo,
|
.admin-interface #branding h1 img.logo,
|
||||||
.admin-interface.login #header #branding h1 img.logo {
|
.admin-interface.login #header #branding h1 img.logo {
|
||||||
{% if theme.logo_max_width > 0 %}
|
max-width: var(--admin-interface-logo-max-width);
|
||||||
max-width: {{ theme.logo_max_width }}px;
|
max-height: var(--admin-interface-logo-max-height);
|
||||||
max-width: min({{ theme.logo_max_width }}px, 100%);
|
|
||||||
{% else %}
|
|
||||||
max-width: 100%;
|
|
||||||
{% endif %}
|
|
||||||
{% if theme.logo_max_height > 0 %}
|
|
||||||
max-height: {{ theme.logo_max_height }}px;
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #header #user-tools a {
|
.admin-interface #header #user-tools a {
|
||||||
color:{{ theme.css_header_link_color }};
|
color: var(--admin-interface-header-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #header #user-tools a:hover,
|
.admin-interface #header #user-tools a:hover,
|
||||||
.admin-interface #header #user-tools a:active {
|
.admin-interface #header #user-tools a:active {
|
||||||
color:{{ theme.css_header_link_hover_color }};
|
color: var(--admin-interface-header-link-hover-color);
|
||||||
border-bottom-color:rgba(255, 255, 255, 0.5);
|
border-bottom-color: rgba(255, 255, 255, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #nav-sidebar .current-app .section:link,
|
.admin-interface #nav-sidebar .current-app .section:link,
|
||||||
.admin-interface #nav-sidebar .current-app .section:visited {
|
.admin-interface #nav-sidebar .current-app .section:visited {
|
||||||
color: {{ theme.css_module_link_selected_color }};
|
color: var(--admin-interface-module-link-selected-color);
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #nav-sidebar .current-app .section:focus,
|
.admin-interface #nav-sidebar .current-app .section:focus,
|
||||||
.admin-interface #nav-sidebar .current-app .section:hover {
|
.admin-interface #nav-sidebar .current-app .section:hover {
|
||||||
color: {{ theme.css_module_link_hover_color }};
|
color: var(--admin-interface-module-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #nav-sidebar .current-model {
|
.admin-interface #nav-sidebar .current-model {
|
||||||
background: {{ theme.css_module_background_selected_color }};
|
background: var(--admin-interface-module-background-selected-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #changelist table tbody tr.selected {
|
.admin-interface #changelist table tbody tr.selected {
|
||||||
background-color: {{ theme.css_module_background_selected_color }};
|
background-color: var(--admin-interface-module-background-selected-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .module h2,
|
.admin-interface .module h2,
|
||||||
.admin-interface .module caption,
|
.admin-interface .module caption,
|
||||||
.admin-interface .module.filtered h2 {
|
.admin-interface .module.filtered h2 {
|
||||||
background:{{ theme.css_module_background_color }};
|
background: var(--admin-interface-module-background-color);
|
||||||
color:{{ theme.css_module_text_color }};
|
color: var(--admin-interface-module-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .module a.section:link,
|
.admin-interface .module a.section:link,
|
||||||
.admin-interface .module a.section:visited {
|
.admin-interface .module a.section:visited {
|
||||||
color:{{ theme.css_module_link_color }};
|
color: var(--admin-interface-module-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .module a.section:active,
|
.admin-interface .module a.section:active,
|
||||||
.admin-interface .module a.section:hover {
|
.admin-interface .module a.section:hover {
|
||||||
color:{{ theme.css_module_link_hover_color }};
|
color: var(--admin-interface-module-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface div.breadcrumbs {
|
.admin-interface div.breadcrumbs {
|
||||||
background:{{ theme.css_module_background_color }};
|
background: var(--admin-interface-module-background-color);
|
||||||
color:{{ theme.css_module_text_color }};
|
color: var(--admin-interface-module-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface div.breadcrumbs a {
|
.admin-interface div.breadcrumbs a {
|
||||||
color:{{ theme.css_module_link_color }};
|
color: var(--admin-interface-module-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface div.breadcrumbs a:active,
|
.admin-interface div.breadcrumbs a:active,
|
||||||
.admin-interface div.breadcrumbs a:focus,
|
.admin-interface div.breadcrumbs a:focus,
|
||||||
.admin-interface div.breadcrumbs a:hover {
|
.admin-interface div.breadcrumbs a:hover {
|
||||||
color:{{ theme.css_module_link_hover_color }};
|
color: var(--admin-interface-module-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface fieldset.collapse.collapsed a.collapse-toggle {
|
.admin-interface fieldset.collapse.collapsed a.collapse-toggle {
|
||||||
color:{{ theme.css_module_link_color }};
|
color: var(--admin-interface-module-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface fieldset.collapse.collapsed a.collapse-toggle:hover,
|
.admin-interface fieldset.collapse.collapsed a.collapse-toggle:hover,
|
||||||
.admin-interface fieldset.collapse.collapsed a.collapse-toggle:active {
|
.admin-interface fieldset.collapse.collapsed a.collapse-toggle:active {
|
||||||
color:{{ theme.css_module_link_hover_color }};
|
color: var(--admin-interface-module-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface fieldset.collapse a.collapse-toggle {
|
.admin-interface fieldset.collapse a.collapse-toggle {
|
||||||
color:{{ theme.css_module_link_color }};
|
color: var(--admin-interface-module-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface fieldset.collapse a.collapse-toggle:hover,
|
.admin-interface fieldset.collapse a.collapse-toggle:hover,
|
||||||
.admin-interface fieldset.collapse a.collapse-toggle:active {
|
.admin-interface fieldset.collapse a.collapse-toggle:active {
|
||||||
color:{{ theme.css_module_link_hover_color }};
|
color: var(--admin-interface-module-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .inline-group h2 {
|
.admin-interface .inline-group h2 {
|
||||||
background:{{ theme.css_module_background_color }};
|
background: var(--admin-interface-module-background-color);
|
||||||
color:{{ theme.css_module_text_color }};
|
color: var(--admin-interface-module-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .selector .selector-chosen h2 {
|
.admin-interface .selector .selector-chosen h2 {
|
||||||
border-color:{{ theme.css_module_background_color }};
|
border-color: var(--admin-interface-module-background-color);
|
||||||
background:{{ theme.css_module_background_color }};
|
background: var(--admin-interface-module-background-color);
|
||||||
color:{{ theme.css_module_text_color }};
|
color: var(--admin-interface-module-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .selector .selector-available h2,
|
.admin-interface .selector .selector-available h2,
|
||||||
.admin-interface .selector .selector-chosen h2 {
|
.admin-interface .selector .selector-chosen h2 {
|
||||||
{% if theme.css_module_rounded_corners %}
|
border-bottom-left-radius: 0px;
|
||||||
border-bottom-left-radius:0;
|
border-bottom-right-radius: 0px;
|
||||||
border-bottom-right-radius:0;
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .selector a.selector-chooseall:focus,
|
.admin-interface .selector a.selector-chooseall:focus,
|
||||||
.admin-interface .selector a.selector-chooseall:hover,
|
.admin-interface .selector a.selector-chooseall:hover,
|
||||||
.admin-interface .selector a.selector-clearall:focus,
|
.admin-interface .selector a.selector-clearall:focus,
|
||||||
.admin-interface .selector a.selector-clearall:hover {
|
.admin-interface .selector a.selector-clearall:hover {
|
||||||
color:{{ theme.css_generic_link_hover_color }};
|
color: var(--admin-interface-generic-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface a:link,
|
.admin-interface a:link,
|
||||||
.admin-interface a:visited {
|
.admin-interface a:visited {
|
||||||
color:{{ theme.css_generic_link_color }};
|
color: var(--admin-interface-generic-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface a:hover {
|
.admin-interface a:hover {
|
||||||
color:{{ theme.css_generic_link_hover_color }};
|
color: var(--admin-interface-generic-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface thead th a,
|
.admin-interface thead th a,
|
||||||
@@ -291,8 +256,8 @@
|
|||||||
.admin-interface input[type=button],
|
.admin-interface input[type=button],
|
||||||
.admin-interface .submit-row input,
|
.admin-interface .submit-row input,
|
||||||
.admin-interface a.button {
|
.admin-interface a.button {
|
||||||
background:{{ theme.css_save_button_background_color }};
|
background: var(--admin-interface-save-button-background-color);
|
||||||
color:{{ theme.css_save_button_text_color }};
|
color: var(--admin-interface-save-button-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .button:active,
|
.admin-interface .button:active,
|
||||||
@@ -304,16 +269,16 @@
|
|||||||
.admin-interface input[type=button]:active,
|
.admin-interface input[type=button]:active,
|
||||||
.admin-interface input[type=button]:focus,
|
.admin-interface input[type=button]:focus,
|
||||||
.admin-interface input[type=button]:hover {
|
.admin-interface input[type=button]:hover {
|
||||||
background:{{ theme.css_save_button_background_hover_color }};
|
background: var(--admin-interface-save-button-background-hover-color);
|
||||||
color:{{ theme.css_save_button_text_color }};
|
color: var(--admin-interface-save-button-text-color);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .button.default,
|
.admin-interface .button.default,
|
||||||
.admin-interface input[type=submit].default,
|
.admin-interface input[type=submit].default,
|
||||||
.admin-interface .submit-row input.default {
|
.admin-interface .submit-row input.default {
|
||||||
background:{{ theme.css_save_button_background_color }};
|
background: var(--admin-interface-save-button-background-color);
|
||||||
color:{{ theme.css_save_button_text_color }};
|
color: var(--admin-interface-save-button-text-color);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,83 +289,91 @@
|
|||||||
.admin-interface input[type=submit].default:focus,
|
.admin-interface input[type=submit].default:focus,
|
||||||
.admin-interface input[type=submit].default:hover,
|
.admin-interface input[type=submit].default:hover,
|
||||||
.admin-interface.delete-confirmation form .cancel-link:hover {
|
.admin-interface.delete-confirmation form .cancel-link:hover {
|
||||||
background:{{ theme.css_save_button_background_hover_color }};
|
background: var(--admin-interface-save-button-background-hover-color);
|
||||||
color:{{ theme.css_save_button_text_color }};
|
color: var(--admin-interface-save-button-text-color);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .submit-row a.deletelink:link,
|
.admin-interface .submit-row a.deletelink:link,
|
||||||
.admin-interface .submit-row a.deletelink:visited,
|
.admin-interface .submit-row a.deletelink:visited,
|
||||||
.admin-interface.delete-confirmation form input[type="submit"] {
|
.admin-interface.delete-confirmation form input[type="submit"] {
|
||||||
background:{{ theme.css_delete_button_background_color }};
|
background: var(--admin-interface-delete-button-background-color);
|
||||||
color:{{ theme.css_delete_button_text_color }};
|
color: var(--admin-interface-delete-button-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .submit-row a.deletelink:hover,
|
.admin-interface .submit-row a.deletelink:hover,
|
||||||
.admin-interface.delete-confirmation form input[type="submit"]:hover {
|
.admin-interface.delete-confirmation form input[type="submit"]:hover {
|
||||||
background:{{ theme.css_delete_button_background_hover_color }};
|
background: var(--admin-interface-delete-button-background-hover-color);
|
||||||
color:{{ theme.css_delete_button_text_color }};
|
color: var(--admin-interface-delete-button-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .paginator a,
|
.admin-interface .paginator a,
|
||||||
.admin-interface .paginator a:link,
|
.admin-interface .paginator a:link,
|
||||||
.admin-interface .paginator a:visited,
|
.admin-interface .paginator a:visited,
|
||||||
.admin-interface .paginator .this-page {
|
.admin-interface .paginator .this-page {
|
||||||
{% if theme.css_module_rounded_corners %}border-radius:4px;{% endif %}
|
border-radius: var(--admin-interface-module-border-radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .paginator a,
|
.admin-interface .paginator a,
|
||||||
.admin-interface .paginator a:link,
|
.admin-interface .paginator a:link,
|
||||||
.admin-interface .paginator a:visited {
|
.admin-interface .paginator a:visited {
|
||||||
background-color:#FFFFFF;
|
background-color: #FFFFFF;
|
||||||
color:{{ theme.css_generic_link_color }};
|
color: var(--admin-interface-generic-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .paginator a:hover,
|
.admin-interface .paginator a:hover,
|
||||||
.admin-interface .paginator a:active {
|
.admin-interface .paginator a:active {
|
||||||
background-color:#F8F8F8;
|
background-color: #F8F8F8;
|
||||||
color:{{ theme.css_generic_link_hover_color }};
|
color: var(--admin-interface-generic-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .paginator .this-page {
|
.admin-interface .paginator .this-page {
|
||||||
background-color:{{ theme.css_module_background_color }};
|
background-color: var(--admin-interface-module-background-color);
|
||||||
color:{{ theme.css_module_link_color }};
|
color: var(--admin-interface-module-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .paginator a.showall,
|
.admin-interface .paginator a.showall,
|
||||||
.admin-interface .paginator a.showall:link,
|
.admin-interface .paginator a.showall:link,
|
||||||
.admin-interface .paginator a.showall:visited {
|
.admin-interface .paginator a.showall:visited {
|
||||||
color:{{ theme.css_generic_link_color }};
|
color: var(--admin-interface-generic-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .paginator a.showall:hover,
|
.admin-interface .paginator a.showall:hover,
|
||||||
.admin-interface .paginator a.showall:active {
|
.admin-interface .paginator a.showall:active {
|
||||||
color:{{ theme.css_generic_link_hover_color }};
|
color: var(--admin-interface-generic-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* list-filter sticky */
|
/* list-filter sticky */
|
||||||
{% if theme.list_filter_sticky %}
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.admin-interface .module.filtered #changelist-filter {
|
.admin-interface.list-filter-sticky .module.filtered #changelist-filter {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 40px;
|
top: 30px;
|
||||||
float: right;
|
float: right;
|
||||||
z-index: 30;
|
z-index: 30;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow-y: auto;
|
||||||
|
height: 100%;
|
||||||
|
max-height: calc(100vh - 60px);
|
||||||
}
|
}
|
||||||
|
.admin-interface.list-filter-sticky.sticky-pagination .module.filtered #changelist-filter {
|
||||||
|
max-height: calc(100vh - 125px);
|
||||||
|
}
|
||||||
|
|
||||||
/* feature not available for django < 3.1.2 */
|
/* feature not available for django < 3.1.2 */
|
||||||
.admin-interface .module.filtered #toolbar + #changelist-filter {
|
.admin-interface.list-filter-sticky .module.filtered #toolbar + #changelist-filter {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
z-index: 30;
|
z-index: 30;
|
||||||
|
max-height: calc(100vh - 105px);
|
||||||
|
}
|
||||||
|
.admin-interface.list-filter-sticky.sticky-pagination .module.filtered #toolbar + #changelist-filter {
|
||||||
|
max-height: calc(100vh - 170px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
.admin-interface .module.filtered #changelist-filter {
|
.admin-interface .module.filtered #changelist-filter {
|
||||||
{% if theme.css_module_rounded_corners %}
|
border-radius: var(--admin-interface-module-border-radius);
|
||||||
border-bottom-left-radius: 4px;
|
|
||||||
border-bottom-right-radius: 4px;
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .module.filtered #changelist-filter #changelist-filter-clear a:focus,
|
.admin-interface .module.filtered #changelist-filter #changelist-filter-clear a:focus,
|
||||||
@@ -421,7 +394,7 @@
|
|||||||
.admin-interface .module.filtered #changelist-filter li.selected a:focus,
|
.admin-interface .module.filtered #changelist-filter li.selected a:focus,
|
||||||
.admin-interface .module.filtered #changelist-filter li.selected a:hover {
|
.admin-interface .module.filtered #changelist-filter li.selected a:hover {
|
||||||
/* color: #666; */
|
/* color: #666; */
|
||||||
color: {{ theme.css_generic_link_hover_color }};
|
color: var(--admin-interface-generic-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* begin fix issue #11 - Inline border bottom should not be rounded */
|
/* begin fix issue #11 - Inline border bottom should not be rounded */
|
||||||
@@ -430,50 +403,41 @@
|
|||||||
.admin-interface #nav-sidebar .module th,
|
.admin-interface #nav-sidebar .module th,
|
||||||
.admin-interface #nav-sidebar .module caption,
|
.admin-interface #nav-sidebar .module caption,
|
||||||
.admin-interface .module.filtered h2 {
|
.admin-interface .module.filtered h2 {
|
||||||
{% if theme.css_module_rounded_corners %}
|
border-radius: var(--admin-interface-module-border-radius);
|
||||||
border-radius:4px;
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .inline-group h2 {
|
.admin-interface .inline-group h2 {
|
||||||
{% if theme.css_module_rounded_corners %}
|
border-bottom-left-radius: 0px;
|
||||||
border-bottom-left-radius:0;
|
border-bottom-right-radius: 0px;
|
||||||
border-bottom-right-radius:0;
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .module.collapse.collapsed h2 {
|
.admin-interface .module.collapse.collapsed h2 {
|
||||||
/* fix collapsed inlines rounded bottom borders */
|
/* fix collapsed inlines rounded bottom borders */
|
||||||
{% if theme.css_module_rounded_corners %}
|
border-bottom-left-radius: var(--admin-interface-module-border-radius);
|
||||||
border-bottom-left-radius:4px;
|
border-bottom-right-radius: var(--admin-interface-module-border-radius);
|
||||||
border-bottom-right-radius:4px;
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end fix */
|
/* end fix */
|
||||||
|
|
||||||
.admin-interface #content-related {
|
.admin-interface #content-related {
|
||||||
{% if theme.css_module_rounded_corners %}
|
border-radius: var(--admin-interface-module-border-radius);
|
||||||
border-radius:4px;
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {
|
.admin-interface .select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {
|
||||||
background-color: {{ theme.css_module_background_color }};
|
background-color: var(--admin-interface-module-background-color);
|
||||||
color: {{ theme.css_module_text_color }};
|
color: var(--admin-interface-module-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #toggle-nav-sidebar {
|
.admin-interface #toggle-nav-sidebar {
|
||||||
{% if theme.css_module_rounded_corners %}
|
border-top-right-radius: var(--admin-interface-module-border-radius);
|
||||||
border-top-right-radius: 4px;
|
border-bottom-right-radius: var(--admin-interface-module-border-radius);
|
||||||
border-bottom-right-radius: 4px;
|
color: var(--admin-interface-generic-link-color);
|
||||||
{% endif %}
|
|
||||||
color: {{ theme.css_generic_link_color }};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface #toggle-nav-sidebar:focus,
|
.admin-interface #toggle-nav-sidebar:focus,
|
||||||
.admin-interface #toggle-nav-sidebar:hover,
|
.admin-interface #toggle-nav-sidebar:hover,
|
||||||
.admin-interface #toggle-nav-sidebar:active {
|
.admin-interface #toggle-nav-sidebar:active {
|
||||||
color: {{ theme.css_generic_link_hover_color }};
|
color: var(--admin-interface-generic-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .calendar td.selected a,
|
.admin-interface .calendar td.selected a,
|
||||||
@@ -483,5 +447,5 @@
|
|||||||
.admin-interface .timelist a:active,
|
.admin-interface .timelist a:active,
|
||||||
.admin-interface .timelist a:focus,
|
.admin-interface .timelist a:focus,
|
||||||
.admin-interface .timelist a:hover {
|
.admin-interface .timelist a:hover {
|
||||||
background: {{ theme.css_module_background_color }};
|
background: var(--admin-interface-module-background-color);
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
border-top: 1px solid #EEEEEE;
|
border-top: 1px solid #EEEEEE !important;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
.admin-interface .language-chooser {
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
right: 15px;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.admin-interface .language-chooser {
|
||||||
|
right: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.admin-interface .language-chooser {
|
||||||
|
position: static;
|
||||||
|
float: right;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .language-chooser-hidden-form {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .language-chooser-select-form {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
@@ -3,8 +3,12 @@ list-filter-dropdown
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.admin-interface .list-filter-dropdown {
|
.admin-interface .list-filter-dropdown {
|
||||||
margin-top:10px;
|
margin-top: 0;
|
||||||
margin-bottom:20px;
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .list-filter-dropdown h3 {
|
||||||
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface .list-filter-dropdown select {
|
.admin-interface .list-filter-dropdown select {
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
{% if not theme.recent_actions_visible %}
|
{% if not theme.recent_actions_visible %}
|
||||||
.admin-interface.dashboard #content {
|
.admin-interface.dashboard #content {
|
||||||
max-width:600px;
|
width: auto;
|
||||||
margin-right:0;
|
max-width: 600px;
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-interface.dashboard #content #recent-actions-module {
|
.admin-interface.dashboard #content #recent-actions-module {
|
||||||
display:none;
|
display: none;
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
django-streamfield support
|
||||||
|
https://github.com/raagin/django-streamfield/
|
||||||
|
*/
|
||||||
|
|
||||||
|
.admin-interface .form-row.field-stream {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .form-row.field-stream label[for=id_stream] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app {
|
||||||
|
clear: both;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-help-text {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-help-text .stream-help-text__title {
|
||||||
|
align-self: flex-end;
|
||||||
|
user-select: none;
|
||||||
|
padding: 8px;
|
||||||
|
padding-right: 0;
|
||||||
|
color: var(--admin-interface-generic-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-help-text .stream-help-text__title:hover {
|
||||||
|
color: var(--admin-interface-generic-link-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-help-text .stream-help-text__content {
|
||||||
|
background: var(--admin-interface-module-background-selected-color);
|
||||||
|
border-radius: var(--admin-interface-module-border-radius);
|
||||||
|
border: 1px solid rgba(0,0,0,0.1);
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-help-text .stream-help-text__content > ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .collapse-handler {
|
||||||
|
user-select: none;
|
||||||
|
padding: 8px;
|
||||||
|
padding-right: 0;
|
||||||
|
margin: 0 0 5px 0;
|
||||||
|
color: var(--admin-interface-generic-link-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .collapse-handler:hover {
|
||||||
|
color: var(--admin-interface-generic-link-hover-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block {
|
||||||
|
position: relative;
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid rgba(0,0,0,0.1);
|
||||||
|
border-radius: var(--admin-interface-module-border-radius);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block,
|
||||||
|
.admin-interface .streamfield_app .streamfield-models.collapsed .stream-model-block {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .streamblock__block__title {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px 10px 10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .streamblock__block__title span {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle {
|
||||||
|
position: static;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
color: var(--admin-interface-generic-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle:hover {
|
||||||
|
color: var(--admin-interface-generic-link-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle .block-move,
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle .block-delete {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
font-weight: normal;
|
||||||
|
background: none;
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: inherit;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle .block-move {
|
||||||
|
cursor: move; /* fallback if grab cursor is unsupported */
|
||||||
|
cursor: grab;
|
||||||
|
cursor: -moz-grab;
|
||||||
|
cursor: -webkit-grab;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle .block-move:before {
|
||||||
|
content: "↕";
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle .block-delete:before {
|
||||||
|
content: "×";
|
||||||
|
display: block;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .block-fields > div {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .stream-model-block__content {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-model-block .stream-model-block__content.no-subblocks.abstract-block {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-insert-new-block {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-insert-new-block .add-new-block-button {
|
||||||
|
color: var(--admin-interface-generic-link-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-insert-new-block .add-new-block-button:hover {
|
||||||
|
color: var(--admin-interface-generic-link-hover-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-insert-new-block ul {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0 0 0;
|
||||||
|
padding: 0;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-insert-new-block ul li {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 12px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-btn {
|
||||||
|
font-weight: normal;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: var(--admin-interface-generic-link-color);
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-btn:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: var(--admin-interface-generic-link-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-interface .streamfield_app .stream-insert-new-block ul li .stream-btn {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
@@ -67,10 +67,10 @@ def get_admin_interface_languages(context):
|
|||||||
|
|
||||||
@simple_tag(takes_context=True)
|
@simple_tag(takes_context=True)
|
||||||
def get_admin_interface_theme(context):
|
def get_admin_interface_theme(context):
|
||||||
theme = get_cached_active_theme()
|
# theme = get_cached_active_theme()
|
||||||
if not theme:
|
# if not theme:
|
||||||
theme = Theme.get_active_theme()
|
theme = Theme.get_active_theme()
|
||||||
set_cached_active_theme(theme)
|
# set_cached_active_theme(theme)
|
||||||
return theme
|
return theme
|
||||||
|
|
||||||
|
|
||||||
@@ -80,9 +80,9 @@ def get_admin_interface_version():
|
|||||||
|
|
||||||
|
|
||||||
def hash_string(text):
|
def hash_string(text):
|
||||||
hash_object = hashlib.md5(text.encode())
|
hash_object = hashlib.sha224(text.encode())
|
||||||
md5_hash = hash_object.hexdigest()
|
sha224_hash = hash_object.hexdigest()
|
||||||
return md5_hash
|
return sha224_hash
|
||||||
|
|
||||||
|
|
||||||
@simple_tag(takes_context=False)
|
@simple_tag(takes_context=False)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
__version__ = "0.18.7"
|
__version__ = "0.20.0"
|
||||||
@@ -12,7 +12,6 @@ sponsor_url = "https://github.com/sponsors/fabiocaccamo/"
|
|||||||
twitter_url = "https://twitter.com/fabiocaccamo"
|
twitter_url = "https://twitter.com/fabiocaccamo"
|
||||||
package_name = "django-admin-interface"
|
package_name = "django-admin-interface"
|
||||||
package_url = "{}/{}".format(github_url, package_name)
|
package_url = "{}/{}".format(github_url, package_name)
|
||||||
package_issues_url = "{}/issues".format(github_url)
|
|
||||||
package_path = os.path.abspath(os.path.dirname(__file__))
|
package_path = os.path.abspath(os.path.dirname(__file__))
|
||||||
long_description_file_path = os.path.join(package_path, "README.md")
|
long_description_file_path = os.path.join(package_path, "README.md")
|
||||||
long_description_content_type = "text/markdown"
|
long_description_content_type = "text/markdown"
|
||||||
@@ -39,8 +38,8 @@ setup(
|
|||||||
url=package_url,
|
url=package_url,
|
||||||
download_url="{}/archive/{}.tar.gz".format(package_url, __version__),
|
download_url="{}/archive/{}.tar.gz".format(package_url, __version__),
|
||||||
project_urls={
|
project_urls={
|
||||||
"Documentation": package_url,
|
"Documentation": "{}#readme".format(package_url),
|
||||||
"Issues": package_issues_url,
|
"Issues": "{}/issues".format(package_url),
|
||||||
"Funding": sponsor_url,
|
"Funding": sponsor_url,
|
||||||
"Twitter": twitter_url,
|
"Twitter": twitter_url,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in new issue
Block a user