From b8252030a4497cc4d06831b8c3e0822a55df832a Mon Sep 17 00:00:00 2001 From: Davide Borgonovo Date: Thu, 7 Mar 2024 16:33:26 +0100 Subject: [PATCH] Aggiornato con i contenuti del remoto al 07/03/2024 --- .github/FUNDING.yml | 6 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 - .github/dependabot.yml | 10 +- .github/pull_request_template.md | 17 + .github/workflows/codeql-analysis.yml | 12 +- .github/workflows/create-release.yml | 34 +- .github/workflows/pre-commit-autoupdate.yml | 25 + .github/workflows/test-package.yml | 90 ++- .gitignore | 4 + .pre-commit-config.yaml | 32 + CHANGELOG.md | 347 ++++++++--- CODE_OF_CONDUCT.md | 128 ++++ README.md | 185 ++++-- admin_interface/__init__.py | 19 +- admin_interface/admin.py | 49 +- admin_interface/apps.py | 10 +- admin_interface/cache.py | 2 - admin_interface/compat.py | 26 - admin_interface/context_processor.py | 8 - .../locale/de/LC_MESSAGES/django.mo | Bin 0 -> 3820 bytes .../locale/de/LC_MESSAGES/django.po | 316 ++++++++++ .../locale/es/LC_MESSAGES/django.mo | Bin 2248 -> 4072 bytes .../locale/es/LC_MESSAGES/django.po | 259 +++++--- .../locale/fa/LC_MESSAGES/django.mo | Bin 2994 -> 3025 bytes .../locale/fa/LC_MESSAGES/django.po | 256 +++++--- .../locale/fr/LC_MESSAGES/django.mo | Bin 2647 -> 3731 bytes .../locale/fr/LC_MESSAGES/django.po | 233 +++++-- .../locale/it/LC_MESSAGES/django.mo | Bin 2814 -> 3504 bytes .../locale/it/LC_MESSAGES/django.po | 230 +++++-- .../locale/pl/LC_MESSAGES/django.mo | Bin 2835 -> 2889 bytes .../locale/pl/LC_MESSAGES/django.po | 234 +++++-- .../locale/pt_BR/LC_MESSAGES/django.mo | Bin 3275 -> 3343 bytes .../locale/pt_BR/LC_MESSAGES/django.po | 197 ++++-- .../locale/ru/LC_MESSAGES/django.mo | Bin 0 -> 5920 bytes .../locale/ru/LC_MESSAGES/django.po | 320 ++++++++++ .../locale/tr/LC_MESSAGES/django.mo | Bin 2903 -> 2976 bytes .../locale/tr/LC_MESSAGES/django.po | 240 ++++++-- admin_interface/metadata.py | 10 + admin_interface/migrations/0001_initial.py | 163 +++-- .../migrations/0002_add_related_modal.py | 51 +- .../migrations/0003_add_logo_color.py | 6 - .../migrations/0004_rename_title_color.py | 5 - .../0005_add_recent_actions_visible.py | 10 +- .../migrations/0006_bytes_to_str.py | 45 +- .../migrations/0007_add_favicon.py | 5 - ...e_related_modal_background_opacity_type.py | 8 +- .../migrations/0009_add_enviroment.py | 10 +- .../migrations/0010_add_localization.py | 19 +- .../0011_add_environment_options.py | 23 +- .../migrations/0012_update_verbose_names.py | 6 - .../0013_add_related_modal_close_button.py | 8 +- .../migrations/0014_name_unique.py | 10 +- .../0015_add_language_chooser_active.py | 10 +- .../0016_add_language_chooser_display.py | 10 +- .../0017_change_list_filter_dropdown.py | 10 +- .../0018_theme_list_filter_sticky.py | 10 +- .../migrations/0019_add_form_sticky.py | 15 +- .../migrations/0020_module_selected_colors.py | 10 +- .../0021_file_extension_validator.py | 8 +- .../0022_add_logo_max_width_and_height.py | 13 +- .../migrations/0023_theme_foldable_apps.py | 10 +- .../migrations/0024_remove_theme_css.py | 5 - .../0025_theme_language_chooser_control.py | 23 + .../0026_theme_list_filter_highlight.py | 18 + .../0027_theme_list_filter_removal_links.py | 18 + ...8_theme_show_fieldsets_as_tabs_and_more.py | 26 + ...029_theme_css_generic_link_active_color.py | 24 + ...me_collapsible_stacked_inlines_and_more.py | 42 ++ ...demo_option.py => 0031_add_demo_option.py} | 2 +- ...user_option.py => 0032_add_user_option.py} | 2 +- ...usertheme_m2m.py => 0033_usertheme_m2m.py} | 2 +- ...theme_demo.py => 0034_alter_theme_demo.py} | 2 +- ...025_1559.py => 0035_auto_20221025_1559.py} | 2 +- ...theme_default.py => 0036_theme_default.py} | 2 +- admin_interface/models.py | 269 ++++---- admin_interface/settings.py | 4 - admin_interface/static/admin/js/collapse.js | 49 ++ .../static/admin/js/popup_response.js | 10 +- .../collapsible-inlines.js | 48 ++ .../admin_interface/css/admin-interface.css | 515 ++++++++++++++++ .../admin_interface/css/change-form.css | 34 + .../static/admin_interface/css/changelist.css | 43 ++ .../static/admin_interface/css/fieldsets.css | 14 + .../admin_interface/css/file-upload.css | 52 ++ .../static/admin_interface/css/header.css | 50 ++ .../static/admin_interface/css/inlines.css | 105 ++++ .../admin_interface/css/jquery.ui.tabs.css | 145 ++++- .../admin_interface/css/language-chooser.css | 72 +++ .../css/list-filter-dropdown.css | 27 + .../admin_interface/css/list-filter.css | 28 + .../static/admin_interface/css/login.css | 65 ++ .../static/admin_interface/css/modules.css | 12 + .../admin_interface/css/nav-sidebar.css | 78 +++ .../admin_interface/css/object-tools.css | 10 + .../static/admin_interface/css/paginator.css | 33 + .../admin_interface/css/recent-actions.css | 10 + .../admin_interface/css/rtl.css | 0 .../css/sticky-form-controls.css} | 4 +- .../admin_interface/css/tabbed-changeform.css | 67 ++ .../css/third-party}/ckeditor.css | 2 +- .../css/third-party/import-export.css | 7 + .../css/third-party}/json-widget.css | 16 +- .../css/third-party}/modeltranslation.css | 0 .../css/third-party/rangefilter.css | 25 + .../css/third-party}/sorl-thumbnail.css | 0 .../css/third-party/streamfield.css | 220 +++++++ .../css/third-party}/tabbed-admin.css | 0 .../css/third-party}/tinymce.css | 2 +- .../static/admin_interface/css/widgets.css | 153 +++++ .../foldable-apps/foldable-apps.css | 2 +- .../magnific-popup/jquery.magnific-popup.js | 6 +- .../related-modal}/related-modal.css | 24 +- .../related-modal/related-modal.js | 28 +- .../tabbed-changeform/tabbed-changeform.js | 73 +++ .../ckeditor/ckeditor/skins/light/skin.js | 2 +- .../streamfield/admin_popup_response.js | 24 + .../streamfield/js/admin_popup_response.js | 24 + .../templates/admin/base_site.html | 165 ++++- .../templates/admin/change_form.html | 88 +++ .../templates/admin/change_list.html | 33 + .../admin/edit_inline/headerless_stacked.html | 24 + .../admin/edit_inline/headerless_tabular.html | 61 ++ admin_interface/templates/admin/filter.html | 7 +- .../admin/includes/headerless_fieldset.html | 30 + .../templates/admin/popup_response.html | 5 +- .../admin_interface/collapsible-inlines.html | 5 + .../css/admin-interface-fix.css | 582 ------------------ .../admin_interface/css/admin-interface.css | 490 --------------- .../css/list-filter-dropdown.css | 14 - .../admin_interface/css/recent-actions.css | 9 - .../date_hierarchy_removal_link.html | 3 + .../admin_interface/dropdown_filter.html | 2 +- .../templates/admin_interface/favicon.html | 4 +- .../admin_interface/foldable-apps.html | 4 +- .../admin_interface/language_chooser.html | 21 +- .../list_filter_removal_link.html | 5 + .../admin_interface/related-modal.html | 7 +- .../templatetags/admin_interface_tags.py | 191 ++++-- admin_interface/version.py | 3 - pyproject.toml | 99 +++ requirements-test.txt | 8 +- requirements.txt | 8 +- runtests.py | 7 +- setup.cfg | 2 - setup.py | 100 +-- tests/routers.py | 45 ++ tests/settings.py | 75 ++- tests/test_fixtures.py | 10 +- tests/test_metadata.py | 34 + tests/test_models.py | 72 ++- tests/test_multidb.py | 39 ++ tests/test_settings.py | 50 +- tests/test_templatetags.py | 262 +++++--- tests/urls.py | 18 +- tests/urls_without_i18n_patterns.py | 14 +- tox.ini | 76 ++- 156 files changed, 6303 insertions(+), 2655 deletions(-) create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/pre-commit-autoupdate.yml create mode 100644 .pre-commit-config.yaml create mode 100644 CODE_OF_CONDUCT.md delete mode 100644 admin_interface/compat.py create mode 100644 admin_interface/locale/de/LC_MESSAGES/django.mo create mode 100644 admin_interface/locale/de/LC_MESSAGES/django.po create mode 100644 admin_interface/locale/ru/LC_MESSAGES/django.mo create mode 100644 admin_interface/locale/ru/LC_MESSAGES/django.po create mode 100644 admin_interface/metadata.py create mode 100644 admin_interface/migrations/0025_theme_language_chooser_control.py create mode 100644 admin_interface/migrations/0026_theme_list_filter_highlight.py create mode 100644 admin_interface/migrations/0027_theme_list_filter_removal_links.py create mode 100644 admin_interface/migrations/0028_theme_show_fieldsets_as_tabs_and_more.py create mode 100644 admin_interface/migrations/0029_theme_css_generic_link_active_color.py create mode 100644 admin_interface/migrations/0030_theme_collapsible_stacked_inlines_and_more.py rename admin_interface/migrations/{0025_add_demo_option.py => 0031_add_demo_option.py} (87%) rename admin_interface/migrations/{0026_add_user_option.py => 0032_add_user_option.py} (89%) rename admin_interface/migrations/{0027_usertheme_m2m.py => 0033_usertheme_m2m.py} (95%) rename admin_interface/migrations/{0028_alter_theme_demo.py => 0034_alter_theme_demo.py} (87%) rename admin_interface/migrations/{0029_auto_20221025_1559.py => 0035_auto_20221025_1559.py} (94%) rename admin_interface/migrations/{0030_theme_default.py => 0036_theme_default.py} (86%) create mode 100644 admin_interface/static/admin/js/collapse.js create mode 100644 admin_interface/static/admin_interface/collapsible-inlines/collapsible-inlines.js create mode 100644 admin_interface/static/admin_interface/css/admin-interface.css create mode 100644 admin_interface/static/admin_interface/css/change-form.css create mode 100644 admin_interface/static/admin_interface/css/changelist.css create mode 100644 admin_interface/static/admin_interface/css/fieldsets.css create mode 100644 admin_interface/static/admin_interface/css/file-upload.css create mode 100644 admin_interface/static/admin_interface/css/header.css create mode 100644 admin_interface/static/admin_interface/css/inlines.css rename admin_interface/{templates => static}/admin_interface/css/jquery.ui.tabs.css (61%) create mode 100644 admin_interface/static/admin_interface/css/language-chooser.css create mode 100644 admin_interface/static/admin_interface/css/list-filter-dropdown.css create mode 100644 admin_interface/static/admin_interface/css/list-filter.css create mode 100644 admin_interface/static/admin_interface/css/login.css create mode 100644 admin_interface/static/admin_interface/css/modules.css create mode 100644 admin_interface/static/admin_interface/css/nav-sidebar.css create mode 100644 admin_interface/static/admin_interface/css/object-tools.css create mode 100644 admin_interface/static/admin_interface/css/paginator.css create mode 100644 admin_interface/static/admin_interface/css/recent-actions.css rename admin_interface/{templates => static}/admin_interface/css/rtl.css (100%) rename admin_interface/{templates/admin_interface/css/form-controls.css => static/admin_interface/css/sticky-form-controls.css} (98%) create mode 100644 admin_interface/static/admin_interface/css/tabbed-changeform.css rename admin_interface/{templates/admin_interface/css => static/admin_interface/css/third-party}/ckeditor.css (99%) create mode 100644 admin_interface/static/admin_interface/css/third-party/import-export.css rename admin_interface/{templates/admin_interface/css => static/admin_interface/css/third-party}/json-widget.css (52%) rename admin_interface/{templates/admin_interface/css => static/admin_interface/css/third-party}/modeltranslation.css (100%) create mode 100644 admin_interface/static/admin_interface/css/third-party/rangefilter.css rename admin_interface/{templates/admin_interface/css => static/admin_interface/css/third-party}/sorl-thumbnail.css (100%) create mode 100644 admin_interface/static/admin_interface/css/third-party/streamfield.css rename admin_interface/{templates/admin_interface/css => static/admin_interface/css/third-party}/tabbed-admin.css (100%) rename admin_interface/{templates/admin_interface/css => static/admin_interface/css/third-party}/tinymce.css (97%) create mode 100644 admin_interface/static/admin_interface/css/widgets.css rename admin_interface/{templates/admin_interface/css => static/admin_interface/related-modal}/related-modal.css (81%) create mode 100644 admin_interface/static/admin_interface/tabbed-changeform/tabbed-changeform.js create mode 100644 admin_interface/static/streamfield/admin_popup_response.js create mode 100644 admin_interface/static/streamfield/js/admin_popup_response.js create mode 100644 admin_interface/templates/admin/change_form.html create mode 100644 admin_interface/templates/admin/change_list.html create mode 100644 admin_interface/templates/admin/edit_inline/headerless_stacked.html create mode 100644 admin_interface/templates/admin/edit_inline/headerless_tabular.html create mode 100644 admin_interface/templates/admin/includes/headerless_fieldset.html create mode 100644 admin_interface/templates/admin_interface/collapsible-inlines.html delete mode 100644 admin_interface/templates/admin_interface/css/admin-interface-fix.css delete mode 100644 admin_interface/templates/admin_interface/css/admin-interface.css delete mode 100644 admin_interface/templates/admin_interface/css/list-filter-dropdown.css delete mode 100644 admin_interface/templates/admin_interface/css/recent-actions.css create mode 100644 admin_interface/templates/admin_interface/date_hierarchy_removal_link.html create mode 100644 admin_interface/templates/admin_interface/list_filter_removal_link.html delete mode 100644 admin_interface/version.py create mode 100644 pyproject.toml delete mode 100644 setup.cfg create mode 100644 tests/routers.py create mode 100644 tests/test_metadata.py create mode 100644 tests/test_multidb.py diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 50ac1cd..e633e40 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,6 @@ github: [fabiocaccamo] -custom: ['https://www.paypal.me/fabiocaccamo'] +polar: fabiocaccamo +ko_fi: fabiocaccamo +liberapay: fabiocaccamo +tidelift: pypi/django-admin-interface +custom: ["https://www.buymeacoffee.com/fabiocaccamo", "https://www.paypal.me/fabiocaccamo"] diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index cd25dd1..521aae1 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -6,5 +6,3 @@ labels: enhancement assignees: fabiocaccamo --- - - diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c75da03..b00d57e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,14 @@ version: 2 updates: + - package-ecosystem: "pip" directory: "/" schedule: - interval: "weekly" \ No newline at end of file + interval: "monthly" + open-pull-requests-limit: 100 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 100 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..98d5f60 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,17 @@ +--- +name: Pull request +about: Submit a pull request for this project +assignees: fabiocaccamo + +--- + +**Describe your changes** +? + +**Related issue** +? + +**Checklist before requesting a review** +- [ ] I have performed a self-review of my code. +- [ ] I have added tests for the proposed changes. +- [ ] I have run the tests and there are not errors. diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c898e38..9dfd4da 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,10 +13,10 @@ name: "CodeQL" on: push: - branches: [ master ] + branches: [ main ] pull_request: # The branches below must be a subset of the branches above - branches: [ master ] + branches: [ main ] schedule: - cron: '26 21 * * 0' @@ -39,11 +39,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -54,7 +54,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -68,4 +68,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index fc4df59..fece2a2 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -8,22 +8,38 @@ on: jobs: build: runs-on: ubuntu-latest + # environment: release + permissions: + id-token: write steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Extract release notes id: extract-release-notes - uses: ffurrer2/extract-release-notes@v1 + uses: ffurrer2/extract-release-notes@v2 - name: Create release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ncipollo/release-action@v1 with: - tag_name: ${{ github.ref }} - release_name: ${{ github.ref }} - draft: false - prerelease: false body: ${{ steps.extract-release-notes.outputs.release_notes }} + token: ${{ secrets.WORKFLOWS_CREATE_RELEASE_TOKEN }} + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + cache: 'pip' + + - name: Build Package + run: | + pip install pip --upgrade + pip install build + python -m build + + - name: Publish on PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist/ + # password: ${{ secrets.WORKFLOWS_PUBLISH_TO_PYPI_TOKEN }} diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml new file mode 100644 index 0000000..1d6fb30 --- /dev/null +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -0,0 +1,25 @@ +name: Pre-commit auto-update + +on: + # every month + schedule: + - cron: "0 0 1 * *" + # on demand + workflow_dispatch: + +jobs: + auto-update: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + - uses: browniebroke/pre-commit-autoupdate-action@main + - uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: update/pre-commit-hooks + title: Update pre-commit hooks + commit-message: "Update pre-commit hooks." + body: Update versions of pre-commit hooks to latest version. diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml index f5093db..57cab08 100644 --- a/.github/workflows/test-package.yml +++ b/.github/workflows/test-package.yml @@ -8,34 +8,62 @@ on: jobs: prepare: - - runs-on: ubuntu-latest + + runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 - + uses: actions/checkout@v4 + - name: Create matrix - uses: fabiocaccamo/create-matrix-action@v2 + uses: fabiocaccamo/create-matrix-action@v4 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} - + python-version {3.8}, django-version {3.0, 3.1, 3.2, 4.0, 4.1, 4.2}, database {sqlite, postgres} + python-version {3.9}, django-version {3.0, 3.1, 3.2, 4.0, 4.1, 4.2}, database {sqlite, postgres} + python-version {3.10}, django-version {3.2, 4.0, 4.1, 4.2, 5.0}, database {sqlite, postgres} + python-version {3.11}, django-version {4.1, 4.2, 5.0}, database {sqlite, postgres} + python-version {3.12}, django-version {4.2, 5.0}, database {sqlite, postgres} + outputs: matrix: ${{ steps.create_matrix.outputs.matrix }} - + + + lint: + + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + cache: 'pip' + + - name: Install tools needed + run: | + sudo apt install gettext + python -m pip install --upgrade pip + pip install tox + + - name: Check migrations + run: | + tox -e migrations + + - name: Check translations + run: | + tox -e translations + + test: - - needs: prepare + + needs: [prepare] runs-on: ubuntu-latest strategy: fail-fast: false - matrix: + matrix: include: ${{fromJson(needs.prepare.outputs.matrix)}} services: @@ -52,42 +80,46 @@ jobs: steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install psycopg2 prerequisites - run: sudo apt-get install libpq-dev + run: sudo apt install libpq-dev - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: 'pip' - + - name: Upgrade pip version run: | pip install pip --upgrade - + - name: Install django run: | - pip install "Django ~= ${{ matrix.django-version }}" - + pip install "Django == ${{ matrix.django-version }}.*" + - name: Install requirements run: | pip install -r requirements.txt pip install -r requirements-test.txt - + + - name: Run pre-commit + run: | + pre-commit run --all-files --show-diff-on-failure --verbose + - name: Run tests - env: + env: DATABASE_ENGINE: ${{ matrix.database }} run: | - coverage run --append --source=admin_interface setup.py test + coverage run --append --source=admin_interface runtests.py + coverage report --show-missing coverage xml -o ./coverage.xml - + - name: Upload coverage to Codecov - uses: codecov/codecov-action@v2 + uses: codecov/codecov-action@v4 with: fail_ci_if_error: false files: ./coverage.xml flags: unittests verbose: true - diff --git a/.gitignore b/.gitignore index 3508eca..46d726b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,10 @@ __pycache__/ # C extensions *.so +## Local setup +.vscode/ +.venv/ + # Distribution / packaging .Python env/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..b6a3eb9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,32 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: + + - repo: https://github.com/asottile/pyupgrade + rev: v3.15.1 + hooks: + - id: pyupgrade + args: ["--py38-plus"] + + - repo: https://github.com/adamchainz/django-upgrade + rev: 1.16.0 + hooks: + - id: django-upgrade + args: ["--target-version", "3.0"] + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.0 + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: fix-encoding-pragma + args: [--remove] + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files diff --git a/CHANGELOG.md b/CHANGELOG.md index a226380..ba49bc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,166 +4,335 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.28.6](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.28.6) - 2024-03-07 +- [python] Fix date hierarchy params. #374 (by [@jeroenpeters1986](https://github.com/jeroenpeters1986) in #375) +- [js] Open any link with `_popup=1` query-string parameter in a modal window. +- [ci] Bump requirements. +- [ci] Bump `pre-commit` hooks. + +## [0.28.5](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.28.5) - 2024-01-30 +- [css] Fix related widget height and buttons alignment when there is a multiline label. +- [css] Fix inputs height when there is a multiline label. + +## [0.28.4](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.28.4) - 2024-01-29 +- [css] Fix header logo not displayed correctly. + +## [0.28.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.28.3) - 2024-01-08 +- [css] Fix help text horizontal alignment when using `show-fieldsets-as-tabs` / `show-inlines-as-tabs` theme options. #317 +- [css] Fix file-upload widget margin-left. +- [css] Fix related widget links add button position on `many-to-many` selector. +- [css] Fix related widget links margin from `select2` (`autocomplete_fields`). +- [css] Reduce paginator vertical padding. + +## [0.28.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.28.2) - 2024-01-08 +- [css] Fix related widget icon alignment. #348 #350 + +## [0.28.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.28.1) - 2023-12-28 +- [python] Fix `TemplateDoesNotExist` when using `django-nested-admin` by returning custom template for other third-party packages. #341 (by [@markdrrr](https://github.com/markdrrr) in #342) +- [html] Display language chooser language name uppercase. +- [css] Move save buttons to right in change form. +- [css] Fix related widget links icons size and vertical alignment. +- [css] Fix admin `raw_id_fields` appearance. +- [css] Fix `autocomplete_fields` appearance. +- [ci] Bump requirements. + +### Contributors +- [@markdrrr](https://github.com/markdrrr) + +## [0.28.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.28.0) - 2023-12-21 +- [html] Remove old `flat-theme` body class. +- [html] Remove `type="text/css"` and `type="text/javascript"` attributes. +- [css] Fix filter input fields collapsing on different layouts. #338 +- [css] Fix paginator buttons height. +- [css] Fix `foldable-apps` +/- button vertical alignment. +- [css] Split `admin-interface-fix.css` CSS file into multiple files for easier debugging. +- [css] Rename `form-controls.css` to `sticky-form-controls.css`. +- [css] Move third-party compatibility CSS files to a `third-party` folder. +- [css] Move `related-modal.css` to related-modal plugin folder. +- [third-party] Update compatibility with `django-streamfield`. +- [ci] Replace `Black` and `isort` with `Ruff-format`. +- [ci] Bump `pre-commit` hooks. + +## [0.27.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.27.0) - 2023-12-05 +- Add `Python 3.12` support. +- Add `Django 5.0` support. +- Fix broken language-chooser with `i18n_patterns(..., prefix_default_language=False)`. #327 (by [@julianwachholz](https://github.com/julianwachholz) in #328) +- Simplify language-chooser. #327 (by [@julianwachholz](https://github.com/julianwachholz) in #328) +- Speed-up test workflow. +- Bump requirements. +- Bump `pre-commit` hooks. + +### Contributors +- [@julianwachholz](https://github.com/julianwachholz) + +## [0.26.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.26.1) - 2023-09-05 +- Fix logout and theme buttons style. #246 +- Add Russian translation. (by [@rustzzdevel](https://github.com/rustzzdevel) in #295) +- Update Italian translations. +- Update Spanish translations. (by [@smunoz-ml](https://github.com/smunoz-ml) in #307) +- Prevent multiple `.collapse-toggle` button. +- Bump requirements. +- Bump `pre-commit` hooks. + +## [0.26.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.26.0) - 2023-05-11 +- Add options for collapsible inlines. #263 (by [@fabiocaccamo](https://github.com/fabiocaccamo) in #282) +- Bump requirements. +- Bump `pre-commit` hooks. + +## [0.25.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.25.0) - 2023-04-18 +- Add `Django 4.2` support. +- Drop `Django 2.2` support. +- Fix `date_hierarchy` with multiple fields (`ForeignKey`). #244 +- Fix tabs not working with non-ASCII alphanumeric characters. #237 +- Fix multidb tests. +- Add `css_generic_link_active_color` field to use on active tab (tabbed changeform). #232 +- Replace `flake8` with `Ruff`. +- Switch from `setup.py` to `pyproject.toml`. +- Add `pyupgrade` to `pre-commit` config. +- Add `django-upgrade` to `pre-commit` hooks. +- Upgrade syntax for `Python >= 3.8`. +- Run `pre-commit` also with `tox`. +- Reformat migrations. +- Bump requirements. +- Bump `pre-commit` hooks. +- Pin test requirements. +- Add pull request template. +- Add `CODE_OF_CONDUCT.md`. #238 +- Rename default branch from `master` to `main`. + +## [0.24.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.24.2) - 2022-12-19 +- Fix modal and popup opening at the same time. #228 +- Make `Theme.get_active_theme` class method a manager method. (by [@MounirMesselmeni](https://github.com/MounirMesselmeni) in #230) + +## [0.24.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.24.1) - 2022-12-14 +- Fix modal opener buttons not working when added to the DOM asynchronously. #228 +- [css] Improve changelist filter margins. + +## [0.24.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.24.0) - 2022-12-11 +- Drop `Python < 3.8` and `Django < 2.2` versions support. (by [@merwok](https://github.com/merwok) in #220) +- Replace `str.format` with `f-strings`. +- Remove `post_migrate` signal handler and multi db test. +- Add german translation. (by [@derzinn](https://github.com/derzinn) in #222) +- Include date hierarchy in quick removal links (by [@merwok](https://github.com/merwok) in #218) +- Fix broken tabbed inline name. (by [@VaZark](https://github.com/VaZark) in #221) +- Minor cleanups. (by [@merwok](https://github.com/merwok) in #225) +- Bump actions and requirements. +- [css] Fix inlines vertical alignement. (by [@VaZark](https://github.com/VaZark) in #201) +- [css] Fix tabbed changeform tabs text color on focus. (by [@VaZark](https://github.com/VaZark) in #223) +- [CI] Add Farsi language to `tests.settings.LANGUAGES`. (by [@merwok](https://github.com/merwok)) +- [CI] Update `pre-commit` config. +- [CI] Automate package build and publish on PyPI. + +## [0.23.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.23.0) - 2022-11-30 +- Add `Python 3.11` support. +- Add tabbed changeform support. (by [@VaZark](https://github.com/VaZark) in #211) +- Fix #208 / Do not assume active DB when not specified. (by [@VaZark](https://github.com/VaZark) in #210) +- Update translations. +- Bump actions and requirements. +- [css] Adjust list filter dropdown vertical margins. +- [css] Improve nav filter style. #214 +- [css] Improve language chooser style. +- [css] Reduce secondary scrollbars size. +- [CI] Update `dependabot.yml` +- [CI] Add `pre-commit-autoupdate.yml` workflow. +- [CI] Update `pre-commit` hooks. + +## [0.22.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.22.2) - 2022-11-18 +- [CI] Add `django 4.1` to tests. +- [CI] Add `pre-commit` with `black`, `isort` and `flake8`. +- Respect `using` in signals. #199 (by [@VaZark](https://github.com/VaZark) in #200) +- Remove translations line numbers to avoid `lint` step failures. + +## [0.22.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.22.1) - 2022-10-13 +- Fix `KeyError` raised by `django-rangefilter`. +- [css] Add `django-rangefilter` style optimizations. +- [css] Fix list-filter dropdown vertical margins. +- [css] Fix calendar prev/next arrows style. + +## [0.22.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.22.0) - 2022-10-12 +- Add CI checks for migrations and translations. #184 (by [@merwok](https://github.com/merwok) in #186) +- Add option for list filter quick remove. #181 (by [@merwok](https://github.com/merwok) in #183) +- [css] Fix left/right scrolling broken with django-import-export. #165 +- [html] Fix duplicated welcome message. #185 + +## [0.21.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.21.0) - 2022-10-06 +- Add language chooser control option (default select, minimal select). #136 +- Add option to make active list filters more visible. #174 (by [@merwok](https://github.com/merwok) in #178) +- Add support for collapsible fieldsets that start expanded. #173 (by [@merwok](https://github.com/merwok) in #177) +- [js] Fix modal window not closing on save with `django >= 4.0`. #169 +- [css] Move `language-chooser` style to its own CSS file. +- [css] Fix sticky list filter scrolling. #175 +- [css] Fix paginator missing `border-top` on mobile. + +## [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)) +- 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 -- Removed public disclosures of the lib's version. #154 (thanks to [@mintyPT](https://github.com/mintyPT)) -- Reformatted code with **Black**. +- Removed public disclosures of the lib's version. #154 (thanks to [@mintyPT](https://github.com/mintyPT)) +- Reformatted code with **Black**. ## [0.18.6](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.18.6) - 2022-02-04 -- Added polish (`pl`) localization by [paduszyk](https://github.com/paduszyk). #152 -- Fixed login logo `max-width` and title `color`. +- Added polish (`pl`) localization by [paduszyk](https://github.com/paduszyk). #152 +- Fixed login logo `max-width` and title `color`. ## [0.18.5](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.18.5) - 2022-01-21 -- Added portuguese brazil (`pt_BR`) localization by [leandromsd](https://github.com/leandromsd). #149 -- Fixed body scroll reset to top when opening related modal. #150 +- Added portuguese brazil (`pt_BR`) localization by [leandromsd](https://github.com/leandromsd). #149 +- Fixed body scroll reset to top when opening related modal. #150 ## [0.18.4](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.18.4) - 2022-01-05 -- Added official django 4.0 support. -- Added link to admin home page on logo and title. #147 -- Fixed collapsed inlines rounded bottom borders. -- Fixed missing comma in tests settings `MIDDLEWARE_CLASSES`. #145 +- Added official django 4.0 support. +- Added link to admin home page on logo and title. #147 +- Fixed collapsed inlines rounded bottom borders. +- Fixed missing comma in tests settings `MIDDLEWARE_CLASSES`. #145 ## [0.18.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.18.3) - 2021-12-07 -- Added official python 3.10 support. -- Replaced travis with GitHub action workflow. #142 -- Fixed `check_installed_apps` checks. -- Fixed django default appconfig deprecation warning. #141 +- Added official python 3.10 support. +- Replaced travis with GitHub action workflow. #142 +- Fixed `check_installed_apps` checks. +- Fixed django default appconfig deprecation warning. #141 ## [0.18.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.18.2) - 2021-10-25 -- Fixed migration error. +- Fixed migration error. ## [0.18.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.18.1) - 2021-10-25 -- Removed wrong migration. +- Removed wrong migration. ## [0.18.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.18.0) - 2021-10-24 -- Added foldable apps support. #117 -- Removed `css` field from `Theme` model. +- Added foldable apps support. #117 +- Removed `css` field from `Theme` model. ## [0.17.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.17.3) - 2021-10-12 -- Fixed `FileExtensionValidator` `TypeError` on django < 1.11. +- Fixed `FileExtensionValidator` `TypeError` on django < 1.11. ## [0.17.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.17.2) - 2021-10-08 -- Fixed `FileExtensionValidator` `TypeError` on django < 1.11. +- Fixed `FileExtensionValidator` `TypeError` on django < 1.11. ## [0.17.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.17.1) - 2021-09-24 -- Fixed `TemplateDoesNotExist` error on `django==4.0.a1` removing checking condition for `colorfield` package. #134 -- Fixed favicon fetching incompatible with `django-storages` `S3`. #128 +- Fixed `TemplateDoesNotExist` error on `django==4.0.a1` removing checking condition for `colorfield` package. #134 +- Fixed favicon fetching incompatible with `django-storages` `S3`. #128 ## [0.17.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.17.0) - 2021-09-16 -- Added `logo_max_width` and `logo_max_height`. #127 +- Added `logo_max_width` and `logo_max_height`. #127 ## [0.16.4](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.16.4) - 2021-09-04 -- Fixed `0020_module_selected_colors` migration for multiple dbs. #132 -- Fixed sticky pagination `width` and `border-bottom`. -- Fixed inlines vertical overlow. -- Improved header elements vertical alignment. +- Fixed `0020_module_selected_colors` migration for multiple dbs. #132 +- Fixed sticky pagination `width` and `border-bottom`. +- Fixed inlines vertical overlow. +- Improved header elements vertical alignment. ## [0.16.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.16.3) - 2021-04-26 -- Added `compat` module. -- Added missing `0021_file_extension_validator` migration. #126 -- Formatted migrations. +- Added `compat` module. +- Added missing `0021_file_extension_validator` migration. #126 +- Formatted migrations. ## [0.16.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.16.2) - 2021-04-23 -- Added `python 3.9` and `django 3.2` to CI. -- Added `FileExtensionValidator` to `logo` and `favicon` fields. #112 -- Fixed `models.W042` warning on `django 3.2`. -- Fixed header `min-height`. -- Fixed selects `min-width`. -- Fixed changelist search, actions and submit button horizontal margins. -- Fixed related widget wrapper margin/padding with normal select and in inlines. -- Fixed tabular inlines horizontal scroll. +- Added `python 3.9` and `django 3.2` to CI. +- Added `FileExtensionValidator` to `logo` and `favicon` fields. #112 +- Fixed `models.W042` warning on `django 3.2`. +- Fixed header `min-height`. +- Fixed selects `min-width`. +- Fixed changelist search, actions and submit button horizontal margins. +- Fixed related widget wrapper margin/padding with normal select and in inlines. +- Fixed tabular inlines horizontal scroll. ## [0.16.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.16.1) - 2021-04-07 -- Fixed style of "Delete" and "Save" buttons in the delete confirmation page. #123 -- Overridden dark-mode css variables introduced in `django 3.2`. #124 +- Fixed style of "Delete" and "Save" buttons in the delete confirmation page. #123 +- Overridden dark-mode css variables introduced in `django 3.2`. #124 ## [0.16.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.16.0) - 2021-03-30 -- Added customizable colors for selected apps and models in dashboard. #122 -- Added `responsive_rtl.css` stylesheet. #98 -- Updated `vazir-font` version to `27.2.2`. #98 +- Added customizable colors for selected apps and models in dashboard. #122 +- Added `responsive_rtl.css` stylesheet. #98 +- Updated `vazir-font` version to `27.2.2`. #98 ## [0.15.6](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.15.6) - 2021-03-26 -- Fixed `show_change_link` related modal support. #120 -- Fixed inline changelink style. -- Made globally available `presentRelatedObjectModal` and `presentRelatedObjectModalOnClickOn` js functions. +- Fixed `show_change_link` related modal support. #120 +- Fixed inline changelink style. +- Made globally available `presentRelatedObjectModal` and `presentRelatedObjectModalOnClickOn` js functions. ## [0.15.5](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.15.5) - 2021-03-02 -- Fixed sticky submit and pagination `z-index` issue with related modal. +- Fixed sticky submit and pagination `z-index` issue with related modal. ## [0.15.4](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.15.4) - 2021-03-01 -- Fixed sticky submit and pagination `z-index` issue with sticky `list_filter` and `django-json-widget`. +- Fixed sticky submit and pagination `z-index` issue with sticky `list_filter` and `django-json-widget`. ## [0.15.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.15.3) - 2021-02-08 -- Fixed sticky submit and pagination width when `admin.site.enable_nav_sidebar = False`. #113 +- Fixed sticky submit and pagination width when `admin.site.enable_nav_sidebar = False`. #113 ## [0.15.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.15.2) - 2021-02-03 -- Fixed body classes template rendering. -- Improved sticky submit and pagination backward compatibility. +- Fixed body classes template rendering. +- Improved sticky submit and pagination backward compatibility. ## [0.15.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.15.1) - 2021-02-03 -- Fixed and improved sticky form controls and pagination style. +- Fixed and improved sticky form controls and pagination style. ## [0.15.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.15.0) - 2021-02-03 -- Added sticky form controls and pagination options. #110 -- Added support to 4-digit language code in language chooser. #111 -- Added theme css variables for third-party libraries. -- Fixed app module section link hover color. +- Added sticky form controls and pagination options. #110 +- Added support to 4-digit language code in language chooser. #111 +- Added theme css variables for third-party libraries. +- Fixed app module section link hover color. ## [0.14.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.14.2) - 2021-01-04 -- Fixed tabular inline scroll bar. #101 -- Fixed module header selected link color. #102 -- Fixed main content width when `admin.site.enable_nav_sidebar = False`. #105 +- Fixed tabular inline scroll bar. #101 +- Fixed module header selected link color. #102 +- Fixed main content width when `admin.site.enable_nav_sidebar = False`. #105 ## [0.14.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.14.1) - 2020-11-12 -- Fixed sticky list-filter floating. #100 +- Fixed sticky list-filter floating. #100 ## [0.14.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.14.0) - 2020-10-15 -- Added list filter sticky option (only for `django >= 3.1.2`). -- Enabled list filter dropdown by default. -- Fixed changelist searchbar style. +- Added list filter sticky option (only for `django >= 3.1.2`). +- Enabled list filter dropdown by default. +- Fixed changelist searchbar style. ## [0.13.7](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.13.7) - 2020-10-14 -- Improved responsive widgets style. -- Prevented body horizontal scroll. -- Fixed tabular inline horizontal scroll. -- Fixed changelist filter min-width. -- Fixed changelist and toolbar theme rounded corners. -- Fixed calendar and timelist buttons theme color. -- Fixed list filter select size. -- Fixed content max-width with `django >= 3.1`. +- Improved responsive widgets style. +- Prevented body horizontal scroll. +- Fixed tabular inline horizontal scroll. +- Fixed changelist filter min-width. +- Fixed changelist and toolbar theme rounded corners. +- Fixed calendar and timelist buttons theme color. +- Fixed list filter select size. +- Fixed content max-width with `django >= 3.1`. ## [0.13.6](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.13.6) - 2020-10-14 -- Added persian language. #98 -- Fixed logo max-width on small screens. -- Fixed content max-width when nav-sidebar is collapsed. -- Fixed changelist max-width on medium screens. +- Added persian language. #98 +- Fixed logo max-width on small screens. +- Fixed content max-width when nav-sidebar is collapsed. +- Fixed changelist max-width on medium screens. ## [0.13.5](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.13.5) - 2020-09-15 -- Fixed loaddata error with initial_data.json fixture. #97 -- Fixed tests warning (admin.W411). -- Fixed changelist thead links color. -- Fixed changelist filter links hover color. +- Fixed loaddata error with initial_data.json fixture. #97 +- Fixed tests warning (admin.W411). +- Fixed changelist thead links color. +- Fixed changelist filter links hover color. ## [0.13.4](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.13.4) - 2020-09-04 -- Added conditional imports to avoid Django deprecation warnings. #92 -- Changed admin header content vertical align to top. +- Added conditional imports to avoid Django deprecation warnings. #92 +- Changed admin header content vertical align to top. ## [0.13.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.13.3) - 2020-09-02 -- Added `django-json-widget` theming support. +- Added `django-json-widget` theming support. ## [0.13.2](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.13.2) - 2020-08-21 -- Fixed related modal not closing on edit save and create with django 3.1 - #96 +- Fixed related modal not closing on edit save and create with django 3.1 - #96 ## [0.13.1](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.13.1) - 2020-08-18 -- Improved header and nav-sidebar style. -- Added `max-width` to logo. -- Added `requirements-dev.txt` +- Improved header and nav-sidebar style. +- Added `max-width` to logo. +- Added `requirements-dev.txt` ## [0.13.0](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.13.0) - 2020-08-05 -- Improved nav-sidebar style (`django>=3.1` support). -- Improved header style. +- Improved nav-sidebar style (`django>=3.1` support). +- Improved header style. ## [0.12.3](https://github.com/fabiocaccamo/django-admin-interface/releases/tag/0.12.3) - 2020-07-20 - Fixed unreadable text in autocomplete multi-selects. #83 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..23be9cb --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +fabio.caccamo@gmail.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/README.md b/README.md index 24f5d00..822ad0f 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,23 @@ [![](https://img.shields.io/pypi/djversions/django-admin-interface?color=0C4B33&logo=django&logoColor=white&label=django)](https://www.djangoproject.com/) [![](https://img.shields.io/pypi/v/django-admin-interface.svg?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/django-admin-interface/) -[![](https://pepy.tech/badge/django-admin-interface/month)](https://pepy.tech/project/django-admin-interface) -[![](https://img.shields.io/github/stars/fabiocaccamo/django-admin-interface?logo=github)](https://github.com/fabiocaccamo/django-admin-interface/) -[![](https://badges.pufler.dev/visits/fabiocaccamo/django-admin-interface?label=visitors&color=blue)](https://badges.pufler.dev) -[![](https://img.shields.io/pypi/l/django-admin-interface.svg?color=blue)](https://github.com/fabiocaccamo/django-admin-interface/blob/master/LICENSE.txt) +[![](https://static.pepy.tech/badge/django-admin-interface/month)](https://pepy.tech/project/django-admin-interface) +[![](https://img.shields.io/github/stars/fabiocaccamo/django-admin-interface?logo=github&style=flat)](https://github.com/fabiocaccamo/django-admin-interface/stargazers) +[![](https://img.shields.io/pypi/l/django-admin-interface.svg?color=blue)](https://github.com/fabiocaccamo/django-admin-interface/blob/main/LICENSE.txt) -[![](https://img.shields.io/github/workflow/status/fabiocaccamo/django-admin-interface/Test%20package?label=build&logo=github)](https://github.com/fabiocaccamo/django-admin-interface) +[![](https://results.pre-commit.ci/badge/github/fabiocaccamo/django-admin-interface/main.svg)](https://results.pre-commit.ci/latest/github/fabiocaccamo/django-admin-interface/main) +[![](https://img.shields.io/github/actions/workflow/status/fabiocaccamo/django-admin-interface/test-package.yml?branch=main&label=build&logo=github)](https://github.com/fabiocaccamo/django-admin-interface) [![](https://img.shields.io/codecov/c/gh/fabiocaccamo/django-admin-interface?logo=codecov)](https://codecov.io/gh/fabiocaccamo/django-admin-interface) [![](https://img.shields.io/codacy/grade/21cb657283c04e70b56fb935277a1ad1?logo=codacy)](https://www.codacy.com/app/fabiocaccamo/django-admin-interface) [![](https://img.shields.io/codeclimate/maintainability/fabiocaccamo/django-admin-interface?logo=code-climate)](https://codeclimate.com/github/fabiocaccamo/django-admin-interface/) -[![](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![](https://img.shields.io/badge/code%20style-black-000000.svg?logo=python&logoColor=black)](https://github.com/psf/black) +[![](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) # django-admin-interface django-admin-interface is a modern **responsive flat admin interface customizable by the admin itself**. ![django-admin-interface-preview](https://user-images.githubusercontent.com/1035294/35631521-64b0cab8-06a4-11e8-8f57-c04fdfbb7e8b.gif) ---- - ## Features - Beautiful default **django-theme** - Themes management and customization *(you can **customize admin title, logo and colors**)* @@ -27,50 +26,62 @@ django-admin-interface is a modern **responsive flat admin interface customizabl - Related modal *(instead of the old popup window)* - Environment name/marker - Language chooser +- Foldable apps *(accordions in the navigation bar)* +- [Collapsible fieldsets](https://docs.djangoproject.com/en/4.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets) can have their initial state expanded instead of collapsed +- `NEW` Collapsible inlines +- `NEW` Tabbed fieldsets and inlines +- `NEW` List filter removal links +- `NEW` List filter highlight selected options - List filter dropdown -- `NEW` **Foldable apps** *(accordions in the navigation bar)* -- `NEW` **List filter sticky** -- `NEW` **Form controls sticky** *(pagination and save/delete buttons)* -- Compatibility / Style optimizations for: +- List filter sticky +- Form controls sticky *(pagination and save/delete buttons)* +- Compatibility / style optimizations for: - `django-ckeditor` - `django-dynamic-raw-id` - `django-json-widget` - `django-modeltranslation` + - `django-rangefilter` + - `django-streamfield` - `django-tabbed-admin` - `sorl-thumbnail` - ---- +- Translated in many languages: `de`, `es`, `fa`, `fr`, `it`, `pl`, `pt_BR`, `ru`, `tr` ## Installation - Run `pip install django-admin-interface` -- Add `admin_interface`, `flat_responsive`, `flat` and `colorfield` to `settings.INSTALLED_APPS` **before** `django.contrib.admin` +- Add `admin_interface` and `colorfield` to `settings.INSTALLED_APPS` **before** `django.contrib.admin` ```python INSTALLED_APPS = ( #... "admin_interface", - "flat_responsive", # only if django version < 2.0 - "flat", # only if django version < 1.9 "colorfield", #... "django.contrib.admin", #... ) -# only if django version >= 3.0 X_FRAME_OPTIONS = "SAMEORIGIN" SILENCED_SYSTEM_CHECKS = ["security.W019"] ``` - Run `python manage.py migrate` -- Run `python manage.py collectstatic` -- Restart your application server - -#### Upgrade -- Run `pip install django-admin-interface --upgrade` -- Run `python manage.py migrate` *(add* `--fake-initial` *if you are upgrading from 0.1.0 version)* - Run `python manage.py collectstatic --clear` - Restart your application server ---- +> [!WARNING] +> if you want use modals instead of popup windows, ensure to add `X_FRAME_OPTIONS = "SAMEORIGIN"` setting. + +### Optional features +To make a fieldset start expanded with a `Hide` button to collapse, add the class `"expanded"` to its classes: +```python +class MyModelAdmin(admin.ModelAdmin): + # ... + fieldsets = [ + ("Section title", { + "classes": ("collapse", "expanded"), + "fields": (...), + }), + ] + # ... +``` ## Optional themes This package ships with optional themes as fixtures, they can be installed using the [loaddata admin command](https://docs.djangoproject.com/en/1.11/ref/django-admin/#django-admin-loaddata). Optional themes are activated on installation. @@ -100,33 +111,49 @@ 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. ### 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` -- `--admin-interface-logo-color` -- `--admin-interface-env-color` -- `--admin-interface-header-background-color:` +#### Header + +- `--admin-interface-header-background-color` - `--admin-interface-header-text-color` - `--admin-interface-header-link-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-selected-color` +- `--admin-interface-module-border-radius` - `--admin-interface-module-text-color` - `--admin-interface-module-link-color` - `--admin-interface-module-link-selected-color` - `--admin-interface-module-link-hover-color` - `--admin-interface-generic-link-color` - `--admin-interface-generic-link-hover-color` +- `--admin-interface-generic-link-active-color` + +#### Buttons - `--admin-interface-save-button-background-color` - `--admin-interface-save-button-background-hover-color` - `--admin-interface-save-button-text-color` - `--admin-interface-delete-button-background-color` - `--admin-interface-delete-button-background-hover-color` - `--admin-interface-delete-button-text-color` + +#### Related Modal - `--admin-interface-related-modal-background-color` - `--admin-interface-related-modal-background-opacity` - ---- +- `--admin-interface-related-modal-border-radius` +- `--admin-interface-related-modal-close-button-display` ## Screenshots ###### Admin login @@ -141,7 +168,40 @@ You can add **theme support to existing third-party libraries** using the follow ###### Admin theme customization ![django-admin-interface_theme_customization](https://cloud.githubusercontent.com/assets/1035294/11240250/7350d942-8df1-11e5-9b28-f2f54c333cdc.gif) ---- +## Localization +At the moment, this package has been translated into the following languages: `de`, `es`, `fa`, `fr`, `it`, `pl`, `pt_BR`, `tr`. + +### Translate into another language + +- Run `python -m django makemessages --ignore ".tox" --ignore "venv" --add-location "file" --extension "html,py" --locale "it"` *(example for Italian localization)* + +- Update translations in `admin_interface/locale/it/LC_MESSAGES/django.po` + +- Run `python -m django compilemessages --ignore ".tox" --ignore "venv"` + +### Update translations + +If you do some changes to the project, remember to update translations, because if the translations files are not up-to-date, the `lint` step in the CI will fail: +- Run `tox -e translations` + +## Caching + +This package uses caching to improve theme load time and overall performance. +You can customise the app caching options using `settings.CACHES["admin_interface"]` setting, otherwise the `"default"` cache will be used: + +```python +CACHES = { + # ... + "admin_interface": { + "BACKEND": "django.core.cache.backends.locmem.LocMemCache", + "TIMEOUT": 60 * 5, + }, + # ... +} +``` + +> [!WARNING] +> There is a [known compatibility issue](https://github.com/fabiocaccamo/django-admin-interface/issues/356) when using this package with `django-redis`, more specifically, using the `JSONSerializer` the following error is raised: `TypeError: Object of type Theme is not JSON serializable`, to mitigate this problem, simply use a specific cache for this app that does not use any `json` serializer. ## FAQ @@ -150,6 +210,16 @@ You can add **theme support to existing third-party libraries** using the follow You can use [django-apptemplates](https://github.com/bittner/django-apptemplates), then add `{% extends "admin_interface:admin/base_site.html" %}` to your `base_site.html` +### Custom `LocaleMiddleware` warning +> I'm using a `django.middleware.locale.LocaleMiddleware` subclass, but I see an unnecessary warning for missing `django.middleware.locale.LocaleMiddleware`, what can I do? + +You can simply ignore the warning (this has been discussed [here](https://github.com/fabiocaccamo/django-admin-interface/issues/354)) +```python +import warnings + +warnings.filterwarnings("ignore", module="admin_interface.templatetags.admin_interface_tags") +``` + ### Language Chooser not showing > I have enabled the **Language Chooser**, but it is not visible in the admin, what should I do? @@ -158,7 +228,7 @@ You must configure multilanguage `settings` and `urls` correctly: LANGUAGES = ( ("en", _("English")), ("it", _("Italiano")), - ("fr", _("Française")), + ("fr", _("Français")), # more than one language is expected here ) LANGUAGE_CODE = "en" @@ -183,38 +253,61 @@ urlpatterns = [ urlpatterns += i18n_patterns(path("admin/", admin.site.urls)) ``` ---- +### Open any url in modal window +> I have an application with some cross-links in the admin and I would like to open them in modal windows instead of same/new window, how can I do? + +You just need to add `_popup=1` query-string parameter to the urls: +```python +url = reverse(f"admin:myapp_mymodel_change", args=[mymodel_instance.pk]) +url = f"{url}?_popup=1" +``` ## Testing ```bash -# create python virtual environment -virtualenv testing_django_admin_interface +# clone repository +git clone https://github.com/fabiocaccamo/django-admin-interface.git && cd django-admin-interface -# activate virtualenv -cd testing_django_admin_interface && . bin/activate +# create virtualenv and activate it +python -m venv venv && . venv/bin/activate -# clone repo -git clone https://github.com/fabiocaccamo/django-admin-interface.git src && cd src +# upgrade pip +python -m pip install --upgrade pip -# install dependencies -pip install -r requirements.txt -pip install -r requirements-test.txt +# install requirements +pip install -r requirements.txt -r requirements-test.txt + +# install pre-commit to run formatters and linters +pre-commit install --install-hooks # run tests tox # or -python setup.py test +python runtests.py # or python -m django test --settings "tests.settings" ``` ---- +## Contributing +Contributions are always welcome, please follow these steps for submitting good quality PRs: + +- :exclamation: **Open an issue**, please don't submit any PR that doesn't refer to an existing issue. +- :computer: **Work on changes**, changes should *preferably* be covered by tests to avoid regressions in the future. +- :globe_with_meridians: **Update the translations** files. +- :test_tube: **Run tests** ensuring that there are no errors. +- :inbox_tray: **Submit a pull-request** and mark it as **"Ready for review"** only if it passes the `CI`. ## License 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 - [`django-colorfield`](https://github.com/fabiocaccamo/django-colorfield) - simple color field for models with a nice color-picker in the admin. 🎨 diff --git a/admin_interface/__init__.py b/admin_interface/__init__.py index dcf03df..d64097e 100644 --- a/admin_interface/__init__.py +++ b/admin_interface/__init__.py @@ -1,4 +1,17 @@ -import django +from admin_interface.metadata import ( + __author__, + __copyright__, + __description__, + __license__, + __title__, + __version__, +) -if django.VERSION < (3, 2): - default_app_config = "admin_interface.apps.AdminInterfaceConfig" +__all__ = [ + "__author__", + "__copyright__", + "__description__", + "__license__", + "__title__", + "__version__", +] diff --git a/admin_interface/admin.py b/admin_interface/admin.py index 84722f0..eeb92fa 100644 --- a/admin_interface/admin.py +++ b/admin_interface/admin.py @@ -1,9 +1,6 @@ -# -*- coding: utf-8 -*- - from django.contrib import admin -from django.contrib.auth import models as auth_models +from django.utils.translation import gettext_lazy as _ -from admin_interface.compat import gettext_lazy as _ from admin_interface.models import Theme, UserTheme from .import_tema.admin import ImportMixin @@ -15,6 +12,7 @@ class UserInline(admin.TabularInline): autocomplete_fields = ('user', ) +@admin.register(Theme) class ThemeAdmin(ImportMixin, admin.ModelAdmin): inlines = [UserInline, ] @@ -59,6 +57,7 @@ class ThemeAdmin(ImportMixin, admin.ModelAdmin): "classes": ("wide",), "fields": ( "language_chooser_active", + "language_chooser_control", "language_chooser_display", ), }, @@ -122,6 +121,7 @@ class ThemeAdmin(ImportMixin, admin.ModelAdmin): "fields": ( "css_generic_link_color", "css_generic_link_hover_color", + "css_generic_link_active_color", ), }, ), @@ -147,8 +147,13 @@ class ThemeAdmin(ImportMixin, admin.ModelAdmin): ), }, ), - (_("Navigation Bar"), {"classes": ( - "wide",), "fields": ("foldable_apps",)}), + ( + _("Navigation Bar"), + { + "classes": ("wide",), + "fields": ("foldable_apps",), + }, + ), ( _("Related Modal"), { @@ -177,18 +182,42 @@ class ThemeAdmin(ImportMixin, admin.ModelAdmin): { "classes": ("wide",), "fields": ( + "list_filter_highlight", "list_filter_dropdown", "list_filter_sticky", + "list_filter_removal_links", + ), + }, + ), + ( + _("Change Form"), + { + "classes": ("wide",), + "fields": ( + "show_fieldsets_as_tabs", + "show_inlines_as_tabs", + ), + }, + ), + ( + _("Inlines"), + { + "classes": ("wide",), + "fields": ( + "collapsible_stacked_inlines", + "collapsible_stacked_inlines_collapsed", + "collapsible_tabular_inlines", + "collapsible_tabular_inlines_collapsed", ), }, ), ( _("Recent Actions"), - {"classes": ("wide",), "fields": ("recent_actions_visible",)}, + { + "classes": ("wide",), + "fields": ("recent_actions_visible",), + }, ), ) save_on_top = True - - -admin.site.register(Theme, ThemeAdmin) diff --git a/admin_interface/apps.py b/admin_interface/apps.py index ac7eacf..93fe695 100644 --- a/admin_interface/apps.py +++ b/admin_interface/apps.py @@ -1,21 +1,13 @@ -# -*- coding: utf-8 -*- - -from admin_interface.compat import gettext_lazy as _ - from django.apps import AppConfig -from django.db.models.signals import post_migrate +from django.utils.translation import gettext_lazy as _ class AdminInterfaceConfig(AppConfig): - name = "admin_interface" verbose_name = _("Admin Interface") default_auto_field = "django.db.models.AutoField" def ready(self): - from admin_interface import settings - from admin_interface.models import Theme settings.check_installed_apps() - post_migrate.connect(Theme.post_migrate_handler, sender=self) diff --git a/admin_interface/cache.py b/admin_interface/cache.py index b256c1a..78d1ffe 100644 --- a/admin_interface/cache.py +++ b/admin_interface/cache.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - from django.conf import settings from django.core.cache import cache, caches diff --git a/admin_interface/compat.py b/admin_interface/compat.py deleted file mode 100644 index fed1d1b..0000000 --- a/admin_interface/compat.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- - -import django - -if django.VERSION >= (1, 11): - from django.core.validators import FileExtensionValidator -else: - - def FileExtensionValidator(*args, **kwargs): - def noop(*args, **kwargs): - pass - - return noop - - -if django.VERSION < (1, 10): - from django.core.urlresolvers import NoReverseMatch, reverse -else: - from django.urls import NoReverseMatch, reverse - -if django.VERSION < (2, 0): - from django.utils.encoding import force_text as force_str - from django.utils.translation import ugettext_lazy as gettext_lazy -else: - from django.utils.encoding import force_str - from django.utils.translation import gettext_lazy diff --git a/admin_interface/context_processor.py b/admin_interface/context_processor.py index 197feba..b473c69 100644 --- a/admin_interface/context_processor.py +++ b/admin_interface/context_processor.py @@ -18,14 +18,6 @@ def get_active_theme(request): 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 = user_theme_manager.filter(user=user, theme__active=True).first().theme diff --git a/admin_interface/locale/de/LC_MESSAGES/django.mo b/admin_interface/locale/de/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..fed60dbd047a5a7212fad80179b0b8293bc126b2 GIT binary patch literal 3820 zcma);Uu+yl9mj`|KyeF!QlO=U{7M7Zsn?F}5IdK+^z6Hf4R=1v=M)tl%G~YT-sbjZ zj+x!F9U`Qvg_l<11q2Tf2ni%aC7w_uAP*ov6bYfe@K7Ow1mb}QBpxaxRFL5N+nw{D z6eLzR_u2Wgzklh^w38=`~dnV-cigy489Znv*5eIY0nafpIF1+d%-4n4*Vj>a$f>Zg5LsJ z{w>c}Kwked-~Tnpa(@Rt0R9Dp3F7Y{e&V0Le*#8u|2~kPKMj5mB=A9S5qt#v4EPWj zf~D+1+pDK23h_ckmL0mKYtgTK>u%k{!Q@x=-+=|q2~<9 z^Jl?#fwO-661a%|Qy|M5fvoRqzW;5I_5Kj#=Wl~-?=L})$EzSziQj^cg1-l!0RI85 zybXH^WxUVN;o%1OJjn8213wJ@5#;#%3uOJLu{rGD8Ibq+JP1*u2C|+e$j^Tc7oa%lO>;qrC zH+->t&ZC_{=$iBO3d-)Edd;~0-G zj=z|ki96=z%uq)+XQH@E0nJ_9ox6B*VSaaEo`$`E~r)f_miP^zGZEp3#`Pwu^Rw<4Ce06noac-L0Nyh6JE?iowtW1e=IEXc^>r~mU z>?pBfl?*#J8?+tGQp1E>E7V9-D&W4kwCMwDAe zE7FQhGt7q6NsNniG&3_Jwp0h!Qn|wpICK-4s*nRC6VYNb#x8I7)If>+--+!wO_Y#$ zYNSM4cKVSunGUIA5@U}J^vp=vw+@@3?8NEb(UmR_G;|j-*ha)4k2j5C7q_9XV?zF8 z9f&Q5RD`h`CUQ@7eZ0G|NOH#(>w4NLTFwY(KH znn9&ZYt2$){mIWaH>wkL>C#{umBArdjV)2_TD?vi`qSk~Wvkk1J%y#k z(F(Se9F(YD-ne>=ExA&!Kb^!g#zu#0U_oQOQ9U$!Zsz<1pIjV}V0&)}dpLx%NViyD z#$lBfdA59QyA~`Ru4A*h$_7=9WW^yX(Na53CpMGJ$|T@w;7X*2dDkt^U#8-Ac~aBk z%QQE2dE)=7k|yP%_`j-Tq>}cr8o7Vxc#V|Vy)`muwoxLJ{qJ{r|Fud6zF6(Qs8K63 z9XTZJAWM*#8aEQ>tDLzV*-J!y|F(k^jjcUeErYxkA6Cn2gGjX@=vb*_fi6{9uELi~ z7IwU1wuV+B{$5`tRt^WahJ#OuLb*w#b4pV-pb$mCm&;a)B$YNKE|YX4qqfpndPAW^ z=SNQJ8#u12sG?lfkNI?1M_r=egYu;mwk5IJ|E|(pO*ddT=BV7~^9Rv+9i{I69ZRT# zJFoz=&GvQGhlJKp#c<6Y28yezENZOg8mkf^A!;PnVt#`~hLS1azrIAwsmd)Hq!i{i?0F%TWoN7hSM4!894Mf#v1uqY+r5wz76tR zAp@Ja4B{x@O^au>&kEU&ICVq*Sg3aT@Qgnxda9f9NU>CBg8{w*iWEOOy*V!2M+b{d z7@y2-RG=aQiu9=X`W^6xfFhsK2m3X?AtZ<2A)0LXa(;BOINjqp;&(YmV@mu7;y=5E literal 0 HcmV?d00001 diff --git a/admin_interface/locale/de/LC_MESSAGES/django.po b/admin_interface/locale/de/LC_MESSAGES/django.po new file mode 100644 index 0000000..73683d9 --- /dev/null +++ b/admin_interface/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,316 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-05-10 18:20-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: admin_interface/admin.py +msgid "Environment" +msgstr "Umgebung" + +#: admin_interface/admin.py +msgid "Language chooser" +msgstr "Sprachauswahl" + +#: admin_interface/admin.py +msgid "Logo" +msgstr "Logo" + +#: admin_interface/admin.py +msgid "Favicon" +msgstr "Favicon" + +#: admin_interface/admin.py +msgid "Title" +msgstr "Titel" + +#: admin_interface/admin.py +msgid "Header" +msgstr "Header" + +#: admin_interface/admin.py +msgid "Breadcrumbs / Module headers" +msgstr "Breadcrumbs / Modul-Header" + +#: admin_interface/admin.py +msgid "Generic Links" +msgstr "Generische Links" + +#: admin_interface/admin.py +msgid "Save Buttons" +msgstr "Speichern-Buttons" + +#: admin_interface/admin.py +msgid "Delete Buttons" +msgstr "Löschen-Buttons" + +#: admin_interface/admin.py +msgid "Navigation Bar" +msgstr "Navigationsleiste" + +#: admin_interface/admin.py +msgid "Related Modal" +msgstr "Modal für verwandte Objekte" + +#: admin_interface/admin.py +msgid "Form Controls" +msgstr "Formularsteuerung" + +#: admin_interface/admin.py +msgid "List Filter" +msgstr "Filteranzeige" + +#: admin_interface/admin.py +msgid "Change Form" +msgstr "Änderungsformular" + +#: admin_interface/admin.py +msgid "Inlines" +msgstr "" + +#: admin_interface/admin.py +msgid "Recent Actions" +msgstr "Neueste Aktionen" + +#: admin_interface/apps.py +msgid "Admin Interface" +msgstr "Admin-Oberfläche" + +#: admin_interface/models.py +msgid "name" +msgstr "Name" + +#: admin_interface/models.py +msgid "active" +msgstr "aktiv" + +#: admin_interface/models.py admin_interface/templates/admin/base_site.html +msgid "Django administration" +msgstr "Django-Administration" + +#: admin_interface/models.py +msgid "title" +msgstr "Titel" + +#: admin_interface/models.py +msgid "color" +msgstr "Farbe" + +#: admin_interface/models.py +msgid "visible" +msgstr "sichtbar" + +#: admin_interface/models.py +msgid "Leave blank to use the default Django logo" +msgstr "Dieses Feld leer lassen um das Django Standard Logo zu benutzen" + +#: admin_interface/models.py +msgid "logo" +msgstr "Logo" + +#: admin_interface/models.py +msgid "max width" +msgstr "maximale Breite" + +#: admin_interface/models.py +msgid "max height" +msgstr "maximale Höhe" + +#: admin_interface/models.py +msgid "(.ico|.png|.gif - 16x16|32x32 px)" +msgstr "(.ico|.png|.gif - 16x16|32x32 px)" + +#: admin_interface/models.py +msgid "favicon" +msgstr "Favicon" + +#: admin_interface/models.py +msgid "" +"(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: " +"#3498DB)" +msgstr "" +"(rot: #E74C3C, orange: #E67E22, gelb: #F1C40F, grün: #2ECC71, blau: #3498DB)" + +#: admin_interface/models.py +msgid "visible in header (marker and name)" +msgstr "sichtbar im Header (Marker und Name)" + +#: admin_interface/models.py +msgid "visible in favicon (marker)" +msgstr "sichtbar im Favicon (Marker)" + +#: admin_interface/models.py +msgid "Default Select" +msgstr "normale Auswahl" + +#: admin_interface/models.py +msgid "Minimal Select" +msgstr "minimale Auswahl" + +#: admin_interface/models.py +msgid "control" +msgstr "Regler" + +#: admin_interface/models.py +msgid "code" +msgstr "Code" + +#: admin_interface/models.py +msgid "display" +msgstr "Anzeige" + +#: admin_interface/models.py +msgid "background color" +msgstr "Hintergrundfarbe" + +#: admin_interface/models.py +msgid "text color" +msgstr "Textfarbe" + +#: admin_interface/models.py +msgid "link color" +msgstr "Linkfarbe" + +#: admin_interface/models.py +msgid "link hover color" +msgstr "Linkfarbe beim Überfahren" + +#: admin_interface/models.py +msgid "background selected color" +msgstr "Hintergrundfarbe bei Auswahl" + +#: admin_interface/models.py +msgid "link selected color" +msgstr "Linkfarbe bei Auswahl" + +#: admin_interface/models.py +msgid "rounded corners" +msgstr "abgerundete Ecken" + +#: admin_interface/models.py +msgid "link active color" +msgstr "Linkfarbe beim aktiv" + +#: admin_interface/models.py +msgid "background hover color" +msgstr "Hintergrundfarbe beim Überfahren" + +#: admin_interface/models.py +msgid "background opacity" +msgstr "Deckkraft des Hintergrunds" + +#: admin_interface/models.py +msgid "close button visible" +msgstr "Schließen-Schalter sichtbar" + +#: admin_interface/models.py +msgid "highlight active" +msgstr "Aktiv hervorheben" + +#: admin_interface/models.py +msgid "use dropdown" +msgstr "Dropdown-Liste nutzen" + +#: admin_interface/models.py +msgid "sticky position" +msgstr "angeheftete Position" + +#: admin_interface/models.py +msgid "quick remove links for active filters at top of sidebar" +msgstr "Schnellentfernung für aktive Filter oben in der Seitenleiste" + +#: admin_interface/models.py +msgid "foldable apps" +msgstr "einklappbare Apps" + +#: admin_interface/models.py +msgid "fieldsets as tabs" +msgstr "Fieldsets als Tabs" + +#: admin_interface/models.py +msgid "inlines as tabs" +msgstr "Inlines als Tabs" + +#: admin_interface/models.py +msgid "collapsible stacked inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "sticky submit" +msgstr "angeheftete Schaltfläche" + +#: admin_interface/models.py +msgid "sticky pagination" +msgstr "angeheftete Seitennummerierung" + +#: admin_interface/models.py +msgid "Theme" +msgstr "Thema" + +#: admin_interface/models.py +msgid "Themes" +msgstr "Themen" + +#: admin_interface/templates/admin/change_list.html +msgid "Filter" +msgstr "" + +#. Translators: don't translate this, the django catalog already contains it +#: admin_interface/templates/admin/change_list.html +msgid "Clear all filters" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Change" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View on site" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Delete?" +msgstr "" + +#: admin_interface/templates/admin/filter.html +#: admin_interface/templates/admin_interface/dropdown_filter.html +#, python-format +msgid " By %(filter_title)s " +msgstr "" + +#: admin_interface/templates/admin/popup_response.html +msgid "Popup closing..." +msgstr "Popup schließen..." diff --git a/admin_interface/locale/es/LC_MESSAGES/django.mo b/admin_interface/locale/es/LC_MESSAGES/django.mo index f29ebec8e3c4b86b1566685912dc7a8831a8ea7c..289e0d60498045c87291364ef43c7548a31366fb 100644 GIT binary patch literal 4072 zcmaKuO^h5z8HOuhVzMLwOl*Eal1fPMu1Syg$2QB_8{)NhiN$VM*&7gtVAXWj%#^pg zs?*i8*)bLekO&;OM9L)+kq{j4A&8I*h)d8SA#z1R2qXj?av_%pOUP0rc;D)pAFrdd zrskQduKMb$ufBR~{(k7dO9IcAQ9g@u-v@;FCV2M&eBmiSB*bCxIq+fd1@NQbb&&mk z1AYYjGk7ofugG^mjuUq_?~i~7QGEow2Rs(J2;w8w@bxip13U(P3#8p2f^_92koI4W zybiMeuVej>AnpDIyc>KAgbU(7AU@(|tkVhB?*uvi9`FeGAb1Eo3El@j1#;eJ!TZ5B z_!#(|SpQk9zX5Wdw?KTv+mSaS-vvL8_5&Yo{5t}2-bX>k@g&IitKby)jrhI|a(*A% zcfq?*|6XkW5%@*aUj%9AO^|l}8tZR^jK{km?M`7Z{X7gZKKFz4cN*mSX2H*a>!7;> z`wlWL|G?lS@V_AY&0|v-ho?cts|MNc1(5T<0)86&C5WlTn;_@;6Zk3cZy?9r0O{93 zIKy}!0=b@}AmeixEE7wi87Iqn9?_1*+I|NlVl`#}VS zd2}yGzaIeU_X&{xt%2-+8T<^`1-ahuf?WU4!Ow%g2WkJ`Ap5@)c{B13Ov3!X3*FuF`tj{pe-V_ZzYIPO{uacxj~@DtkcBm}@eIG>!+qj&3}qRGe$jVo$Rj9E zpqxNyp?m>_@#Dk%Ivsuq@j(zN5ORx6kD@RiAV0x>#$fnx{R=3}Cq8ox#9}1lz_s&v zuz@%VegcIW^#BUBix2k@sV$D9%%Ct=`C$2C9%YslJd7zH#*p!2j-5oAMwxsVJLbuk zV&kbu2`2G3^OiZo_zSr*kdIAwOkV5ia&78d&v+@OTPAhaTBYq?YjsUWCUWl7?%b(s z3-h}R^RnEX5ofc)Sb4!>SVyH=tW;WMY1J>sF;uATMb{1xrgFB>wiat@2fkTBWAdD{ zb>(s|zM`$JOe)un-S*B@d7)7*JuyRBABT+}JNm1k2fz@wV0 zT4xN5%EcwRFRfY!XYs>(zjLnVJ{{7x@Dvs0HExl^h?&qp{PYe6r-D&}= z!7g(1L}q-MtAXgmo$VN%XI|G{DlcKgi;l}Pg%wCumR|Hsx0j>TGR7&oKkAOfY{z$; z6jOzkiJz0v3)@|&U1Teb3jTcFWOYwig^hWxZ_;g9=>h?lwBu#RRYUX5!GWhW5~`H0 zBfZIV8yOMy4Y5sKh1B%I*RV5?rRo~nWc9EGITNxx)_uQSm|E0&w~pS2V=0)eS>?*i zJ#WQuOCu3~8N(;13sr6FYG&An@0x=+d?gh!ii?{Oo0YqQW0+jXlCQ%{>!*@-Vtn|A+*>X#AYV&K!MNK!HP0l07m*o8H{6aFjn9QD#b8|~4 z=abom+1aUelgz~yJQ){@0>KRVyhRkCVvl5ozK@Q=56eQh7o_@=MZ| zq3W0CPs`@#^0bu?FUz@^(^EojB6n`rTaHCkyo9tpE+MWnvOec7ljT1qfgAIvI zr$8b}oLF%XX&sztyQ)H#hif1Rb<-P8G%702!YHDvM}i%-ItIUZgD z(dE%4kgB3Y>~Q=MZ;f5sdkyhXWp2_C%v)y6*dfJ&!-X(j-oDYJaO#k8a=N)cX2yYS zUhJ=rA|0*@mDf1$ve^5{E;B`0{JV%XC#);ll@`r)!3=FuJLG4~x#*;4`sRwMg8x6h zU*i8uv)O3G1%fH~mjTKmw8tf6aT!)RLn1H^Hs!6`TqaF&4x4bB+|n@4fnmOl!a&J$ wqnvw&$0v^m1UGV%5W`z!NP3MkHhI~k$cTySrs<$ZViRti&_@nr6Q3FJfBn@UQUCw| delta 1072 zcmYk)Pe@cj9Ki80UES3+bF;L}d?^_OyY6a#R4Ns;I;=qvUdmv0cZ_Gd@7a5A1%ucw zK}YFP7pdqJf)Ei!hoB&cpi`%AbqVUw#X8g_==DparT0yH;HD=70; zv4Q+*z51fmBb1#zMVa^-CE+`i0^Xwp`h<&|(pQv3b5t{i0e0g<+>39q9XD_X*0VT@ zJt%PocqGWLQoKmQNgTl}N`=>v9O`y$yo$1;b?n6#wed%kdEZb9{(=0|FCOGp5wgmO z#!(9HMk#CvD>8A47uk6hJMlb9zyKw{GRlH$D1mOGthsC6yk4^N zt`p8i`#Kz5GRkwyPQetcyz8;Z4`Z=?;bLs|OlBmR8A=YPt<30HW;mHXm`*omwI3wU zdfM@eI&i%)Yesv4?O3yAQw+3qq*NWIma4-E-<=O~$I2D8lXtB}?P;s*YZH#g4~2K)3w4uW rwDs7(t&}&Xx=y*JoM)8rFPCjc`<7=4u2ax{m~R`5&f316D;o71m3oz) diff --git a/admin_interface/locale/es/LC_MESSAGES/django.po b/admin_interface/locale/es/LC_MESSAGES/django.po index c6c60af..b74e44c 100644 --- a/admin_interface/locale/es/LC_MESSAGES/django.po +++ b/admin_interface/locale/es/LC_MESSAGES/django.po @@ -3,15 +3,16 @@ # # Translators: # Martin Vuelta , 2018 +# Santiago Muñoz , 2023 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: django-admin-interface\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-09-04 09:18+0000\n" -"PO-Revision-Date: 2018-12-30 19:13-0500\n" -"Last-Translator: Martin Vuelta \n" +"POT-Creation-Date: 2023-05-10 18:20-0500\n" +"PO-Revision-Date: 2023-08-04 11:52-0300\n" +"Last-Translator: Santiago Muñoz \n" "Language-Team: Spanish \n" "Language: Spanish \n" "MIME-Version: 1.0\n" @@ -19,188 +20,304 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: admin_interface/admin.py:21 +#: admin_interface/admin.py msgid "Environment" msgstr "Ambiente" -#: admin_interface/admin.py:30 +#: admin_interface/admin.py msgid "Language chooser" -msgstr "" +msgstr "Selección de idioma" -#: admin_interface/admin.py:37 +#: admin_interface/admin.py msgid "Logo" msgstr "Logo" -#: admin_interface/admin.py:45 +#: admin_interface/admin.py msgid "Favicon" msgstr "Favicon" -#: admin_interface/admin.py:49 +#: admin_interface/admin.py msgid "Title" msgstr "Título" -#: admin_interface/admin.py:57 +#: admin_interface/admin.py msgid "Header" msgstr "Encabezado" -#: admin_interface/admin.py:66 +#: admin_interface/admin.py msgid "Breadcrumbs / Module headers" msgstr "Breadcrumbs / Encabezados de módulos" -#: admin_interface/admin.py:76 +#: admin_interface/admin.py msgid "Generic Links" msgstr "Enlaces genéricos" -#: admin_interface/admin.py:83 +#: admin_interface/admin.py msgid "Save Buttons" msgstr "Botones de guardar" -#: admin_interface/admin.py:91 +#: admin_interface/admin.py msgid "Delete Buttons" msgstr "Botones de borrar" -#: admin_interface/admin.py:99 +#: admin_interface/admin.py +msgid "Navigation Bar" +msgstr "Barra de navegación" + +#: admin_interface/admin.py msgid "Related Modal" msgstr "Modal para objetos relacionados" -#: admin_interface/admin.py:109 +#: admin_interface/admin.py +msgid "Form Controls" +msgstr "Controles del formulario" + +#: admin_interface/admin.py msgid "List Filter" msgstr "Lista de filtros" -#: admin_interface/admin.py:113 +#: admin_interface/admin.py +msgid "Change Form" +msgstr "Cambiar Formulario" + +#: admin_interface/admin.py +msgid "Inlines" +msgstr "" + +#: admin_interface/admin.py msgid "Recent Actions" msgstr "Acciones recientes" -#: admin_interface/apps.py:11 +#: admin_interface/apps.py msgid "Admin Interface" msgstr "Interfaz de administración" -#: admin_interface/models.py:72 admin_interface/models.py:116 -#: admin_interface/models.py:135 +#: admin_interface/models.py msgid "name" -msgstr "Nombre" +msgstr "nombre" -#: admin_interface/models.py:75 admin_interface/models.py:132 -#: admin_interface/models.py:253 +#: admin_interface/models.py msgid "active" -msgstr "Activo" +msgstr "activo" -#: admin_interface/models.py:79 -#: admin_interface/templates/admin/base_site.html:6 -#: admin_interface/templates/admin/base_site.html:60 +#: admin_interface/models.py admin_interface/templates/admin/base_site.html msgid "Django administration" msgstr "Administración de Django" -#: admin_interface/models.py:81 +#: admin_interface/models.py msgid "title" msgstr "Título" -#: admin_interface/models.py:87 admin_interface/models.py:102 -#: admin_interface/models.py:122 -#, fuzzy -#| msgid "logo color" +#: admin_interface/models.py msgid "color" -msgstr "color de logo" +msgstr "color" -#: admin_interface/models.py:90 admin_interface/models.py:105 -#: admin_interface/models.py:289 +#: admin_interface/models.py msgid "visible" -msgstr "Visible" +msgstr "visible" -#: admin_interface/models.py:95 +#: admin_interface/models.py msgid "Leave blank to use the default Django logo" -msgstr "Dejar en blanco para usaer el logo por defecto de Django" +msgstr "Dejar en blanco para usar el logo por defecto de Django" -#: admin_interface/models.py:96 +#: admin_interface/models.py msgid "logo" msgstr "logo" -#: admin_interface/models.py:110 +#: admin_interface/models.py +msgid "max width" +msgstr "ancho máximo" + +#: admin_interface/models.py +msgid "max height" +msgstr "altura máxima" + +#: admin_interface/models.py msgid "(.ico|.png|.gif - 16x16|32x32 px)" msgstr "Formatos ico, png o gif. Tamaños de 16x16 o 32x32 pixeles" -#: admin_interface/models.py:111 +#: admin_interface/models.py msgid "favicon" msgstr "favicon" -#: admin_interface/models.py:120 +#: admin_interface/models.py msgid "" "(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: " "#3498DB)" msgstr "" -#: admin_interface/models.py:125 +#: admin_interface/models.py msgid "visible in header (marker and name)" -msgstr "" +msgstr "visible en el encabezado (marcador y nombre)" -#: admin_interface/models.py:128 +#: admin_interface/models.py msgid "visible in favicon (marker)" -msgstr "" +msgstr "visible en el favicon (marcador)" -#: admin_interface/models.py:134 +#: admin_interface/models.py +msgid "Default Select" +msgstr "Selección por defecto" + +#: admin_interface/models.py +msgid "Minimal Select" +msgstr "Selección mínima" + +#: admin_interface/models.py +msgid "control" +msgstr "control" + +#: admin_interface/models.py msgid "code" -msgstr "" +msgstr "código" -#: admin_interface/models.py:141 +#: admin_interface/models.py msgid "display" -msgstr "" +msgstr "mostrar" -#: admin_interface/models.py:148 admin_interface/models.py:173 -#: admin_interface/models.py:214 admin_interface/models.py:233 -#: admin_interface/models.py:259 +#: admin_interface/models.py msgid "background color" msgstr "color de fondo" -#: admin_interface/models.py:154 admin_interface/models.py:179 -#: admin_interface/models.py:226 admin_interface/models.py:245 -#: admin_interface/models.py:249 +#: admin_interface/models.py msgid "text color" msgstr "color de texto" -#: admin_interface/models.py:160 admin_interface/models.py:185 -#: admin_interface/models.py:201 +#: admin_interface/models.py msgid "link color" msgstr "color de enlace" -#: admin_interface/models.py:166 admin_interface/models.py:191 -#: admin_interface/models.py:207 +#: admin_interface/models.py msgid "link hover color" msgstr "color de enlace (hover)" -#: admin_interface/models.py:194 admin_interface/models.py:279 +#: admin_interface/models.py +#, fuzzy +#| msgid "background color" +msgid "background selected color" +msgstr "color de fondo" + +#: admin_interface/models.py +#, fuzzy +#| msgid "link color" +msgid "link selected color" +msgstr "color de enlace" + +#: admin_interface/models.py msgid "rounded corners" msgstr "esquinas redondas" -#: admin_interface/models.py:220 admin_interface/models.py:239 +#: admin_interface/models.py +msgid "link active color" +msgstr "color de enlace (active)" + +#: admin_interface/models.py msgid "background hover color" msgstr "color de fondo (hover)" -#: admin_interface/models.py:276 +#: admin_interface/models.py msgid "background opacity" msgstr "opacidad de fondo" -#: admin_interface/models.py:282 +#: admin_interface/models.py msgid "close button visible" -msgstr "" +msgstr "mostrar botón de cerrar" -#: admin_interface/models.py:286 +#: admin_interface/models.py +msgid "highlight active" +msgstr "destacar activo" + +#: admin_interface/models.py msgid "use dropdown" msgstr "Usar lista desplegable" -#: admin_interface/models.py:298 +#: admin_interface/models.py +msgid "sticky position" +msgstr "anclar posición" + +#: admin_interface/models.py +msgid "quick remove links for active filters at top of sidebar" +msgstr "remover enlaces para filtros activos en la parte superior de la barra lateral" + +#: admin_interface/models.py +msgid "foldable apps" +msgstr "aplicaciones plegables" + +#: admin_interface/models.py +msgid "fieldsets as tabs" +msgstr "campos como pestañas" + +#: admin_interface/models.py +msgid "inlines as tabs" +msgstr "inlines como pestañas" + +#: admin_interface/models.py +msgid "collapsible stacked inlines" +msgstr "inlines apilados plegables" + +#: admin_interface/models.py +msgid "collapsible stacked inlines collapsed" +msgstr "inlines apilados plegables colapsados" + +#: admin_interface/models.py +msgid "collapsible tabular inlines" +msgstr "inlines tabulares plegables" + +#: admin_interface/models.py +msgid "collapsible tabular inlines collapsed" +msgstr "inlines tabulares plegables colapsados" + +#: admin_interface/models.py +msgid "sticky submit" +msgstr "anclar botón de guardar" + +#: admin_interface/models.py +msgid "sticky pagination" +msgstr "anclar paginación" + +#: admin_interface/models.py msgid "Theme" msgstr "Tema" -#: admin_interface/models.py:299 +#: admin_interface/models.py msgid "Themes" msgstr "Temas" -#: admin_interface/templates/admin/filter.html:13 -#: admin_interface/templates/admin_interface/dropdown_filter.html:4 +#: admin_interface/templates/admin/change_list.html +#, fuzzy +#| msgid "List Filter" +msgid "Filter" +msgstr "Lista de filtros" + +#. Translators: don't translate this, the django catalog already contains it +#: admin_interface/templates/admin/change_list.html +msgid "Clear all filters" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Change" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View on site" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Delete?" +msgstr "" + +#: admin_interface/templates/admin/filter.html +#: admin_interface/templates/admin_interface/dropdown_filter.html #, python-format msgid " By %(filter_title)s " msgstr " Por %(filter_title)s " -#: admin_interface/templates/admin/popup_response.html:3 +#: admin_interface/templates/admin/popup_response.html msgid "Popup closing..." msgstr "Cerando popup..." diff --git a/admin_interface/locale/fa/LC_MESSAGES/django.mo b/admin_interface/locale/fa/LC_MESSAGES/django.mo index eea320d252d862e31adc926dfb00181bc4657130..537e1295fc333589927984bba40d74d970636412 100644 GIT binary patch delta 963 zcmXZaKWLLd7{~FaNow<^shU_5lR6}}wkGW$4uXm}Nx{X69Yp95gNPs&M8u&O3awFy zgB&fmxHtqsj2b}&iGwJu6s5SlFNr$nqVA%C;`b*x-n-A;``(}D?!8Cp^>pQ9GO}c( z3G#OGT#wlS?1U&tD`B&(xQcoFgh#O_Vzvp7p~jVPBVIxEzk&UD2m7#r1Na0t;49p0 zR{P^7C}*D*mmz!-i~c>IO-%4sD62*i%p;c-GiF<5Dwua4r3Xo zD;#&V`=LWG9q~_`!EDrQ3tmPAQbQf>?XHiJ$KFsVfcKce&&ZVa2h~5~u_$Iy-%lZ* zYz`|r`b8>=>;a~64b|}rYKMPO1Hx=iJB(APoklH?L*1XfsCmjbh85KKIx3)h$YV_k z1>A~p{#hz-yDz@tDD7XU1#(;n4J@Dn+KsvcN02Ud0(W8=b=22UC%BB;@F{Y@|C8>3 zev1O$LDrqhnEMt=4vbJ${F-8y^TOi={htC^K`3cbEjUirj`TZ}#@tMJIH3@VWbH{m zY_xeZd@vL*l`o#XbUIg_JvV!yxzhVQ%l@UXtis>wcx7XaIa%iF4KSOA1#}8b^rhX delta 982 zcmYMxO=uHA7{>9}BsIy_)_$nfrb=s@)--}gE#e_iEqKv_=taGV9!k}Vpa&%iCb{Gm zg7l;wG=9;LMq4W)2!aTT6hwC$5EKMaQG=JBs{dyjaG2TO%o26doeW zC-t8F?FqA#+V^-2m#`BLN6gxB0ypACRBDSzwfj7DfQP87dx6BXPpElcaSWFm-}gmV z)}26Qd=k@J=v<@IjkBmg3#dQ+iMoH)S%NzzeP$%xd?WjLIibHq-wf+X`K(~-; z4|wRna}8fQcFG2M@qrf#yo_29W>+1g6?NxHpJnBGGNM`+_JJ)q6 z6McnxAl9Pft7zp=VN)=f*h+63O?#^(Y1(I)rXNuDRR#;EgZ=FT^b$1vg6=0?y&2pS zsQzx64Fo@5&KGV+_WFL0T=AWZ9vtDlmvc+Ce6L$_r)zn)VqV5AdsqK|U|ezUxp&+- zbIXf&y^NPrv>(x!A0_Mz^e}d3yi6_cWxbra6)(G3?)9FzRZUDe#X{W~^C$0Wp85w_ CZ\n" "Language-Team: Farsi \n" -"Language: Farsi" -"MIME-Version: 1.0\n" +"Language: FarsiMIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: admin_interface/admin.py:21 +#: admin_interface/admin.py msgid "Environment" msgstr "محیط" -#: admin_interface/admin.py:30 +#: admin_interface/admin.py msgid "Language chooser" msgstr "انتخاب زبان" -#: admin_interface/admin.py:37 +#: admin_interface/admin.py msgid "Logo" msgstr "لوگو" -#: admin_interface/admin.py:45 +#: admin_interface/admin.py msgid "Favicon" msgstr "آیکون تب" -#: admin_interface/admin.py:49 +#: admin_interface/admin.py msgid "Title" msgstr "عنوان" -#: admin_interface/admin.py:57 +#: admin_interface/admin.py msgid "Header" msgstr "هدر" -#: admin_interface/admin.py:66 +#: admin_interface/admin.py msgid "Breadcrumbs / Module headers" msgstr "مسیر صفحه" -#: admin_interface/admin.py:76 +#: admin_interface/admin.py msgid "Generic Links" -msgstr "لینک‌های عمومی" +msgstr "لینکهای عمومی" -#: admin_interface/admin.py:83 +#: admin_interface/admin.py msgid "Save Buttons" -msgstr "دکمه‌های ذخیره" +msgstr "دکمههای ذخیره" -#: admin_interface/admin.py:91 +#: admin_interface/admin.py msgid "Delete Buttons" -msgstr "دکمه‌های حذف" +msgstr "دکمههای حذف" -#: admin_interface/admin.py:99 +#: admin_interface/admin.py +msgid "Navigation Bar" +msgstr "" + +#: admin_interface/admin.py msgid "Related Modal" -msgstr "مدل‌های مرتبط" +msgstr "مدلهای مرتبط" -#: admin_interface/admin.py:109 +#: admin_interface/admin.py +msgid "Form Controls" +msgstr "" + +#: admin_interface/admin.py msgid "List Filter" -msgstr "فیلتر‌های لیست" +msgstr "فیلترهای لیست" -#: admin_interface/admin.py:113 +#: admin_interface/admin.py +msgid "Change Form" +msgstr "" + +#: admin_interface/admin.py +msgid "Inlines" +msgstr "" + +#: admin_interface/admin.py msgid "Recent Actions" -msgstr "فعالیت‌های اخیر" +msgstr "فعالیتهای اخیر" -#: admin_interface/apps.py:11 +#: admin_interface/apps.py msgid "Admin Interface" msgstr "ظاهر ادمین" -#: admin_interface/models.py:72 admin_interface/models.py:116 -#: admin_interface/models.py:135 +#: admin_interface/models.py msgid "name" msgstr "نام" -#: admin_interface/models.py:75 admin_interface/models.py:132 -#: admin_interface/models.py:253 +#: admin_interface/models.py msgid "active" msgstr "فعال" -#: admin_interface/models.py:79 -#: admin_interface/templates/admin/base_site.html:6 -#: admin_interface/templates/admin/base_site.html:60 +#: admin_interface/models.py admin_interface/templates/admin/base_site.html msgid "Django administration" msgstr "مدیریت جنگو" -#: admin_interface/models.py:81 +#: admin_interface/models.py msgid "title" msgstr "عنوان" -#: admin_interface/models.py:87 admin_interface/models.py:102 -#: admin_interface/models.py:122 +#: admin_interface/models.py msgid "color" msgstr "رنگ" -#: admin_interface/models.py:90 admin_interface/models.py:105 -#: admin_interface/models.py:289 +#: admin_interface/models.py msgid "visible" msgstr "نمایان" -#: admin_interface/models.py:95 +#: admin_interface/models.py msgid "Leave blank to use the default Django logo" msgstr "برای نمایش لوگوی پیش فرض، خالی بگذارید." -#: admin_interface/models.py:96 +#: admin_interface/models.py msgid "logo" msgstr "لوگو" -#: admin_interface/models.py:110 +#: admin_interface/models.py +msgid "max width" +msgstr "" + +#: admin_interface/models.py +msgid "max height" +msgstr "" + +#: admin_interface/models.py msgid "(.ico|.png|.gif - 16x16|32x32 px)" msgstr "(.ico|.png|.gif - 16x16|32x32 px)" -#: admin_interface/models.py:111 +#: admin_interface/models.py msgid "favicon" msgstr "آیکون تب" -#: admin_interface/models.py:120 +#: admin_interface/models.py msgid "" "(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: " "#3498DB)" msgstr "" -"(قرمز: #E74C3C, نارنجی: #E67E22, زرد: #F1C40F, سبز: #2ECC71, آبی: " -"#3498DB)" +"(قرمز: #E74C3C, نارنجی: #E67E22, زرد: #F1C40F, سبز: #2ECC71, آبی: #3498DB)" -#: admin_interface/models.py:125 +#: admin_interface/models.py msgid "visible in header (marker and name)" msgstr "نمایان در هدر" -#: admin_interface/models.py:128 +#: admin_interface/models.py msgid "visible in favicon (marker)" msgstr "نمایان در آیکون تب" -#: admin_interface/models.py:134 +#: admin_interface/models.py +msgid "Default Select" +msgstr "" + +#: admin_interface/models.py +msgid "Minimal Select" +msgstr "" + +#: admin_interface/models.py +msgid "control" +msgstr "" + +#: admin_interface/models.py msgid "code" msgstr "کد" -#: admin_interface/models.py:141 +#: admin_interface/models.py msgid "display" msgstr "نمایش" -#: admin_interface/models.py:148 admin_interface/models.py:173 -#: admin_interface/models.py:214 admin_interface/models.py:233 -#: admin_interface/models.py:259 +#: admin_interface/models.py msgid "background color" -msgstr "رنگ پس‌زمینه" +msgstr "رنگ پسزمینه" -#: admin_interface/models.py:154 admin_interface/models.py:179 -#: admin_interface/models.py:226 admin_interface/models.py:245 -#: admin_interface/models.py:249 +#: admin_interface/models.py msgid "text color" msgstr "رنگ متن" -#: admin_interface/models.py:160 admin_interface/models.py:185 -#: admin_interface/models.py:201 +#: admin_interface/models.py msgid "link color" msgstr "رنگ لینک" -#: admin_interface/models.py:166 admin_interface/models.py:191 -#: admin_interface/models.py:207 +#: admin_interface/models.py msgid "link hover color" msgstr "رنگ لینک در حالت هاور" -#: admin_interface/models.py:194 admin_interface/models.py:279 +#: admin_interface/models.py +#, fuzzy +#| msgid "background color" +msgid "background selected color" +msgstr "رنگ پسزمینه" + +#: admin_interface/models.py +#, fuzzy +#| msgid "link color" +msgid "link selected color" +msgstr "رنگ لینک" + +#: admin_interface/models.py msgid "rounded corners" -msgstr "گوشه‌های خمیده" +msgstr "گوشههای خمیده" -#: admin_interface/models.py:220 admin_interface/models.py:239 +#: admin_interface/models.py +msgid "link active color" +msgstr "رنگ فعال پیوند" + +#: admin_interface/models.py msgid "background hover color" -msgstr "رنگ پس‌زمینه در حالت هاور" +msgstr "رنگ پسزمینه در حالت هاور" -#: admin_interface/models.py:276 +#: admin_interface/models.py msgid "background opacity" msgstr "شفافیت بکگراند" -#: admin_interface/models.py:282 +#: admin_interface/models.py msgid "close button visible" msgstr "دکمه بستن نمایان باشد" -#: admin_interface/models.py:286 +#: admin_interface/models.py +msgid "highlight active" +msgstr "" + +#: admin_interface/models.py msgid "use dropdown" msgstr "استفاده از دراپ داون" -#: admin_interface/models.py:298 +#: admin_interface/models.py +msgid "sticky position" +msgstr "" + +#: admin_interface/models.py +msgid "quick remove links for active filters at top of sidebar" +msgstr "" + +#: admin_interface/models.py +msgid "foldable apps" +msgstr "" + +#: admin_interface/models.py +msgid "fieldsets as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "inlines as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "sticky submit" +msgstr "" + +#: admin_interface/models.py +msgid "sticky pagination" +msgstr "" + +#: admin_interface/models.py msgid "Theme" msgstr "تم" -#: admin_interface/models.py:299 +#: admin_interface/models.py msgid "Themes" -msgstr "تم‌ها" +msgstr "تمها" -#: admin_interface/templates/admin/filter.html:13 -#: admin_interface/templates/admin_interface/dropdown_filter.html:4 +#: admin_interface/templates/admin/change_list.html +#, fuzzy +#| msgid "List Filter" +msgid "Filter" +msgstr "فیلترهای لیست" + +#. Translators: don't translate this, the django catalog already contains it +#: admin_interface/templates/admin/change_list.html +msgid "Clear all filters" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Change" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View on site" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Delete?" +msgstr "" + +#: admin_interface/templates/admin/filter.html +#: admin_interface/templates/admin_interface/dropdown_filter.html #, python-format msgid " By %(filter_title)s " msgstr " توسط %(filter_title)s " -#: admin_interface/templates/admin/popup_response.html:3 +#: admin_interface/templates/admin/popup_response.html msgid "Popup closing..." msgstr "پاپ آپ در حال بسته شدن..." diff --git a/admin_interface/locale/fr/LC_MESSAGES/django.mo b/admin_interface/locale/fr/LC_MESSAGES/django.mo index 01909d660f948b98ed541a2989439ad57a898f88..1f2544609a30e7d070d83926d1de0f3376857834 100644 GIT binary patch literal 3731 zcmbW2OKc=Z8OIA)@)#a@@K^{0J~o8)ByR88Ue>#_4>GpLj>GsN+q)u>2r5t4^whei zs#DcHYfB3XTmT^s2q7g32QEnKAR-RCCxV2S0}?{wuy;^$K_CRVAO$H%{J-uR+iS>$ zlFPrY>guZRRsZ?p!^eIk&>HBUM*rJ;gjfY%e;@v#y?soGkAeRJKLG5-+w1b71E@0URwEuIB= z|K~wo*AL@wfV|)L!4HD3fY?&p1o0J^S3~@^L3EF`+eY>Vg7B9&$$o5;5eQDdEfIOOcR#_ zp8@#_T?L;3p98sme+sf)w?Mu(cfe18Z-HDt_hS+J^$5s*5Xkmk1UWDB;FDkiBAsP! z&x2>tIS$;oe!hT?l!(uxhpQ|m@XU?vs~yPR`Y+vHu7| zSr43Zwu>9*n{BV7v(210ZjV@Lnpr0(Cs(&0;jtMu8$vJe6@e}CW zIDVf+=Qz9<{ct-S1{633ay}6*aR&VqdW0@$c9$L>>*_RD?rXWuQ&smQ#wK*f-k8Wt za$_RVU5aS(?9Sxb8`D!e(^Hh~)Ww)naf2Rf&77H=o*O6Yq)8M{oSkV+O^ws8N>h6s z6AP1bXHGASQ{t2|7*Dn4=4K|xX)7&w{q&jh=jLbYq8azKp(O(|y0W9htWz@XxT3%1 z=@c#7xJVWCFsGas^D0%jqS+$Pt-i$#YH7A9w^VpVc~4QS zy0S=f3O1xRv7!wlC>+)1i4`25lvdHKbYjhBMMj;}dTo-4i3zc;Ie$q}!xKF_Q0~8{Z6-T9-#xt2 zBeESnyV`?ogwti5X`sE{!hszd^FKZVG36MFSos&QyDrkB2QTCyp3a#6yOha9o2sftGss<8Wnt`#t-j7hu6FX^ zQF)gHmr3kw7TfDai~<-)DEJUC8tY59tz3PyhTm1yK6*tGnPundV$IoW$WpWvM^|Ab zYNkPJ&ABf(7h80-wZ5^mx>8$LnRR)z>=PYFvqj>gP1~T_+G@0}_r%Wc@--(3*7rr|j9H(z$mNzH72DENmm)!_CX@l08)%lD&Pwqf!7_peQ~mot8#H z_mqk9;j6jw&>8BNA}D5U!Kz2T$TFwtd*3{j7Vdr(YBGNjnCe&T-m9J{bkLLI9)v#*$9LAk!li?CL57-XtgHiKT0 z8}6}w!qQSPgAsP?n#!R8sUGgZhf&mIF;Izg_#J_a4sVuf$|&U&F0w>*A#C`)VK0#j zSNa~ICe6XTf}r3+$^vZ#g;V|erBm=$@QX-(4%r_fH1*@pt<`ValrBRh@aK$VgIUC`~DsMKG6fzu|P@WBgr0-V#pJ$zDwJ2kBUR;UM+d^#g|7Hyj1ye5us=ix4QTbC+M_u delta 1075 zcmYMyOK1~O6vpw>M_wjvY^`m5v>mIh#Ug^xjR;y7RjJ}iT2PQQnaW@?qj?lmBnt(R zA_zklQbiCq>P8R|L=u0#Y^u2k^#|B?|ebLTgAxO48gXKpy~uBX1z-M(bB zG5SXO@fNcQywS>ycDl`MEuO(mco~o2UCiPS)OV?NvrZgE&7Z(DPGbURumewE980*( ztZr2vH1QU4*?n%S@c}B}3)F{iF@q}@!!M{nU!(E&X#5-XeT+%H*o)n`9eZ#ua@kRC z3D&n`JgnkH9`&J*#ISngCDcx@pypjiF1y1`3Ee~O@G)+{=eQX^;3U=jgGywQNvhy1 zs)FY*%lh_;hhcn=UHA)C!fdj+zzFincA|E&3sZO)^{Zx330_4deiPT>ZB)Fc(fAFn zVf-0Yxt~~9;5MR>q@^Rfu#a&cD$owp&JLmyb5Y-&kGzOVU=cNc8I{N*E8`T<1thvl(Z_Prk!q~tF)?ynhvfG_YhrY zg?-ux-JE@AosqG5FKmf@>fZ1AZrRH_hdlpO#SXZ+LO2xP6PDuFhV#Xs;yQD+YBlhk z1+U`G6%+HlvD+e{d;1-;GP$p*O;Z$;|HB)l^s!c`H xQ|ZBQcX~QpPQMH\n" "Language-Team: LANGUAGE \n" @@ -18,109 +18,127 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: admin_interface/admin.py:21 +#: admin_interface/admin.py msgid "Environment" -msgstr "Environnment" +msgstr "Environnement" -#: admin_interface/admin.py:30 +#: admin_interface/admin.py msgid "Language chooser" -msgstr "" +msgstr "Sélecteur de langue" -#: admin_interface/admin.py:37 +#: admin_interface/admin.py msgid "Logo" msgstr "Logo" -#: admin_interface/admin.py:45 +#: admin_interface/admin.py msgid "Favicon" msgstr "Favicon" -#: admin_interface/admin.py:49 +#: admin_interface/admin.py msgid "Title" msgstr "Titre" -#: admin_interface/admin.py:57 +#: admin_interface/admin.py msgid "Header" msgstr "Bannière" -#: admin_interface/admin.py:66 +#: admin_interface/admin.py msgid "Breadcrumbs / Module headers" msgstr "Fil d'ariane / en-têtes de module" -#: admin_interface/admin.py:76 +#: admin_interface/admin.py msgid "Generic Links" msgstr "Liens génériques" -#: admin_interface/admin.py:83 +#: admin_interface/admin.py msgid "Save Buttons" msgstr "Boutons sauvegarder" -#: admin_interface/admin.py:91 +#: admin_interface/admin.py msgid "Delete Buttons" msgstr "Boutons supprimer" -#: admin_interface/admin.py:99 +#: admin_interface/admin.py +msgid "Navigation Bar" +msgstr "Barre de navigation" + +#: admin_interface/admin.py msgid "Related Modal" msgstr "Modale pour objet reliés" -#: admin_interface/admin.py:109 +#: admin_interface/admin.py +msgid "Form Controls" +msgstr "Contrôles de formulaires" + +#: admin_interface/admin.py msgid "List Filter" msgstr "Filtre de liste" -#: admin_interface/admin.py:113 +#: admin_interface/admin.py +msgid "Change Form" +msgstr "" + +#: admin_interface/admin.py +msgid "Inlines" +msgstr "" + +#: admin_interface/admin.py msgid "Recent Actions" msgstr "Actions récentes" -#: admin_interface/apps.py:11 +#: admin_interface/apps.py msgid "Admin Interface" msgstr "Interface Admin" -#: admin_interface/models.py:72 admin_interface/models.py:116 -#: admin_interface/models.py:135 +#: admin_interface/models.py msgid "name" msgstr "nom" -#: admin_interface/models.py:75 admin_interface/models.py:132 -#: admin_interface/models.py:253 +#: admin_interface/models.py msgid "active" msgstr "actif" -#: admin_interface/models.py:79 -#: admin_interface/templates/admin/base_site.html:6 -#: admin_interface/templates/admin/base_site.html:60 +#: admin_interface/models.py admin_interface/templates/admin/base_site.html msgid "Django administration" msgstr "Administration Django" -#: admin_interface/models.py:81 +#: admin_interface/models.py msgid "title" msgstr "titre" -#: admin_interface/models.py:87 admin_interface/models.py:102 -#: admin_interface/models.py:122 +#: admin_interface/models.py msgid "color" msgstr "couleur" -#: admin_interface/models.py:90 admin_interface/models.py:105 -#: admin_interface/models.py:289 +#: admin_interface/models.py msgid "visible" msgstr "visible" -#: admin_interface/models.py:95 +#: admin_interface/models.py msgid "Leave blank to use the default Django logo" msgstr "Laisser vide pour utiliser le logo Django par défaut" -#: admin_interface/models.py:96 +#: admin_interface/models.py msgid "logo" msgstr "logo" -#: admin_interface/models.py:110 +#: admin_interface/models.py +msgid "max width" +msgstr "largeur max" + +#: admin_interface/models.py +msgid "max height" +msgstr "hauteur max" + +#: admin_interface/models.py msgid "(.ico|.png|.gif - 16x16|32x32 px)" msgstr "(.ico|.png|.gif - 16x16|32x32 px)" -#: admin_interface/models.py:111 +#: admin_interface/models.py msgid "favicon" msgstr "favicon" -#: admin_interface/models.py:120 +#: admin_interface/models.py msgid "" "(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: " "#3498DB)" @@ -128,78 +146,173 @@ msgstr "" "(rouge: #E74C3C, orange: #E67E22, jaune: #F1C40F, vert: #2ECC71, bleu: " "#3498DB)" -#: admin_interface/models.py:125 +#: admin_interface/models.py msgid "visible in header (marker and name)" msgstr "visible dans l’en-tête (marqueur et nom)" -#: admin_interface/models.py:128 +#: admin_interface/models.py msgid "visible in favicon (marker)" msgstr "visible dans la favicon (marqueur)" -#: admin_interface/models.py:134 +#: admin_interface/models.py +msgid "Default Select" +msgstr "" + +#: admin_interface/models.py +msgid "Minimal Select" +msgstr "" + +#: admin_interface/models.py +msgid "control" +msgstr "contrôle" + +#: admin_interface/models.py msgid "code" -msgstr "" +msgstr "code" -#: admin_interface/models.py:141 +#: admin_interface/models.py msgid "display" -msgstr "" +msgstr "affichage" -#: admin_interface/models.py:148 admin_interface/models.py:173 -#: admin_interface/models.py:214 admin_interface/models.py:233 -#: admin_interface/models.py:259 +#: admin_interface/models.py msgid "background color" msgstr "couleur d'arrière-plan" -#: admin_interface/models.py:154 admin_interface/models.py:179 -#: admin_interface/models.py:226 admin_interface/models.py:245 -#: admin_interface/models.py:249 +#: admin_interface/models.py msgid "text color" msgstr "couleur du texte" -#: admin_interface/models.py:160 admin_interface/models.py:185 -#: admin_interface/models.py:201 +#: admin_interface/models.py msgid "link color" msgstr "couleur de lien" -#: admin_interface/models.py:166 admin_interface/models.py:191 -#: admin_interface/models.py:207 +#: admin_interface/models.py msgid "link hover color" msgstr "couleur de lien au survol" -#: admin_interface/models.py:194 admin_interface/models.py:279 +#: admin_interface/models.py +msgid "background selected color" +msgstr "couleur d'arrière-plan choisi" + +#: admin_interface/models.py +msgid "link selected color" +msgstr "couleur de lien choisi" + +#: admin_interface/models.py msgid "rounded corners" msgstr "coins arrondis" -#: admin_interface/models.py:220 admin_interface/models.py:239 +#: admin_interface/models.py +msgid "link active color" +msgstr "couleur de lien actif" + +#: admin_interface/models.py msgid "background hover color" msgstr "couleur de fond au survol" -#: admin_interface/models.py:276 +#: admin_interface/models.py msgid "background opacity" msgstr "opacité de l'arrière-plan" -#: admin_interface/models.py:282 +#: admin_interface/models.py msgid "close button visible" msgstr "bouton fermer visible" -#: admin_interface/models.py:286 +#: admin_interface/models.py +msgid "highlight active" +msgstr "mise en valeur active" + +#: admin_interface/models.py msgid "use dropdown" msgstr "utiliser un menu déroulant" -#: admin_interface/models.py:298 +#: admin_interface/models.py +msgid "sticky position" +msgstr "position adhérente (sticky)" + +#: admin_interface/models.py +msgid "quick remove links for active filters at top of sidebar" +msgstr "" +"liens de suppression pour les filtres actifs en haut de la barre latérale" + +#: admin_interface/models.py +msgid "foldable apps" +msgstr "apps repliables" + +#: admin_interface/models.py +msgid "fieldsets as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "inlines as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "sticky submit" +msgstr "envoi adhérent (sticky)" + +#: admin_interface/models.py +msgid "sticky pagination" +msgstr "pagination adhérente (sticky)" + +#: admin_interface/models.py msgid "Theme" msgstr "Thème" -#: admin_interface/models.py:299 +#: admin_interface/models.py msgid "Themes" msgstr "Thèmes" -#: admin_interface/templates/admin/filter.html:13 -#: admin_interface/templates/admin_interface/dropdown_filter.html:4 +#: admin_interface/templates/admin/change_list.html +msgid "Filter" +msgstr "Filtre" + +#. Translators: don't translate this, the django catalog already contains it +#: admin_interface/templates/admin/change_list.html +msgid "Clear all filters" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Change" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View on site" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Delete?" +msgstr "" + +#: admin_interface/templates/admin/filter.html +#: admin_interface/templates/admin_interface/dropdown_filter.html #, python-format msgid " By %(filter_title)s " msgstr " Par %(filter_title)s " -#: admin_interface/templates/admin/popup_response.html:3 +#: admin_interface/templates/admin/popup_response.html msgid "Popup closing..." msgstr "Fermeture de la modale..." diff --git a/admin_interface/locale/it/LC_MESSAGES/django.mo b/admin_interface/locale/it/LC_MESSAGES/django.mo index 540e31c51b5546bae2bf2b1709aeb4b0a17e6284..a75aa70a61141692c635328695a5658edf3163b8 100644 GIT binary patch delta 1755 zcmY+EOK4qH6o$8Hu6Z~Dw2uSDkxY)sC3{!M694rM4b5e{&UYAxVh_m`>eC~+H3u5 zC;yC`Sl{}7xcgPZ*oJMuzP-qp-SFrN9*h&+#*Dy|a3lO2?t>TLCGhS_d*5z&G4FM_ z5=QV+xCn>f5!eG?hl+O`vaV%5EI)h-2l?<-$@5SFe}=2z?{Ev0QwNMeaxmMV4!93$ z-JbIONvL>pZ~!hsLYU_vKXbHrZyA#_QJ`Z`3*UhJ%sV_3@D#iZo`%ElJX`~Rh1%Ce zSqj_(RpDUC5hw*lVLu#)igypxzCH4DzS+;D4?a%7CDKNQ`{!7ZoaY(A9T<{#U zyuS?f{Up?eGbO)-I^ZlMwmAoN&<~~mPpCrvhDvw{xpe6^!?o}MsQr%)puZ*uaY*U_ zs-h-T<SD-e&1(nEh>Hh>O@o!51kMKd>FO>c<DLCC?q87}- zYv2(`>x!ZGTQD7l@+F>V>I7^eTk-yzt9op*-`x%${B(^(Tn)g=rt(x+|g3-g` zZ1^mntSk<=YUU3Iwwi=VntxH*^ho5MwzGksnazx*3%-`kn%G5wIn?ykIhzJi!iLbt za}8ThNUKsuErd|5pZB;K5`~>>CEi^ zJaK|DZ8114^-)rsWm7lrYh<9L=wIr~u-3;kHA`$<)Ld$0rjwNIB%RRP8htbBNd8iP F@*g6t9C!c# delta 1062 zcmX}rPiPZC6vy#r-8437Ym7E(|JeAa*0$n7L=TEkEglrqD%e{g!is@pQ`#-+L2|Me zkAs3BNGal>SPDUGpdf+>g5pIK74#%RFVchJLDcVWv-;TC&u*B^ym>Rb*!8=k`YG$( zGGd6^#xd)S5#uo)j= z#;j_~JPh)~E7Tu;BA0oIsDrhj2JS=+Fo3Oi2)S&8n+7}?zmLZ6W5@(HjybGg7H4o1 z-a(J~ZGi_at8r7N_1LGF;{63`pf{+*zQnGeD)0@}?+ZhS{fBR zj#|Ju+<;?PRcVVnpLxLhn#}zKUBgNjcO%AKQ|szP<#h3}EdMxlynJCv9Xt`@3f zwLp!f=+ypePZS!spQeMagSeUYFO-Br``8mbneD(mG$o?Y7sUM0Vb)@_0LAVGMscDq zObh-WM|jeyRQ3Zjl}UToM^oq=XoV`9_E^D}7j2ihhhDvX#4q`wpFcJohLvE-%_fH2 zhr~s9s`<2=Z@%IVB)h$!Q1)xH$;VB(v(u%iLJ$`76aHl0FBQwhpfKsX`P5#wlA3Up V^kw%WecR2o_Ig33?7P9XnZNzGXx9J$ diff --git a/admin_interface/locale/it/LC_MESSAGES/django.po b/admin_interface/locale/it/LC_MESSAGES/django.po index 0bdda44..580ab43 100644 --- a/admin_interface/locale/it/LC_MESSAGES/django.po +++ b/admin_interface/locale/it/LC_MESSAGES/django.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: django-admin-interface\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-09-04 09:19+0000\n" +"POT-Creation-Date: 2023-05-10 18:20-0500\n" "PO-Revision-Date: 2018-12-30 19:13-0500\n" "Last-Translator: Fabio Caccamo \n" "Language-Team: Italian \n" @@ -19,109 +19,127 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: admin_interface/admin.py:21 +#: admin_interface/admin.py msgid "Environment" msgstr "Ambiente" -#: admin_interface/admin.py:30 +#: admin_interface/admin.py msgid "Language chooser" msgstr "Selettore di lingua" -#: admin_interface/admin.py:37 +#: admin_interface/admin.py msgid "Logo" msgstr "Logo" -#: admin_interface/admin.py:45 +#: admin_interface/admin.py msgid "Favicon" msgstr "Favicon" -#: admin_interface/admin.py:49 +#: admin_interface/admin.py msgid "Title" msgstr "Titolo" -#: admin_interface/admin.py:57 +#: admin_interface/admin.py msgid "Header" msgstr "Header" -#: admin_interface/admin.py:66 +#: admin_interface/admin.py msgid "Breadcrumbs / Module headers" msgstr "Breadcrumbs / Header dei moduli" -#: admin_interface/admin.py:76 +#: admin_interface/admin.py msgid "Generic Links" msgstr "Link generici" -#: admin_interface/admin.py:83 +#: admin_interface/admin.py msgid "Save Buttons" msgstr "Pulsanti per salvare" -#: admin_interface/admin.py:91 +#: admin_interface/admin.py msgid "Delete Buttons" msgstr "Pulsanti per eliminare" -#: admin_interface/admin.py:99 +#: admin_interface/admin.py +msgid "Navigation Bar" +msgstr "Barra di Navigazione" + +#: admin_interface/admin.py msgid "Related Modal" msgstr "Modale per gli oggetti correlati" -#: admin_interface/admin.py:109 +#: admin_interface/admin.py +msgid "Form Controls" +msgstr "Controlli dei form" + +#: admin_interface/admin.py msgid "List Filter" msgstr "Filtro listato" -#: admin_interface/admin.py:113 +#: admin_interface/admin.py +msgid "Change Form" +msgstr "Form di modifica" + +#: admin_interface/admin.py +msgid "Inlines" +msgstr "" + +#: admin_interface/admin.py msgid "Recent Actions" msgstr "Azioni recenti" -#: admin_interface/apps.py:11 +#: admin_interface/apps.py msgid "Admin Interface" msgstr "Interfaccia di amministrazione" -#: admin_interface/models.py:72 admin_interface/models.py:116 -#: admin_interface/models.py:135 +#: admin_interface/models.py msgid "name" msgstr "nome" -#: admin_interface/models.py:75 admin_interface/models.py:132 -#: admin_interface/models.py:253 +#: admin_interface/models.py msgid "active" msgstr "attivo" -#: admin_interface/models.py:79 -#: admin_interface/templates/admin/base_site.html:6 -#: admin_interface/templates/admin/base_site.html:60 +#: admin_interface/models.py admin_interface/templates/admin/base_site.html msgid "Django administration" msgstr "Amministrazione di Django" -#: admin_interface/models.py:81 +#: admin_interface/models.py msgid "title" msgstr "titolo" -#: admin_interface/models.py:87 admin_interface/models.py:102 -#: admin_interface/models.py:122 +#: admin_interface/models.py msgid "color" msgstr "colore" -#: admin_interface/models.py:90 admin_interface/models.py:105 -#: admin_interface/models.py:289 +#: admin_interface/models.py msgid "visible" msgstr "visibile" -#: admin_interface/models.py:95 +#: admin_interface/models.py msgid "Leave blank to use the default Django logo" msgstr "Lasciare vuoto per usare il logo Django di default" -#: admin_interface/models.py:96 +#: admin_interface/models.py msgid "logo" msgstr "logo" -#: admin_interface/models.py:110 +#: admin_interface/models.py +msgid "max width" +msgstr "larghezza massima" + +#: admin_interface/models.py +msgid "max height" +msgstr "altezza massima" + +#: admin_interface/models.py msgid "(.ico|.png|.gif - 16x16|32x32 px)" msgstr "(formato ico, png o gif - dimensioni 16x16 o 32x32 px)" -#: admin_interface/models.py:111 +#: admin_interface/models.py msgid "favicon" msgstr "favicon" -#: admin_interface/models.py:120 +#: admin_interface/models.py msgid "" "(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: " "#3498DB)" @@ -129,78 +147,178 @@ msgstr "" "(rosso: #E74C3C, arancione: #E67E22, giallo: #F1C40F, verde: #2ECC71, blu: " "#3498DB)" -#: admin_interface/models.py:125 +#: admin_interface/models.py msgid "visible in header (marker and name)" msgstr "visibile nell'header (marker e nome)" -#: admin_interface/models.py:128 +#: admin_interface/models.py msgid "visible in favicon (marker)" msgstr "visibile nella favicon (marker)" -#: admin_interface/models.py:134 +#: admin_interface/models.py +msgid "Default Select" +msgstr "" + +#: admin_interface/models.py +msgid "Minimal Select" +msgstr "" + +#: admin_interface/models.py +msgid "control" +msgstr "" + +#: admin_interface/models.py msgid "code" msgstr "codice" -#: admin_interface/models.py:141 +#: admin_interface/models.py msgid "display" msgstr "visualizzazione" -#: admin_interface/models.py:148 admin_interface/models.py:173 -#: admin_interface/models.py:214 admin_interface/models.py:233 -#: admin_interface/models.py:259 +#: admin_interface/models.py msgid "background color" msgstr "colore di sfondo" -#: admin_interface/models.py:154 admin_interface/models.py:179 -#: admin_interface/models.py:226 admin_interface/models.py:245 -#: admin_interface/models.py:249 +#: admin_interface/models.py msgid "text color" msgstr "colore del testo" -#: admin_interface/models.py:160 admin_interface/models.py:185 -#: admin_interface/models.py:201 +#: admin_interface/models.py msgid "link color" msgstr "colore dei link" -#: admin_interface/models.py:166 admin_interface/models.py:191 -#: admin_interface/models.py:207 +#: admin_interface/models.py msgid "link hover color" msgstr "colore dei link in hover" -#: admin_interface/models.py:194 admin_interface/models.py:279 +#: admin_interface/models.py +#, fuzzy +#| msgid "background color" +msgid "background selected color" +msgstr "colore di sfondo" + +#: admin_interface/models.py +#, fuzzy +#| msgid "link color" +msgid "link selected color" +msgstr "colore dei link" + +#: admin_interface/models.py msgid "rounded corners" msgstr "bordi arrotondati" -#: admin_interface/models.py:220 admin_interface/models.py:239 +#: admin_interface/models.py +msgid "link active color" +msgstr "colore dei link attivi" + +#: admin_interface/models.py msgid "background hover color" msgstr "colore di sfondo in hover" -#: admin_interface/models.py:276 +#: admin_interface/models.py msgid "background opacity" msgstr "opacità dello sfondo" -#: admin_interface/models.py:282 +#: admin_interface/models.py msgid "close button visible" msgstr "pulsante chiudi visibile" -#: admin_interface/models.py:286 +#: admin_interface/models.py +msgid "highlight active" +msgstr "" + +#: admin_interface/models.py msgid "use dropdown" msgstr "usa dropdown" -#: admin_interface/models.py:298 +#: admin_interface/models.py +msgid "sticky position" +msgstr "" + +#: admin_interface/models.py +msgid "quick remove links for active filters at top of sidebar" +msgstr "links di rimozione rapida dei filtri attivi in alto nella sidebar" + +#: admin_interface/models.py +msgid "foldable apps" +msgstr "" + +#: admin_interface/models.py +msgid "fieldsets as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "inlines as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "sticky submit" +msgstr "" + +#: admin_interface/models.py +msgid "sticky pagination" +msgstr "" + +#: admin_interface/models.py msgid "Theme" msgstr "Tema" -#: admin_interface/models.py:299 +#: admin_interface/models.py msgid "Themes" msgstr "Temi" -#: admin_interface/templates/admin/filter.html:13 -#: admin_interface/templates/admin_interface/dropdown_filter.html:4 +#: admin_interface/templates/admin/change_list.html +#, fuzzy +#| msgid "List Filter" +msgid "Filter" +msgstr "Filtro listato" + +#. Translators: don't translate this, the django catalog already contains it +#: admin_interface/templates/admin/change_list.html +msgid "Clear all filters" +msgstr "Cancella tutti i filtri" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Change" +msgstr "Modifica" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View" +msgstr "Visualizza" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View on site" +msgstr "Visualizza sul sito" + +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Delete?" +msgstr "Eliminare?" + +#: admin_interface/templates/admin/filter.html +#: admin_interface/templates/admin_interface/dropdown_filter.html #, python-format msgid " By %(filter_title)s " msgstr " Per %(filter_title)s " -#: admin_interface/templates/admin/popup_response.html:3 +#: admin_interface/templates/admin/popup_response.html msgid "Popup closing..." msgstr "Chiusura popup..." diff --git a/admin_interface/locale/pl/LC_MESSAGES/django.mo b/admin_interface/locale/pl/LC_MESSAGES/django.mo index 9a5a6bb646deda0ed512409d2475262a7301f7a9..0587f3fdf49fd1c389fa5643fe07e7364236c578 100644 GIT binary patch delta 899 zcmXZa!AsL&9LMpm+jP1%ZELMof$4vLd5W5Cq?OyVuvwBWMe{DG0=V&K_oiF zkNg9wi(Wi<2rpeka2iM_5llM-K?&Xzywv+szlS})*Yo@BdA`s0`SN(FTFO02gx(n~ zPj98q)tU9+VSop1J7{(lYuJv*ID~Z}vlbjitt((NzCz7^gO~6FhH(vJ_z4?u3oo0w z_Ju)?58qG=8tcs%S`wLHX;k1GD!>Db;sElq$2=5p%zrQV?^CGt6-=Rv30%e`u3(7$ z?K1;@w#h@8)_lKWoc9Ba;BQpGGgN|Mc9l_7CE}=g?Z_0%qY}M~ira@baR589h~qBh zUSyz>{a{u8C*1brY?uA;H_cYiUzs)E|*DcU-?ySEJ p_6DMb;_UQ`NvAkdo_V&uUB4KL6-u+!mzAnhp01RhdygW!e*v@nQ%nE= delta 847 zcmXZaKP)6+7{~F)?ks1|I=jm{)}PyB&#qNmMR8FO4UKFe3Zf8ys&mC@6tZ^((GL-o zY(+z}k(@*%E)?YC8imGn*KEV8M1k*b&6|1W^S(3h`^+=X%z4a><^DyS4Wnh~E%e0- zvoH9^$BFjKZ`Oc^n83d{iY0u91J3KdEY>n#K&@ZKx9DOOZes{{uo4fj&Map~47#~+ ziQ4dh9OeYd3#=LyxEU27jWyVZ95%#B0Y|)f)|-zb53nhW;Wv!nD%Rr`Iy~R@8E{yE zlQKQ@Ji#FIb5x)!RAT=M0RqSielhXu(-3D%+FwPGBT*ntB$NtI`@f#=(ARt@4c z&S3nF*$4cADa@lXzd&VvgR0a$62qQQl?hb8CKAQ>%-c{8>_e@aK)t{;D#3ZoMHwtI zP>I)2-)<9?`5qG64p0G(z3XSFH@-yu6W7>?kJy9}Zt{Cr52_-cQ3>~=;tYE8;h@cx zGaciCGFw1x_>RrEgvxXswK0!+vt3kTC)kb`n8G4b*>cl2S1i3y!Y%pYA=N@n5xd+b ye\n" "Language-Team: Polish \n" @@ -19,188 +19,306 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: admin_interface/admin.py:21 +#: admin_interface/admin.py msgid "Environment" msgstr "Środowisko" -#: admin_interface/admin.py:30 +#: admin_interface/admin.py msgid "Language chooser" msgstr "Wybór wersji językowej" -#: admin_interface/admin.py:37 +#: admin_interface/admin.py msgid "Logo" msgstr "Logo" -#: admin_interface/admin.py:45 +#: admin_interface/admin.py msgid "Favicon" msgstr "Ikonka" -#: admin_interface/admin.py:49 +#: admin_interface/admin.py msgid "Title" msgstr "Tytuł" -#: admin_interface/admin.py:57 +#: admin_interface/admin.py msgid "Header" msgstr "Nagłówek" -#: admin_interface/admin.py:66 +#: admin_interface/admin.py msgid "Breadcrumbs / Module headers" msgstr "Pasek nawigacyjny / nagłówki modułów" -#: admin_interface/admin.py:76 +#: admin_interface/admin.py msgid "Generic Links" msgstr "Zwykłe linki" -#: admin_interface/admin.py:83 +#: admin_interface/admin.py msgid "Save Buttons" msgstr "Przyciski zapisywania" -#: admin_interface/admin.py:91 +#: admin_interface/admin.py msgid "Delete Buttons" msgstr "Przyciski usuwania" -#: admin_interface/admin.py:99 +#: admin_interface/admin.py +msgid "Navigation Bar" +msgstr "" + +#: admin_interface/admin.py msgid "Related Modal" msgstr "Okno dialogowe" -#: admin_interface/admin.py:109 +#: admin_interface/admin.py +msgid "Form Controls" +msgstr "" + +#: admin_interface/admin.py msgid "List Filter" msgstr "Filtry" -#: admin_interface/admin.py:113 +#: admin_interface/admin.py +msgid "Change Form" +msgstr "" + +#: admin_interface/admin.py +msgid "Inlines" +msgstr "" + +#: admin_interface/admin.py msgid "Recent Actions" msgstr "Ostatnie działania" -#: admin_interface/apps.py:11 +#: admin_interface/apps.py msgid "Admin Interface" msgstr "Wygląd panelu administracyjnego" -#: admin_interface/models.py:72 admin_interface/models.py:116 -#: admin_interface/models.py:135 +#: admin_interface/models.py msgid "name" msgstr "nazwa" -#: admin_interface/models.py:75 admin_interface/models.py:132 -#: admin_interface/models.py:253 +#: admin_interface/models.py msgid "active" msgstr "aktywny" -#: admin_interface/models.py:79 -#: admin_interface/templates/admin/base_site.html:6 -#: admin_interface/templates/admin/base_site.html:60 +#: admin_interface/models.py admin_interface/templates/admin/base_site.html msgid "Django administration" msgstr "Administracja Django" -#: admin_interface/models.py:81 +#: admin_interface/models.py msgid "title" msgstr "tytuł" -#: admin_interface/models.py:87 admin_interface/models.py:102 -#: admin_interface/models.py:122 +#: admin_interface/models.py msgid "color" msgstr "kolor" -#: admin_interface/models.py:90 admin_interface/models.py:105 -#: admin_interface/models.py:289 +#: admin_interface/models.py msgid "visible" msgstr "widoczny" -#: admin_interface/models.py:95 +#: admin_interface/models.py msgid "Leave blank to use the default Django logo" msgstr "Puste ustawia domyślne logo Django" -#: admin_interface/models.py:96 +#: admin_interface/models.py msgid "logo" msgstr "logo" -#: admin_interface/models.py:110 +#: admin_interface/models.py +msgid "max width" +msgstr "" + +#: admin_interface/models.py +msgid "max height" +msgstr "" + +#: admin_interface/models.py msgid "(.ico|.png|.gif - 16x16|32x32 px)" msgstr "(Format pliku: .ico, .png, .gif; wymiary: 16 x 16 lub 32 x 32 px)." -#: admin_interface/models.py:111 +#: admin_interface/models.py msgid "favicon" msgstr "ikonka" -#: admin_interface/models.py:120 +#: admin_interface/models.py msgid "" "(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: " "#3498DB)" msgstr "" -"(czerwony: #E74C3C, pomarańczowy: #E67E22, żółty: #F1C40F, zielony: #2ECC71, niebieski: " -"#3498DB)" +"(czerwony: #E74C3C, pomarańczowy: #E67E22, żółty: #F1C40F, zielony: #2ECC71, " +"niebieski: #3498DB)" -#: admin_interface/models.py:125 +#: admin_interface/models.py msgid "visible in header (marker and name)" msgstr "widoczne w nagłówku (znacznik i nazwa)" -#: admin_interface/models.py:128 +#: admin_interface/models.py msgid "visible in favicon (marker)" msgstr "widoczne przy ikonce (znacznik)" -#: admin_interface/models.py:134 +#: admin_interface/models.py +msgid "Default Select" +msgstr "" + +#: admin_interface/models.py +msgid "Minimal Select" +msgstr "" + +#: admin_interface/models.py +msgid "control" +msgstr "" + +#: admin_interface/models.py msgid "code" msgstr "kod" -#: admin_interface/models.py:141 +#: admin_interface/models.py msgid "display" msgstr "wyświetlaj" -#: admin_interface/models.py:148 admin_interface/models.py:173 -#: admin_interface/models.py:214 admin_interface/models.py:233 -#: admin_interface/models.py:259 +#: admin_interface/models.py msgid "background color" msgstr "kolor tła" -#: admin_interface/models.py:154 admin_interface/models.py:179 -#: admin_interface/models.py:226 admin_interface/models.py:245 -#: admin_interface/models.py:249 +#: admin_interface/models.py msgid "text color" msgstr "kolor tekstu" -#: admin_interface/models.py:160 admin_interface/models.py:185 -#: admin_interface/models.py:201 +#: admin_interface/models.py msgid "link color" msgstr "kolor linku" -#: admin_interface/models.py:166 admin_interface/models.py:191 -#: admin_interface/models.py:207 +#: admin_interface/models.py msgid "link hover color" msgstr "kolor wskazywanego linku" -#: admin_interface/models.py:194 admin_interface/models.py:279 +#: admin_interface/models.py +#, fuzzy +#| msgid "background color" +msgid "background selected color" +msgstr "kolor tła" + +#: admin_interface/models.py +#, fuzzy +#| msgid "link color" +msgid "link selected color" +msgstr "kolor linku" + +#: admin_interface/models.py msgid "rounded corners" msgstr "zaokrąglenie narożników" -#: admin_interface/models.py:220 admin_interface/models.py:239 +#: admin_interface/models.py +msgid "link active color" +msgstr "kolor aktywny linku" + +#: admin_interface/models.py msgid "background hover color" msgstr "kolor tła wskazywanego przycisku" -#: admin_interface/models.py:276 +#: admin_interface/models.py msgid "background opacity" msgstr "przeźroczystość tła" -#: admin_interface/models.py:282 +#: admin_interface/models.py msgid "close button visible" msgstr "pokaż przycisk zamykania" -#: admin_interface/models.py:286 +#: admin_interface/models.py +msgid "highlight active" +msgstr "" + +#: admin_interface/models.py msgid "use dropdown" msgstr "zastosuj listy rozwijane" -#: admin_interface/models.py:298 +#: admin_interface/models.py +msgid "sticky position" +msgstr "" + +#: admin_interface/models.py +msgid "quick remove links for active filters at top of sidebar" +msgstr "" + +#: admin_interface/models.py +msgid "foldable apps" +msgstr "" + +#: admin_interface/models.py +msgid "fieldsets as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "inlines as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "sticky submit" +msgstr "" + +#: admin_interface/models.py +msgid "sticky pagination" +msgstr "" + +#: admin_interface/models.py msgid "Theme" msgstr "Schemat" -#: admin_interface/models.py:299 +#: admin_interface/models.py msgid "Themes" msgstr "Schematy" -#: admin_interface/templates/admin/filter.html:13 -#: admin_interface/templates/admin_interface/dropdown_filter.html:4 +#: admin_interface/templates/admin/change_list.html +#, fuzzy +#| msgid "List Filter" +msgid "Filter" +msgstr "Filtry" + +#. Translators: don't translate this, the django catalog already contains it +#: admin_interface/templates/admin/change_list.html +msgid "Clear all filters" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Change" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View on site" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Delete?" +msgstr "" + +#: admin_interface/templates/admin/filter.html +#: admin_interface/templates/admin_interface/dropdown_filter.html #, python-format msgid " By %(filter_title)s " msgstr " po %(filter_title)s " -#: admin_interface/templates/admin/popup_response.html:3 +#: admin_interface/templates/admin/popup_response.html msgid "Popup closing..." msgstr "Zamykanie..." diff --git a/admin_interface/locale/pt_BR/LC_MESSAGES/django.mo b/admin_interface/locale/pt_BR/LC_MESSAGES/django.mo index 024f9f6ae60687638a0cb2cbcd459fd4c6ebe662..c81bb244bbcf4a81c2c2132e1e668abe80183094 100644 GIT binary patch delta 1244 zcmXxkOGs2v9LMqh=wwr4nxmyNJ-n4YMs3P6DVXT7($z%Zw25FCrx=okLVCkpL`1l- zO|>d27X~f@hbV&F3>5T0XqAM~A|hI}ObDXBzk5%I`@f%a&)oC)pL6wXaw6q_PDF1T zWq?>qyo;C(;njL>lm}6>RrnA$;4{qOJT_x`N!V{6Hu0QCyzQPLN3d>=e&D9j_O~;)i{O; z=C^SwNgD2B8$L%({2n#n2UG?honKHBf5#U5h08IdSswFv5mPva z`uzv`nlQpF+JP2~VGlBf^IX6SSii)QehSA1bqhuKft={b5u_W#?togyYC%cerUmlc)txqjq){ z*W+v4hTnWD99d90xo;x7s+mYBRxn$=)h?#;Y*yrceoMrYn$y#n4>&~em{;`yo71Ij%|1|I)&>( zsD>FHHu2&a4&Xf6@GCM#_>OkGjDGhgmeaJh!%l3)KIByxMy_x)md9fG6x#kYcH#vr zFn+kfLpK%ou^ng8f#0AVE}#)CMn9kff5r^f(T;y&5&xp?b2RdO5jS8jTHlYZ+&;`R zemD^;CeV&2(T3O13EV;>yo+4nA-63!gS+rGo@CpW(8xL%&8-^3b9e@Oa1MRHh)&=e zR*ig_hxM3ZRQd=R?7{*X*&uR-=zo*3R>UFENqZRBPmBm(Sa(+70z;VB9rJuub?Y>8+-8{_TwvLr@{fU zD_?T|SEv0H{230Cosj7uxux;cJlRHMazg%WT@hE!)JHx{-cH_2j=y4_nrFaCxfQ0( zH&0xjG9Gjob(|yd6+$@tJ59|1F?dY c&NcolhN(D2Zm+#aF1FO#(qEF=O17B#4~MZ&&j0`b diff --git a/admin_interface/locale/pt_BR/LC_MESSAGES/django.po b/admin_interface/locale/pt_BR/LC_MESSAGES/django.po index e87d687..78169b0 100644 --- a/admin_interface/locale/pt_BR/LC_MESSAGES/django.po +++ b/admin_interface/locale/pt_BR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-28 10:01-0300\n" +"POT-Creation-Date: 2023-05-10 18:20-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,120 +18,127 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: admin.py:21 +#: admin_interface/admin.py msgid "Environment" msgstr "Ambiente" -#: admin.py:30 +#: admin_interface/admin.py msgid "Language chooser" msgstr "Seletor de idioma" -#: admin.py:37 +#: admin_interface/admin.py msgid "Logo" msgstr "Logo" -#: admin.py:47 +#: admin_interface/admin.py msgid "Favicon" msgstr "Favicon" -#: admin.py:51 +#: admin_interface/admin.py msgid "Title" msgstr "Título" -#: admin.py:59 +#: admin_interface/admin.py msgid "Header" msgstr "Cabeçalho" -#: admin.py:68 +#: admin_interface/admin.py msgid "Breadcrumbs / Module headers" msgstr "Cabeçalhos de módulo" -#: admin.py:80 +#: admin_interface/admin.py msgid "Generic Links" msgstr "Links Genéricos" -#: admin.py:87 +#: admin_interface/admin.py msgid "Save Buttons" msgstr "Botões Salvar" -#: admin.py:95 +#: admin_interface/admin.py msgid "Delete Buttons" msgstr "Botões Deletar" -#: admin.py:103 +#: admin_interface/admin.py msgid "Navigation Bar" msgstr "Barra de Navegação" -#: admin.py:109 +#: admin_interface/admin.py msgid "Related Modal" msgstr "Modal Relacionado" -#: admin.py:119 +#: admin_interface/admin.py msgid "Form Controls" msgstr "Controles de Formulário" -#: admin.py:126 +#: admin_interface/admin.py msgid "List Filter" msgstr "Filtro de lista" -#: admin.py:133 +#: admin_interface/admin.py +msgid "Change Form" +msgstr "" + +#: admin_interface/admin.py +msgid "Inlines" +msgstr "" + +#: admin_interface/admin.py msgid "Recent Actions" msgstr "Ações recentes" -#: apps.py:12 +#: admin_interface/apps.py msgid "Admin Interface" msgstr "Interface do administrador" -#: models.py:73 models.py:129 models.py:148 +#: admin_interface/models.py msgid "name" msgstr "nome" -#: models.py:76 models.py:145 models.py:274 +#: admin_interface/models.py msgid "active" msgstr "ativo" -#: models.py:80 templates/admin/base_site.html:6 -#: templates/admin/base_site.html:78 +#: admin_interface/models.py admin_interface/templates/admin/base_site.html msgid "Django administration" msgstr "Administração do Django" -#: models.py:82 +#: admin_interface/models.py msgid "title" msgstr "título" -#: models.py:88 models.py:105 models.py:135 +#: admin_interface/models.py msgid "color" msgstr "cor" -#: models.py:91 models.py:116 models.py:318 +#: admin_interface/models.py msgid "visible" msgstr "visível" -#: models.py:98 +#: admin_interface/models.py msgid "Leave blank to use the default Django logo" msgstr "Deixe em branco para usar o logotipo padrão do Django" -#: models.py:99 +#: admin_interface/models.py msgid "logo" msgstr "logo" -#: models.py:109 +#: admin_interface/models.py msgid "max width" msgstr "largura máxima" -#: models.py:113 +#: admin_interface/models.py msgid "max height" msgstr "altura máxima" -#: models.py:123 +#: admin_interface/models.py msgid "(.ico|.png|.gif - 16x16|32x32 px)" msgstr "(.ico|.png|.gif - 16x16|32x32 px)" -#: models.py:124 +#: admin_interface/models.py msgid "favicon" msgstr "favicon" -#: models.py:133 +#: admin_interface/models.py msgid "" "(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: " "#3498DB)" @@ -139,96 +146,176 @@ msgstr "" "(vermelho: #E74C3C, laranja: #E67E22, amarelo: #F1C40F, verde: #2ECC71, " "azul: #3498DB)" -#: models.py:138 +#: admin_interface/models.py msgid "visible in header (marker and name)" msgstr "visível no cabeçalho (marcador e nome)" -#: models.py:141 +#: admin_interface/models.py msgid "visible in favicon (marker)" msgstr "visível no favicon (marcador)" -#: models.py:147 +#: admin_interface/models.py +msgid "Default Select" +msgstr "" + +#: admin_interface/models.py +msgid "Minimal Select" +msgstr "" + +#: admin_interface/models.py +#, fuzzy +#| msgid "Form Controls" +msgid "control" +msgstr "Controles de Formulário" + +#: admin_interface/models.py msgid "code" msgstr "código" -#: models.py:154 +#: admin_interface/models.py msgid "display" msgstr "exibição" -#: models.py:161 models.py:186 models.py:239 models.py:258 models.py:280 +#: admin_interface/models.py msgid "background color" msgstr "cor de fundo" -#: models.py:167 models.py:198 models.py:251 models.py:270 +#: admin_interface/models.py msgid "text color" msgstr "cor do texto" -#: models.py:173 models.py:204 models.py:226 +#: admin_interface/models.py msgid "link color" msgstr "cor do link" -#: models.py:179 models.py:216 models.py:232 +#: admin_interface/models.py msgid "link hover color" msgstr "cor de foco do link" -#: models.py:192 +#: admin_interface/models.py msgid "background selected color" msgstr "cor de fundo selecionada" -#: models.py:210 +#: admin_interface/models.py msgid "link selected color" msgstr "link cor selecionada" -#: models.py:219 models.py:300 +#: admin_interface/models.py msgid "rounded corners" msgstr "cantos arredondados" -#: models.py:245 models.py:264 +#: admin_interface/models.py +msgid "link active color" +msgstr "cor de ativação do link" + +#: admin_interface/models.py msgid "background hover color" msgstr "cor de fundo do foco" -#: models.py:297 +#: admin_interface/models.py msgid "background opacity" msgstr "opacidade de fundo" -#: models.py:303 +#: admin_interface/models.py msgid "close button visible" msgstr "botão fechar visível" -#: models.py:307 +#: admin_interface/models.py +msgid "highlight active" +msgstr "" + +#: admin_interface/models.py msgid "use dropdown" msgstr "usar menu suspenso" -#: models.py:310 +#: admin_interface/models.py msgid "sticky position" msgstr "posição sticky" -#: models.py:314 +#: admin_interface/models.py +msgid "quick remove links for active filters at top of sidebar" +msgstr "" + +#: admin_interface/models.py msgid "foldable apps" msgstr "aplicativos dobráveis" -#: models.py:322 +#: admin_interface/models.py +msgid "fieldsets as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "inlines as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines collapsed" +msgstr "" + +#: admin_interface/models.py msgid "sticky submit" msgstr "envio fixo" -#: models.py:325 +#: admin_interface/models.py msgid "sticky pagination" msgstr "paginação fixa" -#: models.py:334 +#: admin_interface/models.py msgid "Theme" msgstr "Tema" -#: models.py:335 +#: admin_interface/models.py msgid "Themes" msgstr "Temas" -#: templates/admin/filter.html:13 -#: templates/admin_interface/dropdown_filter.html:4 +#: admin_interface/templates/admin/change_list.html +#, fuzzy +#| msgid "List Filter" +msgid "Filter" +msgstr "Filtro de lista" + +#. Translators: don't translate this, the django catalog already contains it +#: admin_interface/templates/admin/change_list.html +msgid "Clear all filters" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Change" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View on site" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Delete?" +msgstr "" + +#: admin_interface/templates/admin/filter.html +#: admin_interface/templates/admin_interface/dropdown_filter.html #, python-format msgid " By %(filter_title)s " msgstr " por %(filter_title)s " -#: templates/admin/popup_response.html:3 +#: admin_interface/templates/admin/popup_response.html msgid "Popup closing..." msgstr "Pop-up fechando..." diff --git a/admin_interface/locale/ru/LC_MESSAGES/django.mo b/admin_interface/locale/ru/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..1f77b53695bb7f794ed8679de1878617dfdeb1fa GIT binary patch literal 5920 zcmbW3TX0=f8OIklfp`N%sN!WIP#frJlQg9zZQABqGA3rU>CV~d-a9E} zaE7!ZVhd4bPzF!|ePHmVEeTE2Hg$aQ#ld}MoKXj5lqVk?ozW*RGy40ly-#vlLOa8r zv-W?l+xLCz|6SI3=ccQlGdw$KpP>z2X^aORyP6lz4IeUQH+UoXanJ*`?f}ToJj3h5 z;B(-O;49$Az&8r~1$Zs}D)>q8_n_AQy%_%w$j@BGqK|?N1+D@$z8d6bO1y3WH-dMA zy`bbA0A=boKz-z#_LFxH((f%>!9`@0B-}Qz`MX_i~fAk{|zYp{{~TE%=I~5SKtkx_*@0b z?z=&qXEP{2^cC|DferNc7xPo#C+I&3%8nO{`IkX{=4ZwD9Jq=80w{U^0HyCrgsFcs zD7|-rlHbBh_O^rKr3;kZdqAD@E8rbq3jXQ}W1a^erSG$NBlss!Jl%p&oudi76YKz2 zgCpPu~bj;BBDn=mn*BA9yQx5Ja_^0TpjAfS&`8gA?Gd zLFwIra6XL>-VUbV=fUrTviHqm{I8&R`WQxQT`!2s%vga3K-u*uDE~hVO8%=LKl4jo z7W^I92L20d0$U-w8}vc-Uk4S3Z-cGiyWp3>TM@nk3_$f?2c`eNAfn7QI9u^}3s?e6 zpyYiGRNNf{#otL#cKrbq-&bI)_*nz42e*OuffZ1^yasCjsRI89O5as%l3#BI#m5Y& zbtk|tg1;^L{{#7%yD$z@%@$DS-vvtkQ(zzXJlGDt3tj=D#>Jg%(tgd!Ug@fTN zTAKX5gXZ!GR2*%i=~+cnd~T=VN*5!tM={Y%yNA|FL%pjfp9aO>I+~tdn&M1n+)1lF zib0*Xvo=uRRp3_Iy)>wHkNl+=+K_kMTO8CL#hrZARSZ~Au~B;n1?OAw*Fw9VrW&kA zKJB4xREOtk+7|bf`}0b^uPOS1&BgZ`Q2D4waVOs@@64LmFSpq{dN#FoZRlESqu8sA z`Wm=*Q%_6FT6@S3!{{Ibz0F;%O}%UFXzcqH`Yko>ICx4FBs(R7r@ zgNp5|q<%c&4g01u_Pz3OJUKp;*!6ZGDo=*K9b?Ro6Vo*&Z3WogC>}Rmq3^}k3qv~+ zga}DYw?E=dhN<1>hyHL%H}q5Ac21^gRMD)u+fDbwh>ENy^+A%xUK&Id(^HuW;;1t2 zS5njKO$Eb@^*Xsm+H6-;N#iI?%uc`J$HB1e4=Vc;bHB6C^i{&3;wPpb(Uab&Z->XC zDDh*{?|V}|C-*A*Z5r9h#JA~~Z_9nFzf@W~2y;k-!hjiJvCcODsYXGZKYmj}usLVj?kP!RS~>OKrhmp?qmM zk+Q#-lTuWpp7^yX>k)rCT%*|&M-P+T zrM`0ML98U!+w7i>t}k`$?6D8_?A_P5dso9=edwcfn+s4v7;Y)+QH{NFZJ9h1SK$dLn@81yy>!Nscc?}i}^bPbZ zo87#wsX=vxv@H!Dn!p}WxSnteDqAQaUQC>|KQP!^+Pu6@W{vo9si#81kos+Q^H7jB z>lT}Twy&w&)!fwH-fUN|w)$+ky}h~FZnsUA<@C3;x74P# zwzulj?P%KC++rVlEZ?%NxwVlk&Bd1X_9jiab=%rEE^oiDacLa6sHy4P+Kz;Bh zs|l;!JjkC%)V$M>-#;dMo@Ix#x$5K9Z?ffdb=snDHanXytxhBU@ob*9n4NT%%vWbj z_8On(vxRKlvT`w-tsZe2PfOk@hEUF?!_{LZdlpHv7U??5+3HbCzqTY_hP)qDpJYAC z@?Dm*PG@u4HJ_cS9+MH(qsZc@CnU(CebJ&-+Rw0A9L-msG1&`zEEcvgKg*2cf?4$Z zq!@6vZ8zC>FMU)@$nPdBl#dW7M~K5Y9d!X!=Xf7?q;bAE`H;cWwqR~iB$@1|%jb|0 z=UI9jJ`2n8lRADFhI*+xQGH5kBxssrpUDN)h(BH??Fq+`kv4KaUqt*t)E;3BH=(#izmJ&wqn+=3rnRLId53m3CDa1K7q&M)y+xLCIm3r+nb*kOY|ea?sSRGTlmK#@aX zaGE5_aV4k0zGfDQIf9(jBp+Oa!I((;K)RgkB@b!Juflc9EJGYFLb#%4N#BB7TofuP zUy2D)uI!yPPU@+=tT=K=IaRa8BGtuL9zYPN*ib^t>8QyMC|2{BB40TwF|m>WHlA_k zSJ`v|sJdu8f*X%sR-$yDK)}2h{U9b?PQVH#6)}=C#WjJsF7J&3kk1p2ySj=v?>H?g z;z_I1vSh`gIA`#Uj#R7WoQ-57Q~5bhiu5JURNLUJMq$B#3&A>HxlB@Vnl1R{R&ma8 z1*$FwSb_n|rPJMH6q9VBUa9l+QlebA-BtMI!n~AE`2RAam&lwIrC<^M&bfa7=)a)) z8do|OAfc{^5~DLt7Q^x%DWd|r(yHpWi8HcWF3SCMN;J}S7a#Y7%V@$up`I7S8C4^K zX!-cH3h9(A6(8#3#TUR*=usArSjB{kBNaUY;=EI=zciGVS`r_j1mw485eoS~s2P)A zXWFU16wdkNqbi4TTm!lX-?NH%kfyxaE=Tlx);SKvUhN8Z(rPinxQf2JVsl$BD&X&X zdCJ8)C|tVRi9cy#CBHP?#lBSDSjqpa3%a;ff2(SLM>xtQGH>3l!SU37G10h!B)p&h RyPK, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-06-23 16:28-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || " +"(n%100>=11 && n%100<=14)? 2 : 3);\n" + +#: admin_interface/admin.py +msgid "Environment" +msgstr "Окружение" + +#: admin_interface/admin.py +msgid "Language chooser" +msgstr "Вид выбора языка" + +#: admin_interface/admin.py +msgid "Logo" +msgstr "Логотип" + +#: admin_interface/admin.py +msgid "Favicon" +msgstr "Иконка адресной строки" + +#: admin_interface/admin.py +msgid "Title" +msgstr "Заголовок" + +#: admin_interface/admin.py +msgid "Header" +msgstr "Шапка" + +#: admin_interface/admin.py +msgid "Breadcrumbs / Module headers" +msgstr "Шапки модулей" + +#: admin_interface/admin.py +msgid "Generic Links" +msgstr "Общие ссылки" + +#: admin_interface/admin.py +msgid "Save Buttons" +msgstr "Кнопки сохранения" + +#: admin_interface/admin.py +msgid "Delete Buttons" +msgstr "Кнопки удаления" + +#: admin_interface/admin.py +msgid "Navigation Bar" +msgstr "Строка навигации" + +#: admin_interface/admin.py +msgid "Related Modal" +msgstr "Модаль для связанных объектов" + +#: admin_interface/admin.py +msgid "Form Controls" +msgstr "Управление формами" + +#: admin_interface/admin.py +msgid "List Filter" +msgstr "Вид списка фильтров" + +#: admin_interface/admin.py +msgid "Change Form" +msgstr "Вид формы изменения" + +#: admin_interface/admin.py +msgid "Inlines" +msgstr "Вид вставок" + +#: admin_interface/admin.py +msgid "Recent Actions" +msgstr "Недавние действия" + +#: admin_interface/apps.py +msgid "Admin Interface" +msgstr "Интерфейс администрирования" + +#: admin_interface/models.py +msgid "name" +msgstr "название" + +#: admin_interface/models.py +msgid "active" +msgstr "активный" + +#: admin_interface/models.py admin_interface/templates/admin/base_site.html +msgid "Django administration" +msgstr "Администрирование Django" + +#: admin_interface/models.py +msgid "title" +msgstr "заголовок" + +#: admin_interface/models.py +msgid "color" +msgstr "цвет" + +#: admin_interface/models.py +msgid "visible" +msgstr "видимый" + +#: admin_interface/models.py +msgid "Leave blank to use the default Django logo" +msgstr "Оставьте пустым, чтобы по умолчанию использовать логотип Django" + +#: admin_interface/models.py +msgid "logo" +msgstr "логотип" + +#: admin_interface/models.py +msgid "max width" +msgstr "максимальная ширина" + +#: admin_interface/models.py +msgid "max height" +msgstr "максимальная высота" + +#: admin_interface/models.py +msgid "(.ico|.png|.gif - 16x16|32x32 px)" +msgstr "" + +#: admin_interface/models.py +msgid "favicon" +msgstr "иконка в адресной строке" + +#: admin_interface/models.py +msgid "" +"(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: " +"#3498DB)" +msgstr "" +"(красный: #E74C3C, оранжевый: #E67E22, желтый: #F1C40F, зеленый: #2ECC71, " +"синий: #3498DB" + +#: admin_interface/models.py +msgid "visible in header (marker and name)" +msgstr "видимый в шапке (метка и название)" + +#: admin_interface/models.py +msgid "visible in favicon (marker)" +msgstr "видимый в иконке адресной строки (метка)" + +#: admin_interface/models.py +msgid "Default Select" +msgstr "Выбор по умолчанию" + +#: admin_interface/models.py +msgid "Minimal Select" +msgstr "Минимальный выбор" + +#: admin_interface/models.py +msgid "control" +msgstr "контроль" + +#: admin_interface/models.py +msgid "code" +msgstr "код" + +#: admin_interface/models.py +msgid "display" +msgstr "отображение" + +#: admin_interface/models.py +msgid "background color" +msgstr "цвет заднего фона" + +#: admin_interface/models.py +msgid "text color" +msgstr "цвет текста" + +#: admin_interface/models.py +msgid "link color" +msgstr "цвет ссылки" + +#: admin_interface/models.py +msgid "link hover color" +msgstr "цвет ссылки при наведении" + +#: admin_interface/models.py +msgid "background selected color" +msgstr "цвет заднего фона выбранного объекта" + +#: admin_interface/models.py +msgid "link selected color" +msgstr "цвет ссылки выбранного объекта" + +#: admin_interface/models.py +msgid "rounded corners" +msgstr "закругленные края" + +#: admin_interface/models.py +msgid "link active color" +msgstr "цвет активной ссылки" + +#: admin_interface/models.py +msgid "background hover color" +msgstr "цвет заднего фона при наведении" + +#: admin_interface/models.py +msgid "background opacity" +msgstr "прозрачность заднего фона" + +#: admin_interface/models.py +msgid "close button visible" +msgstr "видимость кнопки закрытия" + +#: admin_interface/models.py +msgid "highlight active" +msgstr "подсвечивать активное" + +#: admin_interface/models.py +msgid "use dropdown" +msgstr "использовать выпадающий список" + +#: admin_interface/models.py +msgid "sticky position" +msgstr "устойчивое положение" + +#: admin_interface/models.py +msgid "quick remove links for active filters at top of sidebar" +msgstr "быстро удалять ссылки для активных фильтров сверху боковой панели" + +#: admin_interface/models.py +msgid "foldable apps" +msgstr "складные приложения" + +#: admin_interface/models.py +msgid "fieldsets as tabs" +msgstr "набор полей в виде вкладок" + +#: admin_interface/models.py +msgid "inlines as tabs" +msgstr "вставки как вкладки" + +#: admin_interface/models.py +msgid "collapsible stacked inlines" +msgstr "разборные уложенные вставки" + +#: admin_interface/models.py +msgid "collapsible stacked inlines collapsed" +msgstr "сворачивающиеся уложенные вкладки свернуты" + +#: admin_interface/models.py +msgid "collapsible tabular inlines" +msgstr "сворачивающиеся табличные вставки" + +#: admin_interface/models.py +msgid "collapsible tabular inlines collapsed" +msgstr "сворачивающиеся табличные вставки свернуты" + +#: admin_interface/models.py +msgid "sticky submit" +msgstr "устойчивая отправка" + +#: admin_interface/models.py +msgid "sticky pagination" +msgstr "устойчивая разбивка" + +#: admin_interface/models.py +msgid "Theme" +msgstr "Тема" + +#: admin_interface/models.py +msgid "Themes" +msgstr "Темы" + +#: admin_interface/templates/admin/change_list.html +msgid "Filter" +msgstr "Фильтр" + +#. Translators: don't translate this, the django catalog already contains it +#: admin_interface/templates/admin/change_list.html +msgid "Clear all filters" +msgstr "Очистить все фильтры" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Change" +msgstr "Изменить" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View" +msgstr "Посмотреть" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View on site" +msgstr "Посмотреть на сайте" + +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Delete?" +msgstr "Удалить?" + +#: admin_interface/templates/admin/filter.html +#: admin_interface/templates/admin_interface/dropdown_filter.html +#, fuzzy, python-format +#| msgid " By %(filter_title)s " +msgid " By %(filter_title)s " +msgstr " По %(filter_title)ы " + +#: admin_interface/templates/admin/popup_response.html +msgid "Popup closing..." +msgstr "Закрытие всплывающего окна..." diff --git a/admin_interface/locale/tr/LC_MESSAGES/django.mo b/admin_interface/locale/tr/LC_MESSAGES/django.mo index 0177177107abc631df5c1aef723d9b83d725c0e6..9a1606f05849b46d88fc1f453c8a202967e0e363 100644 GIT binary patch delta 935 zcmXZaKWGzS7{~D^e`@}iT9Y=_QZ1>~YSS$K0kNVT3lb1P5vmSHdY(r@iXplvy-A%M z zVDA}}dGHyvAl+le&<2nRHiX)^jN0HB=5Pl2*;zVmI2+wN(Y=RS-^4)-uz(M70H0x! z__oA=pS`A2rpu8ZFwgxb%;G9)!#}75Q$&?HR3-ALd85b_tDq7+gxYr+hj9kSu!ge% z<-WsUga_Z5bq-@`vx|5h`|$gP!m^BC-{cMw4bQJYp9d|MZLl_$KQ#EQ75e;pNm~V?bARd zb``bXLYDfEGq}wIooEp!a0#{GN91qRJ6uDZC_|@2il~4is11+eBu?WItRn^9Xj-qN z^>M12s>G0mzv6}7y$mZ{%I!dyNlZ@Y{U{LyQPY=C?2XNpn5v_;KfII}%kN`U=29(G z&+*Q^#EE#$skQyNLG;j^|F5+O4oZb)j=3wH_aK>TUmW$#WZi VbIyPBnBJ}XrIy?D{IHf?{||o1Uq%1` delta 869 zcmXZaKS*0q6vy#nUSc$je-dr_$3IkUsxhllh;)#OgA^n~5kv&BsZ%XTLZ_0gOSe8c zC_*e0Z5NjyBvPoIM6k3&tBdHQltNoYEJ6qS{l#~A?|tso^Ugi@jpg^F{@2Dx za<_74tIP&)+sA`Za?Gw`89VR`j^YV6;GqBVy)@Rdo<+q!$1CV!5DQp`D_D(d*l3ow z4@`Rb!)MeB=g4LLKqbIxQHgJ&5+pE;cah76cqrkBw@!QOF=PXq#27xsD89gEoJT+V z+bR<-EAmjKWzSC-V!ee*^bJ+mq32Ij2mYYqE|AMYRHFhLQTf`i1>@L-gE&r?GuY1l zwn5ZGJirO;uQ6-FSJ;WmsLHoch3ug=`i0uy6czsuwQ)o3WhYxP#kvR8!D-Y1=1}p^ zFt2~SWTMtCUGfzD50J?@`~x2C9H<)JES?iGHI#+`rg|odna_%Fz2NRv%-Bd*W-U zQ}Z=cO1FE%NhZ|Y9&Y8JoCAw(2xIQ^HVke diff --git a/admin_interface/locale/tr/LC_MESSAGES/django.po b/admin_interface/locale/tr/LC_MESSAGES/django.po index fdda55a..8ae3bba 100644 --- a/admin_interface/locale/tr/LC_MESSAGES/django.po +++ b/admin_interface/locale/tr/LC_MESSAGES/django.po @@ -8,201 +8,319 @@ msgid "" msgstr "" "Project-Id-Version: django-admin-interface\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-01-24 06:07+0300\n" +"POT-Creation-Date: 2023-05-10 18:20-0500\n" "PO-Revision-Date: 2020-01-29 04:53+0300\n" "Last-Translator: Ishak Okutan \n" "Language-Team: \n" +"Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: tr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Poedit 2.2.4\n" -#: admin_interface/admin.py:21 +#: admin_interface/admin.py msgid "Environment" msgstr "Ortam" -#: admin_interface/admin.py:30 +#: admin_interface/admin.py msgid "Language chooser" msgstr "Dil seçimi" -#: admin_interface/admin.py:37 +#: admin_interface/admin.py msgid "Logo" msgstr "Logo" -#: admin_interface/admin.py:45 +#: admin_interface/admin.py msgid "Favicon" msgstr "Favicon" -#: admin_interface/admin.py:49 +#: admin_interface/admin.py msgid "Title" msgstr "Başlık" -#: admin_interface/admin.py:57 +#: admin_interface/admin.py msgid "Header" msgstr "Üst Kısım" -#: admin_interface/admin.py:66 +#: admin_interface/admin.py msgid "Breadcrumbs / Module headers" msgstr "Link alanı / Modül başlıkları" -#: admin_interface/admin.py:76 +#: admin_interface/admin.py msgid "Generic Links" msgstr "Genel Bağlantılar" -#: admin_interface/admin.py:83 +#: admin_interface/admin.py msgid "Save Buttons" msgstr "Kaydet Butonları" -#: admin_interface/admin.py:91 +#: admin_interface/admin.py msgid "Delete Buttons" msgstr "Kaldır Butonları" -#: admin_interface/admin.py:99 +#: admin_interface/admin.py +msgid "Navigation Bar" +msgstr "" + +#: admin_interface/admin.py msgid "Related Modal" msgstr "İlgili Modal" -#: admin_interface/admin.py:109 +#: admin_interface/admin.py +msgid "Form Controls" +msgstr "" + +#: admin_interface/admin.py msgid "List Filter" msgstr "Liste Filtresi" -#: admin_interface/admin.py:113 +#: admin_interface/admin.py +msgid "Change Form" +msgstr "" + +#: admin_interface/admin.py +msgid "Inlines" +msgstr "" + +#: admin_interface/admin.py msgid "Recent Actions" msgstr "Son İşlemler" -#: admin_interface/apps.py:11 +#: admin_interface/apps.py msgid "Admin Interface" msgstr "Yönetici Arayüzü" -#: admin_interface/models.py:72 admin_interface/models.py:116 -#: admin_interface/models.py:135 +#: admin_interface/models.py msgid "name" msgstr "adı" -#: admin_interface/models.py:75 admin_interface/models.py:132 -#: admin_interface/models.py:253 +#: admin_interface/models.py msgid "active" msgstr "aktif" -#: admin_interface/models.py:79 -#: admin_interface/templates/admin/base_site.html:6 -#: admin_interface/templates/admin/base_site.html:60 +#: admin_interface/models.py admin_interface/templates/admin/base_site.html msgid "Django administration" msgstr "Django yönetimi" -#: admin_interface/models.py:81 +#: admin_interface/models.py msgid "title" msgstr "başlık" -#: admin_interface/models.py:87 admin_interface/models.py:102 -#: admin_interface/models.py:122 +#: admin_interface/models.py msgid "color" msgstr "renk" -#: admin_interface/models.py:90 admin_interface/models.py:105 -#: admin_interface/models.py:289 +#: admin_interface/models.py msgid "visible" msgstr "göster" -#: admin_interface/models.py:95 +#: admin_interface/models.py msgid "Leave blank to use the default Django logo" msgstr "Varsayılan Django logosunu kullanmak için boş bırakın" -#: admin_interface/models.py:96 +#: admin_interface/models.py msgid "logo" msgstr "logo" -#: admin_interface/models.py:110 +#: admin_interface/models.py +msgid "max width" +msgstr "" + +#: admin_interface/models.py +msgid "max height" +msgstr "" + +#: admin_interface/models.py msgid "(.ico|.png|.gif - 16x16|32x32 px)" msgstr "" -"(favicon simgesi, png veya (GIF 16x16) veya (32x32) piksel " -"boyutlarında olmalıdır)" +"(favicon simgesi, png veya (GIF 16x16) veya (32x32) piksel boyutlarında " +"olmalıdır)" -#: admin_interface/models.py:111 +#: admin_interface/models.py msgid "favicon" msgstr "favicon" -#: admin_interface/models.py:120 +#: admin_interface/models.py msgid "" "(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: " "#3498DB)" msgstr "" -"(kırmızı: # E74C3C, turuncu: # E67E22, sarı: # F1C40F, yeşil: # " -"2ECC71, mavi: # 3498DB)" +"(kırmızı: # E74C3C, turuncu: # E67E22, sarı: # F1C40F, yeşil: # 2ECC71, " +"mavi: # 3498DB)" -#: admin_interface/models.py:125 +#: admin_interface/models.py msgid "visible in header (marker and name)" msgstr "üst kısım da görünsün (yuvarlak işaret ve ad)" -#: admin_interface/models.py:128 +#: admin_interface/models.py msgid "visible in favicon (marker)" msgstr "favicon’da görünsün (yuvarlak işaret)" -#: admin_interface/models.py:134 +#: admin_interface/models.py +msgid "Default Select" +msgstr "" + +#: admin_interface/models.py +msgid "Minimal Select" +msgstr "" + +#: admin_interface/models.py +msgid "control" +msgstr "" + +#: admin_interface/models.py msgid "code" msgstr "kod" -#: admin_interface/models.py:141 +#: admin_interface/models.py msgid "display" msgstr "görüntüle" -#: admin_interface/models.py:148 admin_interface/models.py:173 -#: admin_interface/models.py:214 admin_interface/models.py:233 -#: admin_interface/models.py:259 +#: admin_interface/models.py msgid "background color" msgstr "arka plan rengi" -#: admin_interface/models.py:154 admin_interface/models.py:179 -#: admin_interface/models.py:226 admin_interface/models.py:245 -#: admin_interface/models.py:249 +#: admin_interface/models.py msgid "text color" msgstr "metin rengi" -#: admin_interface/models.py:160 admin_interface/models.py:185 -#: admin_interface/models.py:201 +#: admin_interface/models.py msgid "link color" msgstr "bağlantı rengi" -#: admin_interface/models.py:166 admin_interface/models.py:191 -#: admin_interface/models.py:207 +#: admin_interface/models.py msgid "link hover color" msgstr "bağlantı üzerine gelindiğindeki rengi" -#: admin_interface/models.py:194 admin_interface/models.py:279 +#: admin_interface/models.py +#, fuzzy +#| msgid "background color" +msgid "background selected color" +msgstr "arka plan rengi" + +#: admin_interface/models.py +#, fuzzy +#| msgid "link color" +msgid "link selected color" +msgstr "bağlantı rengi" + +#: admin_interface/models.py msgid "rounded corners" msgstr "köşeleri ovalleştir" -#: admin_interface/models.py:220 admin_interface/models.py:239 +#: admin_interface/models.py +msgid "link active color" +msgstr "bağlantı aktif gelindiğindeki rengi" + +#: admin_interface/models.py msgid "background hover color" msgstr "arka planın üzerine gelindiğindeki renk" -#: admin_interface/models.py:276 +#: admin_interface/models.py msgid "background opacity" msgstr "arka plan şeffaflığı" -#: admin_interface/models.py:282 +#: admin_interface/models.py msgid "close button visible" msgstr "kapat düğmesi görünsün" -#: admin_interface/models.py:286 +#: admin_interface/models.py +msgid "highlight active" +msgstr "" + +#: admin_interface/models.py msgid "use dropdown" msgstr "açılır listeyi kullan" -#: admin_interface/models.py:298 +#: admin_interface/models.py +msgid "sticky position" +msgstr "" + +#: admin_interface/models.py +msgid "quick remove links for active filters at top of sidebar" +msgstr "" + +#: admin_interface/models.py +msgid "foldable apps" +msgstr "" + +#: admin_interface/models.py +msgid "fieldsets as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "inlines as tabs" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible stacked inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines" +msgstr "" + +#: admin_interface/models.py +msgid "collapsible tabular inlines collapsed" +msgstr "" + +#: admin_interface/models.py +msgid "sticky submit" +msgstr "" + +#: admin_interface/models.py +msgid "sticky pagination" +msgstr "" + +#: admin_interface/models.py msgid "Theme" msgstr "Tema" -#: admin_interface/models.py:299 +#: admin_interface/models.py msgid "Themes" msgstr "Temalar" -#: admin_interface/templates/admin/filter.html:13 -#: admin_interface/templates/admin_interface/dropdown_filter.html:4 +#: admin_interface/templates/admin/change_list.html +#, fuzzy +#| msgid "List Filter" +msgid "Filter" +msgstr "Liste Filtresi" + +#. Translators: don't translate this, the django catalog already contains it +#: admin_interface/templates/admin/change_list.html +msgid "Clear all filters" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Change" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_stacked.html +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "View on site" +msgstr "" + +#: admin_interface/templates/admin/edit_inline/headerless_tabular.html +msgid "Delete?" +msgstr "" + +#: admin_interface/templates/admin/filter.html +#: admin_interface/templates/admin_interface/dropdown_filter.html #, python-format msgid " By %(filter_title)s " msgstr " %(filter_title)s tarafından " -#: admin_interface/templates/admin/popup_response.html:3 +#: admin_interface/templates/admin/popup_response.html msgid "Popup closing..." msgstr "Popup kapanıyor..." diff --git a/admin_interface/metadata.py b/admin_interface/metadata.py new file mode 100644 index 0000000..fadb570 --- /dev/null +++ b/admin_interface/metadata.py @@ -0,0 +1,10 @@ +__author__ = "Fabio Caccamo" +__copyright__ = "Copyright (c) 2016-present Fabio Caccamo" +__description__ = ( + "django's default admin interface with superpowers - " + "customizable themes, popup windows replaced by modals and many other features." +) +__email__ = "fabio.caccamo@gmail.com" +__license__ = "MIT" +__title__ = "django-admin-interface" +__version__ = "0.28.6" diff --git a/admin_interface/migrations/0001_initial.py b/admin_interface/migrations/0001_initial.py index b96b05e..7ab0a90 100644 --- a/admin_interface/migrations/0001_initial.py +++ b/admin_interface/migrations/0001_initial.py @@ -1,14 +1,8 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - -from django.db import models, migrations - import colorfield.fields +from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [] operations = [ @@ -24,202 +18,237 @@ class Migration(migrations.Migration): primary_key=True, ), ), - ("name", models.CharField(default=b"Django", max_length=50)), - ("active", models.BooleanField(default=True)), + ( + "name", + models.CharField( + default="Django", + max_length=50, + ), + ), + ( + "active", + models.BooleanField( + default=True, + ), + ), ( "title", models.CharField( - default=b"Django administration", max_length=50, blank=True + default="Django administration", + max_length=50, + blank=True, ), ), ( "title_visible", - models.BooleanField(default=True, verbose_name=b"visible"), + models.BooleanField( + default=True, + verbose_name="visible", + ), ), ( "logo", - models.FileField(upload_to=b"admin-interface/logo/", blank=True), + models.FileField( + upload_to="admin-interface/logo/", + blank=True, + ), ), ( "logo_visible", - models.BooleanField(default=True, verbose_name=b"visible"), + models.BooleanField( + default=True, + verbose_name="visible", + ), ), ( "css_header_background_color", colorfield.fields.ColorField( - default=b"#0C4B33", - help_text=b"#0C4B33", + default="#0C4B33", + help_text="#0C4B33", max_length=10, - verbose_name=b"background color", + verbose_name="background color", blank=True, ), ), ( "css_header_title_color", colorfield.fields.ColorField( - default=b"#F5DD5D", - help_text=b"#F5DD5D", + default="#F5DD5D", + help_text="#F5DD5D", max_length=10, - verbose_name=b"title color", + verbose_name="title color", blank=True, ), ), ( "css_header_text_color", colorfield.fields.ColorField( - default=b"#44B78B", - help_text=b"#44B78B", + default="#44B78B", + help_text="#44B78B", max_length=10, - verbose_name=b"text color", + verbose_name="text color", blank=True, ), ), ( "css_header_link_color", colorfield.fields.ColorField( - default=b"#FFFFFF", - help_text=b"#FFFFFF", + default="#FFFFFF", + help_text="#FFFFFF", max_length=10, - verbose_name=b"link color", + verbose_name="link color", blank=True, ), ), ( "css_header_link_hover_color", colorfield.fields.ColorField( - default=b"#C9F0DD", - help_text=b"#C9F0DD", + default="#C9F0DD", + help_text="#C9F0DD", max_length=10, - verbose_name=b"link hover color", + verbose_name="link hover color", blank=True, ), ), ( "css_module_background_color", colorfield.fields.ColorField( - default=b"#44B78B", - help_text=b"#44B78B", + default="#44B78B", + help_text="#44B78B", max_length=10, - verbose_name=b"background color", + verbose_name="background color", blank=True, ), ), ( "css_module_text_color", colorfield.fields.ColorField( - default=b"#FFFFFF", - help_text=b"#FFFFFF", + default="#FFFFFF", + help_text="#FFFFFF", max_length=10, - verbose_name=b"text color", + verbose_name="text color", blank=True, ), ), ( "css_module_link_color", colorfield.fields.ColorField( - default=b"#FFFFFF", - help_text=b"#FFFFFF", + default="#FFFFFF", + help_text="#FFFFFF", max_length=10, - verbose_name=b"link color", + verbose_name="link color", blank=True, ), ), ( "css_module_link_hover_color", colorfield.fields.ColorField( - default=b"#C9F0DD", - help_text=b"#C9F0DD", + default="#C9F0DD", + help_text="#C9F0DD", max_length=10, - verbose_name=b"link hover color", + verbose_name="link hover color", blank=True, ), ), ( "css_module_rounded_corners", - models.BooleanField(default=True, verbose_name=b"rounded corners"), + models.BooleanField( + default=True, + verbose_name="rounded corners", + ), ), ( "css_generic_link_color", colorfield.fields.ColorField( - default=b"#0C3C26", - help_text=b"#0C3C26", + default="#0C3C26", + help_text="#0C3C26", max_length=10, - verbose_name=b"link color", + verbose_name="link color", blank=True, ), ), ( "css_generic_link_hover_color", colorfield.fields.ColorField( - default=b"#156641", - help_text=b"#156641", + default="#156641", + help_text="#156641", max_length=10, - verbose_name=b"link hover color", + verbose_name="link hover color", blank=True, ), ), ( "css_save_button_background_color", colorfield.fields.ColorField( - default=b"#0C4B33", - help_text=b"#0C4B33", + default="#0C4B33", + help_text="#0C4B33", max_length=10, - verbose_name=b"background color", + verbose_name="background color", blank=True, ), ), ( "css_save_button_background_hover_color", colorfield.fields.ColorField( - default=b"#0C3C26", - help_text=b"#0C3C26", + default="#0C3C26", + help_text="#0C3C26", max_length=10, - verbose_name=b"background hover color", + verbose_name="background hover color", blank=True, ), ), ( "css_save_button_text_color", colorfield.fields.ColorField( - default=b"#FFFFFF", - help_text=b"#FFFFFF", + default="#FFFFFF", + help_text="#FFFFFF", max_length=10, - verbose_name=b"text color", + verbose_name="text color", blank=True, ), ), ( "css_delete_button_background_color", colorfield.fields.ColorField( - default=b"#BA2121", - help_text=b"#BA2121", + default="#BA2121", + help_text="#BA2121", max_length=10, - verbose_name=b"background color", + verbose_name="background color", blank=True, ), ), ( "css_delete_button_background_hover_color", colorfield.fields.ColorField( - default=b"#A41515", - help_text=b"#A41515", + default="#A41515", + help_text="#A41515", max_length=10, - verbose_name=b"background hover color", + verbose_name="background hover color", blank=True, ), ), ( "css_delete_button_text_color", colorfield.fields.ColorField( - default=b"#FFFFFF", - help_text=b"#FFFFFF", + default="#FFFFFF", + help_text="#FFFFFF", max_length=10, - verbose_name=b"text color", + verbose_name="text color", blank=True, ), ), - ("css", models.TextField(blank=True)), - ("list_filter_dropdown", models.BooleanField(default=False)), + ( + "css", + models.TextField( + blank=True, + ), + ), + ( + "list_filter_dropdown", + models.BooleanField( + default=False, + ), + ), ], options={ "verbose_name": "Theme", diff --git a/admin_interface/migrations/0002_add_related_modal.py b/admin_interface/migrations/0002_add_related_modal.py index 8d7c50e..0540177 100644 --- a/admin_interface/migrations/0002_add_related_modal.py +++ b/admin_interface/migrations/0002_add_related_modal.py @@ -1,14 +1,8 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - -from django.db import migrations, models - import colorfield.fields +from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0001_initial"), ] @@ -17,22 +11,28 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="theme", name="list_filter_dropdown", - field=models.BooleanField(default=False, verbose_name=b"use dropdown"), + field=models.BooleanField( + default=False, + verbose_name="use dropdown", + ), ), migrations.AddField( model_name="theme", name="related_modal_active", - field=models.BooleanField(default=True, verbose_name=b"active"), + field=models.BooleanField( + default=True, + verbose_name="active", + ), ), migrations.AddField( model_name="theme", name="related_modal_background_color", field=colorfield.fields.ColorField( blank=True, - default=b"#000000", - help_text=b"#000000", + default="#000000", + help_text="#000000", max_length=10, - verbose_name=b"background color", + verbose_name="background color", ), ), migrations.AddField( @@ -40,24 +40,27 @@ class Migration(migrations.Migration): name="related_modal_background_opacity", field=models.FloatField( choices=[ - (0.1, b"10%"), - (0.2, b"20%"), - (0.3, b"30%"), - (0.4, b"40%"), - (0.5, b"50%"), - (0.6, b"60%"), - (0.7, b"70%"), - (0.8, b"80%"), - (0.9, b"90%"), + (0.1, "10%"), + (0.2, "20%"), + (0.3, "30%"), + (0.4, "40%"), + (0.5, "50%"), + (0.6, "60%"), + (0.7, "70%"), + (0.8, "80%"), + (0.9, "90%"), ], default=0.2, - help_text=b"20%", - verbose_name=b"background opacity", + help_text="20%", + verbose_name="background opacity", ), ), migrations.AddField( model_name="theme", name="related_modal_rounded_corners", - field=models.BooleanField(default=True, verbose_name=b"rounded corners"), + field=models.BooleanField( + default=True, + verbose_name="rounded corners", + ), ), ] diff --git a/admin_interface/migrations/0003_add_logo_color.py b/admin_interface/migrations/0003_add_logo_color.py index 9336d38..e38e308 100644 --- a/admin_interface/migrations/0003_add_logo_color.py +++ b/admin_interface/migrations/0003_add_logo_color.py @@ -1,14 +1,8 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import colorfield.fields - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0002_add_related_modal"), ] diff --git a/admin_interface/migrations/0004_rename_title_color.py b/admin_interface/migrations/0004_rename_title_color.py index 3ad1363..a514b8e 100644 --- a/admin_interface/migrations/0004_rename_title_color.py +++ b/admin_interface/migrations/0004_rename_title_color.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0003_add_logo_color"), ] diff --git a/admin_interface/migrations/0005_add_recent_actions_visible.py b/admin_interface/migrations/0005_add_recent_actions_visible.py index 8995675..432001d 100644 --- a/admin_interface/migrations/0005_add_recent_actions_visible.py +++ b/admin_interface/migrations/0005_add_recent_actions_visible.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0004_rename_title_color"), ] @@ -15,6 +10,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name="theme", name="recent_actions_visible", - field=models.BooleanField(default=True, verbose_name="visible"), + field=models.BooleanField( + default=True, + verbose_name="visible", + ), ), ] diff --git a/admin_interface/migrations/0006_bytes_to_str.py b/admin_interface/migrations/0006_bytes_to_str.py index 1829f23..52cdb89 100644 --- a/admin_interface/migrations/0006_bytes_to_str.py +++ b/admin_interface/migrations/0006_bytes_to_str.py @@ -1,14 +1,8 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import colorfield.fields - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0005_add_recent_actions_visible"), ] @@ -149,7 +143,10 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="theme", name="css_module_rounded_corners", - field=models.BooleanField(default=True, verbose_name="rounded corners"), + field=models.BooleanField( + default=True, + verbose_name="rounded corners", + ), ), migrations.AlterField( model_name="theme", @@ -198,22 +195,34 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="theme", name="list_filter_dropdown", - field=models.BooleanField(default=False, verbose_name="use dropdown"), + field=models.BooleanField( + default=False, + verbose_name="use dropdown", + ), ), migrations.AlterField( model_name="theme", name="logo_visible", - field=models.BooleanField(default=True, verbose_name="visible"), + field=models.BooleanField( + default=True, + verbose_name="visible", + ), ), migrations.AlterField( model_name="theme", name="name", - field=models.CharField(default="Django", max_length=50), + field=models.CharField( + default="Django", + max_length=50, + ), ), migrations.AlterField( model_name="theme", name="related_modal_active", - field=models.BooleanField(default=True, verbose_name="active"), + field=models.BooleanField( + default=True, + verbose_name="active", + ), ), migrations.AlterField( model_name="theme", @@ -249,13 +258,18 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="theme", name="related_modal_rounded_corners", - field=models.BooleanField(default=True, verbose_name="rounded corners"), + field=models.BooleanField( + default=True, + verbose_name="rounded corners", + ), ), migrations.AlterField( model_name="theme", name="title", field=models.CharField( - blank=True, default="Django administration", max_length=50 + blank=True, + default="Django administration", + max_length=50, ), ), migrations.AlterField( @@ -272,6 +286,9 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="theme", name="title_visible", - field=models.BooleanField(default=True, verbose_name="visible"), + field=models.BooleanField( + default=True, + verbose_name="visible", + ), ), ] diff --git a/admin_interface/migrations/0007_add_favicon.py b/admin_interface/migrations/0007_add_favicon.py index b19c99c..c405a21 100644 --- a/admin_interface/migrations/0007_add_favicon.py +++ b/admin_interface/migrations/0007_add_favicon.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0006_bytes_to_str"), ] diff --git a/admin_interface/migrations/0008_change_related_modal_background_opacity_type.py b/admin_interface/migrations/0008_change_related_modal_background_opacity_type.py index 8ab2365..b4bda24 100644 --- a/admin_interface/migrations/0008_change_related_modal_background_opacity_type.py +++ b/admin_interface/migrations/0008_change_related_modal_background_opacity_type.py @@ -1,19 +1,15 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0007_add_favicon"), ] operations = [ migrations.RemoveField( - model_name="theme", name="related_modal_background_opacity" + model_name="theme", + name="related_modal_background_opacity", ), migrations.AddField( model_name="theme", diff --git a/admin_interface/migrations/0009_add_enviroment.py b/admin_interface/migrations/0009_add_enviroment.py index 2ff83c0..9c19b2c 100644 --- a/admin_interface/migrations/0009_add_enviroment.py +++ b/admin_interface/migrations/0009_add_enviroment.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0008_change_related_modal_background_opacity_type"), ] @@ -30,6 +25,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name="theme", name="env_visible", - field=models.BooleanField(default=True, verbose_name="visible"), + field=models.BooleanField( + default=True, + verbose_name="visible", + ), ), ] diff --git a/admin_interface/migrations/0010_add_localization.py b/admin_interface/migrations/0010_add_localization.py index 6fd16ae..08e504f 100644 --- a/admin_interface/migrations/0010_add_localization.py +++ b/admin_interface/migrations/0010_add_localization.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0009_add_enviroment"), ] @@ -15,12 +10,18 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="theme", name="active", - field=models.BooleanField(default=True, verbose_name="active"), + field=models.BooleanField( + default=True, + verbose_name="active", + ), ), migrations.AlterField( model_name="theme", name="css", - field=models.TextField(blank=True, verbose_name="text color"), + field=models.TextField( + blank=True, + verbose_name="text color", + ), ), migrations.AlterField( model_name="theme", @@ -51,7 +52,9 @@ class Migration(migrations.Migration): model_name="theme", name="name", field=models.CharField( - default="Django", max_length=50, verbose_name="name" + default="Django", + max_length=50, + verbose_name="name", ), ), migrations.AlterField( diff --git a/admin_interface/migrations/0011_add_environment_options.py b/admin_interface/migrations/0011_add_environment_options.py index e84e648..1876cdb 100644 --- a/admin_interface/migrations/0011_add_environment_options.py +++ b/admin_interface/migrations/0011_add_environment_options.py @@ -1,14 +1,8 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import colorfield.fields - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0010_add_localization"), ] @@ -22,7 +16,11 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="theme", name="env_name", - field=models.CharField(blank=True, max_length=50, verbose_name="name"), + field=models.CharField( + blank=True, + max_length=50, + verbose_name="name", + ), ), migrations.AddField( model_name="theme", @@ -30,7 +28,10 @@ class Migration(migrations.Migration): field=colorfield.fields.ColorField( blank=True, default="#E74C3C", - help_text="(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: #3498DB)", + help_text=( + "(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, " + "green: #2ECC71, blue: #3498DB)" + ), max_length=10, verbose_name="color", ), @@ -44,14 +45,16 @@ class Migration(migrations.Migration): model_name="theme", name="env_visible_in_header", field=models.BooleanField( - default=True, verbose_name="visible in header (marker and name)" + default=True, + verbose_name="visible in header (marker and name)", ), ), migrations.AddField( model_name="theme", name="env_visible_in_favicon", field=models.BooleanField( - default=True, verbose_name="visible in favicon (marker)" + default=True, + verbose_name="visible in favicon (marker)", ), ), ] diff --git a/admin_interface/migrations/0012_update_verbose_names.py b/admin_interface/migrations/0012_update_verbose_names.py index 9b3e6a6..88b7e87 100644 --- a/admin_interface/migrations/0012_update_verbose_names.py +++ b/admin_interface/migrations/0012_update_verbose_names.py @@ -1,14 +1,8 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import colorfield.fields - from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0011_add_environment_options"), ] diff --git a/admin_interface/migrations/0013_add_related_modal_close_button.py b/admin_interface/migrations/0013_add_related_modal_close_button.py index 197021a..f67063e 100644 --- a/admin_interface/migrations/0013_add_related_modal_close_button.py +++ b/admin_interface/migrations/0013_add_related_modal_close_button.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0012_update_verbose_names"), ] @@ -16,7 +11,8 @@ class Migration(migrations.Migration): model_name="theme", name="related_modal_close_button_visible", field=models.BooleanField( - default=True, verbose_name="close button visible" + default=True, + verbose_name="close button visible", ), ), ] diff --git a/admin_interface/migrations/0014_name_unique.py b/admin_interface/migrations/0014_name_unique.py index 7a4ae37..7404a45 100644 --- a/admin_interface/migrations/0014_name_unique.py +++ b/admin_interface/migrations/0014_name_unique.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0013_add_related_modal_close_button"), ] @@ -16,7 +11,10 @@ class Migration(migrations.Migration): model_name="theme", name="name", field=models.CharField( - default="Django", max_length=50, unique=True, verbose_name="name" + default="Django", + max_length=50, + unique=True, + verbose_name="name", ), ), ] diff --git a/admin_interface/migrations/0015_add_language_chooser_active.py b/admin_interface/migrations/0015_add_language_chooser_active.py index 4986183..a679a58 100644 --- a/admin_interface/migrations/0015_add_language_chooser_active.py +++ b/admin_interface/migrations/0015_add_language_chooser_active.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0014_name_unique"), ] @@ -15,6 +10,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name="theme", name="language_chooser_active", - field=models.BooleanField(default=True, verbose_name="active"), + field=models.BooleanField( + default=True, + verbose_name="active", + ), ), ] diff --git a/admin_interface/migrations/0016_add_language_chooser_display.py b/admin_interface/migrations/0016_add_language_chooser_display.py index 1094b59..8b56f59 100644 --- a/admin_interface/migrations/0016_add_language_chooser_display.py +++ b/admin_interface/migrations/0016_add_language_chooser_display.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0015_add_language_chooser_active"), ] @@ -16,7 +11,10 @@ class Migration(migrations.Migration): model_name="theme", name="language_chooser_display", field=models.CharField( - choices=[("code", "code"), ("name", "name")], + choices=[ + ("code", "code"), + ("name", "name"), + ], default="code", max_length=10, verbose_name="display", diff --git a/admin_interface/migrations/0017_change_list_filter_dropdown.py b/admin_interface/migrations/0017_change_list_filter_dropdown.py index d918ed7..90a071a 100644 --- a/admin_interface/migrations/0017_change_list_filter_dropdown.py +++ b/admin_interface/migrations/0017_change_list_filter_dropdown.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0016_add_language_chooser_display"), ] @@ -15,6 +10,9 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="theme", name="list_filter_dropdown", - field=models.BooleanField(default=True, verbose_name="use dropdown"), + field=models.BooleanField( + default=True, + verbose_name="use dropdown", + ), ), ] diff --git a/admin_interface/migrations/0018_theme_list_filter_sticky.py b/admin_interface/migrations/0018_theme_list_filter_sticky.py index 2787e3c..38b819a 100644 --- a/admin_interface/migrations/0018_theme_list_filter_sticky.py +++ b/admin_interface/migrations/0018_theme_list_filter_sticky.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0017_change_list_filter_dropdown"), ] @@ -15,6 +10,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name="theme", name="list_filter_sticky", - field=models.BooleanField(default=True, verbose_name="sticky position"), + field=models.BooleanField( + default=True, + verbose_name="sticky position", + ), ), ] diff --git a/admin_interface/migrations/0019_add_form_sticky.py b/admin_interface/migrations/0019_add_form_sticky.py index 5244992..978ac67 100644 --- a/admin_interface/migrations/0019_add_form_sticky.py +++ b/admin_interface/migrations/0019_add_form_sticky.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0018_theme_list_filter_sticky"), ] @@ -15,11 +10,17 @@ class Migration(migrations.Migration): migrations.AddField( model_name="theme", name="form_pagination_sticky", - field=models.BooleanField(default=False, verbose_name="sticky pagination"), + field=models.BooleanField( + default=False, + verbose_name="sticky pagination", + ), ), migrations.AddField( model_name="theme", name="form_submit_sticky", - field=models.BooleanField(default=False, verbose_name="sticky submit"), + field=models.BooleanField( + default=False, + verbose_name="sticky submit", + ), ), ] diff --git a/admin_interface/migrations/0020_module_selected_colors.py b/admin_interface/migrations/0020_module_selected_colors.py index 2bfcfe2..69c73b7 100644 --- a/admin_interface/migrations/0020_module_selected_colors.py +++ b/admin_interface/migrations/0020_module_selected_colors.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - +import colorfield.fields from django.db import migrations from django.db.models import F -import colorfield.fields - def default_link_selected(apps, schema_editor): Theme = apps.get_model("admin_interface", "Theme") @@ -17,7 +12,6 @@ def default_link_selected(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0019_add_form_sticky"), ] @@ -45,5 +39,5 @@ class Migration(migrations.Migration): verbose_name="link selected color", ), ), - migrations.RunPython(default_link_selected,migrations.RunPython.noop), + migrations.RunPython(default_link_selected), ] diff --git a/admin_interface/migrations/0021_file_extension_validator.py b/admin_interface/migrations/0021_file_extension_validator.py index b9b9214..ddf106d 100644 --- a/admin_interface/migrations/0021_file_extension_validator.py +++ b/admin_interface/migrations/0021_file_extension_validator.py @@ -1,14 +1,8 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - -from admin_interface.compat import FileExtensionValidator - +from django.core.validators import FileExtensionValidator from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0020_module_selected_colors"), ] diff --git a/admin_interface/migrations/0022_add_logo_max_width_and_height.py b/admin_interface/migrations/0022_add_logo_max_width_and_height.py index 3e4d6ce..10960ba 100644 --- a/admin_interface/migrations/0022_add_logo_max_width_and_height.py +++ b/admin_interface/migrations/0022_add_logo_max_width_and_height.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0021_file_extension_validator"), ] @@ -16,14 +11,18 @@ class Migration(migrations.Migration): model_name="theme", name="logo_max_height", field=models.PositiveSmallIntegerField( - blank=True, default=100, verbose_name="max height" + blank=True, + default=100, + verbose_name="max height", ), ), migrations.AddField( model_name="theme", name="logo_max_width", field=models.PositiveSmallIntegerField( - blank=True, default=400, verbose_name="max width" + blank=True, + default=400, + verbose_name="max width", ), ), ] diff --git a/admin_interface/migrations/0023_theme_foldable_apps.py b/admin_interface/migrations/0023_theme_foldable_apps.py index 9770fcc..2b4c60b 100644 --- a/admin_interface/migrations/0023_theme_foldable_apps.py +++ b/admin_interface/migrations/0023_theme_foldable_apps.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0022_add_logo_max_width_and_height"), ] @@ -15,6 +10,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name="theme", name="foldable_apps", - field=models.BooleanField(default=True, verbose_name="foldable apps"), + field=models.BooleanField( + default=True, + verbose_name="foldable apps", + ), ), ] diff --git a/admin_interface/migrations/0024_remove_theme_css.py b/admin_interface/migrations/0024_remove_theme_css.py index 308af27..827241e 100644 --- a/admin_interface/migrations/0024_remove_theme_css.py +++ b/admin_interface/migrations/0024_remove_theme_css.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ("admin_interface", "0023_theme_foldable_apps"), ] diff --git a/admin_interface/migrations/0025_theme_language_chooser_control.py b/admin_interface/migrations/0025_theme_language_chooser_control.py new file mode 100644 index 0000000..815d467 --- /dev/null +++ b/admin_interface/migrations/0025_theme_language_chooser_control.py @@ -0,0 +1,23 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("admin_interface", "0024_remove_theme_css"), + ] + + operations = [ + migrations.AddField( + model_name="theme", + name="language_chooser_control", + field=models.CharField( + choices=[ + ("default-select", "Default Select"), + ("minimal-select", "Minimal Select"), + ], + default="default-select", + max_length=20, + verbose_name="control", + ), + ), + ] diff --git a/admin_interface/migrations/0026_theme_list_filter_highlight.py b/admin_interface/migrations/0026_theme_list_filter_highlight.py new file mode 100644 index 0000000..4010e22 --- /dev/null +++ b/admin_interface/migrations/0026_theme_list_filter_highlight.py @@ -0,0 +1,18 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("admin_interface", "0025_theme_language_chooser_control"), + ] + + operations = [ + migrations.AddField( + model_name="theme", + name="list_filter_highlight", + field=models.BooleanField( + default=True, + verbose_name="highlight active", + ), + ), + ] diff --git a/admin_interface/migrations/0027_theme_list_filter_removal_links.py b/admin_interface/migrations/0027_theme_list_filter_removal_links.py new file mode 100644 index 0000000..7366eab --- /dev/null +++ b/admin_interface/migrations/0027_theme_list_filter_removal_links.py @@ -0,0 +1,18 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("admin_interface", "0026_theme_list_filter_highlight"), + ] + + operations = [ + migrations.AddField( + model_name="theme", + name="list_filter_removal_links", + field=models.BooleanField( + default=False, + verbose_name="quick remove links for active filters at top of sidebar", + ), + ), + ] diff --git a/admin_interface/migrations/0028_theme_show_fieldsets_as_tabs_and_more.py b/admin_interface/migrations/0028_theme_show_fieldsets_as_tabs_and_more.py new file mode 100644 index 0000000..d331d81 --- /dev/null +++ b/admin_interface/migrations/0028_theme_show_fieldsets_as_tabs_and_more.py @@ -0,0 +1,26 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("admin_interface", "0027_theme_list_filter_removal_links"), + ] + + operations = [ + migrations.AddField( + model_name="theme", + name="show_fieldsets_as_tabs", + field=models.BooleanField( + default=False, + verbose_name="fieldsets as tabs", + ), + ), + migrations.AddField( + model_name="theme", + name="show_inlines_as_tabs", + field=models.BooleanField( + default=False, + verbose_name="inlines as tabs", + ), + ), + ] diff --git a/admin_interface/migrations/0029_theme_css_generic_link_active_color.py b/admin_interface/migrations/0029_theme_css_generic_link_active_color.py new file mode 100644 index 0000000..cb48728 --- /dev/null +++ b/admin_interface/migrations/0029_theme_css_generic_link_active_color.py @@ -0,0 +1,24 @@ +import colorfield.fields +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("admin_interface", "0028_theme_show_fieldsets_as_tabs_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="theme", + name="css_generic_link_active_color", + field=colorfield.fields.ColorField( + blank=True, + default="#29B864", + help_text="#29B864", + image_field=None, + max_length=10, + samples=None, + verbose_name="link active color", + ), + ), + ] diff --git a/admin_interface/migrations/0030_theme_collapsible_stacked_inlines_and_more.py b/admin_interface/migrations/0030_theme_collapsible_stacked_inlines_and_more.py new file mode 100644 index 0000000..5b77ee7 --- /dev/null +++ b/admin_interface/migrations/0030_theme_collapsible_stacked_inlines_and_more.py @@ -0,0 +1,42 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("admin_interface", "0029_theme_css_generic_link_active_color"), + ] + + operations = [ + migrations.AddField( + model_name="theme", + name="collapsible_stacked_inlines", + field=models.BooleanField( + default=False, + verbose_name="collapsible stacked inlines", + ), + ), + migrations.AddField( + model_name="theme", + name="collapsible_stacked_inlines_collapsed", + field=models.BooleanField( + default=True, + verbose_name="collapsible stacked inlines collapsed", + ), + ), + migrations.AddField( + model_name="theme", + name="collapsible_tabular_inlines", + field=models.BooleanField( + default=False, + verbose_name="collapsible tabular inlines", + ), + ), + migrations.AddField( + model_name="theme", + name="collapsible_tabular_inlines_collapsed", + field=models.BooleanField( + default=True, + verbose_name="collapsible tabular inlines collapsed", + ), + ), + ] diff --git a/admin_interface/migrations/0025_add_demo_option.py b/admin_interface/migrations/0031_add_demo_option.py similarity index 87% rename from admin_interface/migrations/0025_add_demo_option.py rename to admin_interface/migrations/0031_add_demo_option.py index 6f2c3f1..c73feda 100644 --- a/admin_interface/migrations/0025_add_demo_option.py +++ b/admin_interface/migrations/0031_add_demo_option.py @@ -8,7 +8,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ("admin_interface", "0024_remove_theme_css"), + ("admin_interface", "0030_theme_default"), ] operations = [ diff --git a/admin_interface/migrations/0026_add_user_option.py b/admin_interface/migrations/0032_add_user_option.py similarity index 89% rename from admin_interface/migrations/0026_add_user_option.py rename to admin_interface/migrations/0032_add_user_option.py index b81a0b3..1c6d9f8 100644 --- a/admin_interface/migrations/0026_add_user_option.py +++ b/admin_interface/migrations/0032_add_user_option.py @@ -8,7 +8,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ("admin_interface", "0025_add_demo_option"), + ("admin_interface", "0031_add_demo_option"), ] operations = [ diff --git a/admin_interface/migrations/0027_usertheme_m2m.py b/admin_interface/migrations/0033_usertheme_m2m.py similarity index 95% rename from admin_interface/migrations/0027_usertheme_m2m.py rename to admin_interface/migrations/0033_usertheme_m2m.py index 4d79017..ae73fbd 100644 --- a/admin_interface/migrations/0027_usertheme_m2m.py +++ b/admin_interface/migrations/0033_usertheme_m2m.py @@ -9,7 +9,7 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('admin_interface', '0026_add_user_option'), + ('admin_interface', '0032_add_user_option'), ] operations = [ diff --git a/admin_interface/migrations/0028_alter_theme_demo.py b/admin_interface/migrations/0034_alter_theme_demo.py similarity index 87% rename from admin_interface/migrations/0028_alter_theme_demo.py rename to admin_interface/migrations/0034_alter_theme_demo.py index 46c444c..357ee0c 100644 --- a/admin_interface/migrations/0028_alter_theme_demo.py +++ b/admin_interface/migrations/0034_alter_theme_demo.py @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin_interface', '0027_usertheme_m2m'), + ('admin_interface', '0033_usertheme_m2m'), ] operations = [ diff --git a/admin_interface/migrations/0029_auto_20221025_1559.py b/admin_interface/migrations/0035_auto_20221025_1559.py similarity index 94% rename from admin_interface/migrations/0029_auto_20221025_1559.py rename to admin_interface/migrations/0035_auto_20221025_1559.py index 2b0405e..80a6a7f 100644 --- a/admin_interface/migrations/0029_auto_20221025_1559.py +++ b/admin_interface/migrations/0035_auto_20221025_1559.py @@ -19,7 +19,7 @@ def reverse(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('admin_interface', '0028_alter_theme_demo'), + ('admin_interface', '0034_alter_theme_demo'), ] operations = [ diff --git a/admin_interface/migrations/0030_theme_default.py b/admin_interface/migrations/0036_theme_default.py similarity index 86% rename from admin_interface/migrations/0030_theme_default.py rename to admin_interface/migrations/0036_theme_default.py index cc96ed0..558f5bf 100644 --- a/admin_interface/migrations/0030_theme_default.py +++ b/admin_interface/migrations/0036_theme_default.py @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin_interface', '0029_auto_20221025_1559'), + ('admin_interface', '0035_auto_20221025_1559'), ] operations = [ diff --git a/admin_interface/models.py b/admin_interface/models.py index f927abf..8e2e93f 100644 --- a/admin_interface/models.py +++ b/admin_interface/models.py @@ -1,20 +1,16 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import inspect from colorfield.fields import ColorField +from django.core.validators import FileExtensionValidator from django.db import models from django.db.models.signals import post_delete, post_save, pre_save -from six import python_2_unicode_compatible +from django.dispatch import receiver +from django.utils.encoding import force_str +from django.utils.translation import gettext_lazy as _ -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 _ +from .cache import del_cached_active_theme -@python_2_unicode_compatible class UserTheme(models.Model): class Meta: verbose_name = 'Users theme' @@ -25,49 +21,19 @@ class UserTheme(models.Model): theme = models.ForeignKey('Theme', on_delete=models.CASCADE) -@python_2_unicode_compatible -class Theme(models.Model): - @staticmethod - def post_migrate_handler(**kwargs): - del_cached_active_theme() - Theme.get_active_theme() - - @staticmethod - def post_delete_handler(**kwargs): - del_cached_active_theme() - Theme.get_active_theme() - - # @staticmethod - # def post_save_handler(instance, **kwargs): - # del_cached_active_theme() - # if instance.active: - # Theme.objects.exclude(pk=instance.pk).update(active=False) - # Theme.get_active_theme() - - # @staticmethod - # def pre_save_handler(instance, **kwargs): - # if instance.pk is None: - # try: - # obj = Theme.objects.get(name=instance.name) - # if obj: - # instance.pk = obj.pk - # except Theme.DoesNotExist: - # pass - - @staticmethod - def get_active_theme(): - objs_manager = Theme.objects +class ThemeQuerySet(models.QuerySet): + def get_active(self): user_theme_manager = UserTheme.objects - objs_active_qs = objs_manager.filter(active=True) + objs_active_qs = self.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.all().first() + obj = self.all().first() if obj: obj.set_active() # else: - # obj = objs_manager.create() + # obj = self.create() elif objs_active_count == 1: obj = objs_active_ls[0] @@ -94,13 +60,21 @@ class Theme(models.Model): return obj + +class Theme(models.Model): name = models.CharField( - unique=True, max_length=50, default="Django", verbose_name=_("name") + unique=True, + max_length=50, + default="Django", + verbose_name=_("name"), + ) + 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")) - + default = models.BooleanField(default=False, verbose_name="default") users = models.ManyToManyField('auth.User', through=UserTheme) @@ -119,7 +93,9 @@ class Theme(models.Model): verbose_name=_("color"), ) title_visible = models.BooleanField( - default=True, verbose_name=_("visible")) + default=True, + verbose_name=_("visible"), + ) logo = models.FileField( upload_to="admin-interface/logo/", @@ -140,12 +116,19 @@ class Theme(models.Model): verbose_name=_("color"), ) logo_max_width = models.PositiveSmallIntegerField( - blank=True, default=400, verbose_name=_("max width") + blank=True, + default=400, + verbose_name=_("max width"), ) logo_max_height = models.PositiveSmallIntegerField( - blank=True, default=100, verbose_name=_("max height") + blank=True, + default=100, + verbose_name=_("max height"), + ) + logo_visible = models.BooleanField( + default=True, + verbose_name=_("visible"), ) - logo_visible = models.BooleanField(default=True, verbose_name=_("visible")) favicon = models.FileField( upload_to="admin-interface/favicon/", @@ -160,35 +143,46 @@ class Theme(models.Model): ) env_name = models.CharField( - blank=True, max_length=50, verbose_name=_("name")) + blank=True, + max_length=50, + verbose_name=_("name"), + ) env_color = ColorField( blank=True, default="#E74C3C", help_text=_( - "(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, green: #2ECC71, blue: #3498DB)" + "(red: #E74C3C, orange: #E67E22, yellow: #F1C40F, " + "green: #2ECC71, blue: #3498DB)" ), max_length=10, verbose_name=_("color"), ) env_visible_in_header = models.BooleanField( - default=True, verbose_name=_("visible in header (marker and name)") + default=True, + verbose_name=_("visible in header (marker and name)"), ) env_visible_in_favicon = models.BooleanField( - default=True, verbose_name=_("visible in favicon (marker)") + default=True, + verbose_name=_("visible in favicon (marker)"), ) language_chooser_active = models.BooleanField( - default=True, verbose_name=_("active") + default=True, + verbose_name=_("active"), + ) + language_chooser_control_choices = ( + ("default-select", _("Default Select")), + ("minimal-select", _("Minimal Select")), + ) + language_chooser_control = models.CharField( + max_length=20, + choices=language_chooser_control_choices, + default="default-select", + verbose_name=_("control"), ) language_chooser_display_choices = ( - ( - "code", - _("code"), - ), - ( - "name", - _("name"), - ), + ("code", _("code")), + ("name", _("name")), ) language_chooser_display = models.CharField( max_length=10, @@ -269,7 +263,8 @@ class Theme(models.Model): verbose_name=_("link hover color"), ) css_module_rounded_corners = models.BooleanField( - default=True, verbose_name=_("rounded corners") + default=True, + verbose_name=_("rounded corners"), ) css_generic_link_color = ColorField( @@ -286,6 +281,13 @@ class Theme(models.Model): max_length=10, verbose_name=_("link hover color"), ) + css_generic_link_active_color = ColorField( + blank=True, + default="#29B864", + help_text="#29B864", + max_length=10, + verbose_name=_("link active color"), + ) css_save_button_background_color = ColorField( blank=True, @@ -332,7 +334,9 @@ class Theme(models.Model): ) related_modal_active = models.BooleanField( - default=True, verbose_name=_("active")) + default=True, + verbose_name=_("active"), + ) related_modal_background_color = ColorField( blank=True, default="#000000", @@ -341,42 +345,15 @@ class Theme(models.Model): verbose_name=_("background color"), ) related_modal_background_opacity_choices = ( - ( - "0.1", - "10%", - ), - ( - "0.2", - "20%", - ), - ( - "0.3", - "30%", - ), - ( - "0.4", - "40%", - ), - ( - "0.5", - "50%", - ), - ( - "0.6", - "60%", - ), - ( - "0.7", - "70%", - ), - ( - "0.8", - "80%", - ), - ( - "0.9", - "90%", - ), + ("0.1", "10%"), + ("0.2", "20%"), + ("0.3", "30%"), + ("0.4", "40%"), + ("0.5", "50%"), + ("0.6", "60%"), + ("0.7", "70%"), + ("0.8", "80%"), + ("0.9", "90%"), ) related_modal_background_opacity = models.CharField( max_length=5, @@ -386,33 +363,79 @@ class Theme(models.Model): verbose_name=_("background opacity"), ) related_modal_rounded_corners = models.BooleanField( - default=True, verbose_name=_("rounded corners") + default=True, + verbose_name=_("rounded corners"), ) related_modal_close_button_visible = models.BooleanField( - default=True, verbose_name=_("close button visible") + default=True, + verbose_name=_("close button visible"), ) + list_filter_highlight = models.BooleanField( + default=True, + verbose_name=_("highlight active"), + ) list_filter_dropdown = models.BooleanField( - default=True, verbose_name=_("use dropdown") + default=True, + verbose_name=_("use dropdown"), ) list_filter_sticky = models.BooleanField( - default=True, verbose_name=_("sticky position") + default=True, + verbose_name=_("sticky position"), + ) + list_filter_removal_links = models.BooleanField( + default=False, + verbose_name=_("quick remove links for active filters at top of sidebar"), ) foldable_apps = models.BooleanField( - default=True, verbose_name=_("foldable apps")) + default=True, + verbose_name=_("foldable apps"), + ) + + show_fieldsets_as_tabs = models.BooleanField( + default=False, + verbose_name=_("fieldsets as tabs"), + ) + + show_inlines_as_tabs = models.BooleanField( + default=False, + verbose_name=_("inlines as tabs"), + ) + + collapsible_stacked_inlines = models.BooleanField( + default=False, + verbose_name=_("collapsible stacked inlines"), + ) + collapsible_stacked_inlines_collapsed = models.BooleanField( + default=True, + verbose_name=_("collapsible stacked inlines collapsed"), + ) + collapsible_tabular_inlines = models.BooleanField( + default=False, + verbose_name=_("collapsible tabular inlines"), + ) + collapsible_tabular_inlines_collapsed = models.BooleanField( + default=True, + verbose_name=_("collapsible tabular inlines collapsed"), + ) recent_actions_visible = models.BooleanField( - default=True, verbose_name=_("visible") + default=True, + verbose_name=_("visible"), ) form_submit_sticky = models.BooleanField( - default=False, verbose_name=_("sticky submit") + default=False, + verbose_name=_("sticky submit"), ) form_pagination_sticky = models.BooleanField( - default=False, verbose_name=_("sticky pagination") + default=False, + verbose_name=_("sticky pagination"), ) + objects = ThemeQuerySet.as_manager() + def set_active(self): self.active = True self.save() @@ -428,7 +451,6 @@ class Theme(models.Model): class Meta: app_label = "admin_interface" - verbose_name = _("Theme") verbose_name_plural = _("Themes") @@ -436,6 +458,25 @@ class Theme(models.Model): return force_str(self.name) -post_delete.connect(Theme.post_delete_handler, sender=Theme) -# post_save.connect(Theme.post_save_handler, sender=Theme) -# pre_save.connect(Theme.pre_save_handler, sender=Theme) +@receiver(post_delete, sender=Theme) +def post_delete_handler(sender, instance, **kwargs): + del_cached_active_theme() + Theme.objects.get_active() + + +# @receiver(post_save, sender=Theme) +# def post_save_handler(sender, instance, **kwargs): +# del_cached_active_theme() +# if instance.active: +# Theme.objects.exclude(pk=instance.pk).update(active=False) +# Theme.objects.get_active() + + +# @receiver(pre_save, sender=Theme) +# def pre_save_handler(sender, instance, **kwargs): +# if instance.pk is None: +# try: +# obj = Theme.objects.get(name=instance.name) +# instance.pk = obj.pk +# except Theme.DoesNotExist: +# pass diff --git a/admin_interface/settings.py b/admin_interface/settings.py index 340b809..f63f139 100644 --- a/admin_interface/settings.py +++ b/admin_interface/settings.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import django from django.conf import settings from django.core.exceptions import ImproperlyConfigured @@ -29,5 +27,3 @@ def check_installed_app(app, max_dj_version=None): def check_installed_apps(): check_installed_app("colorfield") - check_installed_app("flat", max_dj_version=(1, 9)) - check_installed_app("flat_responsive", max_dj_version=(2, 0)) diff --git a/admin_interface/static/admin/js/collapse.js b/admin_interface/static/admin/js/collapse.js new file mode 100644 index 0000000..efe0b1b --- /dev/null +++ b/admin_interface/static/admin/js/collapse.js @@ -0,0 +1,49 @@ +/*global gettext*/ +/* copied from django 4.0.7 */ +'use strict'; +{ + window.addEventListener('load', function() { + // Add anchor tag for Show/Hide link + const fieldsets = document.querySelectorAll('fieldset.collapse'); + for (const [i, elem] of fieldsets.entries()) { + // Don't hide if fields in this fieldset have errors + if (elem.querySelectorAll('div.errors, ul.errorlist').length === 0) { + const h2 = elem.querySelector('h2'); + const link = document.createElement('a'); + link.id = 'fieldsetcollapser' + i; + link.className = 'collapse-toggle'; + link.href = '#'; + // changed: can opt into starting visible + if (elem.classList.contains('expanded')) { + link.textContent = gettext('Hide'); + } else { + link.textContent = gettext('Show'); + elem.classList.add('collapsed'); + } + h2.appendChild(document.createTextNode(' (')); + h2.appendChild(link); + h2.appendChild(document.createTextNode(')')); + } + } + // Add toggle to hide/show anchor tag + const toggleFunc = function(ev) { + if (ev.target.matches('.collapse-toggle')) { + ev.preventDefault(); + ev.stopPropagation(); + const fieldset = ev.target.closest('fieldset'); + if (fieldset.classList.contains('collapsed')) { + // Show + ev.target.textContent = gettext('Hide'); + fieldset.classList.remove('collapsed'); + } else { + // Hide + ev.target.textContent = gettext('Show'); + fieldset.classList.add('collapsed'); + } + } + }; + document.querySelectorAll('fieldset.module').forEach(function(el) { + el.addEventListener('click', toggleFunc); + }); + }); +} diff --git a/admin_interface/static/admin/js/popup_response.js b/admin_interface/static/admin/js/popup_response.js index d184b50..dc24ef2 100644 --- a/admin_interface/static/admin/js/popup_response.js +++ b/admin_interface/static/admin/js/popup_response.js @@ -3,6 +3,7 @@ 'use strict'; var windowRef = window; + var windowRefProxy; var windowName, widgetName; var openerRef = windowRef.opener; if (!openerRef) { @@ -14,13 +15,14 @@ // django < 3.1 compatibility widgetName = openerRef.id_to_windowname(widgetName); } - windowRef = { + windowRefProxy = { name: widgetName, location: windowRef.location, close: function() { openerRef.dismissRelatedObjectModal(); } }; + windowRef = windowRefProxy; } // default django popup_response.js @@ -40,11 +42,7 @@ if (typeof(openerRef.dismissAddRelatedObjectPopup) === 'function') { openerRef.dismissAddRelatedObjectPopup(windowRef, initData.value, initData.obj); } - else if (typeof(openerRef.dismissAddAnotherPopup) === 'function') { - // django 1.7 compatibility - openerRef.dismissAddAnotherPopup(windowRef, initData.value, initData.obj); - } break; } -})(); \ No newline at end of file +})(); diff --git a/admin_interface/static/admin_interface/collapsible-inlines/collapsible-inlines.js b/admin_interface/static/admin_interface/collapsible-inlines/collapsible-inlines.js new file mode 100644 index 0000000..60c4d48 --- /dev/null +++ b/admin_interface/static/admin_interface/collapsible-inlines/collapsible-inlines.js @@ -0,0 +1,48 @@ +/** global: django */ + +if (typeof(django) !== 'undefined' && typeof(django.jQuery) !== 'undefined') +{ + (function($) { + + $(document).ready(function(){ + + function collapsibleInline(scope, collapsed) { + var fieldsetCollapsed = collapsed; + var fieldsetEl = $(scope).find('> fieldset.module'); + fieldsetEl.addClass('collapse'); + var fieldsetHasErrors = (fieldsetEl.children('.errors').length > 0); + if (fieldsetHasErrors === true) { + fieldsetCollapsed = false; + } + if (fieldsetCollapsed === true) { + fieldsetEl.addClass('collapsed'); + } + var collapseToggleText = (fieldsetCollapsed ? gettext('Show') : gettext('Hide')); + var collapseToggleHTML = ' (' + collapseToggleText + ')'; + var headerEl = fieldsetEl.find('> h2,> h3'); + if (headerEl.find(".collapse-toggle").length === 0) { + // don't add collapse toggle button if already present + headerEl.append(collapseToggleHTML); + } + } + + var stackedInlinesOptionSel = '.admin-interface.collapsible-stacked-inlines'; + var stackedInlinesSel = stackedInlinesOptionSel + ' .inline-group[data-inline-type="stacked"]'; + var stackedInlinesCollapsed = $(stackedInlinesOptionSel).hasClass('collapsible-stacked-inlines-collapsed'); + + var tabularInlinesOptionSel = '.admin-interface.collapsible-tabular-inlines'; + var tabularInlinesSel = tabularInlinesOptionSel + ' .inline-group[data-inline-type="tabular"] .inline-related.tabular'; + var tabularInlinesCollapsed = $(stackedInlinesOptionSel).hasClass('collapsible-tabular-inlines-collapsed'); + + $(stackedInlinesSel).each(function() { + collapsibleInline(this, stackedInlinesCollapsed); + }); + + $(tabularInlinesSel).each(function() { + collapsibleInline(this, tabularInlinesCollapsed); + }); + + }); + + })(django.jQuery); +} diff --git a/admin_interface/static/admin_interface/css/admin-interface.css b/admin_interface/static/admin_interface/css/admin-interface.css new file mode 100644 index 0000000..268c1af --- /dev/null +++ b/admin_interface/static/admin_interface/css/admin-interface.css @@ -0,0 +1,515 @@ +@media (prefers-color-scheme: dark) { + :root .admin-interface { + --primary: #79aec8; + --secondary: #417690; + --accent: #f5dd5d; + --primary-fg: #fff; + --body-fg: #333; + --body-bg: #fff; + --body-quiet-color: #666; + --body-loud-color: #000; + --header-color: #ffc; + --header-branding-color: var(--accent); + --header-bg: var(--secondary); + --header-link-color: var(--primary-fg); + --breadcrumbs-fg: #c4dce8; + --breadcrumbs-link-fg: var(--body-bg); + --breadcrumbs-bg: var(--primary); + --link-fg: #447e9b; + --link-hover-color: #036; + --link-selected-fg: #5b80b2; + --hairline-color: #e8e8e8; + --border-color: #ccc; + --error-fg: #ba2121; + --message-success-bg: #dfd; + --message-warning-bg: #ffc; + --message-error-bg: #ffefef; + --darkened-bg: #f8f8f8; + --selected-bg: #e4e4e4; + --selected-row: #ffc; + --button-fg: #fff; + --button-bg: var(--primary); + --button-hover-bg: #609ab6; + --default-button-bg: var(--secondary); + --default-button-hover-bg: #205067; + --close-button-bg: #888; + --close-button-hover-bg: #747474; + --delete-button-bg: #ba2121; + --delete-button-hover-bg: #a41515; + --object-tools-fg: var(--button-fg); + --object-tools-bg: var(--close-button-bg); + --object-tools-hover-bg: var(--close-button-hover-bg); + } +} + +.admin-interface { + overflow-x: hidden; +} + +.admin-interface #header { + background: var(--admin-interface-header-background-color); + color: var(--admin-interface-header-text-color); +} + +.admin-interface #header + #main { + border-top: var(--admin-interface-main-border-top); +} + +.admin-interface .environment-label { +} + +.admin-interface .environment-label::before { + content: ""; + display: inline-block; + width: 8px; + height: 8px; + background-color: var(--admin-interface-env-color); + border-radius: 100%; + margin-right: 6px; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; +} + +.admin-interface .environment-label::after { + content: " - "; +} + +@media (max-width: 1024px) { + .admin-interface .environment-label::after { + content: ""; + } +} + +.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; +} + +.admin-interface #branding h1, +.admin-interface.login #header h1, +.admin-interface.login #header h1 a { + color: var(--admin-interface-title-color); +} + +.admin-interface #branding h1 a { + color: inherit; +} + +.admin-interface #branding h1 .logo.default { + background-color: transparent; + background-repeat: no-repeat; + background-position: center center; + background-size: 104px 36px; + background-image: var(--admin-interface-logo-default-background-image); +} + +.admin-interface #branding h1 img.logo, +.admin-interface.login #header #branding h1 img.logo { + max-width: var(--admin-interface-logo-max-width); + max-height: var(--admin-interface-logo-max-height); +} + +.admin-interface #header #user-tools a, +.admin-interface #header #user-tools #logout-form button { + color: var(--admin-interface-header-link-color); +} + +.admin-interface #header #user-tools a:hover, +.admin-interface #header #user-tools a:active, +.admin-interface #header #user-tools #logout-form button:hover, +.admin-interface #header #user-tools #logout-form button:active { + color: var(--admin-interface-header-link-hover-color); + border-bottom-color: rgba(255, 255, 255, 0.5); +} + +.admin-interface #header #user-tools button.theme-toggle svg { + color: transparent; + fill: var(--admin-interface-header-link-color); +} + +.admin-interface #header #user-tools button.theme-toggle:hover svg, +.admin-interface #header #user-tools button.theme-toggle:active svg { + color: transparent; + fill: var(--admin-interface-header-link-hover-color); +} + +.admin-interface #nav-sidebar .current-app .section:link, +.admin-interface #nav-sidebar .current-app .section:visited { + color: var(--admin-interface-module-link-selected-color); + font-weight: normal; +} + +.admin-interface #nav-sidebar .current-app .section:focus, +.admin-interface #nav-sidebar .current-app .section:hover { + color: var(--admin-interface-module-link-hover-color); +} + +.admin-interface #nav-sidebar .current-model { + background: var(--admin-interface-module-background-selected-color); +} + +.admin-interface #changelist table tbody tr.selected { + background-color: var(--admin-interface-module-background-selected-color); +} + +.admin-interface .module h2, +.admin-interface .module caption, +.admin-interface .module.filtered h2 { + background: var(--admin-interface-module-background-color); + color: var(--admin-interface-module-text-color); +} + +.admin-interface .module a.section:link, +.admin-interface .module a.section:visited { + color: var(--admin-interface-module-link-color); +} + +.admin-interface .module a.section:active, +.admin-interface .module a.section:hover { + color: var(--admin-interface-module-link-hover-color); +} + +.admin-interface div.breadcrumbs { + background: var(--admin-interface-module-background-color); + color: var(--admin-interface-module-text-color); +} + +.admin-interface div.breadcrumbs a { + color: var(--admin-interface-module-link-color); +} + +.admin-interface div.breadcrumbs a:active, +.admin-interface div.breadcrumbs a:focus, +.admin-interface div.breadcrumbs a:hover { + color: var(--admin-interface-module-link-hover-color); +} + +.admin-interface fieldset.collapse a.collapse-toggle, +.admin-interface fieldset.collapse.collapsed a.collapse-toggle, +.admin-interface .inline-group .inline-related fieldset.module a.collapse-toggle, +.admin-interface .inline-group .inline-related fieldset.module.collapsed a.collapse-toggle { + color: var(--admin-interface-module-link-color); +} + +.admin-interface fieldset.collapse a.collapse-toggle:hover, +.admin-interface fieldset.collapse a.collapse-toggle:active, +.admin-interface fieldset.collapse.collapsed a.collapse-toggle:hover, +.admin-interface fieldset.collapse.collapsed a.collapse-toggle:active, +.admin-interface .inline-group .inline-related fieldset.module a.collapse-toggle:hover, +.admin-interface .inline-group .inline-related fieldset.module a.collapse-toggle:active, +.admin-interface .inline-group .inline-related fieldset.module.collapsed a.collapse-toggle:hover, +.admin-interface .inline-group .inline-related fieldset.module.collapsed a.collapse-toggle:active { + color: var(--admin-interface-module-link-hover-color); +} + +.admin-interface .inline-group h2 { + background: var(--admin-interface-module-background-color); + color: var(--admin-interface-module-text-color); +} + +.admin-interface .selector .selector-chosen h2 { + border-color: var(--admin-interface-module-background-color); + background: var(--admin-interface-module-background-color); + color: var(--admin-interface-module-text-color); +} + +.admin-interface .selector .selector-available h2, +.admin-interface .selector .selector-chosen h2 { + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; +} + +.admin-interface .selector a.selector-chooseall:focus, +.admin-interface .selector a.selector-chooseall:hover, +.admin-interface .selector a.selector-clearall:focus, +.admin-interface .selector a.selector-clearall:hover { + color: var(--admin-interface-generic-link-hover-color); +} + +.admin-interface a:link, +.admin-interface a:visited { + color: var(--admin-interface-generic-link-color); +} + +.admin-interface a:hover { + color: var(--admin-interface-generic-link-hover-color); +} + +.admin-interface thead th a, +.admin-interface thead th a:link, +.admin-interface thead th a:visited, +.admin-interface thead th a:focus, +.admin-interface thead th a:hover { + color: #666666; +} + +.admin-interface .button, +.admin-interface input[type=submit], +.admin-interface input[type=button], +.admin-interface .submit-row input, +.admin-interface a.button { + background: var(--admin-interface-save-button-background-color); + color: var(--admin-interface-save-button-text-color); +} + +.admin-interface .button:active, +.admin-interface .button:focus, +.admin-interface .button:hover, +.admin-interface input[type=submit]:active, +.admin-interface input[type=submit]:focus, +.admin-interface input[type=submit]:hover, +.admin-interface input[type=button]:active, +.admin-interface input[type=button]:focus, +.admin-interface input[type=button]:hover { + background: var(--admin-interface-save-button-background-hover-color); + color: var(--admin-interface-save-button-text-color); + outline: none; +} + +.admin-interface .button.default, +.admin-interface input[type=submit].default, +.admin-interface .submit-row input.default { + background: var(--admin-interface-save-button-background-color); + color: var(--admin-interface-save-button-text-color); + outline: none; +} + +.admin-interface .button.default:active, +.admin-interface .button.default:focus, +.admin-interface .button.default:hover, +.admin-interface input[type=submit].default:active, +.admin-interface input[type=submit].default:focus, +.admin-interface input[type=submit].default:hover, +.admin-interface.delete-confirmation form .cancel-link:hover { + background: var(--admin-interface-save-button-background-hover-color); + color: var(--admin-interface-save-button-text-color); + outline: none; +} + +.admin-interface .submit-row a.deletelink:link, +.admin-interface .submit-row a.deletelink:visited, +.admin-interface.delete-confirmation form input[type="submit"] { + background: var(--admin-interface-delete-button-background-color); + color: var(--admin-interface-delete-button-text-color); +} + +.admin-interface .submit-row a.deletelink:hover, +.admin-interface.delete-confirmation form input[type="submit"]:hover { + background: var(--admin-interface-delete-button-background-hover-color); + color: var(--admin-interface-delete-button-text-color); +} + +.admin-interface .paginator a, +.admin-interface .paginator a:link, +.admin-interface .paginator a:visited, +.admin-interface .paginator .this-page { + border-radius: var(--admin-interface-module-border-radius); +} + +.admin-interface .paginator a, +.admin-interface .paginator a:link, +.admin-interface .paginator a:visited { + background-color: #FFFFFF; + color: var(--admin-interface-generic-link-color); +} + +.admin-interface .paginator a:hover, +.admin-interface .paginator a:active { + background-color: #F8F8F8; + color: var(--admin-interface-generic-link-hover-color); +} + +.admin-interface .paginator .this-page { + background-color: var(--admin-interface-module-background-color); + color: var(--admin-interface-module-link-color); +} + +.admin-interface .paginator a.showall, +.admin-interface .paginator a.showall:link, +.admin-interface .paginator a.showall:visited { + color: var(--admin-interface-generic-link-color); +} + +.admin-interface .paginator a.showall:hover, +.admin-interface .paginator a.showall:active { + color: var(--admin-interface-generic-link-hover-color); +} + +/* list-filter sticky */ +@media (min-width: 768px) { + .admin-interface.list-filter-sticky .module.filtered #changelist-filter { + position: sticky; + top: 30px; + float: right; + z-index: 30; + display: flex; + flex-direction: column; + overflow-y: auto; + scrollbar-width: thin; + 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 */ + .admin-interface.list-filter-sticky .module.filtered #toolbar + #changelist-filter { + position: absolute; + top: 0px; + 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); + } +} + +.admin-interface .module.filtered #changelist-filter { + border-radius: var(--admin-interface-module-border-radius); +} + +.admin-interface .module.filtered #changelist-filter h3#changelist-filter-clear { + margin-bottom: 0; +} + +.admin-interface .module.filtered #changelist-filter .changelist-filter-clear a { + font-size: 13px; + margin: .3em 0; + padding: 0 15px; +} + +.admin-interface .module.filtered #changelist-filter .changelist-filter-clear a:focus, +.admin-interface .module.filtered #changelist-filter .changelist-filter-clear a:hover, +.admin-interface .module.filtered #changelist-filter #changelist-filter-clear a:focus, +.admin-interface .module.filtered #changelist-filter #changelist-filter-clear a:hover { + color: #666; + text-decoration: none; +} + +.admin-interface .module.filtered #changelist-filter .changelist-filter-clear a span { + font-weight: bold; +} + +.admin-interface .module.filtered #changelist-filter li a:focus, +.admin-interface .module.filtered #changelist-filter li a:hover { + color: #666; + text-decoration: none; +} + +.admin-interface.list-filter-highlight .module.filtered #changelist-filter h3.active { + font-weight: bold; +} + +.admin-interface.list-filter-highlight .module.filtered #changelist-filter ul.active li.selected { + color: var(--admin-interface-module-text-color); + background: var(--admin-interface-module-background-color); + margin-left: -10px; + padding-left: 5px; + margin-right: -10px; + border-left: 5px solid var(--admin-interface-module-background-color); + border-right: 5px solid var(--admin-interface-module-background-color); + border-radius: var(--admin-interface-module-border-radius); +} + +.admin-interface.list-filter-highlight .module.filtered #changelist-filter ul.active li.selected a, +.admin-interface.list-filter-highlight .module.filtered #changelist-filter ul.active li.selected a:link, +.admin-interface.list-filter-highlight .module.filtered #changelist-filter ul.active li.selected a:visited, +.admin-interface.list-filter-highlight .module.filtered #changelist-filter ul.active li.selected a:focus, +.admin-interface.list-filter-highlight .module.filtered #changelist-filter ul.active li.selected a:hover { + background: inherit; + color: inherit; +} + +.admin-interface .module.filtered #changelist-filter li.selected a, +.admin-interface .module.filtered #changelist-filter li.selected a:link, +.admin-interface .module.filtered #changelist-filter li.selected a:visited, +.admin-interface .module.filtered #changelist-filter li.selected a:focus, +.admin-interface .module.filtered #changelist-filter li.selected a:hover { + color: var(--admin-interface-generic-link-hover-color); +} + +/* begin fix issue #11 - Inline border bottom should not be rounded */ +.admin-interface .module h2, +.admin-interface.dashboard .module caption, +.admin-interface #nav-sidebar .module th, +.admin-interface #nav-sidebar .module caption, +.admin-interface .module.filtered h2 { + border-radius: var(--admin-interface-module-border-radius); +} + +.admin-interface .inline-group h2 { + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; +} + +.admin-interface .module.collapse.collapsed h2 { + /* fix collapsed inlines rounded bottom borders */ + border-bottom-left-radius: var(--admin-interface-module-border-radius); + border-bottom-right-radius: var(--admin-interface-module-border-radius); +} + +/* end fix */ + +.admin-interface #content-related { + border-radius: var(--admin-interface-module-border-radius); +} + +.admin-interface .select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] { + background-color: var(--admin-interface-module-background-color); + color: var(--admin-interface-module-text-color); +} + +.admin-interface #toggle-nav-sidebar { + border-top-right-radius: var(--admin-interface-module-border-radius); + border-bottom-right-radius: var(--admin-interface-module-border-radius); + color: var(--admin-interface-generic-link-color); +} + +.admin-interface #toggle-nav-sidebar:focus, +.admin-interface #toggle-nav-sidebar:hover, +.admin-interface #toggle-nav-sidebar:active { + color: var(--admin-interface-generic-link-hover-color); +} + +.admin-interface .calendar td.selected a, +.admin-interface .calendar td a:active, +.admin-interface .calendar td a:focus, +.admin-interface .calendar td a:hover, +.admin-interface .timelist a:active, +.admin-interface .timelist a:focus, +.admin-interface .timelist a:hover { + background: var(--admin-interface-module-background-color); +} + +.admin-interface .calendarbox .calendarnav-previous, +.admin-interface .calendarbox .calendarnav-next { + transition: none; + filter: invert(100%); +} diff --git a/admin_interface/static/admin_interface/css/change-form.css b/admin_interface/static/admin_interface/css/change-form.css new file mode 100644 index 0000000..362ccc5 --- /dev/null +++ b/admin_interface/static/admin_interface/css/change-form.css @@ -0,0 +1,34 @@ +/* fix form submit buttons alignemnt and ordering */ +@media (min-width: 768px) { + .admin-interface .submit-row { + flex-direction: row-reverse; + } + .admin-interface .submit-row input[name="_save"] { + order: 1; + } + .admin-interface .submit-row input[name="_continue"] { + order: 2; + } + .admin-interface .submit-row input[name="_addanother"] { + order: 3; + } + .admin-interface .submit-row a.deletelink { + order: 4; + margin-left: 0; + margin-right: auto; + } +} +/* endfix */ + +/* fix help-text horizontal alignment when using show-fieldsets-as-tabs / show-inlines-as-tabs options - #317 */ +.admin-interface.show-fieldsets-as-tabs fieldset > .form-row .help, +.admin-interface.show-inlines-as-tabs .inline-related > fieldset .help { + margin-left: 0; + padding-left: 0; +} +.admin-interface.show-fieldsets-as-tabs fieldset > .form-row div:has(.related-widget-wrapper .selector) + .help, +.admin-interface.show-inlines-as-tabs .inline-related > fieldset div:has(.related-widget-wrapper .selector) + .help { + display: flex; + width: 100%; +} +/* endfix */ diff --git a/admin_interface/static/admin_interface/css/changelist.css b/admin_interface/static/admin_interface/css/changelist.css new file mode 100644 index 0000000..3c1cbcd --- /dev/null +++ b/admin_interface/static/admin_interface/css/changelist.css @@ -0,0 +1,43 @@ +@media (min-width: 1024px) { + .admin-interface #changelist .actions .button, + .admin-interface #changelist .actions .action-counter { + margin-left: 8px; + } +} + +.admin-interface #changelist-form .results { + scrollbar-width: thin; +} + +/* fix searchbar overriden padding */ +.admin-interface #changelist #changelist-search #searchbar { + padding: 2px 5px 3px 5px; +} + +@media (min-width: 1024px) { + .admin-interface #changelist #changelist-search #searchbar, + .admin-interface #changelist #changelist-search input[type="submit"], + .admin-interface #changelist #changelist-search .quiet { + margin-left: 8px; + } + .admin-interface #changelist #changelist-search label img { + vertical-align: text-top; + margin-right: 0px; + } +} + +@media (max-width: 1024px) { + .admin-interface #changelist #toolbar { + border-top: 1px solid #eee; + border-bottom: 1px solid #eee; + } + /* fixed changelist search size when there are search results and .quiet is visible */ + .admin-interface #changelist-search label img { + margin-top: 2px; + } + .admin-interface #changelist-search .quiet { + margin: 0 0 0 10px; + align-self: center; + flex-basis: content; + } +} diff --git a/admin_interface/static/admin_interface/css/fieldsets.css b/admin_interface/static/admin_interface/css/fieldsets.css new file mode 100644 index 0000000..dc7fabe --- /dev/null +++ b/admin_interface/static/admin_interface/css/fieldsets.css @@ -0,0 +1,14 @@ +.admin-interface fieldset.collapse { + border: 1px solid transparent; +} + +.admin-interface fieldset.collapse.collapsed a.collapse-toggle, +.admin-interface fieldset.collapse a.collapse-toggle, +.admin-interface .inline-group .inline-related fieldset.module a.collapse-toggle, +.admin-interface .inline-group .inline-related fieldset.module.collapsed a.collapse-toggle { + font-weight: normal; + text-transform: lowercase; + font-size: 12px; + text-decoration: underline; + padding: 0 1px; +} diff --git a/admin_interface/static/admin_interface/css/file-upload.css b/admin_interface/static/admin_interface/css/file-upload.css new file mode 100644 index 0000000..8aec5fc --- /dev/null +++ b/admin_interface/static/admin_interface/css/file-upload.css @@ -0,0 +1,52 @@ +.admin-interface .file-thumbnail > a { + display: inline-block; +} + +.admin-interface .aligned p.file-upload { + display: table; + margin-left: 0; +} + +.admin-interface form .form-row p.file-upload > a { + margin-right: 20px; +} + +.admin-interface form .form-row p.file-upload .clearable-file-input { + display: inline-block; +} + +.admin-interface form .form-row p.file-upload .clearable-file-input label { + padding-bottom: 0px; + margin-left: 5px; +} + +.admin-interface form .form-row p.file-upload > input[type="file"] { + margin-top: 0px; +} + +@media (max-width:767px){ + + .admin-interface form .form-row p.file-upload { + width: 100%; + } + + .admin-interface form .form-row p.file-upload > a { + margin-right: 0px; + display: block; + white-space: pre-wrap; + word-break: break-word; + } + + .admin-interface form .form-row p.file-upload .clearable-file-input { + display: block; + margin-top: 10px; + margin-left: 0; + margin-bottom: -10px; + } + + .admin-interface form .form-row p.file-upload > input[type="file"] { + display: block; + width: auto; + padding: 0px; + } +} diff --git a/admin_interface/static/admin_interface/css/header.css b/admin_interface/static/admin_interface/css/header.css new file mode 100644 index 0000000..4d9e3a9 --- /dev/null +++ b/admin_interface/static/admin_interface/css/header.css @@ -0,0 +1,50 @@ +.admin-interface #header { + height: auto; + box-sizing: border-box; + display: flex; + justify-content: space-between; + align-items: center; +} + +@media (max-width:1024px) { + .admin-interface #header { + align-items: start; + } +} + +.admin-interface #branding h1 img.logo { + margin-top: 10px; + margin-bottom: 10px; + margin-right: 15px; + display: inline-block !important; /* override inline display:none; */ +} + +.admin-interface #branding h1 span { + display: inline-block; +} + +.admin-interface #branding h1 img.logo+span { + white-space: nowrap; +} + +.admin-interface #user-tools { + margin-top: 10px; + margin-bottom: 10px; + white-space: nowrap; + align-self: flex-start; +} + +.admin-interface #user-tools br { + display: none; +} + +@media (max-width: 768px) { + .admin-interface #user-tools br { + display: block; + } +} + +/* hide theme toggle button until dark theme will be supported */ +.admin-interface #user-tools button.theme-toggle { + display: none; +} diff --git a/admin_interface/static/admin_interface/css/inlines.css b/admin_interface/static/admin_interface/css/inlines.css new file mode 100644 index 0000000..1ebc730 --- /dev/null +++ b/admin_interface/static/admin_interface/css/inlines.css @@ -0,0 +1,105 @@ +/* begin fix help text icon on newline */ +.admin-interface .inline-group thead th { + white-space:nowrap; +} + +.admin-interface .inline-group thead th img { + vertical-align: -2px; + margin-left: 5px; +} + +.admin-interface .inline-group .inlinechangelink { + margin-left: 10px; +} + +.admin-interface .inline-group .inline-related.tabular .inlinechangelink { + background-size: contain; +} +/* end fix */ + +/* begin fix restrict tabular-inline horizontal-scroll to inline-group instead of whole page */ +.admin-interface .inline-group[data-inline-type="tabular"] { + overflow-x: auto; +} +/* end fix */ + +/* begin fix stacked-inline margin-bottom in responsive small viewport */ +.admin-interface .inline-group[data-inline-type="stacked"] .module { + margin-bottom: 0px; +} +/* end fix */ + +/* begin fix tabular inlines horizontal scroll */ +.admin-interface .inline-related.tabular { + overflow-x: scroll; + overflow-y: hidden; +} +.admin-interface .inline-related.tabular fieldset.module { + display: contents; + width: 100%; + white-space: nowrap; + position: relative; +} +.admin-interface .inline-related.tabular fieldset.module h2 { + position: sticky; + left: 0; +} +.admin-interface .inline-related.tabular fieldset.module table { + scrollbar-width: thin; +} +.admin-interface .inline-related.tabular fieldset.module table tbody tr { + position: relative; +} +/* end fix */ + +.admin-interface .inline-related h3 { + padding: 6px 10px; +} + +/* begin fix issue #12 - Inlines bad delete buttons alignement */ +.admin-interface .inline-group .tabular thead th:last-child:not([class]):not([style]) { + text-align: right; +} + +.admin-interface .inline-group .tabular tr td { + vertical-align: top; +} + +.admin-interface .inline-group .tabular tr td.delete { + text-align: right; + padding-right: 15px; + vertical-align: top; +} + +.admin-interface .inline-group .tabular tr td input[type="checkbox"] { + margin: 7px 0px; +} + +.admin-interface .inline-group .tabular tr td.delete a.inline-deletelink { + margin-top: 4px; + overflow: hidden; + text-indent: 9999px; +} +/* end fix */ + +/* begin fix remove button at the end od dynamically added inline rows */ +.admin-interface .inline-group .tabular tr td:not(.delete) * + div:has(> a.inline-deletelink) { + display: inline-block; + margin-bottom: -3px; + margin-left: 10px; +} +/* end fix */ + +/* begin fix issue #13 - Datetime widget broken in long inlines */ +.admin-interface .inline-group .inline-related p.datetime { + white-space: nowrap; +} +/* end fix */ + +/* begin fix inline horizontal scroll caused by checkbox-row */ +@media (max-width:767px){ + .admin-interface form .form-row > div.checkbox-row { + width: 100%; + } +} +/* end fix */ diff --git a/admin_interface/templates/admin_interface/css/jquery.ui.tabs.css b/admin_interface/static/admin_interface/css/jquery.ui.tabs.css similarity index 61% rename from admin_interface/templates/admin_interface/css/jquery.ui.tabs.css rename to admin_interface/static/admin_interface/css/jquery.ui.tabs.css index d960db5..dfc2f94 100644 --- a/admin_interface/templates/admin_interface/css/jquery.ui.tabs.css +++ b/admin_interface/static/admin_interface/css/jquery.ui.tabs.css @@ -13,27 +13,127 @@ backward compatibility: /* Layout helpers ----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } -.ui-helper-clearfix { display: inline-block; } +.ui-helper-hidden { + display: none; +} + +.ui-helper-hidden-accessible { + position: absolute; + left: -99999999px; +} + +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; +} + +.ui-helper-clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + +.ui-helper-clearfix { + display: inline-block; +} + /* required comment for clearfix to work in Opera \*/ -* html .ui-helper-clearfix { height:1%; } -.ui-helper-clearfix { display:block; } -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } -.ui-state-disabled { cursor: default !important; } -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } +* html .ui-helper-clearfix { + height: 1%; +} + +.ui-helper-clearfix { + display: block; +} + +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter: Alpha(Opacity=0); +} + +.ui-state-disabled { + cursor: default !important; +} + +.ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; +} + /* http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/base/jquery.ui.tabs.css */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } -.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ -.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-active, .ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } -.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-widget-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.ui-tabs { + position: relative; + padding: .2em; + zoom: 1; +} + +/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: .2em .2em 0; +} + +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 1px; + margin: 0 .2em 1px 0; + border-bottom: 0 !important; + padding: 0; + white-space: nowrap; +} + +.ui-tabs .ui-tabs-nav li a { + float: left; + padding: .5em 1em; + text-decoration: none; +} + +.ui-tabs .ui-tabs-nav li.ui-tabs-active, .ui-tabs .ui-tabs-nav li.ui-tabs-selected { + margin-bottom: 0; + padding-bottom: 1px; +} + +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { + cursor: text; +} + +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { + cursor: pointer; +} + +/* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em 1.4em; + background: none; +} + .ui-tabs .ui-tabs-hide { position: absolute; display: none; @@ -55,12 +155,15 @@ backward compatibility: padding: 10px 0 0 10px; border-bottom: none; } + .admin-interface .ui-tabs .ui-tabs-nav li { margin: 0 0 0 -1px; } + .admin-interface .ui-tabs .ui-tabs-nav li.required { font-weight: bold; } + .admin-interface .ui-tabs .ui-tabs-nav li a { border: 1px solid #eeeeee; background-color: #f8f8f8; @@ -86,7 +189,7 @@ backward compatibility: margin-bottom: -1px; font-weight: bold; background-color: #FFFFFF; - color: {{ theme.css_module_background_color }}; + color: var(--admin-interface-module-background-color); border-bottom: 1px solid #FFFFFF; } @@ -107,7 +210,7 @@ backward compatibility: } .admin-interface .inline-group .tabular tr td { - vertical-align: bottom; + vertical-align: top; } .admin-interface .inline-group .tabular tr.has_original td.original, diff --git a/admin_interface/static/admin_interface/css/language-chooser.css b/admin_interface/static/admin_interface/css/language-chooser.css new file mode 100644 index 0000000..8459b9c --- /dev/null +++ b/admin_interface/static/admin_interface/css/language-chooser.css @@ -0,0 +1,72 @@ +.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; + margin-left: 20px; + } +} + +.admin-interface .language-chooser .language-chooser-hidden-form { + display: none; +} + +.admin-interface .language-chooser .language-chooser-select-form { + display: inline-block; + position: relative; + z-index: 0; +} + +.admin-interface .language-chooser select { + width: auto; + min-width: auto; +} + +.admin-interface .language-chooser.minimal .language-chooser-select-form::after { + content: ""; + position: absolute; + right: 2px; + top: 50%; + border: solid var(--admin-interface-header-text-color); + border-width: 0px 0px 1px 1px; + display: inline-block; + padding: 2px; + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); + pointer-events: none; + margin-top: -4px; +} + +.admin-interface .language-chooser.minimal .language-chooser-select-form:hover select { + border-bottom: 1px solid transparent; + color: var(--admin-interface-header-link-hover-color); +} + +.admin-interface .language-chooser.minimal select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: transparent; + border: none; + border-bottom: 1px solid rgba(255, 255, 255, 0.25); + border-radius: 0; + color: var(--admin-interface-header-link-color); + cursor: pointer; + font-weight: inherit; + font-size: inherit; + height: auto; + margin: 0; + padding: 0 15px 0 0; +} diff --git a/admin_interface/static/admin_interface/css/list-filter-dropdown.css b/admin_interface/static/admin_interface/css/list-filter-dropdown.css new file mode 100644 index 0000000..207b3c7 --- /dev/null +++ b/admin_interface/static/admin_interface/css/list-filter-dropdown.css @@ -0,0 +1,27 @@ +/* +list-filter-dropdown +*/ + +.admin-interface #changelist-filter .list-filter-dropdown { + margin-top: 15px; + margin-bottom: 15px; +} + +.admin-interface #changelist-filter h2 + .list-filter-dropdown, +.admin-interface #changelist-filter .list-filter-dropdown + .list-filter-dropdown { + margin-top: 5px; +} + +.admin-interface #changelist-filter .list-filter-dropdown h3 { + margin-top: 0 !important; +} + +.admin-interface #changelist-filter .list-filter-dropdown select { + background-color: #FFFFFF; + width: calc(100% - 30px); + margin-right: 15px; +} + +.admin-interface.list-filter-highlight #changelist-filter .list-filter-dropdown h3.active + div select { + font-weight: bold; +} diff --git a/admin_interface/static/admin_interface/css/list-filter.css b/admin_interface/static/admin_interface/css/list-filter.css new file mode 100644 index 0000000..113abdb --- /dev/null +++ b/admin_interface/static/admin_interface/css/list-filter.css @@ -0,0 +1,28 @@ +.admin-interface .module.filtered h2 { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +.admin-interface .module.filtered #changelist-filter { + min-width: 240px; +} + +@media (max-width: 1024px) { + .admin-interface .module.filtered #changelist-filter { + min-width: 200px; + } +} + +.admin-interface .module.filtered #changelist-filter h2 { + font-size: 11px; + padding: 10px 15px; +} + +.admin-interface .module.filtered #changelist-filter h2 + h3 { + margin-top: 0px; +} + +.admin-interface .module.filtered #changelist-filter h3 { + margin-top: 12px; + margin-bottom: 12px; +} diff --git a/admin_interface/static/admin_interface/css/login.css b/admin_interface/static/admin_interface/css/login.css new file mode 100644 index 0000000..3114373 --- /dev/null +++ b/admin_interface/static/admin_interface/css/login.css @@ -0,0 +1,65 @@ +.admin-interface.login #container { + width: 100%; + max-width: 360px; + margin: 15px auto; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; +} + +.admin-interface.login #content { + padding: 15px 30px 30px 30px; +} + +@media (min-width:768px){ + .admin-interface.login #container { + margin: 90px auto; + } +} + +.admin-interface.login #header { + min-height: auto; + padding: 10px 30px; + line-height: 30px; + align-items: center; + justify-content: flex-start; +} + +.admin-interface.login #header #branding h1 { + margin-right:0; +} + +.admin-interface.login #header #branding h1 img.logo { + margin-right: 0; +} + +.admin-interface.login #header #branding h1 img.logo+span { + display: block; +} + +.admin-interface.login #login-form { + display: flex; + flex-direction: column; +} + +.admin-interface.login .submit-row { + float: left; + width: 100%; + margin-top: 20px; + padding-top: 0; + padding-left: 0; + text-align: right; +} + +.admin-interface.login .submit-row label { + display: none; +} + +.admin-interface.login .submit-row input[type="submit"] { + width: 100%; + text-transform: uppercase; +} + +.admin-interface.login #footer { + display: none; +} diff --git a/admin_interface/static/admin_interface/css/modules.css b/admin_interface/static/admin_interface/css/modules.css new file mode 100644 index 0000000..6208181 --- /dev/null +++ b/admin_interface/static/admin_interface/css/modules.css @@ -0,0 +1,12 @@ +/* begin fix lateral padding to align text with field labels */ +.admin-interface .module h2, +.admin-interface.dashboard .module caption, +.admin-interface.dashboard .module th, +.admin-interface .module.filtered h2, +.admin-interface .inline-group h2, +.admin-interface #nav-sidebar .module caption, +.admin-interface #nav-sidebar .module th { + padding-left: 10px; + padding-right: 10px; +} +/* end fix */ diff --git a/admin_interface/static/admin_interface/css/nav-sidebar.css b/admin_interface/static/admin_interface/css/nav-sidebar.css new file mode 100644 index 0000000..14356e3 --- /dev/null +++ b/admin_interface/static/admin_interface/css/nav-sidebar.css @@ -0,0 +1,78 @@ +/* fix nav-sidebar (added in django 3.1.0) */ +.admin-interface #toggle-nav-sidebar { + top: 10px; + left: 0; + z-index: 20; + flex: 0 0 30px; + width: 30px; + height: 45px; + margin-top: 10px; + margin-right: -30px; + background-color: #FFFFFF; + font-size: 16px; + border: 1px solid #eaeaea; + border-left: none; + outline: none; + -webkit-box-shadow: 4px 4px 8px -4px #DBDBDB; + -moz-box-shadow: 4px 4px 8px -4px #DBDBDB; + box-shadow: 4px 4px 8px -4px #DBDBDB; + /*transition: left .3s;*/ +} + +.admin-interface .toggle-nav-sidebar::before { + margin-top: -2px; +} + +.admin-interface .main > #nav-sidebar + .content, +.admin-interface .main.shifted > #nav-sidebar + .content { + max-width: 100%; +} + +/* hide nav-sidebar below 1280px to prevent horizontal overflow issues */ +@media (max-width:1279px) { + .admin-interface #nav-sidebar, + .admin-interface #toggle-nav-sidebar { + display: none; + } +} + +.admin-interface #nav-sidebar { + flex: 0 0 360px; + left: -360px; + margin-left: -360px; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + padding: 40px 40px 40px 40px; + border-top: none; + border-bottom: none; + border-left: none; + scrollbar-width: thin; + /*transition: left .3s, margin-left .3s;*/ +} + +.admin-interface #nav-filter { + background-color: transparent; + border-radius: 4px; + height: 30px; + margin: 0 0 30px 0; + padding: 5px 6px; + outline-width: initial; +} + +@media (min-width:1280px) { + .admin-interface #main.shifted > #toggle-nav-sidebar { + left: 359px; + } + .admin-interface #main.shifted > #nav-sidebar { + left: 0px; + margin-left: 0; + } + .admin-interface #main:not(.shifted) > .content { + max-width: 100%; + } + .admin-interface.change-list:not(.popup) #main.shifted > #nav-sidebar + .content, + .admin-interface.change-form:not(.popup) #main.shifted > #nav-sidebar + .content { + max-width: calc(100% - 360px); + } +} diff --git a/admin_interface/static/admin_interface/css/object-tools.css b/admin_interface/static/admin_interface/css/object-tools.css new file mode 100644 index 0000000..4e5aa1c --- /dev/null +++ b/admin_interface/static/admin_interface/css/object-tools.css @@ -0,0 +1,10 @@ +/* top-right buttons color on hover -> just a lighten grey */ +.admin-interface .object-tools a { + color: #FFFFFF; +} +.admin-interface .object-tools a:focus, +.admin-interface .object-tools a:hover, +.admin-interface .object-tools li:focus a, +.admin-interface .object-tools li:hover a { + background-color: #AAAAAA; +} diff --git a/admin_interface/static/admin_interface/css/paginator.css b/admin_interface/static/admin_interface/css/paginator.css new file mode 100644 index 0000000..4598a6b --- /dev/null +++ b/admin_interface/static/admin_interface/css/paginator.css @@ -0,0 +1,33 @@ +.admin-interface #changelist .paginator { + margin-top: -1px; /* merge 2 borders into 1 */ + line-height: 1.5em; + padding-top: 12px; + padding-bottom: 12px; +} + +.admin-interface .paginator a, +.admin-interface .paginator a:link, +.admin-interface .paginator a:visited, +.admin-interface .paginator .this-page { + padding: 7px 12px; +} + +.admin-interface .paginator a, +.admin-interface .paginator .this-page { + margin-left: 0px; +} + +.admin-interface .paginator .this-page, +.admin-interface .paginator a.end { + margin-right: 25px; +} + +.admin-interface .paginator .this-page + a:not(.showall) { + margin-left: -25px; +} + +body.admin-interface .paginator a.showall, +body.admin-interface .paginator a.showall:link, +body.admin-interface .paginator a.showall:visited { + margin-left: 20px; +} diff --git a/admin_interface/static/admin_interface/css/recent-actions.css b/admin_interface/static/admin_interface/css/recent-actions.css new file mode 100644 index 0000000..6e25164 --- /dev/null +++ b/admin_interface/static/admin_interface/css/recent-actions.css @@ -0,0 +1,10 @@ +.admin-interface.dashboard #content { + width: auto; + max-width: 600px; + margin-right: 0; + margin-left: 0; +} + +.admin-interface.dashboard #content #recent-actions-module { + display: none; +} diff --git a/admin_interface/templates/admin_interface/css/rtl.css b/admin_interface/static/admin_interface/css/rtl.css similarity index 100% rename from admin_interface/templates/admin_interface/css/rtl.css rename to admin_interface/static/admin_interface/css/rtl.css diff --git a/admin_interface/templates/admin_interface/css/form-controls.css b/admin_interface/static/admin_interface/css/sticky-form-controls.css similarity index 98% rename from admin_interface/templates/admin_interface/css/form-controls.css rename to admin_interface/static/admin_interface/css/sticky-form-controls.css index 500b52a..4307367 100644 --- a/admin_interface/templates/admin_interface/css/form-controls.css +++ b/admin_interface/static/admin_interface/css/sticky-form-controls.css @@ -16,7 +16,7 @@ white-space: nowrap; text-overflow: ellipsis; border-radius: 0; - border-top: 1px solid #EEEEEE; + border-top: 1px solid #EEEEEE !important; border-bottom: none; margin: 0; } @@ -92,4 +92,4 @@ .admin-interface.sticky-submit.change-form:not(.popup) #main.shifted > #nav-sidebar + .content .submit-row:last-of-type { width: calc(100% - 359px); } -} \ No newline at end of file +} diff --git a/admin_interface/static/admin_interface/css/tabbed-changeform.css b/admin_interface/static/admin_interface/css/tabbed-changeform.css new file mode 100644 index 0000000..a0f6718 --- /dev/null +++ b/admin_interface/static/admin_interface/css/tabbed-changeform.css @@ -0,0 +1,67 @@ +.admin-interface .tabbed-changeform-tabs { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + overflow-x: auto; + overflow-y: hidden; + scrollbar-width: thin; + padding-bottom: 15px; +} + +@-moz-document url-prefix() { + .admin-interface .tabbed-changeform-tabs { + padding-bottom: 13px; + } +} + +.admin-interface .tabbed-changeform-tabs .tabbed-changeform-tablink { + appearance: none; + -webkit-appearance: none; + border: 1px solid transparent; + border-bottom: 1px solid var(--border-color); + border-radius: var(--admin-interface-module-border-radius); + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; + flex-shrink: 0; + flex-grow: 0; + cursor: pointer; + padding: 10px 15px; + margin: 0; + background-color: var(--admin-interface-module-header-text-color); + color: var(--admin-interface-generic-link-color); + font-size: 13px; + font-weight: bold; + outline: none !important; +} + +.admin-interface .tabbed-changeform-tabs .tabbed-changeform-tablink + .tabbed-changeform-tablink { + margin-left: -1px; +} + +.admin-interface .tabbed-changeform-tabs .tabbed-changeform-tablink:hover { + color: var(--admin-interface-generic-link-hover-color); +} + +.admin-interface .tabbed-changeform-tabs .tabbed-changeform-tablink:focus { + color: var(--admin-interface-generic-link-hover-color); +} + +.admin-interface .tabbed-changeform-tabs .tabbed-changeform-tablink.active { + border: 1px solid var(--border-color); + border-bottom: 1px solid transparent; + color: var(--admin-interface-generic-link-active-color); +} + +.admin-interface .tabbed-changeform-tabs-remaining-space { + flex: 1; + border-bottom: 1px solid var(--border-color); +} + +.admin-interface .tabbed-changeform-tabcontent { + display: none; + padding: 1em 0; +} + +.admin-interface .tabbed-changeform-tabcontent.active { + display: block; +} diff --git a/admin_interface/templates/admin_interface/css/ckeditor.css b/admin_interface/static/admin_interface/css/third-party/ckeditor.css similarity index 99% rename from admin_interface/templates/admin_interface/css/ckeditor.css rename to admin_interface/static/admin_interface/css/third-party/ckeditor.css index 407bb14..952120c 100644 --- a/admin_interface/templates/admin_interface/css/ckeditor.css +++ b/admin_interface/static/admin_interface/css/third-party/ckeditor.css @@ -123,4 +123,4 @@ https://github.com/Ikimea/ckeditor-light-theme .admin-interface .tabular .cke_contents { height: 90px !important; } -} \ No newline at end of file +} diff --git a/admin_interface/static/admin_interface/css/third-party/import-export.css b/admin_interface/static/admin_interface/css/third-party/import-export.css new file mode 100644 index 0000000..8ea0a09 --- /dev/null +++ b/admin_interface/static/admin_interface/css/third-party/import-export.css @@ -0,0 +1,7 @@ +/* Fix left/right scrolling broken with django-import-export #165 */ +.admin-interface table.import-preview { + display: block; + width: 100%; + max-width: 100%; + overflow: auto; +} diff --git a/admin_interface/templates/admin_interface/css/json-widget.css b/admin_interface/static/admin_interface/css/third-party/json-widget.css similarity index 52% rename from admin_interface/templates/admin_interface/css/json-widget.css rename to admin_interface/static/admin_interface/css/third-party/json-widget.css index d51b9ff..e0a999d 100644 --- a/admin_interface/templates/admin_interface/css/json-widget.css +++ b/admin_interface/static/admin_interface/css/third-party/json-widget.css @@ -4,26 +4,24 @@ https://github.com/jmrivas86/django-json-widget */ .admin-interface div.jsoneditor { - border: 1px solid {{ theme.css_module_background_color }}; - {% if theme.css_module_rounded_corners %} - border-radius: 4px; - overflow: hidden; - {% endif %} + border: 1px solid var(--admin-interface-module-background-color); + border-radius: var(--admin-interface-jsoneditor-border-radius); + overflow: var(--admin-interface-jsoneditor-overflow); } .admin-interface div.jsoneditor-menu { - background-color: {{ theme.css_module_background_color }}; - border-bottom: 1px solid {{ theme.css_module_background_color }}; + background-color: var(--admin-interface-module-background-color); + border-bottom: 1px solid var(--admin-interface-module-background-color); } .admin-interface div.jsoneditor-menu a.jsoneditor-poweredBy { - color: {{ theme.css_module_link_color }}; + color: var(--admin-interface-module-link-color); } .admin-interface div.jsoneditor-contextmenu ul li button.jsoneditor-selected, .admin-interface div.jsoneditor-contextmenu ul li button.jsoneditor-selected:focus, .admin-interface div.jsoneditor-contextmenu ul li button.jsoneditor-selected:hover { - background-color: {{ theme.css_module_background_selected_color }}; + background-color: var(--admin-interface-module-background-selected-color); color: #000000; font-weight: bold; } diff --git a/admin_interface/templates/admin_interface/css/modeltranslation.css b/admin_interface/static/admin_interface/css/third-party/modeltranslation.css similarity index 100% rename from admin_interface/templates/admin_interface/css/modeltranslation.css rename to admin_interface/static/admin_interface/css/third-party/modeltranslation.css diff --git a/admin_interface/static/admin_interface/css/third-party/rangefilter.css b/admin_interface/static/admin_interface/css/third-party/rangefilter.css new file mode 100644 index 0000000..25b4f0b --- /dev/null +++ b/admin_interface/static/admin_interface/css/third-party/rangefilter.css @@ -0,0 +1,25 @@ +.admin-interface #changelist-filter .admindatefilter { + border-bottom: 1px solid var(--hairline-color); +} + +.admin-interface #changelist-filter .admindatefilter .button, +.admin-interface #changelist-filter .admindatefilter .submit-row input, +.admin-interface #changelist-filter .admindatefilter a.button, +.admin-interface #changelist-filter .admindatefilter input[type="submit"], +.admin-interface #changelist-filter .admindatefilter input[type="button"], +.admin-interface #changelist-filter .admindatefilter input[type="reset"] { + background: var(--admin-interface-module-background-color); + color: var(--admin-interface-module-link-color); + padding: 6px 10px; + font-size: 12px; + margin-right: 4px; +} + +.admin-interface #changelist-filter .admindatefilter .button:hover, +.admin-interface #changelist-filter .admindatefilter .submit-row input:hover, +.admin-interface #changelist-filter .admindatefilter a.button:hover, +.admin-interface #changelist-filter .admindatefilter input[type="submit"]:hover, +.admin-interface #changelist-filter .admindatefilter input[type="button"]:hover, +.admin-interface #changelist-filter .admindatefilter input[type="reset"]:hover { + color: var(--admin-interface-module-link-hover-color); +} diff --git a/admin_interface/templates/admin_interface/css/sorl-thumbnail.css b/admin_interface/static/admin_interface/css/third-party/sorl-thumbnail.css similarity index 100% rename from admin_interface/templates/admin_interface/css/sorl-thumbnail.css rename to admin_interface/static/admin_interface/css/third-party/sorl-thumbnail.css diff --git a/admin_interface/static/admin_interface/css/third-party/streamfield.css b/admin_interface/static/admin_interface/css/third-party/streamfield.css new file mode 100644 index 0000000..b1fbb01 --- /dev/null +++ b/admin_interface/static/admin_interface/css/third-party/streamfield.css @@ -0,0 +1,220 @@ +/* +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-handlers .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-handlers .collapse-handler:hover { + color: var(--admin-interface-generic-link-hover-color); + text-decoration: underline; +} + +.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 .streamblock__block__model_title { + white-space: nowrap; + flex-shrink: 0; + margin-right: 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 .stream-model-block .streamblock__block__subtitle { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + flex-shrink: 1; + margin-right: 10px; +} + +.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-model-block .add_here { + display: none !important; +} + +.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: underline; +} + +.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; +} diff --git a/admin_interface/templates/admin_interface/css/tabbed-admin.css b/admin_interface/static/admin_interface/css/third-party/tabbed-admin.css similarity index 100% rename from admin_interface/templates/admin_interface/css/tabbed-admin.css rename to admin_interface/static/admin_interface/css/third-party/tabbed-admin.css diff --git a/admin_interface/templates/admin_interface/css/tinymce.css b/admin_interface/static/admin_interface/css/third-party/tinymce.css similarity index 97% rename from admin_interface/templates/admin_interface/css/tinymce.css rename to admin_interface/static/admin_interface/css/third-party/tinymce.css index 6ab1a8e..76ed1b4 100644 --- a/admin_interface/templates/admin_interface/css/tinymce.css +++ b/admin_interface/static/admin_interface/css/third-party/tinymce.css @@ -1,3 +1,3 @@ .admin-interface textarea.tinymce ~ p.help { margin-top:5px !important; -} \ No newline at end of file +} diff --git a/admin_interface/static/admin_interface/css/widgets.css b/admin_interface/static/admin_interface/css/widgets.css new file mode 100644 index 0000000..6c1be6d --- /dev/null +++ b/admin_interface/static/admin_interface/css/widgets.css @@ -0,0 +1,153 @@ +/* fix generic flex container */ +.admin-interface .flex-container { + width: 100%; +} +/* end-fix */ + +/* fix flex container for boolean fields */ +.admin-interface .flex-container.checkbox-row { + align-items: center; +} +.admin-interface .flex-container.checkbox-row label.vCheckboxLabel { + margin-top: 0 !important; + padding-left: 5px !important; + padding-bottom: 0; +} +/* end-fix */ + +/* fix flex container for related-lookup (raw_id_fields) */ +.admin-interface .flex-container:has(.vForeignKeyRawIdAdminField) { + align-items: center; +} + +.admin-interface .flex-container:has(.vForeignKeyRawIdAdminField) .related-lookup { + margin-left: 12px; +} + +.admin-interface .flex-container:has(.vForeignKeyRawIdAdminField) .related-lookup + * { + margin-left: 8px; +} +/* end-fix */ + +/* fix flex container input fields height inheritance */ +.admin-interface .flex-container label + input[type="text"], +.admin-interface .flex-container label + input[type="password"], +.admin-interface .flex-container label + input[type="email"], +.admin-interface .flex-container label + input[type="url"], +.admin-interface .flex-container label + input[type="number"], +.admin-interface .flex-container label + input[type="tel"] { + height: 1.375em; +} +/* end-fix */ + +/* fixed time widget header border radius */ +.admin-interface .clockbox.module h2 { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} +/* end-fix */ + +/* fixed related widget and select2 */ +/* begin fix issue #10 - Related widget broken in long tabular inline */ +.admin-interface .related-widget-wrapper { + display: flex; + flex-wrap: nowrap; + white-space: nowrap; + height: fit-content; +} +/* end fix */ + +/* fix related widget links icons size and vertical alignment */ +.admin-interface .related-widget-wrapper .related-widget-wrapper-link { + display: flex; + align-items: center; + margin-bottom: 4px; +} +.admin-interface .related-widget-wrapper .related-widget-wrapper-link img { + width: 16px; + height: 16px; +} +/* end fix */ + +/* fix related widget links add button position on many-to-many selector */ +.admin-interface .related-widget-wrapper .related-widget-wrapper-link:has(+ .selector) { + order: 2; + align-self: flex-start; + margin-top: 8px; +} +/* end fix */ + +/* fix related widget links margin from select2 (autocomplete_fields) */ +.admin-interface .related-widget-wrapper .select2-container + .related-widget-wrapper-link { + margin-left: 12px !important; +} +/* end fix */ + +/* improve responsive selector */ + +/* fix [stacked, not-stacked] equalize horizontal and vertical select padding for selector */ +.admin-interface .selector .selector-available select, +.admin-interface .selector .selector-chosen select { + padding: 7px 10px; + display: block; +} + +/* fix [stacked, not-stacked] select options text overflow */ +.admin-interface .selector .selector-available select option, +.admin-interface .selector .selector-chosen select option { + overflow: hidden; + text-overflow: ellipsis; +} + +/* fix [not-stacked] equalize selectors height by adding the height of the .selector-available filter-bar */ +.admin-interface .selector:not(.stacked) .selector-chosen select { + height: calc(46px + 17.2em) !important; +} + +@media (max-width: 767px) { + /* fixed responsive widgets */ + .admin-interface .aligned.collapsed .form-row { + display: none; + } + + .admin-interface .aligned .form-row > div { + display: flex; + width: 100%; + max-width: 100vw; + flex-direction: column; + align-items: flex-start; + } + + .admin-interface .aligned .form-row .help { + margin-left: 0; + } + + .admin-interface .aligned .form-row .checkbox-row label { + margin: 10px 0 0 0; + padding: 0; + } + + .admin-interface .aligned .form-row input[type="file"], + .admin-interface .aligned .form-row input[type="text"], + .admin-interface .aligned .form-row input[type="email"] { + width: 100%; + } + + /* fix textarea horizontal scroll on Firefox */ + .admin-interface .aligned .form-row textarea { + width: 100% !important; + flex: 0 1 auto; + } + + .admin-interface .aligned .form-row .datetime input[type="text"] { + width: 50%; + } + + .admin-interface .aligned .form-row span + .file-upload { + margin-top: 10px; + } + + .admin-interface .aligned .form-row .file-upload input[type="file"] { + margin-top: 5px; + } +} diff --git a/admin_interface/static/admin_interface/foldable-apps/foldable-apps.css b/admin_interface/static/admin_interface/foldable-apps/foldable-apps.css index 59a3744..ee70bff 100644 --- a/admin_interface/static/admin_interface/foldable-apps/foldable-apps.css +++ b/admin_interface/static/admin_interface/foldable-apps/foldable-apps.css @@ -31,7 +31,7 @@ right: 0; z-index: 10; width: auto; - height: 100%; + height: calc(100% - 3px); content: "−"; font-size: 16px; font-weight: lighter; diff --git a/admin_interface/static/admin_interface/magnific-popup/jquery.magnific-popup.js b/admin_interface/static/admin_interface/magnific-popup/jquery.magnific-popup.js index 08aefc2..2d4a921 100755 --- a/admin_interface/static/admin_interface/magnific-popup/jquery.magnific-popup.js +++ b/admin_interface/static/admin_interface/magnific-popup/jquery.magnific-popup.js @@ -1507,7 +1507,7 @@ } }, - // Get element postion relative to viewport + // Get element position relative to viewport _getOffset: function(isLarge) { var el; if(isLarge) { @@ -1808,7 +1808,7 @@ _mfpTrigger('LazyLoad', item); if(item.type === 'image') { - item.img = $('').on('load.mfploader', function() { + item.img = $('').on('load.mfploader', function() { item.hasSize = true; }).on('error.mfploader', function() { item.hasSize = true; @@ -1864,4 +1864,4 @@ /*>>retina*/ _checkInstance(); -})); \ No newline at end of file +})); diff --git a/admin_interface/templates/admin_interface/css/related-modal.css b/admin_interface/static/admin_interface/related-modal/related-modal.css similarity index 81% rename from admin_interface/templates/admin_interface/css/related-modal.css rename to admin_interface/static/admin_interface/related-modal/related-modal.css index 7cae8bd..015752f 100644 --- a/admin_interface/templates/admin_interface/css/related-modal.css +++ b/admin_interface/static/admin_interface/related-modal/related-modal.css @@ -3,15 +3,15 @@ related modal + magnific popup customization https://github.com/dimsemenov/Magnific-Popup */ .admin-interface .related-modal.mfp-bg { - background-color: {{ theme.related_modal_background_color }}; - opacity: {{ theme.related_modal_background_opacity }}; + background-color: var(--admin-interface-related-modal-background-color); + opacity: var(--admin-interface-related-modal-background-opacity); } .admin-interface .related-modal .mfp-content { height: 100%; - -webkit-box-shadow: 0px 5px 30px 0px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 5px 30px 0px rgba(0,0,0,0.2); - box-shadow: 0px 5px 30px 0px rgba(0,0,0,0.2); + -webkit-box-shadow: 0px 5px 30px 0px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0px 5px 30px 0px rgba(0, 0, 0, 0.2); + box-shadow: 0px 5px 30px 0px rgba(0, 0, 0, 0.2); } .admin-interface .related-modal .mfp-container { @@ -22,20 +22,22 @@ https://github.com/dimsemenov/Magnific-Popup padding: 40px 80px 40px 80px; } -@media (max-width:640px){ +@media (max-width: 640px) { .admin-interface .related-modal .mfp-container { padding: 80px 20px 80px 20px; } + .admin-interface .related-modal__nested .mfp-container { padding: 40px 40px 40px 40px; } } -@media (max-height:640px){ +@media (max-height: 640px) { .admin-interface .related-modal .mfp-container { padding-top: 20px; padding-bottom: 20px; } + .admin-interface .related-modal__nested .mfp-container { padding: 40px 40px 40px 40px; } @@ -48,9 +50,7 @@ https://github.com/dimsemenov/Magnific-Popup position: relative; z-index: 100; overflow: hidden; - {% if theme.related_modal_rounded_corners %} - border-radius: 4px; - {% endif %} + border-radius: var(--admin-interface-related-modal-border-radius); } .admin-interface .related-modal #related-modal-iframe { @@ -72,9 +72,7 @@ https://github.com/dimsemenov/Magnific-Popup height: 40px; opacity: 1.0; color: rgba(0, 0, 0, 0.4); - {% if not theme.related_modal_close_button_visible %} - display: none; - {% endif %} + display: var(--admin-interface-related-modal-close-button-display); } .admin-interface .related-modal .mfp-close:hover, diff --git a/admin_interface/static/admin_interface/related-modal/related-modal.js b/admin_interface/static/admin_interface/related-modal/related-modal.js index 49c4fd9..c02ccda 100644 --- a/admin_interface/static/admin_interface/related-modal/related-modal.js +++ b/admin_interface/static/admin_interface/related-modal/related-modal.js @@ -70,7 +70,7 @@ if (typeof(django) !== 'undefined' && typeof(django.jQuery) !== 'undefined') } } - // fix for django 1.7 + // fix for django 1.7 TODO remove if (iframeSrc.indexOf('_popup=1') === -1) { if (iframeSrc.indexOf('?') === -1) { iframeSrc += '?_popup=1'; @@ -125,26 +125,22 @@ if (typeof(django) !== 'undefined' && typeof(django.jQuery) !== 'undefined') var data = { lookup:(lookup === true ? true : false) }; + // remove potential existing click event listener var el = $(selector); el.removeAttr('onclick'); el.unbind('click'); el.click(data, presentRelatedObjectModal); + // listen the event on document for handling it on elements will be added to the DOM later + $(document).on('click', selector, data, presentRelatedObjectModal); } // assign functions to global variables window.presentRelatedObjectModal = presentRelatedObjectModal; window.presentRelatedObjectModalOnClickOn = presentRelatedObjectModalOnClickOn; - // django 1.7 compatibility - // $('a.add-another').removeAttr('onclick').click({ lookup:false }, presentRelatedObjectModal); - presentRelatedObjectModalOnClickOn('a.add-another'); - - // django 1.8 and above - // $('a.related-widget-wrapper-link').click({ lookup:false }, presentRelatedObjectModal); presentRelatedObjectModalOnClickOn('a.related-widget-wrapper-link'); // raw_id_fields support - // $('a.related-lookup').unbind('click').click({ lookup:true }, presentRelatedObjectModal); presentRelatedObjectModalOnClickOn('a.related-lookup', true); // django-dynamic-raw-id support - #61 @@ -153,6 +149,22 @@ if (typeof(django) !== 'undefined' && typeof(django.jQuery) !== 'undefined') // show_change_link=True support presentRelatedObjectModalOnClickOn('a.inlinechangelink'); + + // any link with _popup=1 parameter support + presentRelatedObjectModalOnClickOn('a[href*="_popup=1"]'); + + // django-streamfield support + // 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); diff --git a/admin_interface/static/admin_interface/tabbed-changeform/tabbed-changeform.js b/admin_interface/static/admin_interface/tabbed-changeform/tabbed-changeform.js new file mode 100644 index 0000000..c5e6f0f --- /dev/null +++ b/admin_interface/static/admin_interface/tabbed-changeform/tabbed-changeform.js @@ -0,0 +1,73 @@ +(function (AdminInterface) { + + var scope = AdminInterface; + + scope.tabbedChangeForm = { + + openTab: function (event, tabName) { + this.openTabByName(tabName); + }, + + openTabByName: function(tabName) { + let tablinkEl = document.getElementById("tablink-" + tabName); + let tabcontentEl = document.getElementById("tabcontent-" + tabName); + if (!tablinkEl || !tabcontentEl) { + return false; + } + + let tablinks = document.getElementsByClassName("tabbed-changeform-tablink"); + let tabcontents = document.getElementsByClassName("tabbed-changeform-tabcontent"); + + // toggle tab link + for (let tablink of tablinks) { + tablink.classList.remove("active"); + } + tablinkEl.classList.add("active"); + + // toggle tab content + for (let tabcontent of tabcontents) { + tabcontent.classList.remove("active"); + } + tabcontentEl.classList.add("active"); + + // update location hash + let history = window.history; + if (history) { + history.replaceState(undefined, undefined, "#" + tabName); + } + + return true; + }, + + openTabByLocationHash: function() { + let hash = window.location.hash; + if (hash && hash !== "#") { + let tabName = hash.substring(1); + if (this.openTabByName(tabName)) { + this.scrollTabsToTabByName(tabName); + } + } + }, + + scrollTabsToTabByName: function(tabName) { + let tabsEl = document.getElementById("tabbed-changeform-tabs"); + let tablinkEl = document.getElementById("tablink-" + tabName); + if (!tabsEl || !tablinkEl) { + return; + } + let tablinkLeft = (tablinkEl.offsetLeft - tabsEl.offsetLeft); + let tabsScrollLeft = Math.ceil(tablinkLeft); + tabsEl.scrollTo({ + top: 0, + left: tabsScrollLeft, + behavior: "instant" + }); + } + }; + + // scope.tabbedChangeForm.openTabByLocationHash(); + document.addEventListener('DOMContentLoaded', function() { + scope.tabbedChangeForm.openTabByLocationHash(); + }, false); + +}(window.AdminInterface = window.AdminInterface || {})); diff --git a/admin_interface/static/ckeditor/ckeditor/skins/light/skin.js b/admin_interface/static/ckeditor/ckeditor/skins/light/skin.js index 8373225..0bc63f4 100644 --- a/admin_interface/static/ckeditor/ckeditor/skins/light/skin.js +++ b/admin_interface/static/ckeditor/ckeditor/skins/light/skin.js @@ -49,7 +49,7 @@ CKEDITOR.skin.name = 'husky'; // the complete list: // 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). // // The available browser specific files must be set separately for editor.css diff --git a/admin_interface/static/streamfield/admin_popup_response.js b/admin_interface/static/streamfield/admin_popup_response.js new file mode 100644 index 0000000..5fb2af8 --- /dev/null +++ b/admin_interface/static/streamfield/admin_popup_response.js @@ -0,0 +1,24 @@ +// IMPORTANT: used by django-streamfield >= 2.0.0 + +(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; + } + +})(); diff --git a/admin_interface/static/streamfield/js/admin_popup_response.js b/admin_interface/static/streamfield/js/admin_popup_response.js new file mode 100644 index 0000000..5fb2af8 --- /dev/null +++ b/admin_interface/static/streamfield/js/admin_popup_response.js @@ -0,0 +1,24 @@ +// IMPORTANT: used by django-streamfield >= 2.0.0 + +(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; + } + +})(); diff --git a/admin_interface/templates/admin/base_site.html b/admin_interface/templates/admin/base_site.html index c17ef50..9df4911 100644 --- a/admin_interface/templates/admin/base_site.html +++ b/admin_interface/templates/admin/base_site.html @@ -2,43 +2,136 @@ {% load i18n static admin_interface_tags %} {% block title %} +{% get_admin_interface_theme as theme %} {% if title %}{{ title }} | {% endif %}{% if theme.title %}{% trans theme.title %}{% else %}{{ site_title|default:_('Django administration') }}{% endif %} {% endblock %} {% block extrastyle %} +{% get_admin_interface_theme as theme %} +{% get_admin_interface_nocache as version_md5_cache %} {% get_current_language as current_lang %} - + + + + + + + + + + + + + + + + + + {% if not theme.recent_actions_visible %} + + {% endif %} + + + + + + + + + + + + + + + {% if current_lang == 'fa' %} - + {% endif %} {% endblock %} {% block blockbots %} {{ block.super }} +{% get_admin_interface_theme as theme %} +{% get_admin_interface_nocache as version_md5_cache %} {# https://github.com/elky/django-flat-responsive#important-note #} - - + + {% include "admin_interface/favicon.html" %} {% include "admin_interface/foldable-apps.html" %} {% include "admin_interface/related-modal.html" %} +{% include "admin_interface/collapsible-inlines.html" %} {% endblock %} {% block extrahead %} @@ -46,14 +139,31 @@ {% endblock %} {% block bodyclass %} -flat-theme admin-interface +{% get_admin_interface_theme as theme %} +admin-interface {% if theme.name %} {{ theme.name|slugify }}-theme {% endif %} {% if theme.foldable_apps %} foldable-apps {% endif %} {% if theme.form_submit_sticky %} sticky-submit {% endif %} {% if theme.form_pagination_sticky %} sticky-pagination {% endif %} +{% if theme.list_filter_highlight %} list-filter-highlight {% endif %} +{% if theme.list_filter_sticky %} list-filter-sticky {% endif %} + +{% admin_interface_use_changeform_tabs adminform inline_admin_formsets as admin_interface_use_changeform_tabs %} +{% if admin_interface_use_changeform_tabs %} + {% if theme.show_fieldsets_as_tabs %} show-fieldsets-as-tabs {% endif %} + {% if theme.show_inlines_as_tabs %} show-inlines-as-tabs {% endif %} +{% endif %} + +{% if theme.collapsible_stacked_inlines %} collapsible-stacked-inlines + {% if theme.collapsible_stacked_inlines_collapsed %} collapsible-stacked-inlines-collapsed {% endif %} +{% endif %} +{% if theme.collapsible_tabular_inlines %} collapsible-tabular-inlines + {% if theme.collapsible_tabular_inlines_collapsed %} collapsible-tabular-inlines-collapsed {% endif %} +{% endif %} {% endblock %} {% block branding %} +{% get_admin_interface_theme as theme %}

{% if theme.logo_visible %} @@ -71,9 +181,14 @@ flat-theme admin-interface {% endblock %} {% block welcome-msg %} -{% if theme.language_chooser_active %} - {% get_admin_interface_languages as languages %} - {% include "admin_interface/language_chooser.html" %} -{% endif %} -{% if theme.env_visible_in_header %}
{% endif %}{{ block.super }}
+{% get_admin_interface_theme as theme %} +{% if theme.env_visible_in_header %}{{ theme.env_name }}
{% endif %}{{ block.super }}
+{% endblock %} + +{% block userlinks %} +{{ block.super }} +{% get_admin_interface_theme as theme %} +{% if theme.language_chooser_active %} + {% admin_interface_language_chooser %} +{% endif %} {% endblock %} diff --git a/admin_interface/templates/admin/change_form.html b/admin_interface/templates/admin/change_form.html new file mode 100644 index 0000000..6ea075a --- /dev/null +++ b/admin_interface/templates/admin/change_form.html @@ -0,0 +1,88 @@ +{% extends "admin/change_form.html" %} +{% load static admin_interface_tags %} + +{% block field_sets %} + + {% get_admin_interface_setting "show_fieldsets_as_tabs" as show_fieldsets_as_tabs %} + {% get_admin_interface_setting "show_inlines_as_tabs" as show_inlines_as_tabs %} + {% admin_interface_use_changeform_tabs adminform inline_admin_formsets as admin_interface_use_changeform_tabs %} + + {% if not admin_interface_use_changeform_tabs %} + + {{ block.super }} + + {% else %} + +
+ + {% if show_fieldsets_as_tabs %} + {% for fieldset in adminform %} + {% with fieldset.name|default_if_none:opts.verbose_name as tab_name %} + + {% endwith %} + {% endfor %} + {% else %} + {% with opts.verbose_name as tab_name %} + + {% endwith %} + {% endif %} + + {% if show_inlines_as_tabs %} + {% for inline_admin_formset in inline_admin_formsets %} + {% with inline_admin_formset.opts.verbose_name_plural as tab_name %} + + {% endwith %} + {% endfor %} + {% endif %} + + + +
+ + {% if show_fieldsets_as_tabs %} + {% for fieldset in adminform %} + {% with fieldset.name|default_if_none:opts.verbose_name as tab_name %} +
+ {% include "admin/includes/headerless_fieldset.html" %} +
+ {% endwith %} + {% endfor %} + {% else %} + {% with opts.verbose_name as tab_name %} +
+ {% for fieldset in adminform %} + {% include "admin/includes/fieldset.html" %} + {% endfor %} +
+ {% endwith %} + {% endif %} + + {% for inline_admin_formset in inline_admin_formsets %} + {% with inline_admin_formset.opts.verbose_name_plural as tab_name %} +
+ {% get_admin_interface_inline_template inline_admin_formset.opts.template as inline_template %} + {% include inline_template %} +
+ {% endwith %} + {% endfor %} + + + + {% endif %} + +{% endblock %} + +{% block inline_field_sets %} + + {% get_admin_interface_setting "show_inlines_as_tabs" as show_inlines_as_tabs %} + {% if not show_inlines_as_tabs %} + {{ block.super }} + {% endif %} + +{% endblock %} diff --git a/admin_interface/templates/admin/change_list.html b/admin_interface/templates/admin/change_list.html new file mode 100644 index 0000000..ad40e5d --- /dev/null +++ b/admin_interface/templates/admin/change_list.html @@ -0,0 +1,33 @@ +{% extends "admin/change_list.html" %} +{% load i18n admin_list admin_interface_tags %} +{# copied from django 4.0.7 #} + + {% block filters %} + {% if cl.has_filters %} +
+ {% endif %} + {% endblock %} diff --git a/admin_interface/templates/admin/edit_inline/headerless_stacked.html b/admin_interface/templates/admin/edit_inline/headerless_stacked.html new file mode 100644 index 0000000..9bc1cbd --- /dev/null +++ b/admin_interface/templates/admin/edit_inline/headerless_stacked.html @@ -0,0 +1,24 @@ +{% load i18n admin_urls %} +
+
+{{ inline_admin_formset.formset.management_form }} +{{ inline_admin_formset.formset.non_form_errors }} + +{% for inline_admin_form in inline_admin_formset %}
+

{{ inline_admin_formset.opts.verbose_name|capfirst }}: {% if inline_admin_form.original %}{{ inline_admin_form.original }}{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %} {% if inline_admin_formset.has_change_permission %}{% translate "Change" %}{% else %}{% translate "View" %}{% endif %}{% endif %} +{% else %}#{{ forloop.counter }}{% endif %} + {% if inline_admin_form.show_url %}{% translate "View on site" %}{% endif %} + {% if inline_admin_formset.formset.can_delete and inline_admin_formset.has_delete_permission and inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}{% endif %} +

+ {% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %} + {% for fieldset in inline_admin_form %} + {% include "admin/includes/fieldset.html" %} + {% endfor %} + {% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %} + {% if inline_admin_form.fk_field %}{{ inline_admin_form.fk_field.field }}{% endif %} +
{% endfor %} +
+
diff --git a/admin_interface/templates/admin/edit_inline/headerless_tabular.html b/admin_interface/templates/admin/edit_inline/headerless_tabular.html new file mode 100644 index 0000000..ed9b56a --- /dev/null +++ b/admin_interface/templates/admin/edit_inline/headerless_tabular.html @@ -0,0 +1,61 @@ +{% load i18n admin_urls static admin_modify %} +
+ +
diff --git a/admin_interface/templates/admin/filter.html b/admin_interface/templates/admin/filter.html index 1b8e5b4..1ec7a39 100644 --- a/admin_interface/templates/admin/filter.html +++ b/admin_interface/templates/admin/filter.html @@ -8,10 +8,10 @@ {% else %} - {# Use the default list filter template -> https://github.com/django/django/blob/master/django/contrib/admin/templates/admin/filter.html #} + {# Use a changed default list filter template -> https://github.com/django/django/blob/master/django/contrib/admin/templates/admin/filter.html #} -

{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}

-
    +

    {% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}

    + {% endif %} - diff --git a/admin_interface/templates/admin/includes/headerless_fieldset.html b/admin_interface/templates/admin/includes/headerless_fieldset.html new file mode 100644 index 0000000..fdb5fde --- /dev/null +++ b/admin_interface/templates/admin/includes/headerless_fieldset.html @@ -0,0 +1,30 @@ +
    + {% if fieldset.description %} +
    {{ fieldset.description|safe }}
    + {% endif %} + {% for line in fieldset %} +
    + {% if line.fields|length == 1 %}{{ line.errors }}{% endif %} + {% for field in line %} + + {% if not line.fields|length == 1 and not field.is_readonly %}{{ field.errors }}{% endif %} + {% if field.is_checkbox %} + {{ field.field }}{{ field.label_tag }} + {% else %} + {{ field.label_tag }} + {% if field.is_readonly %} +
    {{ field.contents }}
    + {% else %} + {{ field.field }} + {% endif %} + {% endif %} +
    + {% if field.field.help_text %} +
    + {{ field.field.help_text|safe }} +
    + {% endif %} + {% endfor %} + + {% endfor %} +
    diff --git a/admin_interface/templates/admin/popup_response.html b/admin_interface/templates/admin/popup_response.html index 970ad24..101a2b6 100644 --- a/admin_interface/templates/admin/popup_response.html +++ b/admin_interface/templates/admin/popup_response.html @@ -2,8 +2,7 @@ {% trans 'Popup closing...' %} - - \ No newline at end of file + diff --git a/admin_interface/templates/admin_interface/collapsible-inlines.html b/admin_interface/templates/admin_interface/collapsible-inlines.html new file mode 100644 index 0000000..57d5dd6 --- /dev/null +++ b/admin_interface/templates/admin_interface/collapsible-inlines.html @@ -0,0 +1,5 @@ +{% load static %} + +{% if theme.collapsible_stacked_inlines or theme.collapsible_tabular_inlines %} + +{% endif %} diff --git a/admin_interface/templates/admin_interface/css/admin-interface-fix.css b/admin_interface/templates/admin_interface/css/admin-interface-fix.css deleted file mode 100644 index 9cb41af..0000000 --- a/admin_interface/templates/admin_interface/css/admin-interface-fix.css +++ /dev/null @@ -1,582 +0,0 @@ -.admin-interface { - overflow-x: hidden; -} - -/* fix login */ -.admin-interface.login #container { - width: 100%; - max-width: 360px; - margin: 15px auto; - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; -} - -.admin-interface.login #content { - padding: 15px 30px 30px 30px; -} - -@media (min-width:768px){ - .admin-interface.login #container { - margin: 90px auto; - } -} - -.admin-interface.login #header { - min-height: auto; - padding: 10px 30px; - line-height: 30px; - align-items: center; - justify-content: flex-start; -} - -.admin-interface.login #header #branding h1 { - margin-right:0; -} - -.admin-interface.login #header #branding h1 img.logo { - margin-right: 0; -} - -.admin-interface.login #header #branding h1 img.logo+span { - display: block; -} - -.admin-interface.login #login-form { - display: flex; - flex-direction: column; -} - -.admin-interface.login .submit-row { - float: left; - width: 100%; - margin-top: 20px; - padding-top: 0; - padding-left: 0; - text-align: right; -} - -.admin-interface.login .submit-row label { - display: none; -} - -.admin-interface.login .submit-row input[type="submit"] { - width: 100%; - text-transform: uppercase; -} - -.admin-interface.login #footer { - display: none; -} -/* end login fix*/ - -.admin-interface #header { - height: auto; - min-height: 55px; - box-sizing: border-box; - display: flex; - justify-content: space-between; - align-items: center; -} - -@media (max-width:1024px) { - .admin-interface #header { - align-items: start; - } -} - -.admin-interface #branding h1 img.logo { - margin-top:10px; - margin-bottom:10px; - margin-right:15px; - display:inline-block !important; /* override inline display:none; */ -} - -.admin-interface #branding h1 span { - display: inline-block; -} - -.admin-interface #branding h1 img.logo+span { - white-space:nowrap; -} - -.admin-interface #user-tools { - margin-top: 10px; - margin-bottom: 10px; - white-space: normal; - align-self: flex-start; -} - -.admin-interface #user-tools br { - display: none; -} -@media (max-width: 768px) { - .admin-interface #user-tools br { - display: block; - } -} - -.admin-interface fieldset.collapse { - border: 1px solid transparent; -} - -.admin-interface fieldset.collapse.collapsed a.collapse-toggle, -.admin-interface fieldset.collapse a.collapse-toggle { - font-weight: normal; - text-transform: lowercase; - font-size: 12px; - text-decoration: underline; - padding: 0 1px; -} - -@media (min-width: 1024px) { - .admin-interface #changelist .actions .button, - .admin-interface #changelist .actions .action-counter { - margin-left: 8px; - } -} - -.admin-interface #changelist .paginator { - margin-top:-1px; /* merge 2 borders into 1 */ - line-height:42px; -} - -.admin-interface .paginator a, -.admin-interface .paginator a:link, -.admin-interface .paginator a:visited, -.admin-interface .paginator .this-page { - padding:7px 12px; -} - -.admin-interface .paginator a, -.admin-interface .paginator .this-page { - margin-left:0px; -} - -.admin-interface .paginator .this-page, -.admin-interface .paginator a.end { - margin-right:25px; -} - -.admin-interface .paginator .this-page + a:not(.showall) { - margin-left:-25px; -} - -body.admin-interface .paginator a.showall, -body.admin-interface .paginator a.showall:link, -body.admin-interface .paginator a.showall:visited { - margin-left:20px; -} - -/* fix help text icon on newline */ -.admin-interface .inline-group thead th { - white-space:nowrap; -} - -.admin-interface .inline-group thead th img { - vertical-align: -2px; - margin-left: 5px; -} - -.admin-interface .inline-group .inlinechangelink { - background-size: contain; - padding-left: 15px; - margin-left: 10px; -} - -.admin-interface .file-thumbnail > a { - display: inline-block; -} - -.admin-interface .aligned p.file-upload { - display:table; -} - -.admin-interface form .form-row p.file-upload > a { - margin-right:20px; -} - -.admin-interface form .form-row p.file-upload .clearable-file-input { - display:inline-block; -} - -.admin-interface form .form-row p.file-upload .clearable-file-input label { - padding-bottom:0px; - margin-left:2px; -} - -.admin-interface form .form-row p.file-upload > input[type="file"] { - margin-top: 0px; -} - -@media (max-width:767px){ - - .admin-interface form .form-row p.file-upload { - width: 100%; - } - - .admin-interface form .form-row p.file-upload > a { - margin-right:0px; - display: block; - white-space: pre-wrap; - word-break: break-word; - } - - .admin-interface form .form-row p.file-upload .clearable-file-input { - display: block; - margin-top: 10px; - margin-left: 0; - margin-bottom: -10px; - } - - .admin-interface form .form-row p.file-upload > input[type="file"] { - display: block; - width: auto; - padding: 0px; - } - - /* fix inline horizontal scroll caused by checkbox-row */ - .admin-interface form .form-row > div.checkbox-row { - width: 100%; - } -} - - -/* FIX WIDE FIELDSET HELPS / ERROR MESSAGES */ -.admin-interface form .wide p.help, -.admin-interface form .wide div.help { - padding-left: 50px; -} - -.admin-interface form .wide input + p.help, -.admin-interface form .wide input + div.help { - margin-left: 160px; -} - -@media (max-width:767px){ - .admin-interface form .form-row div.help { - display: block; - width: 100%; - } -} - -.admin-interface form .wide ul.errorlist { - margin-left: 200px; -} - -/* LIST FILTER */ -.admin-interface .module.filtered h2 { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} - -.admin-interface .module.filtered #changelist-filter { - min-width: 240px; -} - -@media (max-width: 1024px) { - .admin-interface .module.filtered #changelist-filter { - min-width: 200px; - } -} - -.admin-interface .module.filtered #changelist-filter h2 { - font-size: 11px; - padding: 10px 15px; -} - -/* begin fix issue #13 - Datetime widget broken in long inlines */ -.admin-interface p.datetime { - white-space:nowrap; -} -/* end fix */ - -/* begin fix lateral padding to align text with field labels */ -.admin-interface .module h2, -.admin-interface.dashboard .module caption, -.admin-interface.dashboard .module th, -.admin-interface .module.filtered h2, -.admin-interface .inline-group h2, -.admin-interface #nav-sidebar .module caption, -.admin-interface #nav-sidebar .module th { - padding-left: 10px; - padding-right: 10px; -} -/* end fix */ - -/* begin fix restrict tabular-inline horizontal-scroll to inline-group instead of whole page */ -.admin-interface .inline-group[data-inline-type="tabular"] { - overflow-x:auto; -} -/* end fix */ - -/* begin fix stacked-inline margin-bottom in responsive small viewport */ -.admin-interface .inline-group[data-inline-type="stacked"] .module { - margin-bottom:0px; -} -/* end fix */ - -/* begin fix tabular inlines horizontal scroll */ -.admin-interface .inline-related.tabular { - overflow-x: scroll; - overflow-y: hidden; -} -.admin-interface .inline-related.tabular fieldset.module { - display: contents; - width: 100%; - white-space: nowrap; - position: relative; -} -.admin-interface .inline-related.tabular fieldset.module h2 { - position: sticky; - left: 0; -} -.admin-interface .inline-related.tabular fieldset.module table tbody tr { - position: relative; -} -/* end fix */ - -.admin-interface .inline-related h3 { - padding:6px 10px; -} - -/* begin fix issue #12 - Inlines bad delete buttons alignement */ -.admin-interface .inline-group .tabular thead th:last-child:not([class]):not([style]) { - text-align:right; -} - -.admin-interface .inline-group .tabular tr td { - vertical-align: top; -} - -.admin-interface .inline-group .tabular tr td.delete { - text-align:right; - padding-right:15px; - vertical-align: top; -} - -.admin-interface .inline-group .tabular tr td input[type="checkbox"] { - margin: 7px 0px; -} - -.admin-interface .inline-group .tabular tr td.delete a.inline-deletelink { - margin-top:4px; - overflow:hidden; - text-indent:9999px; -} -/* end fix */ - -/* top-right buttons color on hover -> just a lighten grey */ -.admin-interface .object-tools a { - color:#FFFFFF; -} -.admin-interface .object-tools a:focus, -.admin-interface .object-tools a:hover, -.admin-interface .object-tools li:focus a, -.admin-interface .object-tools li:hover a { - background-color:#AAAAAA; -} - -/* improve responsive selector */ - -/* fix [stacked, not-stacked] equalize horizontal and vertical select padding for selector */ -.admin-interface .selector .selector-available select, -.admin-interface .selector .selector-chosen select { - padding: 7px 10px; - display: block; -} - -/* fix [stacked, not-stacked] select options text overflow */ -.admin-interface .selector .selector-available select option, -.admin-interface .selector .selector-chosen select option { - overflow: hidden; - text-overflow: ellipsis; -} - -/* fix [not-stacked] equalize selectors height by adding the height of the .selector-available filter-bar */ -.admin-interface .selector:not(.stacked) .selector-chosen select { - height: calc(46px + 17.2em) !important; -} - -/* fix nav-sidebar (added in django 3.1.0) */ -.admin-interface #toggle-nav-sidebar { - top: 10px; - left: 0; - z-index: 20; - flex: 0 0 30px; - width: 30px; - height: 45px; - margin-top: 10px; - margin-right: 10px; - background-color: #FFFFFF; - font-size: 16px; - border: 1px solid #eaeaea; - border-left: none; - outline: none; - -webkit-box-shadow: 4px 2px 8px -4px #DBDBDB; - -moz-box-shadow: 4px 2px 8px -4px #DBDBDB; - box-shadow: 4px 2px 8px -4px #DBDBDB; - /*transition: left .3s;*/ -} - -.admin-interface .toggle-nav-sidebar::before { - margin-top: -2px; -} - -.admin-interface .main > #nav-sidebar + .content, -.admin-interface .main.shifted > #nav-sidebar + .content { - max-width: 100%; -} - -/* hide nav-sidebar below 1280px to prevent horizontal overflow issues */ -@media (max-width:1279px) { - .admin-interface #nav-sidebar, - .admin-interface #toggle-nav-sidebar { - display: none; - } -} - -.admin-interface #nav-sidebar { - flex: 0 0 320px; - left: -320px; - margin-left: -360px; - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - padding: 40px 40px 40px 0px; - border-top: none; - border-bottom: none; - border-left: none; - /*transition: left .3s, margin-left .3s;*/ -} - -@media (min-width:1280px) { - .admin-interface #main.shifted > #toggle-nav-sidebar { - left: 359px; - } - .admin-interface #main.shifted > #nav-sidebar { - left: 0px; - margin-left: 0; - } - .admin-interface #main:not(.shifted) > .content { - max-width: 100%; - } - .admin-interface.change-list:not(.popup) #main.shifted > #nav-sidebar + .content, - .admin-interface.change-form:not(.popup) #main.shifted > #nav-sidebar + .content { - max-width: calc(100% - 360px); - } -} - -/* fixed related widget and select2 */ -/* begin fix issue #10 - Related widget broken in long tabular inline */ -.admin-interface .related-widget-wrapper { - white-space: nowrap; -} -/* end fix */ - -.admin-interface .related-widget-wrapper select + .related-widget-wrapper-link, -.admin-interface .related-widget-wrapper .select2-container + .related-widget-wrapper-link { - margin-left: 12px !important; -} - -@media (min-width: 768px) { - .admin-interface.change-form select { - min-width: 150px; - } -} - -@media (min-width: 1024px) { - .admin-interface.change-form select { - min-width: 200px; - } -} - -.admin-interface.change-form .inline-related.tabular select { - min-width: auto !important; -} - -/* fixed time widget header border radius */ -.admin-interface .clockbox.module h2 { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} - -/* fix searchbar overriden padding */ -.admin-interface #changelist #changelist-search #searchbar { - padding: 2px 5px 3px 5px; -} - -@media (min-width: 1024px) { - .admin-interface #changelist #changelist-search #searchbar, - .admin-interface #changelist #changelist-search input[type="submit"], - .admin-interface #changelist #changelist-search .quiet { - margin-left: 8px; - } - .admin-interface #changelist #changelist-search label img { - vertical-align: text-top; - margin-right: 0px; - } -} - -@media (max-width: 1024px) { - .admin-interface #changelist #toolbar { - border-top: 1px solid #eee; - border-bottom: 1px solid #eee; - } - /* fixed changelist search size when there are search results and .quiet is visible */ - .admin-interface #changelist-search label img { - margin-top: 2px; - } - .admin-interface #changelist-search .quiet { - margin: 0 0 0 10px; - align-self: center; - flex-basis: content; - } -} - -@media (max-width: 767px) { - /* fixed responsive widgets */ - .admin-interface .aligned.collapsed .form-row { - display: none; - } - - .admin-interface .aligned .form-row > div { - display: flex; - max-width: 100vw; - flex-direction: column; - align-items: flex-start; - } - - .admin-interface .aligned .form-row .help { - margin-left: 0; - } - - .admin-interface .aligned .form-row .checkbox-row label { - margin: 10px 0 0 0; - padding: 0; - } - - .admin-interface .aligned .form-row input[type="file"], - .admin-interface .aligned .form-row input[type="text"], - .admin-interface .aligned .form-row input[type="email"] { - width: 100%; - } - - /* fix textarea horizontal scroll on Firefox */ - .admin-interface .aligned .form-row textarea { - width: 100% !important; - flex: 0 1 auto; - } - - .admin-interface .aligned .form-row .datetime input[type="text"] { - width: 50%; - } - - .admin-interface .aligned .form-row span + .file-upload { - margin-top: 10px; - } - - .admin-interface .aligned .form-row .file-upload input[type="file"] { - margin-top: 5px; - } -} \ No newline at end of file diff --git a/admin_interface/templates/admin_interface/css/admin-interface.css b/admin_interface/templates/admin_interface/css/admin-interface.css deleted file mode 100644 index f3cc2eb..0000000 --- a/admin_interface/templates/admin_interface/css/admin-interface.css +++ /dev/null @@ -1,490 +0,0 @@ -@media (prefers-color-scheme: dark) { - :root .admin-interface { - --primary: #79aec8; - --secondary: #417690; - --accent: #f5dd5d; - --primary-fg: #fff; - --body-fg: #333; - --body-bg: #fff; - --body-quiet-color: #666; - --body-loud-color: #000; - --header-color: #ffc; - --header-branding-color: var(--accent); - --header-bg: var(--secondary); - --header-link-color: var(--primary-fg); - --breadcrumbs-fg: #c4dce8; - --breadcrumbs-link-fg: var(--body-bg); - --breadcrumbs-bg: var(--primary); - --link-fg: #447e9b; - --link-hover-color: #036; - --link-selected-fg: #5b80b2; - --hairline-color: #e8e8e8; - --border-color: #ccc; - --error-fg: #ba2121; - --message-success-bg: #dfd; - --message-warning-bg: #ffc; - --message-error-bg: #ffefef; - --darkened-bg: #f8f8f8; - --selected-bg: #e4e4e4; - --selected-row: #ffc; - --button-fg: #fff; - --button-bg: var(--primary); - --button-hover-bg: #609ab6; - --default-button-bg: var(--secondary); - --default-button-hover-bg: #205067; - --close-button-bg: #888; - --close-button-hover-bg: #747474; - --delete-button-bg: #ba2121; - --delete-button-hover-bg: #a41515; - --object-tools-fg: var(--button-fg); - --object-tools-bg: var(--close-button-bg); - --object-tools-hover-bg: var(--close-button-hover-bg); - } -} - -: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 { - background: {{ theme.css_header_background_color }}; - color: {{ theme.css_header_text_color }}; -} - -.admin-interface #header + #main { - {% if theme.css_header_background_color != theme.css_module_background_color %} - border-top: 10px solid {{ theme.css_module_background_color }}; - {% endif %} -} - -.admin-interface .environment-label { -} - -.admin-interface .environment-label::before { - content: ""; - display: inline-block; - width: 8px; - height: 8px; - background-color: {{ theme.env_color }}; - border-radius: 100%; - margin-right: 6px; - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; -} - -.admin-interface .environment-label::after { - content: "{{ theme.env_name }} - "; -} - -@media (max-width:1024px) { - .admin-interface .environment-label::after { - content: "{{ theme.env_name }}"; - } -} - -.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; -} - -.admin-interface #branding h1, -.admin-interface.login #header h1, -.admin-interface.login #header h1 a { - color: {{ theme.title_color }}; -} - -.admin-interface #branding h1 a { - color: inherit; -} - -.admin-interface #branding h1 .logo.default { - background-color: transparent; - background-repeat: no-repeat; - background-position: center center; - background-size: 104px 36px; - background-image: url("data:image/svg+xml;utf8,"); -} - -.admin-interface #branding h1 img.logo, -.admin-interface.login #header #branding h1 img.logo { - {% if theme.logo_max_width > 0 %} - max-width: {{ theme.logo_max_width }}px; - 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 button { - color:{{ theme.css_header_link_color }}; -} - -.admin-interface #header #user-tools a:hover, -.admin-interface #header #user-tools a:active, -.admin-interface #header #user-tools button:active, -.admin-interface #header #user-tools button:hover { - color:{{ theme.css_header_link_hover_color }}; - border-bottom-color:rgba(255, 255, 255, 0.5); -} - -.admin-interface #nav-sidebar .current-app .section:link, -.admin-interface #nav-sidebar .current-app .section:visited { - color: {{ theme.css_module_link_selected_color }}; - font-weight: normal; -} - -.admin-interface #nav-sidebar .current-app .section:focus, -.admin-interface #nav-sidebar .current-app .section:hover { - color: {{ theme.css_module_link_hover_color }}; -} - -.admin-interface #nav-sidebar .current-model { - background: {{ theme.css_module_background_selected_color }}; -} - -.admin-interface #changelist table tbody tr.selected { - background-color: {{ theme.css_module_background_selected_color }}; -} - -.admin-interface .module h2, -.admin-interface .module caption, -.admin-interface .module.filtered h2 { - background:{{ theme.css_module_background_color }}; - color:{{ theme.css_module_text_color }}; -} - -.admin-interface .module a.section:link, -.admin-interface .module a.section:visited { - color:{{ theme.css_module_link_color }}; -} - -.admin-interface .module a.section:active, -.admin-interface .module a.section:hover { - color:{{ theme.css_module_link_hover_color }}; -} - -.admin-interface div.breadcrumbs { - background:{{ theme.css_module_background_color }}; - color:{{ theme.css_module_text_color }}; -} - -.admin-interface div.breadcrumbs a { - color:{{ theme.css_module_link_color }}; -} - -.admin-interface div.breadcrumbs a:active, -.admin-interface div.breadcrumbs a:focus, -.admin-interface div.breadcrumbs a:hover { - color:{{ theme.css_module_link_hover_color }}; -} - -.admin-interface fieldset.collapse.collapsed a.collapse-toggle { - color:{{ theme.css_module_link_color }}; -} - -.admin-interface fieldset.collapse.collapsed a.collapse-toggle:hover, -.admin-interface fieldset.collapse.collapsed a.collapse-toggle:active { - color:{{ theme.css_module_link_hover_color }}; -} - -.admin-interface fieldset.collapse a.collapse-toggle { - color:{{ theme.css_module_link_color }}; -} - -.admin-interface fieldset.collapse a.collapse-toggle:hover, -.admin-interface fieldset.collapse a.collapse-toggle:active { - color:{{ theme.css_module_link_hover_color }}; -} - -.admin-interface .inline-group h2 { - background:{{ theme.css_module_background_color }}; - color:{{ theme.css_module_text_color }}; -} - -.admin-interface .selector .selector-chosen h2 { - border-color:{{ theme.css_module_background_color }}; - background:{{ theme.css_module_background_color }}; - color:{{ theme.css_module_text_color }}; -} - -.admin-interface .selector .selector-available h2, -.admin-interface .selector .selector-chosen h2 { - {% if theme.css_module_rounded_corners %} - border-bottom-left-radius:0; - border-bottom-right-radius:0; - {% endif %} -} - -.admin-interface .selector a.selector-chooseall:focus, -.admin-interface .selector a.selector-chooseall:hover, -.admin-interface .selector a.selector-clearall:focus, -.admin-interface .selector a.selector-clearall:hover { - color:{{ theme.css_generic_link_hover_color }}; -} - -.admin-interface a:link, -.admin-interface a:visited { - color:{{ theme.css_generic_link_color }}; -} - -.admin-interface a:hover { - color:{{ theme.css_generic_link_hover_color }}; -} - -.admin-interface thead th a, -.admin-interface thead th a:link, -.admin-interface thead th a:visited, -.admin-interface thead th a:focus, -.admin-interface thead th a:hover { - color: #666666; -} - -.admin-interface .button, -.admin-interface input[type=submit], -.admin-interface input[type=button], -.admin-interface .submit-row input, -.admin-interface a.button { - background:{{ theme.css_save_button_background_color }}; - color:{{ theme.css_save_button_text_color }}; -} - -.admin-interface .button:active, -.admin-interface .button:focus, -.admin-interface .button:hover, -.admin-interface input[type=submit]:active, -.admin-interface input[type=submit]:focus, -.admin-interface input[type=submit]:hover, -.admin-interface input[type=button]:active, -.admin-interface input[type=button]:focus, -.admin-interface input[type=button]:hover { - background:{{ theme.css_save_button_background_hover_color }}; - color:{{ theme.css_save_button_text_color }}; - outline: none; -} - -.admin-interface .button.default, -.admin-interface input[type=submit].default, -.admin-interface .submit-row input.default { - background:{{ theme.css_save_button_background_color }}; - color:{{ theme.css_save_button_text_color }}; - outline: none; -} - -.admin-interface .button.default:active, -.admin-interface .button.default:focus, -.admin-interface .button.default:hover, -.admin-interface input[type=submit].default:active, -.admin-interface input[type=submit].default:focus, -.admin-interface input[type=submit].default:hover, -.admin-interface.delete-confirmation form .cancel-link:hover { - background:{{ theme.css_save_button_background_hover_color }}; - color:{{ theme.css_save_button_text_color }}; - outline: none; -} - -.admin-interface .submit-row a.deletelink:link, -.admin-interface .submit-row a.deletelink:visited, -.admin-interface.delete-confirmation form input[type="submit"] { - background:{{ theme.css_delete_button_background_color }}; - color:{{ theme.css_delete_button_text_color }}; -} - -.admin-interface .submit-row a.deletelink:hover, -.admin-interface.delete-confirmation form input[type="submit"]:hover { - background:{{ theme.css_delete_button_background_hover_color }}; - color:{{ theme.css_delete_button_text_color }}; -} - -.admin-interface .paginator a, -.admin-interface .paginator a:link, -.admin-interface .paginator a:visited, -.admin-interface .paginator .this-page { - {% if theme.css_module_rounded_corners %}border-radius:4px;{% endif %} -} - -.admin-interface .paginator a, -.admin-interface .paginator a:link, -.admin-interface .paginator a:visited { - background-color:#FFFFFF; - color:{{ theme.css_generic_link_color }}; -} - -.admin-interface .paginator a:hover, -.admin-interface .paginator a:active { - background-color:#F8F8F8; - color:{{ theme.css_generic_link_hover_color }}; -} - -.admin-interface .paginator .this-page { - background-color:{{ theme.css_module_background_color }}; - color:{{ theme.css_module_link_color }}; -} - -.admin-interface .paginator a.showall, -.admin-interface .paginator a.showall:link, -.admin-interface .paginator a.showall:visited { - color:{{ theme.css_generic_link_color }}; -} - -.admin-interface .paginator a.showall:hover, -.admin-interface .paginator a.showall:active { - color:{{ theme.css_generic_link_hover_color }}; -} - -/* list-filter sticky */ -{% if theme.list_filter_sticky %} -@media (min-width: 768px) { - .admin-interface .module.filtered #changelist-filter { - position: sticky; - top: 40px; - float: right; - z-index: 30; - } - /* feature not available for django < 3.1.2 */ - .admin-interface .module.filtered #toolbar + #changelist-filter { - position: absolute; - top: 0px; - z-index: 30; - } -} -{% endif %} - -.admin-interface .module.filtered #changelist-filter { - {% if theme.css_module_rounded_corners %} - 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:hover { - color: #666; - text-decoration: none; -} - -.admin-interface .module.filtered #changelist-filter li a:focus, -.admin-interface .module.filtered #changelist-filter li a:hover { - color: #666; - text-decoration: none; -} - -.admin-interface .module.filtered #changelist-filter li.selected a, -.admin-interface .module.filtered #changelist-filter li.selected a:link, -.admin-interface .module.filtered #changelist-filter li.selected a:visited, -.admin-interface .module.filtered #changelist-filter li.selected a:focus, -.admin-interface .module.filtered #changelist-filter li.selected a:hover { - /* color: #666; */ - color: {{ theme.css_generic_link_hover_color }}; -} - -/* begin fix issue #11 - Inline border bottom should not be rounded */ -.admin-interface .module h2, -.admin-interface.dashboard .module caption, -.admin-interface #nav-sidebar .module th, -.admin-interface #nav-sidebar .module caption, -.admin-interface .module.filtered h2 { - {% if theme.css_module_rounded_corners %} - border-radius:4px; - {% endif %} -} - -.admin-interface .inline-group h2 { - {% if theme.css_module_rounded_corners %} - border-bottom-left-radius:0; - border-bottom-right-radius:0; - {% endif %} -} - -.admin-interface .module.collapse.collapsed h2 { - /* fix collapsed inlines rounded bottom borders */ - {% if theme.css_module_rounded_corners %} - border-bottom-left-radius:4px; - border-bottom-right-radius:4px; - {% endif %} -} -/* end fix */ - -.admin-interface #content-related { - {% if theme.css_module_rounded_corners %} - border-radius:4px; - {% endif %} -} - -.admin-interface .select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] { - background-color: {{ theme.css_module_background_color }}; - color: {{ theme.css_module_text_color }}; -} - -.admin-interface #toggle-nav-sidebar { - {% if theme.css_module_rounded_corners %} - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - {% endif %} - color: {{ theme.css_generic_link_color }}; -} - -.admin-interface #toggle-nav-sidebar:focus, -.admin-interface #toggle-nav-sidebar:hover, -.admin-interface #toggle-nav-sidebar:active { - color: {{ theme.css_generic_link_hover_color }}; -} - -.admin-interface .calendar td.selected a, -.admin-interface .calendar td a:active, -.admin-interface .calendar td a:focus, -.admin-interface .calendar td a:hover, -.admin-interface .timelist a:active, -.admin-interface .timelist a:focus, -.admin-interface .timelist a:hover { - background: {{ theme.css_module_background_color }}; -} diff --git a/admin_interface/templates/admin_interface/css/list-filter-dropdown.css b/admin_interface/templates/admin_interface/css/list-filter-dropdown.css deleted file mode 100644 index d1fc14c..0000000 --- a/admin_interface/templates/admin_interface/css/list-filter-dropdown.css +++ /dev/null @@ -1,14 +0,0 @@ -/* -list-filter-dropdown -*/ - -.admin-interface .list-filter-dropdown { - margin-top:10px; - margin-bottom:20px; -} - -.admin-interface .list-filter-dropdown select { - background-color: #FFFFFF; - width: calc(100% - 30px); - margin-right: 15px; -} \ No newline at end of file diff --git a/admin_interface/templates/admin_interface/css/recent-actions.css b/admin_interface/templates/admin_interface/css/recent-actions.css deleted file mode 100644 index 2f43712..0000000 --- a/admin_interface/templates/admin_interface/css/recent-actions.css +++ /dev/null @@ -1,9 +0,0 @@ -{% if not theme.recent_actions_visible %} -.admin-interface.dashboard #content { - max-width:600px; - margin-right:0; -} -.admin-interface.dashboard #content #recent-actions-module { - display:none; -} -{% endif %} \ No newline at end of file diff --git a/admin_interface/templates/admin_interface/date_hierarchy_removal_link.html b/admin_interface/templates/admin_interface/date_hierarchy_removal_link.html new file mode 100644 index 0000000..bab4a3a --- /dev/null +++ b/admin_interface/templates/admin_interface/date_hierarchy_removal_link.html @@ -0,0 +1,3 @@ + diff --git a/admin_interface/templates/admin_interface/dropdown_filter.html b/admin_interface/templates/admin_interface/dropdown_filter.html index 2ec6ce4..6a37d5c 100644 --- a/admin_interface/templates/admin_interface/dropdown_filter.html +++ b/admin_interface/templates/admin_interface/dropdown_filter.html @@ -1,7 +1,7 @@ {% load i18n %}
    -

    {% blocktrans with title as filter_title %} By {{ filter_title }} {% endblocktrans %}

    +

    {% blocktrans with title as filter_title %} By {{ filter_title }} {% endblocktrans %}

    - - {% endfor %} -
    - {% csrf_token %} - +
    diff --git a/admin_interface/templates/admin_interface/list_filter_removal_link.html b/admin_interface/templates/admin_interface/list_filter_removal_link.html new file mode 100644 index 0000000..9b54c75 --- /dev/null +++ b/admin_interface/templates/admin_interface/list_filter_removal_link.html @@ -0,0 +1,5 @@ +{% if spec.lookup_val or spec.value %} + +{% endif %} diff --git a/admin_interface/templates/admin_interface/related-modal.html b/admin_interface/templates/admin_interface/related-modal.html index 0d56d5a..e96f386 100644 --- a/admin_interface/templates/admin_interface/related-modal.html +++ b/admin_interface/templates/admin_interface/related-modal.html @@ -1,7 +1,8 @@ {% load static %} {% if theme.related_modal_active %} - - - + + + + {% endif %} diff --git a/admin_interface/templatetags/admin_interface_tags.py b/admin_interface/templatetags/admin_interface_tags.py index 9221b77..50ee93c 100644 --- a/admin_interface/templatetags/admin_interface_tags.py +++ b/admin_interface/templatetags/admin_interface_tags.py @@ -1,90 +1,193 @@ -# -*- coding: utf-8 -*- - -import django +import datetime import hashlib import re +import warnings from django import template from django.conf import settings +from django.contrib.admin.utils import get_fields_from_path +from django.urls import NoReverseMatch, reverse from django.utils import translation +from slugify import slugify from admin_interface.cache import get_cached_active_theme, set_cached_active_theme -from admin_interface.compat import NoReverseMatch, reverse +from admin_interface.metadata import __version__ from admin_interface.models import Theme -from admin_interface.version import __version__ - register = template.Library() -if django.VERSION < (1, 9): - simple_tag = register.assignment_tag -else: - simple_tag = register.simple_tag - -@simple_tag(takes_context=True) -def get_admin_interface_languages(context): +@register.inclusion_tag("admin_interface/language_chooser.html", takes_context=True) +def admin_interface_language_chooser(context): if not settings.USE_I18N: # i18n disabled return None if len(settings.LANGUAGES) < 2: # less than 2 languages return None + if "django.middleware.locale.LocaleMiddleware" not in settings.MIDDLEWARE: + warnings.warn( + "Language chooser requires 'django.middleware.locale.LocaleMiddleware' " + "in your MIDDLEWARE to work.", + stacklevel=1, + ) + return None try: - set_language_url = reverse("set_language") + context["set_language_url"] = reverse("set_language") except NoReverseMatch: - # ImproperlyConfigured - must include i18n urls: - # urlpatterns += [url(r'^i18n/', include('django.conf.urls.i18n')),] + warnings.warn( + "Language chooser requires Django's `set_language` view: " + "`urlpatterns += [url(r'^i18n/', include('django.conf.urls.i18n'))]`.", + stacklevel=1, + ) return None request = context.get("request", None) if not request: return None + context["LANGUAGES"] = settings.LANGUAGES + full_path = request.get_full_path() admin_nolang_url = re.sub(r"^\/([\w]{2})([\-\_]{1}[\w]{2,4})?\/", "/", full_path) - if admin_nolang_url == full_path: - # ImproperlyConfigured - must include admin urls using i18n_patterns: - # from django.conf.urls.i18n import i18n_patterns - # urlpatterns += i18n_patterns(url(r'^admin/', admin.site.urls)) - return None - langs_data = [] + default_lang_code = settings.LANGUAGE_CODE current_lang_code = translation.get_language() or default_lang_code - for language in settings.LANGUAGES: - lang_code = language[0].lower() - lang_name = language[1].title() - lang_data = { - "code": lang_code, - "name": lang_name, - "default": lang_code == default_lang_code, - "active": lang_code == current_lang_code, - "activation_url": "{}?next=/{}{}".format( - set_language_url, lang_code, admin_nolang_url - ), - } - langs_data.append(lang_data) - return langs_data + context["LANGUAGE_CODE"] = current_lang_code + context["next"] = admin_nolang_url + return context -@simple_tag(takes_context=True) -def get_admin_interface_theme(context): +@register.simple_tag() +def get_admin_interface_theme(): # theme = get_cached_active_theme() # if not theme: - theme = Theme.get_active_theme() + theme = Theme.objects.get_active() # set_cached_active_theme(theme) return theme -@simple_tag(takes_context=False) +@register.simple_tag() +def get_admin_interface_setting(setting): + theme = get_admin_interface_theme() + return getattr(theme, setting) + + +@register.simple_tag() +def get_admin_interface_inline_template(template): + template_path = template.split("/") + if template_path[0] != "admin": + # return costume inline template for other packages + return template + template_path[-1] = "headerless_" + template_path[-1] + return "/".join(template_path) + + +@register.simple_tag() def get_admin_interface_version(): return __version__ def hash_string(text): - hash_object = hashlib.md5(text.encode()) - md5_hash = hash_object.hexdigest() - return md5_hash + hash_object = hashlib.sha224(text.encode()) + sha224_hash = hash_object.hexdigest() + return sha224_hash -@simple_tag(takes_context=False) +@register.simple_tag() def get_admin_interface_nocache(): return hash_string(__version__) + + +@register.simple_tag(takes_context=False) +def get_admin_interface_active_date_hierarchy(changelist): + date_field_name = changelist.date_hierarchy + if not date_field_name: + return + + params = changelist.get_filters_params() + # link to clear all filters contains f'{date_field_name}__gte', + # only filters with specific year are really active + if f"{date_field_name}__year" not in params: + return + + return date_field_name + + +@register.inclusion_tag("admin_interface/list_filter_removal_link.html") +def admin_interface_filter_removal_link(changelist, list_filter): + title = list_filter.title + choices = [ + choice for choice in list_filter.choices(changelist) if choice.get("selected") + ] + try: + value = choices[0]["display"] + except (IndexError, KeyError): + value = "..." + + removal_link = changelist.get_query_string(remove=list_filter.expected_parameters()) + + return { + "cl": changelist, + "spec": list_filter, + "selected_value": value, + "title": title, + "removal_link": removal_link, + } + + +@register.inclusion_tag("admin_interface/date_hierarchy_removal_link.html") +def admin_interface_date_hierarchy_removal_link(changelist, date_field_name): + date_field_path = get_fields_from_path(changelist.model, date_field_name) + # date_field = date_field_path[-1] + date_labels = [str(field.verbose_name) for field in date_field_path] + date_label = " ".join(date_labels).lower() + + params = changelist.get_filters_params() + date_params = [param for param in params if param.startswith(date_field_name)] + + date_args = [datetime.datetime.now().year, 1, 1] + date_format = "Y" + date_filters = ( + ("year", "Y"), + ("month", "YEAR_MONTH_FORMAT"), + ("day", "DATE_FORMAT"), + ) + for index, date_filter in enumerate(date_filters): + date_filter_key, date_filter_format = date_filter + date_filter_param = f"{date_field_name}__{date_filter_key}" + if date_filter_param in params: + param = params[date_filter_param] + date_args[index] = ( + int(param[0]) if isinstance(param, (list, tuple)) else int(param) + ) + date_format = date_filter_format + continue + break + date_value = datetime.date(*date_args) + + removal_link = changelist.get_query_string(remove=date_params) + + return { + "cl": changelist, + "date_label": date_label, + "date_value": date_value, + "date_format": date_format, + "removal_link": removal_link, + } + + +@register.simple_tag() +def admin_interface_use_changeform_tabs(adminform, inline_forms): + theme = get_admin_interface_theme() + has_fieldset_tabs = ( + theme.show_fieldsets_as_tabs and adminform and len(adminform.fieldsets) > 1 + ) + has_inline_tabs = ( + theme.show_inlines_as_tabs and inline_forms and len(inline_forms) > 0 + ) + has_tabs = has_fieldset_tabs or has_inline_tabs + return has_tabs + + +@register.filter +def admin_interface_slugify(name): + return slugify(str(name or "")) diff --git a/admin_interface/version.py b/admin_interface/version.py deleted file mode 100644 index ef6eeab..0000000 --- a/admin_interface/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -__version__ = "0.19.8" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..1126454 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,99 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "django-admin-interface" +description = "django's default admin interface with superpowers - customizable themes, popup windows replaced by modals and many other features." +authors = [ + { name = "Fabio Caccamo", email = "fabio.caccamo@gmail.com" }, +] +keywords = [ + "django", + "admin", + "interface", + "responsive", + "flat", + "theme", + "custom", + "ui", +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", + "Framework :: Django", + "Framework :: Django :: 3.0", + "Framework :: Django :: 3.1", + "Framework :: Django :: 3.2", + "Framework :: Django :: 4.0", + "Framework :: Django :: 4.1", + "Framework :: Django :: 4.2", + "Framework :: Django :: 5.0", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Software Development :: Build Tools", +] +dependencies = [ + "django-colorfield >= 0.8.0, < 1.0.0", + "python-slugify >= 7.0.0, < 9.0.0", +] +dynamic = ["version"] +maintainers = [ + { name = "Fabio Caccamo", email = "fabio.caccamo@gmail.com" }, +] + +[project.readme] +file = "README.md" +content-type = "text/markdown" + +[project.license] +file = "LICENSE.txt" +content-type = "text/plain" + +[project.urls] +Homepage = "https://github.com/fabiocaccamo/django-admin-interface" +Download = "https://github.com/fabiocaccamo/django-admin-interface/releases" +Documentation = "https://github.com/fabiocaccamo/django-admin-interface#readme" +Issues = "https://github.com/fabiocaccamo/django-admin-interface/issues" +Funding = "https://github.com/sponsors/fabiocaccamo/" +Twitter = "https://twitter.com/fabiocaccamo" + +[tool.black] +line-length = 88 +include = '\.pyi?$' +exclude = ''' +/( + \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist + | venv +)/ +''' + +[tool.ruff] +ignore = [] +line-length = 88 +select = ["B", "B9", "C", "E", "F", "W"] + +[tool.ruff.mccabe] +max-complexity = 10 + +[tool.setuptools.packages.find] +include = ["admin_interface*"] + +[tool.setuptools.dynamic.version] +attr = "admin_interface.metadata.__version__" diff --git a/requirements-test.txt b/requirements-test.txt index c138fc7..649e53c 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,4 +1,4 @@ -codecov -coverage -psycopg2 -tox +coverage == 7.4.* +pre-commit == 3.5.* +psycopg2-binary == 2.9.* +tox == 4.12.* diff --git a/requirements.txt b/requirements.txt index 47d2349..f776940 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,3 @@ -django>=1.7 -django-colorfield -django-flat-theme -django-flat-responsive -six>=1.9.0 +django >= 2.2 +django-colorfield == 0.11.0 +python-slugify == 8.0.4 diff --git a/runtests.py b/runtests.py index 7075c55..06e1173 100755 --- a/runtests.py +++ b/runtests.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import os import sys @@ -14,8 +12,9 @@ def runtests(): TestRunner = get_runner(settings) test_runner = TestRunner() failures = test_runner.run_tests(["tests"]) - sys.exit(bool(failures)) + return failures if __name__ == "__main__": - runtests() + failures = runtests() + sys.exit(bool(failures)) diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 224a779..0000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[metadata] -description-file = README.md \ No newline at end of file diff --git a/setup.py b/setup.py index 7f7233f..7f1a176 100644 --- a/setup.py +++ b/setup.py @@ -1,98 +1,4 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- +from setuptools import setup -from setuptools import find_packages, setup - -import os, sys - -exec(open("admin_interface/version.py").read()) - -github_url = "https://github.com/fabiocaccamo" -sponsor_url = "https://github.com/sponsors/fabiocaccamo/" -twitter_url = "https://twitter.com/fabiocaccamo" -package_name = "django-admin-interface" -package_url = "{}/{}".format(github_url, package_name) -package_issues_url = "{}/issues".format(github_url) -package_path = os.path.abspath(os.path.dirname(__file__)) -long_description_file_path = os.path.join(package_path, "README.md") -long_description_content_type = "text/markdown" -long_description = "" -try: - long_description_file_options = ( - {} if sys.version_info[0] < 3 else {"encoding": "utf-8"} - ) - with open(long_description_file_path, "r", **long_description_file_options) as f: - long_description = f.read() -except IOError: - pass - -setup( - name=package_name, - packages=find_packages(exclude=["contrib", "docs", "tests*"]), - include_package_data=True, - version=__version__, - description="django-admin-interface is a modern responsive flat admin interface customizable by the admin itself.", - long_description=long_description, - long_description_content_type=long_description_content_type, - author="Fabio Caccamo", - author_email="fabio.caccamo@gmail.com", - url=package_url, - download_url="{}/archive/{}.tar.gz".format(package_url, __version__), - project_urls={ - "Documentation": package_url, - "Issues": package_issues_url, - "Funding": sponsor_url, - "Twitter": twitter_url, - }, - keywords=[ - "django", - "admin", - "interface", - "responsive", - "flat", - "theme", - "custom", - "ui", - ], - requires=["django(>=1.7)"], - install_requires=[ - "django-colorfield >= 0.2, < 1.0", - "django-flat-theme >= 1.0, < 2.0", - "django-flat-responsive >= 1.0, < 3.0", - "six >= 1.9.0, < 2.0.0", - ], - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Framework :: Django", - "Framework :: Django :: 1.7", - "Framework :: Django :: 1.8", - "Framework :: Django :: 1.9", - "Framework :: Django :: 1.10", - "Framework :: Django :: 1.11", - "Framework :: Django :: 2.0", - "Framework :: Django :: 2.1", - "Framework :: Django :: 2.2", - "Framework :: Django :: 3.0", - "Framework :: Django :: 3.1", - "Framework :: Django :: 3.2", - "Framework :: Django :: 4.0", - "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", - "Natural Language :: English", - "Operating System :: OS Independent", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Topic :: Software Development :: Build Tools", - ], - license="MIT", - test_suite="runtests.runtests", -) +if __name__ == "__main__": + setup() diff --git a/tests/routers.py b/tests/routers.py new file mode 100644 index 0000000..988acfd --- /dev/null +++ b/tests/routers.py @@ -0,0 +1,45 @@ +DATABASE_APPS_MAPPING = { + "admin_interface": "default", +} + + +class DatabaseAppsRouter: + """ + arouter to control all database operations on models for different + databases. + + in case an app is not set in DATABASE_APPS_MAPPING, the router + will fallback to the `default` database. + + Settings example: + + DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'} + """ + + def __init__(self, db_map=DATABASE_APPS_MAPPING): + """ + If routers is not specified, default to DATABASE_APPS_MAPPING + """ + self.db_map = db_map + + def db_for_read(self, model, **hints): + """Point all read operations to the specific database""" + if model._meta.app_label in self.db_map: + return self.db_map[model._meta.app_label] + + return None + + def db_for_write(self, model, **hints): + """Point all write operations to the specific database""" + if model._meta.app_label in self.db_map: + return self.db_map[model._meta.app_label] + + return None + + def allow_relation(self, obj1, obj2, **hints): + """Allow any relation between apps that use the same database""" + return None + + def allow_migrate(self, db, app_label, model_name=None, **hints): + """Make sure that apps only appear in the related database""" + return None diff --git a/tests/settings.py b/tests/settings.py index ff83efc..812a821 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -1,8 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - -import django import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -17,17 +12,6 @@ INSTALLED_APPS = [ "colorfield", ] -if django.VERSION < (1, 9): - # ONLY if django version < 1.9 - INSTALLED_APPS += [ - "flat", - ] - -if django.VERSION < (2, 0): - # ONLY if django version < 2.0 - INSTALLED_APPS += [ - "flat_responsive", - ] INSTALLED_APPS += [ "django.contrib.admin", @@ -37,20 +21,13 @@ INSTALLED_APPS += [ "django.contrib.sessions", ] -if django.VERSION < (2, 0): - MIDDLEWARE_CLASSES = [ - "django.contrib.auth.middleware.AuthenticationMiddleware", - "django.contrib.messages.middleware.MessageMiddleware", - "django.contrib.sessions.middleware.SessionMiddleware", - "django.middleware.common.CommonMiddleware", - ] -else: - MIDDLEWARE = [ - "django.contrib.auth.middleware.AuthenticationMiddleware", - "django.contrib.messages.middleware.MessageMiddleware", - "django.contrib.sessions.middleware.SessionMiddleware", - "django.middleware.common.CommonMiddleware", - ] +MIDDLEWARE = [ + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.locale.LocaleMiddleware", +] TEMPLATES = [ { @@ -89,6 +66,14 @@ database_config = { "HOST": "", "PORT": "", }, + "postgres_replica": { + "ENGINE": "django.db.backends.postgresql_psycopg2", + "NAME": "admin_interface_2", + "USER": "postgres", + "PASSWORD": "postgres", + "HOST": "", + "PORT": "", + }, } github_workflow = os.environ.get("GITHUB_WORKFLOW") @@ -96,24 +81,38 @@ if github_workflow: database_config["postgres"]["NAME"] = "postgres" database_config["postgres"]["HOST"] = "127.0.0.1" database_config["postgres"]["PORT"] = "5432" + database_config["postgres_replica"]["HOST"] = "127.0.0.1" + database_config["postgres_replica"]["PORT"] = "5432" + +replica_engine = ( + "postgres_replica" if database_engine == "postgres" else database_engine +) DATABASES = { "default": database_config.get(database_engine), + "replica": database_config.get(replica_engine), } + +DATABASE_ROUTERS = ["tests.routers.DatabaseAppsRouter"] + USE_I18N = True LANGUAGES = ( - ( - "en", - "English", - ), - ( - "it", - "Italian", - ), + ("de", "Deutsch"), + ("en", "English"), + ("es", "Español"), + ("fa", "Farsi"), + ("fr", "Français"), + ("it", "Italiano"), + ("pl", "Polski"), + ("pt-BR", "Português"), + ("ru", "Русский"), + ("tr", "Türk"), ) LANGUAGE_CODE = "en" +LOCALE_PATHS = (os.path.join(BASE_DIR, "admin_interface/locale/"),) + ROOT_URLCONF = "tests.urls" MEDIA_ROOT = os.path.join(BASE_DIR, "admin_interface/public/media/") diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 15c8dc3..9e1768e 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.core.management import call_command from django.test import TestCase @@ -16,7 +12,7 @@ class AdminInterfaceFixturesTestCase(TestCase): pass def __load_theme(self, theme_name): - call_command("loaddata", "admin_interface_theme_%s.json" % (theme_name,)) + call_command("loaddata", f"admin_interface_theme_{theme_name}.json") def test_import_initial_data(self): call_command("loaddata", "initial_data.json") @@ -42,10 +38,10 @@ class AdminInterfaceFixturesTestCase(TestCase): self.assertEqual(Theme.objects.count(), 2) def test_import_override(self): - obj1 = Theme.get_active_theme() + obj1 = Theme.objects.get_active() obj1.title = "Custom 1" obj1.save() self.__load_theme("django") - obj2 = Theme.get_active_theme() + obj2 = Theme.objects.get_active() self.assertEqual(obj1.pk, obj2.pk) self.assertTrue(obj1.title != obj2.title) diff --git a/tests/test_metadata.py b/tests/test_metadata.py new file mode 100644 index 0000000..bf19084 --- /dev/null +++ b/tests/test_metadata.py @@ -0,0 +1,34 @@ +import re + +from django.test import TestCase + +from admin_interface.metadata import ( + __author__, + __copyright__, + __description__, + __email__, + __license__, + __title__, + __version__, +) + + +class MetadataTestCase(TestCase): + """ + This class describes a metadata test case. + """ + + def test_metadata(self): + self.assertTrue(isinstance(__author__, str)) + self.assertTrue(isinstance(__copyright__, str)) + self.assertTrue(isinstance(__description__, str)) + self.assertTrue(isinstance(__email__, str)) + self.assertTrue(isinstance(__license__, str)) + self.assertTrue(isinstance(__title__, str)) + self.assertTrue(isinstance(__version__, str)) + + def test_version(self): + v = __version__ + v_re = re.compile(r"^([0-9]+)(\.([0-9]+)){1,2}$") + v_match = v_re.match(v) + self.assertTrue(v_match is not None) diff --git a/tests/test_models.py b/tests/test_models.py index 387f43e..5754e96 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,13 +1,9 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals +import random +import shutil from django.conf import settings from django.test import TestCase -import random -import shutil - from admin_interface.models import Theme @@ -16,12 +12,13 @@ class AdminInterfaceModelsTestCase(TestCase): pass def tearDown(self): + Theme.objects.all().delete() shutil.rmtree(settings.MEDIA_ROOT, ignore_errors=True) def __test_active_theme(self): - theme = Theme.get_active_theme() + theme = Theme.objects.get_active() print(theme) - self.assertTrue(theme != None) + self.assertTrue(theme is not None) self.assertTrue(theme.active) self.assertEqual(Theme.objects.filter(active=True).count(), 1) @@ -35,7 +32,7 @@ class AdminInterfaceModelsTestCase(TestCase): def test_default_theme_activated_on_save_if_no_active_themes(self): Theme.objects.all().delete() - theme = Theme.get_active_theme() + theme = Theme.objects.get_active() theme.active = False theme.save() self.__test_active_theme() @@ -47,27 +44,27 @@ class AdminInterfaceModelsTestCase(TestCase): def test_default_theme_activated_after_update_if_multiple_active_themes(self): Theme.objects.all().delete() - theme_1 = Theme.objects.create(name="Custom 1", active=True) - theme_2 = Theme.objects.create(name="Custom 2", active=True) - theme_3 = Theme.objects.create(name="Custom 3", active=True) + Theme.objects.create(name="Custom 1", active=True) + Theme.objects.create(name="Custom 2", active=True) + Theme.objects.create(name="Custom 3", active=True) Theme.objects.update(active=False) Theme.objects.update(active=True) self.__test_active_theme() def test_default_theme_activated_on_active_theme_deleted(self): Theme.objects.all().delete() - theme_1 = Theme.objects.create(name="Custom 1", active=True) - theme_2 = Theme.objects.create(name="Custom 2", active=True) - theme_3 = Theme.objects.create(name="Custom 3", active=True) - Theme.objects.filter(pk=Theme.get_active_theme().pk).delete() + Theme.objects.create(name="Custom 1", active=True) + Theme.objects.create(name="Custom 2", active=True) + Theme.objects.create(name="Custom 3", active=True) + Theme.objects.filter(pk=Theme.objects.get_active().pk).delete() self.__test_active_theme() def test_last_theme_activated_on_multiple_themes_created(self): Theme.objects.all().delete() - theme_1 = Theme.objects.create(name="Custom 1", active=True) - theme_2 = Theme.objects.create(name="Custom 2", active=True) + Theme.objects.create(name="Custom 1", active=True) + Theme.objects.create(name="Custom 2", active=True) theme_3 = Theme.objects.create(name="Custom 3", active=True) - self.assertEqual(Theme.get_active_theme().pk, theme_3.pk) + self.assertEqual(Theme.objects.get_active().pk, theme_3.pk) self.__test_active_theme() def test_last_theme_activated_on_multiple_themes_activated(self): @@ -78,13 +75,42 @@ class AdminInterfaceModelsTestCase(TestCase): theme_4 = Theme.objects.create(name="Custom 4", active=True) theme_5 = Theme.objects.create(name="Custom 5", active=True) themes = [theme_1, theme_2, theme_3, theme_4, theme_5] - for i in range(5): + for _ in range(5): random.shuffle(themes) for theme in themes: theme.set_active() - self.assertEqual(Theme.get_active_theme().pk, theme.pk) + self.assertEqual(Theme.objects.get_active().pk, theme.pk) self.__test_active_theme() def test_repr(self): - theme = Theme.get_active_theme() - self.assertEqual("{0}".format(theme), "Django") + theme = Theme.objects.get_active() + self.assertEqual(repr(theme), "") + + def test_str(self): + theme = Theme.objects.get_active() + self.assertEqual(str(theme), "Django") + + +# class AdminInterfaceModelsMultiDBTestCase(TestCase): +# databases = ["default", "replica"] + +# @classmethod +# def setUpTestData(cls): +# Theme.objects.create(name="Change Active", active=True) + +# def test_get_theme_from_default_db(self): +# de_theme = Theme.objects.get_active() +# assert de_theme.name == "Change Active" + +# def test_get_theme_from_replica_db(self): +# replica_theme = Theme.objects.get_active(database="replica") +# assert replica_theme.name == "Django" + +# def test_db_are_isolated(self): +# default_theme = Theme.objects.get_active() +# replica_theme = Theme.objects.get_active(database="replica") +# assert default_theme.name != replica_theme.name + +# @expectedFailure +# def test_fail_for_wrong_db_defined_in_kwargs(self): +# Theme.objects.get_active(database="other") diff --git a/tests/test_multidb.py b/tests/test_multidb.py new file mode 100644 index 0000000..456422e --- /dev/null +++ b/tests/test_multidb.py @@ -0,0 +1,39 @@ +from django.test import TestCase + +from admin_interface.models import Theme + +from .routers import DatabaseAppsRouter + +try: + from django.test.testcases import DatabaseOperationForbidden +except ImportError: + DatabaseOperationForbidden = AssertionError + + +class AdminInterfaceModelsWithDBRoutingTestCase(TestCase): + databases = ["replica"] + + def test_standard_dbrouter(self): + router = DatabaseAppsRouter() + db_for_theme = router.db_for_read(Theme) + self.assertEqual(db_for_theme, "default") + + def test_dbrouter_selects_correct_db(self): + DATABASE_APPS_MAPPING = { + "admin_interface": "replica", + } + router = DatabaseAppsRouter(db_map=DATABASE_APPS_MAPPING) + db_for_theme = router.db_for_read(Theme) + self.assertEqual(db_for_theme, "replica") + + def test_dbrouter_errors_when_fetching_from_default(self): + with self.assertRaises(DatabaseOperationForbidden): + Theme.objects.get_active() + + def test_dbrouter_fetches_db(self): + DATABASE_APPS_MAPPING = { + "admin_interface": "replica", + } + router = DatabaseAppsRouter(db_map=DATABASE_APPS_MAPPING) + with self.settings(DATABASE_ROUTERS=[router]): + Theme.objects.get_active() diff --git a/tests/test_settings.py b/tests/test_settings.py index cac8171..4a7e64e 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -1,17 +1,11 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - -import django from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from admin_interface.settings import check_installed_apps class AdminInterfaceSettingsTestCase(TestCase): - DJANGO_APPS = [ "django.contrib.admin", "django.contrib.auth", @@ -27,24 +21,10 @@ class AdminInterfaceSettingsTestCase(TestCase): pass def __test_installed_apps(self): - dj_version = django.VERSION installed_apps = settings.INSTALLED_APPS if "colorfield" not in installed_apps: self.assertRaises(ImproperlyConfigured, check_installed_apps) - - elif "flat" not in installed_apps and dj_version < (1, 9): - self.assertRaises(ImproperlyConfigured, check_installed_apps) - - elif "flat" in installed_apps and dj_version >= (1, 9): - self.assertRaises(ImproperlyConfigured, check_installed_apps) - - elif "flat_responsive" not in installed_apps and dj_version < (2, 0): - self.assertRaises(ImproperlyConfigured, check_installed_apps) - - elif "flat_responsive" in installed_apps and dj_version >= (2, 0): - self.assertRaises(ImproperlyConfigured, check_installed_apps) - else: check_installed_apps() @@ -52,8 +32,6 @@ class AdminInterfaceSettingsTestCase(TestCase): INSTALLED_APPS=[ "admin_interface", "colorfield", - "flat", - "flat_responsive", ] + DJANGO_APPS ) @@ -64,34 +42,8 @@ class AdminInterfaceSettingsTestCase(TestCase): INSTALLED_APPS=[ "admin_interface", # 'colorfield', - "flat", - "flat_responsive", ] + DJANGO_APPS ) def test_installed_apps_no_colorfield(self): self.__test_installed_apps() - - @override_settings( - INSTALLED_APPS=[ - "admin_interface", - "colorfield", - # 'flat', - "flat_responsive", - ] - + DJANGO_APPS - ) - def test_installed_apps_no_flat(self): - self.__test_installed_apps() - - @override_settings( - INSTALLED_APPS=[ - "admin_interface", - "colorfield", - "flat", - # 'flat_responsive', - ] - + DJANGO_APPS - ) - def test_installed_apps_no_flat_responsive(self): - self.__test_installed_apps() diff --git a/tests/test_templatetags.py b/tests/test_templatetags.py index 71165fa..442ba1e 100644 --- a/tests/test_templatetags.py +++ b/tests/test_templatetags.py @@ -1,15 +1,15 @@ -# -*- coding: utf-8 -*- +from datetime import date +from unittest.mock import Mock -from __future__ import unicode_literals - -from django.test import override_settings, TestCase -from django.test.client import RequestFactory +from django.contrib.admin.views.main import ChangeList from django.template import Context, Template +from django.test import TestCase, override_settings +from django.test.client import RequestFactory +from admin_interface.metadata import __version__ from admin_interface.models import Theme from admin_interface.templatetags import admin_interface_tags as templatetags from admin_interface.templatetags.admin_interface_tags import hash_string -from admin_interface.version import __version__ class AdminInterfaceTemplateTagsTestCase(TestCase): @@ -22,87 +22,75 @@ class AdminInterfaceTemplateTagsTestCase(TestCase): def __render_template(self, string, context=None): return Template(string).render(Context(context or {})) - def test_get_admin_interface_languages(self): - context = Context( - { - "request": self.request_factory.get("/en/admin/"), - } - ) - languages = templatetags.get_admin_interface_languages(context) + def test_admin_interface_language_chooser(self): + context = Context({"request": self.request_factory.get("/en/admin/")}) + context = templatetags.admin_interface_language_chooser(context) + languages = context["LANGUAGES"] expected_languages = [ - { - "code": "en", - "name": "English", - "default": True, - "active": True, - "activation_url": "/i18n/setlang/?next=/en/admin/", - }, - { - "code": "it", - "name": "Italian", - "default": False, - "active": False, - "activation_url": "/i18n/setlang/?next=/it/admin/", - }, + ("de", "Deutsch"), + ("en", "English"), + ("es", "Español"), + ("fa", "Farsi"), + ("fr", "Français"), + ("it", "Italiano"), + ("pl", "Polski"), + ("pt-BR", "Português"), + ("ru", "Русский"), + ("tr", "Türk"), ] self.assertEqual(len(languages), len(expected_languages)) self.assertEqual(languages[0], expected_languages[0]) self.assertEqual(languages[1], expected_languages[1]) + self.assertEqual(context["next"], "/admin/") @override_settings( USE_I18N=False, ) - def test_get_admin_interface_languages_with_i18n_disabled(self): - context = Context( - { - "request": self.request_factory.get("/en/admin/"), - } - ) - languages = templatetags.get_admin_interface_languages(context) - self.assertEqual(languages, None) + def test_admin_interface_language_chooser_with_i18n_disabled(self): + context = Context({"request": self.request_factory.get("/en/admin/")}) + tag_context = templatetags.admin_interface_language_chooser(context) + self.assertEqual(tag_context, None) @override_settings( ROOT_URLCONF="tests.urls_without_i18n_patterns", ) - def test_get_admin_interface_languages_without_i18n_url_patterns(self): - context = Context( - { - "request": self.request_factory.get("/en/admin/"), - } - ) - languages = templatetags.get_admin_interface_languages(context) - self.assertEqual(languages, None) + def test_admin_interface_language_chooser_without_i18n_url_patterns(self): + context = Context({"request": self.request_factory.get("/en/admin/")}) + with self.assertWarnsMessage(UserWarning, "django.conf.urls.i18n"): + tag_context = templatetags.admin_interface_language_chooser(context) + self.assertEqual(tag_context, None) + + @override_settings( + MIDDLEWARE=[], + ) + def test_admin_interface_language_chooser_without_locale_middleware(self): + context = Context({"request": self.request_factory.get("/en/admin/")}) + with self.assertWarnsMessage(UserWarning, "LocaleMiddleware"): + tag_context = templatetags.admin_interface_language_chooser(context) + self.assertEqual(tag_context, None) @override_settings( LANGUAGES=(("en", "English"),), ) - def test_get_admin_interface_languages_without_multiple_languages(self): - context = Context( - { - "request": self.request_factory.get("/en/admin/"), - } - ) - languages = templatetags.get_admin_interface_languages(context) - self.assertEqual(languages, None) + def test_admin_interface_language_chooser_without_multiple_languages(self): + context = Context({"request": self.request_factory.get("/en/admin/")}) + tag_context = templatetags.admin_interface_language_chooser(context) + self.assertEqual(tag_context, None) - def test_get_admin_interface_languages_without_request(self): + def test_admin_interface_language_chooser_without_request(self): context = Context({}) - languages = templatetags.get_admin_interface_languages(context) - self.assertEqual(languages, None) + tag_context = templatetags.admin_interface_language_chooser(context) + self.assertEqual(tag_context, None) - def test_get_admin_interface_languages_without_language_prefix_in_url(self): - context = Context( - { - "request": self.request_factory.get("/admin/"), - } - ) - languages = templatetags.get_admin_interface_languages(context) - self.assertEqual(languages, None) + def test_admin_interface_language_chooser_without_language_prefix_in_url(self): + context = Context({"request": self.request_factory.get("/admin/")}) + tag_context = templatetags.admin_interface_language_chooser(context) + self.assertEqual(tag_context["next"], "/admin/") def test_get_theme(self): Theme.objects.all().delete() context = Context({}) - theme = templatetags.get_admin_interface_theme(context) + theme = templatetags.get_admin_interface_theme() self.assertEqual(theme.name, "Django") rendered = self.__render_template( "{% load admin_interface_tags %}" @@ -112,18 +100,9 @@ class AdminInterfaceTemplateTagsTestCase(TestCase): ) self.assertEqual(rendered, "Django") - def test_get_theme_with_request(self): - Theme.objects.all().delete() - context = Context({"request": self.request_factory.get("/")}) - theme = templatetags.get_admin_interface_theme(context) - self.assertEqual(theme.name, "Django") - rendered = self.__render_template( - "{% load admin_interface_tags %}" - "{% get_admin_interface_theme as theme %}" - "{{ theme.name }}", - context, - ) - self.assertEqual(rendered, "Django") + def test_get_setting(self): + title = templatetags.get_admin_interface_setting("title") + self.assertEqual(title, "Django administration") def test_get_version(self): version = templatetags.get_admin_interface_version() @@ -146,3 +125,136 @@ class AdminInterfaceTemplateTagsTestCase(TestCase): "{{ version_md5_hash }}" ) self.assertEqual(rendered, hash_manual) + + def test_get_admin_interface_inline_template(self): + headless_template = templatetags.get_admin_interface_inline_template( + "admin/edit_inline/stacked.html" + ) + self.assertEqual(headless_template, "admin/edit_inline/headerless_stacked.html") + headless_template = templatetags.get_admin_interface_inline_template( + "nesting/admin/inlines/tabular.html" + ) + self.assertEqual(headless_template, "nesting/admin/inlines/tabular.html") + + def test_get_active_date_hierarchy_none(self): + changelist = Mock() + changelist.date_hierarchy = None + + date_field = templatetags.get_admin_interface_active_date_hierarchy(changelist) + + self.assertIsNone(date_field) + + def test_get_active_date_hierarchy_inactive(self): + changelist = Mock() + changelist.date_hierarchy = "last_login" + changelist.get_filters_params.return_value = {} + + date_field = templatetags.get_admin_interface_active_date_hierarchy(changelist) + + self.assertIsNone(date_field) + + def test_get_active_date_hierarchy_active(self): + changelist = Mock() + changelist.date_hierarchy = "last_login" + params = {"some_field": 2, "last_login__year": 2022} + changelist.get_filters_params.return_value = params + + date_field = templatetags.get_admin_interface_active_date_hierarchy(changelist) + + self.assertEqual(date_field, "last_login") + + def _get_changelist_mock(self, params=None): + class ChangelistMock(Mock): + def __init__(self, params=None, *args, **kwargs): + super().__init__(*args, **kwargs) + # django < 5.0 + self.params = params or {} + # django >= 5.0 + self.filter_params = params or {} + + def get_query_string(self, **kwargs): + return ChangeList.get_query_string(self, **kwargs) + + def get_filters_params(self, **kwargs): + return ChangeList.get_filters_params(self, **kwargs) + + return ChangelistMock(params=params) + + def test_filter_removal_link(self): + params = {"shape": "pointy", "size": "small"} + changelist = self._get_changelist_mock(params) + list_filter = Mock() + list_filter.title = "Shape filter" + choices = [{"display": "Round"}, {"display": "Pointy", "selected": True}] + list_filter.choices.return_value = choices + list_filter.expected_parameters.return_value = ("shape",) + + context = templatetags.admin_interface_filter_removal_link( + changelist, list_filter + ) + + self.assertEqual(context["removal_link"], "?size=small") + self.assertEqual(context["title"], "Shape filter") + self.assertEqual(context["selected_value"], "Pointy") + + def test_filter_removal_link_no_display(self): + params = {"shape": "pointy", "size": "small"} + changelist = self._get_changelist_mock(params) + list_filter = Mock() + list_filter.title = "Shape filter" + choices = [{"other": "Round"}, {"other": "Pointy", "selected": True}] + list_filter.choices.return_value = choices + list_filter.expected_parameters.return_value = ("shape",) + + context = templatetags.admin_interface_filter_removal_link( + changelist, list_filter + ) + + self.assertEqual(context["removal_link"], "?size=small") + self.assertEqual(context["title"], "Shape filter") + self.assertEqual(context["selected_value"], "...") + + def test_date_hierarchy_removal_link_year(self): + params = {"shape": "pointy", "last_login__year": 2022} + changelist = self._get_changelist_mock(params) + changelist.model._meta.get_field.return_value.verbose_name = "last login" + + context = templatetags.admin_interface_date_hierarchy_removal_link( + changelist, "last_login" + ) + + self.assertEqual(context["removal_link"], "?shape=pointy") + self.assertEqual(context["date_label"], "last login") + self.assertEqual(context["date_value"], date(2022, 1, 1)) + + def test_date_hierarchy_removal_link_year_month(self): + params = {"last_login__year": 2022, "last_login__month": "11"} + changelist = self._get_changelist_mock(params) + changelist.model._meta.get_field.return_value.verbose_name = "last login" + + context = templatetags.admin_interface_date_hierarchy_removal_link( + changelist, "last_login" + ) + + self.assertEqual(context["removal_link"], "?") + self.assertEqual(context["date_label"], "last login") + self.assertEqual(context["date_value"], date(2022, 11, 1)) + + def test_date_hierarchy_removal_link_year_month_day(self): + params = { + "last_login__year": 2022, + "last_login__month": "11", + "last_login__day": "30", + "shape": "round", + "size": "small", + } + changelist = self._get_changelist_mock(params) + changelist.model._meta.get_field.return_value.verbose_name = "last login" + + context = templatetags.admin_interface_date_hierarchy_removal_link( + changelist, "last_login" + ) + + self.assertEqual(context["removal_link"], "?shape=round&size=small") + self.assertEqual(context["date_label"], "last login") + self.assertEqual(context["date_value"], date(2022, 11, 30)) diff --git a/tests/urls.py b/tests/urls.py index 1f5603f..6ed6eb6 100644 --- a/tests/urls.py +++ b/tests/urls.py @@ -1,21 +1,11 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - -import django -from django.contrib import admin - -if django.VERSION < (2, 0): - from django.conf.urls import include, url as re_path -else: - from django.urls import include, re_path from django.conf.urls.i18n import i18n_patterns - +from django.contrib import admin +from django.urls import include, path urlpatterns = [] urlpatterns += [ - re_path(r"^i18n/", include("django.conf.urls.i18n")), + path("i18n/", include("django.conf.urls.i18n")), ] urlpatterns += i18n_patterns( - re_path(r"^admin/", admin.site.urls), + path("admin/", admin.site.urls), ) diff --git a/tests/urls_without_i18n_patterns.py b/tests/urls_without_i18n_patterns.py index a040402..083932c 100644 --- a/tests/urls_without_i18n_patterns.py +++ b/tests/urls_without_i18n_patterns.py @@ -1,16 +1,6 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - -import django from django.contrib import admin - -if django.VERSION < (2, 0): - from django.conf.urls import url as re_path -else: - from django.urls import re_path - +from django.urls import path urlpatterns = [ - re_path(r"^admin/", admin.site.urls), + path("admin/", admin.site.urls), ] diff --git a/tox.ini b/tox.ini index 2b770b6..a9c656f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,45 +1,61 @@ [tox] envlist = - py27-{dj17,dj18,dj19,dj110,dj111}-{sqlite,postgres}, - py36-{dj18,dj19,dj110,dj111,dj20,dj21,dj22,dj30,dj31,dj32}-{sqlite,postgres}, - py37-{dj20,dj21,dj22,dj30,dj31,dj32}-{sqlite,postgres}, - py38-{dj22,dj30,dj31,dj32}-{sqlite,postgres}, - py39-{dj22,dj30,dj31,dj32}-{sqlite,postgres}, - py310-{dj32,dj40}-{sqlite,postgres}, + py38-{dj30,dj31,dj32,dj40,dj41,dj42}-{sqlite,postgres}, + py39-{dj30,dj31,dj32,dj40,dj41,dj42}-{sqlite,postgres}, + py310-{dj32,dj40,dj41,dj42,dj50}-{sqlite,postgres}, + py311-{dj41,dj42,dj50}-{sqlite,postgres}, + py312-{dj42,dj50}-{sqlite,postgres}, [gh-actions] python = - 2.7: py27 - 3.6: py36 - 3.7: py37 3.8: py38 3.9: py39 3.10: py310 + 3.11: py311 + 3.12: py312 [testenv] -passenv = CI GITHUB_WORKFLOW -deps = - dj17: Django == 1.7.* - dj18: Django == 1.8.* - dj19: Django == 1.9.* - dj110: Django == 1.10.* - dj111: Django == 1.11.* - dj20: Django == 2.0.* - dj21: Django == 2.1.* - dj22: Django == 2.2.* - dj30: Django == 3.0.* - dj31: Django == 3.1.* - dj32: Django == 3.2.* - dj40: Django == 4.0.* - # mysql: mysqlclient - postgres: psycopg2-binary - coverage - codecov +passenv = CI,GITHUB_WORKFLOW + setenv = sqlite: DATABASE_ENGINE=sqlite # mysql: DATABASE_ENGINE=mysql postgres: DATABASE_ENGINE=postgres + +deps = + dj30: Django == 3.0.* + dj31: Django == 3.1.* + dj32: Django == 3.2.* + dj40: Django == 4.0.* + dj41: Django == 4.1.* + dj42: Django == 4.2.* + dj50: Django == 5.0.* + -r requirements.txt + -r requirements-test.txt + commands = - coverage run --append --source=admin_interface setup.py test - coverage report -m - codecov \ No newline at end of file + pre-commit run -a + coverage run --append --source=admin_interface runtests.py + coverage report --show-missing --ignore-errors + +[testenv:migrations] +setenv = + DJANGO_SETTINGS_MODULE=tests.settings + DATABASE_ENGINE=sqlite +deps = + -r requirements.txt +commands = + python -m django makemigrations --check + +[testenv:translations] +setenv = + DJANGO_SETTINGS_MODULE=tests.settings + DATABASE_ENGINE=sqlite +deps = + -r requirements.txt +allowlist_externals = git +commands = + python -m django makemessages --ignore ".tox" --ignore "venv" --all --add-location "file" --extension "html,py" + python -m django compilemessages --ignore ".tox" --ignore "venv" + git diff admin_interface/locale/ + git diff-index --quiet HEAD admin_interface/locale/