django-microsys 2.2.0__tar.gz → 2.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_microsys-2.2.0 → django_microsys-2.2.2}/PKG-INFO +1 -1
- {django_microsys-2.2.0 → django_microsys-2.2.2}/django_microsys.egg-info/PKG-INFO +1 -1
- django_microsys-2.2.2/microsys/VERSION +1 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/context_processors.py +1 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/fetcher.py +21 -4
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/forms.py +89 -8
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/system_setup.css +44 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/js/options.js +3 -1
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/js/system_setup.js +8 -1
- django_microsys-2.2.2/microsys/templates/microsys/includes/font_previews.html +20 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/font_settings_matrix.html +1 -18
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/language_fonts_editor.html +4 -4
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/options.html +3 -3
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/tables/table.html +1 -1
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/translations.py +44 -16
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/utils.py +24 -6
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/views/sections.py +7 -1
- django_microsys-2.2.0/microsys/VERSION +0 -1
- django_microsys-2.2.0/microsys/templates/microsys/includes/font_previews.html +0 -23
- {django_microsys-2.2.0 → django_microsys-2.2.2}/LICENSE +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/MANIFEST.in +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/README.md +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/django_microsys.egg-info/SOURCES.txt +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/django_microsys.egg-info/dependency_links.txt +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/django_microsys.egg-info/entry_points.txt +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/django_microsys.egg-info/requires.txt +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/django_microsys.egg-info/top_level.txt +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/__init__.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/__main__.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/admin.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/api.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/apps.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/cli.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/constants.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/discovery.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/filters.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/fonts.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/formats/__init__.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/formats/ar/__init__.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/formats/ar/formats.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/formats/en/__init__.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/formats/en/formats.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/guards.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/management/commands/__init__.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/management/commands/microsys_check.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/management/commands/microsys_setup.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/management/commands/migrator.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/management/commands/seed_activity_log.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/managers.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/middleware.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/migrations/0001_initial.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/migrations/0002_public_registration.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/migrations/0003_public_root_split.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/migrations/0004_client_ip_and_trusted_devices.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/migrations/0005_systemsettings_allow_user_font_override_and_more.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/migrations/__init__.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/models.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/patches.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/registration.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/README.md.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/__init__.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/apps.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/filters.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/forms.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/migrations/__init__.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/models.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/tables.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/templates/example_record_confirm_delete.html.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/templates/example_record_detail.html.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/templates/example_record_form.html.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/templates/example_record_list.html.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/tests/__init__.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/tests/test_app.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/translations.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/urls.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/app/views.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/.nginx/nginx.conf.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/.secrets/.env.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/Dockerfile.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/README.md.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/compose.dev.yml.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/compose.yml.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/dockerignore.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/docs/README.md.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/entrypoint.sh.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/gitattributes.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/gitignore.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/gunicorn.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/manage.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/package/__init__.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/package/asgi.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/package/celery.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/package/settings.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/package/urls.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/package/wsgi.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/req.txt.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/start.ps1.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/start.sh.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/tests/__init__.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/tests/test_scaffold.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/scaffold_templates/project/tools/smtp_relay.py.tmpl +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/signals.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/bootstrap/bootstrap-icons.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/bootstrap/bootstrap-icons.woff +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/bootstrap/bootstrap-icons.woff2 +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/bootstrap/bootstrap.bundle.min.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/bootstrap/bootstrap.bundle.min.js.map +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/bootstrap/bootstrap.min.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/bootstrap/bootstrap.min.css.map +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/bootstrap/bootstrap.rtl.min.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/bootstrap/bootstrap.rtl.min.css.map +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/favicon.ico +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/img/base_logo.webp +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/img/default_profile.webp +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/img/login_logo.webp +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/accessibility/css/main.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/accessibility/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/activitylog/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/fonts/TwemojiCountryFlags.woff2 +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/fonts/cairo-bold.woff2 +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/fonts/cairo-medium.woff2 +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/fonts/cairo-regular.woff2 +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/fonts/shabwa-bold.woff2 +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/fonts/shabwa-medium.woff2 +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/fonts/shabwa-regular.woff2 +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/forms/css/file_field.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/forms/css/form_actions.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/forms/css/form_fields.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/forms/js/file_field.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/forms/js/filter_form.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/helpers/autofill/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/helpers/context_menu/css/main.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/helpers/context_menu/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/helpers/context_menu/js/section_manager.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/helpers/dynamic_modal/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/helpers/prevent_double_submit.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/helpers/scan_link/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/helpers/scan_link/js/scan_button.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/helpers/wizard/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/language/css/main.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/language/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/language/js/translations.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/buttons.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/dropdowns.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/index_cards.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/main.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/options.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/pagination.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/selectors.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/tables.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/template_cleanup.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/titlebar.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/js/base_head.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/js/base_runtime.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/js/selectors.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/js/tables.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/sections/js/manage_sections.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/sidebar/css/main.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/sidebar/css/reorder.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/sidebar/css/theme_picker.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/sidebar/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/sidebar/js/preload.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/sidebar/js/reorder.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/sidebar/js/theme_picker.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/css/blue.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/css/dark.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/css/gold.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/css/gothic.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/css/green.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/css/light.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/css/mono.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/css/neon.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/css/red.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/css/retro.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/themes/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/tutorial/css/main.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/tutorial/js/driver.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/tutorial/js/main.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/css/login.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/css/permissions.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/css/profile.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/css/user_hub.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/js/login.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/js/manage_users.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/js/permissions.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/js/profile_2fa.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/js/profile_image_widget.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/js/twofa_verify.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/users/js/user_hub.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/vanillajs-datepicker/datepicker-bs5.min.css +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/vanillajs-datepicker/datepicker.min.js +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/tables.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/bootstrap5/layout/field_file.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/2fa/verify.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/activitylog/activity_log.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/activitylog/activity_log_detail_modal.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/base.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/form_base.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/forms/assets_head.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/forms/assets_scripts.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/forms/crispy_file_field.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/forms/file_input.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/forms/filter_assets_head.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/forms/filter_assets_scripts.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/helpers/dynamic_modal.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/helpers/dynamic_modal_combined.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/helpers/dynamic_modal_detail.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/helpers/dynamic_modal_form.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/helpers/dynamic_modal_list.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/helpers/micro_context_menu.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/language_catalog_editor.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/language_previews.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/sidebar_builder.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/sidebar_density_previews.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/sidebar_items.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/system_names_editor.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/system_setup.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/table_density_previews.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/theme_previews.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/theme_settings_matrix.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/titlebar.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/translation_matrix_editor.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/tutorial.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/list_base.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/registration/pending.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/scopes/scope_actions.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/scopes/scope_form.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/scopes/scope_manager.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/sections/manage_sections.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/sections/subsection_select.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/sidebar/auto.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/sidebar/extra_groups.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/sidebar/main.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/sidebar/tree.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/users/grouped_permissions.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/users/manage_users.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/users/profile.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/users/profile_image_widget.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/users/user_detail_modal.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/users/user_hub.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/registration/email/verify_registration.txt +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/registration/login.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/registration/register.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/registration/register_sent.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/registration/register_verify.html +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templatetags/__init__.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templatetags/microsys_tags.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templatetags/microsys_translation.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templatetags/sidebar_tags.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/themes.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/urls.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/views/__init__.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/views/activitylog.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/views/general.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/views/profile.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/views/registration.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/views/scopes.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/views/sidebar.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/views/twofa.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/views/users.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/widgets.py +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/pyproject.toml +0 -0
- {django_microsys-2.2.0 → django_microsys-2.2.2}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.2.2
|
|
@@ -346,6 +346,7 @@ def microsys_context(request):
|
|
|
346
346
|
from .fonts import generate_font_face_css, get_builtin_fonts
|
|
347
347
|
allowed_fonts = normalize_allowed_fonts(final_config.get('allowed_fonts'))
|
|
348
348
|
context['font_face_css'] = generate_font_face_css(allowed_fonts)
|
|
349
|
+
context['option_fonts'] = [font for font in get_builtin_fonts() if font.get('slug') in allowed_fonts]
|
|
349
350
|
|
|
350
351
|
allow_user_font_override = bool(final_config.get('allow_user_font_override', True))
|
|
351
352
|
default_fonts_by_lang = final_config.get('default_fonts', {})
|
|
@@ -4,12 +4,29 @@ from django.http import HttpResponse, HttpResponseRedirect
|
|
|
4
4
|
from django.db.models.query import QuerySet
|
|
5
5
|
from django.contrib import messages
|
|
6
6
|
from django.db.models import FileField
|
|
7
|
+
from django.utils.http import url_has_allowed_host_and_scheme
|
|
7
8
|
from io import BytesIO
|
|
8
9
|
import mimetypes
|
|
9
10
|
import openpyxl
|
|
10
11
|
import zipfile
|
|
11
12
|
from .utils import log_user_action
|
|
12
13
|
|
|
14
|
+
def _safe_referer(request, fallback='/'):
|
|
15
|
+
referer = request.META.get('HTTP_REFERER')
|
|
16
|
+
if referer:
|
|
17
|
+
from django.conf import settings
|
|
18
|
+
allowed_hosts = {request.get_host()}
|
|
19
|
+
if hasattr(settings, 'ALLOWED_HOSTS') and settings.ALLOWED_HOSTS:
|
|
20
|
+
for host in settings.ALLOWED_HOSTS:
|
|
21
|
+
if host:
|
|
22
|
+
if host.startswith('.'):
|
|
23
|
+
allowed_hosts.add(host[1:])
|
|
24
|
+
elif host != '*':
|
|
25
|
+
allowed_hosts.add(host)
|
|
26
|
+
if url_has_allowed_host_and_scheme(url=referer, allowed_hosts=allowed_hosts, require_https=request.is_secure()):
|
|
27
|
+
return referer
|
|
28
|
+
return fallback
|
|
29
|
+
|
|
13
30
|
# Universal Downloader
|
|
14
31
|
#####################################################################
|
|
15
32
|
def fetch_file(request, data, file_type=None):
|
|
@@ -38,7 +55,7 @@ def fetch_file(request, data, file_type=None):
|
|
|
38
55
|
|
|
39
56
|
if not records:
|
|
40
57
|
messages.error(request, "لا توجد سجلات للتحميل.")
|
|
41
|
-
return HttpResponseRedirect(request
|
|
58
|
+
return HttpResponseRedirect(_safe_referer(request))
|
|
42
59
|
|
|
43
60
|
# 2. Collect Files
|
|
44
61
|
files_to_download = []
|
|
@@ -78,7 +95,7 @@ def fetch_file(request, data, file_type=None):
|
|
|
78
95
|
# 3. Decision: Error, Single File, or Zip
|
|
79
96
|
if not files_to_download:
|
|
80
97
|
messages.error(request, "لا توجد ملفات صالحة للتحميل في السجلات المختارة.")
|
|
81
|
-
return HttpResponseRedirect(request
|
|
98
|
+
return HttpResponseRedirect(_safe_referer(request))
|
|
82
99
|
|
|
83
100
|
if len(files_to_download) == 1:
|
|
84
101
|
# Serve Single File
|
|
@@ -248,7 +265,7 @@ def fetch_excel(request, queryset, exclude_fields=None, hidden_fields=None, shee
|
|
|
248
265
|
"""
|
|
249
266
|
if not queryset:
|
|
250
267
|
messages.error(request, "لا توجد بيانات للتصدير.")
|
|
251
|
-
return HttpResponseRedirect(request
|
|
268
|
+
return HttpResponseRedirect(_safe_referer(request))
|
|
252
269
|
|
|
253
270
|
# Normalize to iterable if list passed
|
|
254
271
|
data_list = queryset
|
|
@@ -260,7 +277,7 @@ def fetch_excel(request, queryset, exclude_fields=None, hidden_fields=None, shee
|
|
|
260
277
|
|
|
261
278
|
if not model:
|
|
262
279
|
messages.error(request, "تعذر تحديد نموذج البيانات.")
|
|
263
|
-
return HttpResponseRedirect(request
|
|
280
|
+
return HttpResponseRedirect(_safe_referer(request))
|
|
264
281
|
|
|
265
282
|
from openpyxl.utils import get_column_letter
|
|
266
283
|
from django.db.models import FileField, DateTimeField
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# Imports of the required python modules and libraries
|
|
2
2
|
######################################################
|
|
3
|
+
import os
|
|
3
4
|
import json
|
|
4
5
|
from types import MethodType, SimpleNamespace
|
|
5
6
|
|
|
@@ -1686,6 +1687,12 @@ class SystemSettingsForm(forms.ModelForm):
|
|
|
1686
1687
|
if parsed_step in (0, 1, 2, 3, 4, 5):
|
|
1687
1688
|
self.single_step_mode = True
|
|
1688
1689
|
self.single_step_index = parsed_step
|
|
1690
|
+
if self.mode != 'setup' and self.single_step_mode:
|
|
1691
|
+
# Single-step modal posts can legitimately omit values owned by another
|
|
1692
|
+
# wizard step; field-level required validation must not fire before the
|
|
1693
|
+
# step-preservation cleaners get a chance to restore them.
|
|
1694
|
+
self.fields['default_theme'].required = False
|
|
1695
|
+
self.fields['default_table_density'].required = False
|
|
1689
1696
|
|
|
1690
1697
|
from microsys.discovery import discover_sidebar_catalog, sanitize_sidebar_config
|
|
1691
1698
|
from microsys.utils import get_system_config
|
|
@@ -1766,6 +1773,7 @@ class SystemSettingsForm(forms.ModelForm):
|
|
|
1766
1773
|
'help_sys_allow_user_theme_override',
|
|
1767
1774
|
'Allow users to switch between the allowed themes at runtime from Options and the sidebar toolbar.',
|
|
1768
1775
|
)
|
|
1776
|
+
self.fields['allow_user_language_override'].label = s.get('form_sys_allow_user_language_override', 'Allow user language override')
|
|
1769
1777
|
self.fields['allow_user_language_override'].help_text = s.get(
|
|
1770
1778
|
'help_sys_allow_user_language_override',
|
|
1771
1779
|
'Allow users to change their display language from Options. When disabled, the system default language is enforced.',
|
|
@@ -1786,6 +1794,11 @@ class SystemSettingsForm(forms.ModelForm):
|
|
|
1786
1794
|
'help_sys_default_table_density',
|
|
1787
1795
|
'Choose the default table density for new users; each user can still override it later from Options.',
|
|
1788
1796
|
)
|
|
1797
|
+
self.fields['default_table_density'].choices = (
|
|
1798
|
+
('dense', s.get('table_density_dense', 'Dense')),
|
|
1799
|
+
(DEFAULT_TABLE_DENSITY, s.get('table_density_balanced', 'Balanced')),
|
|
1800
|
+
('roomy', s.get('table_density_roomy', 'Roomy')),
|
|
1801
|
+
)
|
|
1789
1802
|
self.fields['logo'].label = s.get('form_sys_logo', "System Logo (Logo)")
|
|
1790
1803
|
self.fields['favicon'].label = s.get('form_sys_favicon', "Site Icon (Favicon)")
|
|
1791
1804
|
self.fields['logo'].widget = _build_archive_file_widget(
|
|
@@ -2747,11 +2760,7 @@ class SystemSettingsForm(forms.ModelForm):
|
|
|
2747
2760
|
css_class=_step_css_class(3),
|
|
2748
2761
|
),
|
|
2749
2762
|
Div(
|
|
2750
|
-
HTML(f"<div class='mb-3'><span class='badge rounded-pill text-bg-primary'>{s.get('system_setup_step5', 'Step 5:
|
|
2751
|
-
HTML(f"<h6 class='fw-bold my-3'>{s.get('tables_settings_title', 'Tables Settings')}</h6>"),
|
|
2752
|
-
Row(
|
|
2753
|
-
Div(Field('default_table_density'), css_class='col'),
|
|
2754
|
-
),
|
|
2763
|
+
HTML(f"<div class='mb-3'><span class='badge rounded-pill text-bg-primary'>{s.get('system_setup_step5', 'Step 5: Titlebar')}</span></div>"),
|
|
2755
2764
|
HTML(f"<h6 class='fw-bold my-3'>{s.get('titlebar_settings_title', 'Titlebar Settings')}</h6>"),
|
|
2756
2765
|
Row(
|
|
2757
2766
|
build_settings_toggle_field(self, 'titlebar_show_title', css_class='col-lg-6 col-xl-3'),
|
|
@@ -2791,6 +2800,11 @@ class SystemSettingsForm(forms.ModelForm):
|
|
|
2791
2800
|
build_settings_toggle_field(self, 'allow_user_font_override', css_class='col-12 mt-2'),
|
|
2792
2801
|
HTML(self.language_fonts_editor_html),
|
|
2793
2802
|
Field('default_fonts'),
|
|
2803
|
+
HTML(f"<h6 class='fw-bold my-3'>{s.get('tables_settings_title', 'Tables Settings')}</h6>"),
|
|
2804
|
+
Row(
|
|
2805
|
+
Div(Field('default_table_density'), css_class='col'),
|
|
2806
|
+
css_class='mb-3'
|
|
2807
|
+
),
|
|
2794
2808
|
css_class=_step_css_class(5),
|
|
2795
2809
|
),
|
|
2796
2810
|
FormActions(
|
|
@@ -2866,12 +2880,27 @@ class SystemSettingsForm(forms.ModelForm):
|
|
|
2866
2880
|
return str(self.cleaned_data.get('default_language') or 'en').strip().lower().replace('_', '-')
|
|
2867
2881
|
|
|
2868
2882
|
def clean_allowed_fonts(self):
|
|
2883
|
+
if self.is_bound and self.mode != 'setup' and self.single_step_mode and 'allowed_fonts' not in self.data:
|
|
2884
|
+
preserved = getattr(self.instance, 'allowed_fonts', None)
|
|
2885
|
+
if preserved in (None, ''):
|
|
2886
|
+
preserved = self.initial.get('allowed_fonts')
|
|
2887
|
+
return list(normalize_allowed_fonts(preserved))
|
|
2869
2888
|
data = self.cleaned_data.get('allowed_fonts')
|
|
2870
2889
|
if not data:
|
|
2871
2890
|
return []
|
|
2872
2891
|
return list(data)
|
|
2873
2892
|
|
|
2874
2893
|
def clean_default_fonts(self):
|
|
2894
|
+
if self.is_bound and self.mode != 'setup' and self.single_step_mode and 'default_fonts' not in self.data:
|
|
2895
|
+
preserved = getattr(self.instance, 'default_fonts', None)
|
|
2896
|
+
if preserved in (None, ''):
|
|
2897
|
+
preserved = self.initial.get('default_fonts')
|
|
2898
|
+
if isinstance(preserved, str):
|
|
2899
|
+
try:
|
|
2900
|
+
preserved = json.loads(preserved)
|
|
2901
|
+
except json.JSONDecodeError:
|
|
2902
|
+
preserved = {}
|
|
2903
|
+
return preserved if isinstance(preserved, dict) else {}
|
|
2875
2904
|
data = self.cleaned_data.get('default_fonts')
|
|
2876
2905
|
if not data:
|
|
2877
2906
|
return {}
|
|
@@ -2884,12 +2913,27 @@ class SystemSettingsForm(forms.ModelForm):
|
|
|
2884
2913
|
return {}
|
|
2885
2914
|
|
|
2886
2915
|
def clean_default_theme(self):
|
|
2887
|
-
|
|
2916
|
+
if self.is_bound and self.mode != 'setup' and self.single_step_mode and 'default_theme' not in self.data:
|
|
2917
|
+
value = (
|
|
2918
|
+
getattr(self.instance, 'default_theme', None)
|
|
2919
|
+
or self.initial.get('default_theme')
|
|
2920
|
+
or 'light'
|
|
2921
|
+
)
|
|
2922
|
+
else:
|
|
2923
|
+
value = self.cleaned_data.get('default_theme') or 'light'
|
|
2888
2924
|
if not is_valid_theme(value):
|
|
2889
2925
|
raise ValidationError("Invalid theme choice.")
|
|
2890
2926
|
return value
|
|
2891
2927
|
|
|
2892
2928
|
def clean_allowed_themes(self):
|
|
2929
|
+
if self.is_bound and self.mode != 'setup' and self.single_step_mode and 'allowed_themes' not in self.data:
|
|
2930
|
+
values = getattr(self.instance, 'allowed_themes', None)
|
|
2931
|
+
if not values:
|
|
2932
|
+
values = self.initial.get('allowed_themes')
|
|
2933
|
+
normalized = list(normalize_allowed_themes(values))
|
|
2934
|
+
if not normalized:
|
|
2935
|
+
raise ValidationError("At least one theme must remain enabled.")
|
|
2936
|
+
return normalized
|
|
2893
2937
|
values = self.cleaned_data.get('allowed_themes') or []
|
|
2894
2938
|
if not values:
|
|
2895
2939
|
raise ValidationError("At least one theme must remain enabled.")
|
|
@@ -2899,7 +2943,14 @@ class SystemSettingsForm(forms.ModelForm):
|
|
|
2899
2943
|
return normalized
|
|
2900
2944
|
|
|
2901
2945
|
def clean_default_table_density(self):
|
|
2902
|
-
|
|
2946
|
+
if self.is_bound and self.mode != 'setup' and self.single_step_mode and 'default_table_density' not in self.data:
|
|
2947
|
+
value = (
|
|
2948
|
+
getattr(self.instance, 'default_table_density', None)
|
|
2949
|
+
or self.initial.get('default_table_density')
|
|
2950
|
+
or DEFAULT_TABLE_DENSITY
|
|
2951
|
+
)
|
|
2952
|
+
else:
|
|
2953
|
+
value = self.cleaned_data.get('default_table_density') or DEFAULT_TABLE_DENSITY
|
|
2903
2954
|
if value not in TABLE_DENSITY_VALUES:
|
|
2904
2955
|
raise ValidationError("Invalid table density choice.")
|
|
2905
2956
|
return value
|
|
@@ -3239,13 +3290,43 @@ class SystemSettingsForm(forms.ModelForm):
|
|
|
3239
3290
|
if cleaned.get('registration_activation_mode') not in REGISTRATION_ACTIVATION_VALUES:
|
|
3240
3291
|
cleaned['registration_activation_mode'] = 'auto_login_after_verify'
|
|
3241
3292
|
email_ready = get_email_service_status().get('available')
|
|
3242
|
-
|
|
3293
|
+
backend = getattr(settings, 'EMAIL_BACKEND', 'django.core.mail.backends.smtp.EmailBackend')
|
|
3294
|
+
local_backends = {
|
|
3295
|
+
'django.core.mail.backends.console.EmailBackend',
|
|
3296
|
+
'django.core.mail.backends.locmem.EmailBackend',
|
|
3297
|
+
'django.core.mail.backends.filebased.EmailBackend',
|
|
3298
|
+
}
|
|
3299
|
+
if backend in local_backends and getattr(settings, 'DEBUG', False):
|
|
3300
|
+
email_ready = True
|
|
3301
|
+
elif email_config.get('transport') == 'relay':
|
|
3302
|
+
relay_host = str(email_config.get('host') or os.getenv('SMTP_RELAY_HOST') or '').strip()
|
|
3303
|
+
relay_port = email_config.get('port')
|
|
3304
|
+
relay_from_email = str(
|
|
3305
|
+
email_config.get('default_from_email')
|
|
3306
|
+
or getattr(settings, 'DEFAULT_FROM_EMAIL', '')
|
|
3307
|
+
or os.getenv('DEFAULT_FROM_EMAIL')
|
|
3308
|
+
or ''
|
|
3309
|
+
).strip()
|
|
3310
|
+
relay_password_ok = True
|
|
3311
|
+
if email_config.get('secret_storage') == 'encrypted_db' and email_config.get('username'):
|
|
3312
|
+
relay_password_ok = bool(email_config.get('encrypted_password'))
|
|
3313
|
+
email_ready = bool(relay_host and relay_port and relay_from_email and relay_password_ok)
|
|
3314
|
+
elif email_config.get('secret_storage') == 'encrypted_db':
|
|
3243
3315
|
email_ready = bool(
|
|
3244
3316
|
email_config.get('host')
|
|
3245
3317
|
and email_config.get('port')
|
|
3246
3318
|
and email_config.get('default_from_email')
|
|
3247
3319
|
and (not email_config.get('username') or email_config.get('encrypted_password'))
|
|
3248
3320
|
)
|
|
3321
|
+
elif backend == 'django.core.mail.backends.smtp.EmailBackend':
|
|
3322
|
+
email_ready = bool(
|
|
3323
|
+
(email_config.get('host') or getattr(settings, 'EMAIL_HOST', ''))
|
|
3324
|
+
and (email_config.get('port') or getattr(settings, 'EMAIL_PORT', None))
|
|
3325
|
+
and (
|
|
3326
|
+
email_config.get('default_from_email')
|
|
3327
|
+
or getattr(settings, 'DEFAULT_FROM_EMAIL', '')
|
|
3328
|
+
)
|
|
3329
|
+
)
|
|
3249
3330
|
if (cleaned.get('public_registration_enabled') or cleaned.get('email_2fa')) and not email_ready:
|
|
3250
3331
|
self.add_error(
|
|
3251
3332
|
'email_config',
|
{django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/css/system_setup.css
RENAMED
|
@@ -681,3 +681,47 @@
|
|
|
681
681
|
grid-template-columns: 1fr;
|
|
682
682
|
}
|
|
683
683
|
}
|
|
684
|
+
|
|
685
|
+
/* Font Previews Support */
|
|
686
|
+
.ms-font-option {
|
|
687
|
+
align-items: center;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.ms-font-option__icon {
|
|
691
|
+
width: 3.5rem;
|
|
692
|
+
height: 3.5rem;
|
|
693
|
+
border-radius: 1rem;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
.font-preview-sample {
|
|
697
|
+
font-weight: 500;
|
|
698
|
+
font-size: 1.5rem;
|
|
699
|
+
line-height: 1;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/* Specific Font Mapping Rules for Previews */
|
|
703
|
+
.ms-font-option[data-font="shabwa"] .font-preview-sample,
|
|
704
|
+
.ms-font-settings-option[data-font-option="shabwa"] .font-preview-sample {
|
|
705
|
+
font-family: 'Shabwa', sans-serif !important;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
.ms-font-option[data-font="cairo"] .font-preview-sample,
|
|
709
|
+
.ms-font-settings-option[data-font-option="cairo"] .font-preview-sample {
|
|
710
|
+
font-family: 'Cairo', sans-serif !important;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/* Font settings option spacing */
|
|
714
|
+
.ms-font-settings-option__header {
|
|
715
|
+
position: absolute;
|
|
716
|
+
top: 8px;
|
|
717
|
+
right: 8px;
|
|
718
|
+
z-index: 2;
|
|
719
|
+
}
|
|
720
|
+
[dir="rtl"] .ms-font-settings-option__header {
|
|
721
|
+
right: auto;
|
|
722
|
+
left: 8px;
|
|
723
|
+
}
|
|
724
|
+
.ms-font-settings-option {
|
|
725
|
+
position: relative;
|
|
726
|
+
min-width: 120px;
|
|
727
|
+
}
|
|
@@ -103,7 +103,9 @@
|
|
|
103
103
|
element.addEventListener('click', function () {
|
|
104
104
|
const font = this.getAttribute('data-font');
|
|
105
105
|
// Update local UI
|
|
106
|
-
document.querySelectorAll('[data-font]').forEach(
|
|
106
|
+
document.querySelectorAll('[data-font]').forEach((option) => {
|
|
107
|
+
option.classList.toggle('is-active', option === this);
|
|
108
|
+
});
|
|
107
109
|
|
|
108
110
|
// Apply immediately
|
|
109
111
|
const familyName = font.charAt(0).toUpperCase() + font.slice(1);
|
{django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/static/microsys/main/js/system_setup.js
RENAMED
|
@@ -2858,13 +2858,15 @@
|
|
|
2858
2858
|
input.value = activeTheme;
|
|
2859
2859
|
allowedCheckboxes.forEach((checkbox) => {
|
|
2860
2860
|
const theme = checkbox.getAttribute('data-setup-theme-allowed');
|
|
2861
|
-
|
|
2861
|
+
const isLocked = checkbox.checked && resolvedAllowedThemes.length === 1;
|
|
2862
|
+
checkbox.setAttribute('aria-disabled', isLocked ? 'true' : 'false');
|
|
2862
2863
|
const container = checkbox.closest('[data-theme-option]');
|
|
2863
2864
|
if (!container) {
|
|
2864
2865
|
return;
|
|
2865
2866
|
}
|
|
2866
2867
|
const isAllowed = resolvedAllowedThemes.includes(theme);
|
|
2867
2868
|
const isDefault = theme === activeTheme;
|
|
2869
|
+
container.classList.toggle('is-locked', isLocked);
|
|
2868
2870
|
container.classList.toggle('opacity-50', !isAllowed);
|
|
2869
2871
|
container.classList.toggle('is-default', isDefault);
|
|
2870
2872
|
const button = container.querySelector('[data-setup-theme-choice]');
|
|
@@ -2897,6 +2899,11 @@
|
|
|
2897
2899
|
});
|
|
2898
2900
|
|
|
2899
2901
|
allowedCheckboxes.forEach((checkbox) => {
|
|
2902
|
+
checkbox.addEventListener('click', (event) => {
|
|
2903
|
+
if (checkbox.checked && getAllowedThemes().length === 1) {
|
|
2904
|
+
event.preventDefault();
|
|
2905
|
+
}
|
|
2906
|
+
});
|
|
2900
2907
|
checkbox.addEventListener('change', () => {
|
|
2901
2908
|
if (!getAllowedThemes().length) {
|
|
2902
2909
|
checkbox.checked = true;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{% load static %}
|
|
2
|
+
<div class="ms-font-picker" id="msFontPreviews">
|
|
3
|
+
<div class="ms-density-options" role="group" aria-label="{{ MS_TRANS.typography }}">
|
|
4
|
+
{% for font in option_fonts %}
|
|
5
|
+
<button
|
|
6
|
+
type="button"
|
|
7
|
+
class="ms-density-option ms-font-option{% if selected_font == font.slug %} is-active{% endif %}"
|
|
8
|
+
data-font="{{ font.slug }}"
|
|
9
|
+
>
|
|
10
|
+
<span class="ms-density-option__icon ms-font-option__icon" aria-hidden="true">
|
|
11
|
+
<span class="font-preview-sample">Aa</span>
|
|
12
|
+
</span>
|
|
13
|
+
<span class="ms-density-option__copy">
|
|
14
|
+
<strong>{{ font.label }}</strong>
|
|
15
|
+
<small>{{ font.slug }}</small>
|
|
16
|
+
</span>
|
|
17
|
+
</button>
|
|
18
|
+
{% endfor %}
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
</label>
|
|
31
31
|
</div>
|
|
32
32
|
<div class="ms-font-settings-option__content p-2 text-center">
|
|
33
|
-
<div class="font-preview-sample h2 mb-1"
|
|
33
|
+
<div class="font-preview-sample h2 mb-1">
|
|
34
34
|
Aa
|
|
35
35
|
</div>
|
|
36
36
|
<span class="ms-choice-option__copy">
|
|
@@ -44,20 +44,3 @@
|
|
|
44
44
|
</div>
|
|
45
45
|
</div>
|
|
46
46
|
</div>
|
|
47
|
-
|
|
48
|
-
<style>
|
|
49
|
-
.ms-font-settings-option__header {
|
|
50
|
-
position: absolute;
|
|
51
|
-
top: 8px;
|
|
52
|
-
right: 8px;
|
|
53
|
-
z-index: 2;
|
|
54
|
-
}
|
|
55
|
-
[dir="rtl"] .ms-font-settings-option__header {
|
|
56
|
-
right: auto;
|
|
57
|
-
left: 8px;
|
|
58
|
-
}
|
|
59
|
-
.ms-font-settings-option {
|
|
60
|
-
position: relative;
|
|
61
|
-
min-width: 120px;
|
|
62
|
-
}
|
|
63
|
-
</style>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{% load microsys_tags %}
|
|
2
2
|
<div class="ms-language-fonts-editor mt-4" id="msLanguageFontsEditor">
|
|
3
|
-
<h6 class="fw-bold mb-3">{{ MS_TRANS.default_fonts_per_lang
|
|
4
|
-
<p class="text-muted small mb-4">{{ MS_TRANS.default_fonts_per_lang_desc
|
|
3
|
+
<h6 class="fw-bold mb-3">{{ MS_TRANS.default_fonts_per_lang }}</h6>
|
|
4
|
+
<p class="text-muted small mb-4">{{ MS_TRANS.default_fonts_per_lang_desc }}</p>
|
|
5
5
|
|
|
6
6
|
<div class="table-responsive">
|
|
7
7
|
<table class="table table-sm table-borderless align-middle">
|
|
8
8
|
<thead>
|
|
9
9
|
<tr>
|
|
10
|
-
<th width="40%">{{ MS_TRANS.language
|
|
11
|
-
<th>{{ MS_TRANS.default_font
|
|
10
|
+
<th width="40%">{{ MS_TRANS.language }}</th>
|
|
11
|
+
<th>{{ MS_TRANS.default_font }}</th>
|
|
12
12
|
</tr>
|
|
13
13
|
</thead>
|
|
14
14
|
<tbody>
|
{django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/includes/options.html
RENAMED
|
@@ -301,10 +301,10 @@
|
|
|
301
301
|
title="{{ MS_TRANS.sidebar_reorder|default:'Reorder' }}">
|
|
302
302
|
<i class="bi bi-grip-vertical"></i>
|
|
303
303
|
</button>
|
|
304
|
-
<h4 class="mb-3"><i class="bi bi-fonts me-2"></i> {{ MS_TRANS.typography
|
|
305
|
-
<p class="text-muted small mb-4">{{ MS_TRANS.typography_desc
|
|
304
|
+
<h4 class="mb-3"><i class="bi bi-fonts me-2"></i> {{ MS_TRANS.typography }}</h4>
|
|
305
|
+
<p class="text-muted small mb-4">{{ MS_TRANS.typography_desc }}</p>
|
|
306
306
|
|
|
307
|
-
{% include 'microsys/includes/font_previews.html' with selected_font=active_font
|
|
307
|
+
{% include 'microsys/includes/font_previews.html' with selected_font=active_font option_fonts=option_fonts %}
|
|
308
308
|
</div>
|
|
309
309
|
</div>
|
|
310
310
|
{% endif %}
|
{django_microsys-2.2.0 → django_microsys-2.2.2}/microsys/templates/microsys/tables/table.html
RENAMED
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
<div class="ms-table-page-size__options">
|
|
74
74
|
{% for per_page_value in table.microsys_per_page_options %}
|
|
75
75
|
<a
|
|
76
|
-
class="ms-table-page-size__option{% if table.microsys_per_page == per_page_value %} is-active{% endif %}"
|
|
76
|
+
class="ms-table-page-size__option{% if table.microsys_per_page|stringformat:'s' == per_page_value|stringformat:'s' %} is-active{% endif %}"
|
|
77
77
|
href="{% ms_querystring_multi table.prefixed_page_field '' table.microsys_per_page_field per_page_value %}"
|
|
78
78
|
>
|
|
79
79
|
{{ per_page_value }}
|
|
@@ -63,8 +63,8 @@ MICROSYS_STRINGS = {
|
|
|
63
63
|
'system_settings_languages': 'اللغات',
|
|
64
64
|
'system_settings_security': 'الوصول والأمان',
|
|
65
65
|
'system_settings_sidebar': 'الشريط الجانبي',
|
|
66
|
-
'system_settings_ui_layout': '
|
|
67
|
-
'system_settings_appearance': 'المظهر
|
|
66
|
+
'system_settings_ui_layout': 'شريط العنوان',
|
|
67
|
+
'system_settings_appearance': 'المظهر والخط',
|
|
68
68
|
'system_setup_title': 'التهيئة الأولى للبرنامج',
|
|
69
69
|
'system_setup_heading': 'ابدأ تهيئة Microsys',
|
|
70
70
|
'system_setup_desc': 'أكمل إعدادات الهوية واللغات والشريط الجانبي والمظهر قبل البدء.',
|
|
@@ -73,8 +73,8 @@ MICROSYS_STRINGS = {
|
|
|
73
73
|
'system_setup_step2': 'الخطوة 2: اللغات والترجمات',
|
|
74
74
|
'system_setup_step3': 'الخطوة 3: الوصول والأمان',
|
|
75
75
|
'system_setup_step4': 'الخطوة 4: الشريط الجانبي والتنقل',
|
|
76
|
-
'system_setup_step5': 'الخطوة 5:
|
|
77
|
-
'system_setup_step6': 'الخطوة 6: المظهر
|
|
76
|
+
'system_setup_step5': 'الخطوة 5: شريط العنوان',
|
|
77
|
+
'system_setup_step6': 'الخطوة 6: المظهر والخط',
|
|
78
78
|
'apply_language': 'تطبيق اللغة',
|
|
79
79
|
|
|
80
80
|
# System Settings Form
|
|
@@ -97,8 +97,18 @@ MICROSYS_STRINGS = {
|
|
|
97
97
|
'help_sys_allowed_themes': 'اختر المظاهر التي تريد السماح بها داخل هذا المشروع. يجب أن يبقى المظهر الافتراضي ضمن القائمة.',
|
|
98
98
|
'form_sys_allow_user_theme_override': 'السماح للمستخدم بتغيير المظهر',
|
|
99
99
|
'help_sys_allow_user_theme_override': 'السماح للمستخدمين بالتبديل بين المظاهر المسموح بها من صفحة الخيارات ومن شريط أدوات الشريط الجانبي.',
|
|
100
|
+
'form_sys_allowed_fonts': 'الخطوط المسموح بها',
|
|
101
|
+
'help_sys_allowed_fonts': 'اختر الخطوط المتاحة للاستخدام في هذا المشروع. يجب أن تبقى الخطوط الافتراضية لكل لغة مفعلة.',
|
|
102
|
+
'form_sys_allow_user_font_override': 'السماح للمستخدم بتغيير الخط',
|
|
103
|
+
'help_sys_allow_user_font_override': 'السماح للمستخدمين بالتبديل بين الخطوط المسموح بها من صفحة الخيارات.',
|
|
104
|
+
'form_sys_default_fonts': 'الخطوط الافتراضية حسب اللغة',
|
|
100
105
|
'form_sys_allow_user_language_override': 'السماح للمستخدم بتغيير اللغة',
|
|
101
106
|
'help_sys_allow_user_language_override': 'السماح للمستخدمين باختيار لغة العرض من صفحة الخيارات. عند التعطيل سيتم فرض اللغة الافتراضية للنظام.',
|
|
107
|
+
'tables_settings_title': 'إعدادات الجداول',
|
|
108
|
+
'typography_settings_title': 'إعدادات الخطوط والتخصيص',
|
|
109
|
+
'default_fonts_per_lang': 'الخطوط الافتراضية حسب اللغة',
|
|
110
|
+
'default_fonts_per_lang_desc': 'اختر الخط الافتراضي لكل لغة نشطة في النظام.',
|
|
111
|
+
'default_font': 'الخط الافتراضي',
|
|
102
112
|
'form_sys_default_table_density': 'الكثافة الافتراضية للجداول',
|
|
103
113
|
'help_sys_default_table_density': 'اختر كثافة الجداول الافتراضية للمستخدمين الجدد، مع إمكانية تجاوزها لاحقاً من صفحة الخيارات.',
|
|
104
114
|
'form_sys_logo': 'الشعار (Logo)',
|
|
@@ -145,11 +155,11 @@ MICROSYS_STRINGS = {
|
|
|
145
155
|
'sidebar_collapse_hidden_desc': 'يطوي الشريط إلى حالة مخفية بالكامل على سطح المكتب.',
|
|
146
156
|
'sidebar_collapse_locked_expanded': 'يبقى موسعاً دائماً',
|
|
147
157
|
'sidebar_collapse_locked_expanded_desc': 'يعطّل طي الشريط الجانبي ويُبقيه موسعاً دائماً.',
|
|
148
|
-
'form_sys_titlebar_show_title': 'إظهار
|
|
158
|
+
'form_sys_titlebar_show_title': 'إظهار العنوان في الشريط',
|
|
149
159
|
'help_sys_titlebar_show_title': 'إظهار اسم النظام داخل شريط العنوان.',
|
|
150
|
-
'form_sys_titlebar_show_logo': 'إظهار
|
|
160
|
+
'form_sys_titlebar_show_logo': 'إظهار الشعار في الشريط',
|
|
151
161
|
'help_sys_titlebar_show_logo': 'إظهار شعار الهوية بجانب العنوان.',
|
|
152
|
-
'form_sys_titlebar_show_home_button': 'إظهار زر الرئيسية في
|
|
162
|
+
'form_sys_titlebar_show_home_button': 'إظهار زر الرئيسية في الشريط',
|
|
153
163
|
'help_sys_titlebar_show_home_button': 'إظهار زر اختصار الرئيسية في شريط العنوان.',
|
|
154
164
|
'form_sys_titlebar_home_shape': 'شكل زر الرئيسية',
|
|
155
165
|
'form_sys_titlebar_title_align': 'محاذاة العنوان',
|
|
@@ -217,11 +227,13 @@ MICROSYS_STRINGS = {
|
|
|
217
227
|
'form_sys_email_default_from': 'بريد المرسل الافتراضي',
|
|
218
228
|
'form_sys_public_root': 'السماح بالوصول العام للصفحة الرئيسية',
|
|
219
229
|
'help_sys_public_root': 'السماح للمستخدمين غير المسجلين بالدخول بالوصول إلى الرابط الرئيسي (/). عند التفعيل، لن يتم فرض التحويل إلى صفحة تسجيل الدخول.',
|
|
230
|
+
'form_sys_public_registration': 'تفعيل التسجيل العام',
|
|
231
|
+
'help_sys_public_registration': 'السماح للمستخدمين غير المسجلين بطلب إنشاء حساب. يتطلب التحقق من البريد الإلكتروني وتجهيز إعدادات توصيل البريد.',
|
|
220
232
|
'form_sys_public_root_split_enabled': 'فصل الجذر العام للمستخدم غير المسجّل عن رابط الصفحة الرئيسية',
|
|
221
233
|
'help_sys_public_root_split_enabled': 'عند التفعيل، يمكن توجيه المستخدمين غير المسجّلين إلى رابط جذر عام منفصل بينما يستمر المستخدمون المسجّلون في استخدام رابط الصفحة الرئيسية الأساسي.',
|
|
222
234
|
'root_home_settings_title': 'وجهات الصفحة الرئيسية والجذر العام',
|
|
223
|
-
'form_sys_titlebar_hide_on_public_unauthenticated_index': 'إخفاء الشريط
|
|
224
|
-
'help_sys_titlebar_hide_on_public_unauthenticated_index': 'إخفاء الشريط العلوي
|
|
235
|
+
'form_sys_titlebar_hide_on_public_unauthenticated_index': 'إخفاء الشريط في الصفحة العامة للمستخدم غير المسجّل',
|
|
236
|
+
'help_sys_titlebar_hide_on_public_unauthenticated_index': 'إخفاء الشريط العلوي لأي مستخدم غير مسجّل في الصفحة الرئيسية العامة.',
|
|
225
237
|
'sidebar_disabled_navigation_note': 'تعطيل الشريط الجانبي قد يجعل التطبيق بلا تنقل مدمج. ستحتاج إلى الاعتماد على لوحات المعلومات والنوافذ المنبثقة، أو إضافة أزرار رجوع وروابط تنقل مخصصة داخل النماذج والقوائم ولوحات المعلومات. ابتداءً من v2.2.0، مدير الأقسام الديناميكي متاح فقط من خلال الشريط الجانبي، لذلك أضف له زراً في لوحة معلومات أو مدخلاً مخصصاً إذا كنت تحتاج الوصول إليه. سيتم تحديث هذا التحذير مستقبلاً إذا تمت إضافة بديل مدمج.',
|
|
226
238
|
'sidebar_toolbar_disable_note': 'تعطيل شريط أدوات الشريط الجانبي يزيل أيضاً الاختصار المدمج الوحيد لمدير الأقسام الديناميكي. إذا كنت لا تزال تريد الوصول إليه من الواجهة، فعّل عناصر النظام داخل منشئ الشريط الجانبي ثم أضف إدارة الأقسام إلى الشريط الجانبي.',
|
|
227
239
|
'btn_save': 'حفظ التعديلات',
|
|
@@ -292,6 +304,8 @@ MICROSYS_STRINGS = {
|
|
|
292
304
|
'microsys_version': 'إصدار النظام (microSYS)',
|
|
293
305
|
'themes': 'سمة الألوان',
|
|
294
306
|
'themes_desc': 'اختر مظهر الألوان المفضل لديك لواجهة المنظومة.',
|
|
307
|
+
'typography': 'الخطوط والطباعة',
|
|
308
|
+
'typography_desc': 'اختر الخط المفضل لديك لواجهة المنظومة.',
|
|
295
309
|
'table_density': 'كثافة الجداول',
|
|
296
310
|
'table_density_desc': 'تحكم في مقدار المساحة الرأسية التي تستخدمها الجداول أثناء العمل.',
|
|
297
311
|
'sidebar_density': 'كثافة الشريط الجانبي',
|
|
@@ -912,7 +926,7 @@ MICROSYS_STRINGS = {
|
|
|
912
926
|
'system_settings_languages': 'Languages',
|
|
913
927
|
'system_settings_security': 'Access & Security',
|
|
914
928
|
'system_settings_sidebar': 'Sidebar',
|
|
915
|
-
'system_settings_ui_layout': '
|
|
929
|
+
'system_settings_ui_layout': 'Titlebar',
|
|
916
930
|
'system_settings_appearance': 'Themes & Typography',
|
|
917
931
|
'system_setup_title': 'Initial System Setup',
|
|
918
932
|
'system_setup_heading': 'Set up Microsys',
|
|
@@ -922,7 +936,7 @@ MICROSYS_STRINGS = {
|
|
|
922
936
|
'system_setup_step2': 'Step 2: Localization',
|
|
923
937
|
'system_setup_step3': 'Step 3: Access & Security',
|
|
924
938
|
'system_setup_step4': 'Step 4: Navigation',
|
|
925
|
-
'system_setup_step5': 'Step 5:
|
|
939
|
+
'system_setup_step5': 'Step 5: Titlebar',
|
|
926
940
|
'system_setup_step6': 'Step 6: Themes & Typography',
|
|
927
941
|
'apply_language': 'Apply language',
|
|
928
942
|
|
|
@@ -944,12 +958,22 @@ MICROSYS_STRINGS = {
|
|
|
944
958
|
'selector_search_pages': 'Search discovered pages',
|
|
945
959
|
'form_sys_default_lang': 'Default Language',
|
|
946
960
|
'form_sys_default_theme': 'Default Theme',
|
|
947
|
-
'form_sys_allowed_themes': 'Allowed
|
|
961
|
+
'form_sys_allowed_themes': 'Allowed themes',
|
|
948
962
|
'help_sys_allowed_themes': 'Choose which themes are available in this project. The default theme must remain enabled.',
|
|
949
|
-
'form_sys_allow_user_theme_override': 'Allow
|
|
950
|
-
'help_sys_allow_user_theme_override': 'Allow users to switch between the allowed themes from Options and the sidebar toolbar.',
|
|
963
|
+
'form_sys_allow_user_theme_override': 'Allow user theme override',
|
|
964
|
+
'help_sys_allow_user_theme_override': 'Allow users to switch between the allowed themes at runtime from Options and the sidebar toolbar.',
|
|
965
|
+
'form_sys_allowed_fonts': 'Allowed fonts',
|
|
966
|
+
'help_sys_allowed_fonts': 'Choose which fonts are available in this project. The default fonts for each language must remain enabled.',
|
|
967
|
+
'form_sys_allow_user_font_override': 'Allow user font override',
|
|
968
|
+
'help_sys_allow_user_font_override': 'Allow users to switch between the allowed fonts at runtime from Options.',
|
|
969
|
+
'form_sys_default_fonts': 'Default fonts by language',
|
|
951
970
|
'form_sys_allow_user_language_override': 'Allow User Language Override',
|
|
952
971
|
'help_sys_allow_user_language_override': 'Allow users to change their display language from Options. When disabled, the system default language is enforced.',
|
|
972
|
+
'tables_settings_title': 'Tables Settings',
|
|
973
|
+
'typography_settings_title': 'Typography Settings',
|
|
974
|
+
'default_fonts_per_lang': 'Default Fonts by Language',
|
|
975
|
+
'default_fonts_per_lang_desc': 'Choose which font to use as the default for each active language.',
|
|
976
|
+
'default_font': 'Default Font',
|
|
953
977
|
'form_sys_default_table_density': 'Default Table Density',
|
|
954
978
|
'help_sys_default_table_density': 'Choose the default table density for new users; each user can still override it later from Options.',
|
|
955
979
|
'form_sys_logo': 'System Logo (Logo)',
|
|
@@ -1068,6 +1092,8 @@ MICROSYS_STRINGS = {
|
|
|
1068
1092
|
'form_sys_email_default_from': 'Default from email',
|
|
1069
1093
|
'form_sys_public_root': 'Public Root Access',
|
|
1070
1094
|
'help_sys_public_root': 'Allow anonymous (non-logged-in) users to access the root URL (/). When enabled, the system will not force-redirect to login.',
|
|
1095
|
+
'form_sys_public_registration': 'Enable Public Registration',
|
|
1096
|
+
'help_sys_public_registration': 'Allow anonymous users to request an account. Email verification is mandatory and SMTP/email delivery must be configured.',
|
|
1071
1097
|
'form_sys_public_root_split_enabled': 'Separate anonymous public root from Home URL',
|
|
1072
1098
|
'help_sys_public_root_split_enabled': 'When enabled, anonymous users can be redirected to a separate Public Root URL while authenticated users still use the main Home URL.',
|
|
1073
1099
|
'root_home_settings_title': 'Home & Public Root Destinations',
|
|
@@ -1139,8 +1165,10 @@ MICROSYS_STRINGS = {
|
|
|
1139
1165
|
'cache': 'Cache',
|
|
1140
1166
|
'tasks': 'Task Server',
|
|
1141
1167
|
'microsys_version': 'microSYS Version',
|
|
1142
|
-
'themes': '
|
|
1143
|
-
'themes_desc': 'Choose your preferred color
|
|
1168
|
+
'themes': 'Color Theme',
|
|
1169
|
+
'themes_desc': 'Choose your preferred color theme for the interface.',
|
|
1170
|
+
'typography': 'Typography',
|
|
1171
|
+
'typography_desc': 'Choose your preferred font for the interface.',
|
|
1144
1172
|
'table_density': 'Table Density',
|
|
1145
1173
|
'table_density_desc': 'Control how much vertical space data tables use while you work.',
|
|
1146
1174
|
'sidebar_density': 'Sidebar Density',
|