diff --git a/config/menu.py b/config/menu.py index 8dc074e..80d992c 100644 --- a/config/menu.py +++ b/config/menu.py @@ -1,7 +1,9 @@ WAGTAIL_MENU_APPS_ORDER = [ + "markup_doc", "xml_manager", "reference", "tracker", + "model_ai", "django_celery_beat", ] @@ -9,5 +11,5 @@ def get_menu_order(app_name): try: return WAGTAIL_MENU_APPS_ORDER.index(app_name) + 1 - except: + except ValueError: return 9000 diff --git a/config/settings/base.py b/config/settings/base.py index a207502..68b9724 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -233,6 +233,16 @@ # e.g. in notification emails. Don't include '/admin' or a trailing slash WAGTAILADMIN_BASE_URL = "http://example.com" +WAGTAILIMAGES_EXTENSIONS = [ + "avif", + "gif", + "jpg", + "jpeg", + "png", + "webp", + "svg", +] + # Allowed file extensions for documents in the document library. # This can be omitted to allow all files, but note that this may present a security risk # if untrusted users are allowed to upload files - diff --git a/core/migrations/0002_wagtailsearch_indexentry_text_defaults.py b/core/migrations/0002_wagtailsearch_indexentry_text_defaults.py new file mode 100644 index 0000000..7e0899c --- /dev/null +++ b/core/migrations/0002_wagtailsearch_indexentry_text_defaults.py @@ -0,0 +1,33 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("core", "0001_initial"), + ] + + operations = [ + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_schema = current_schema() + AND table_name = 'wagtailsearch_indexentry' + AND column_name = 'title_text' + ) THEN + UPDATE wagtailsearch_indexentry + SET title_text = COALESCE(title_text, ''), + body_text = COALESCE(body_text, ''); + + ALTER TABLE wagtailsearch_indexentry + ALTER COLUMN title_text SET DEFAULT '', + ALTER COLUMN body_text SET DEFAULT ''; + END IF; + END $$; + """, + reverse_sql=migrations.RunSQL.noop, + ), + ] diff --git a/core/wagtail_hooks.py b/core/wagtail_hooks.py index e69de29..385612f 100644 --- a/core/wagtail_hooks.py +++ b/core/wagtail_hooks.py @@ -0,0 +1,16 @@ +import os + +from django.db.models.signals import pre_save +from wagtail.images import get_image_model + + +def ensure_image_title(sender, instance, **kwargs): + if (instance.title or "").strip(): + return + if not instance.file: + return + basename = os.path.basename(instance.file.name) + instance.title = os.path.splitext(basename)[0] + + +pre_save.connect(ensure_image_title, sender=get_image_model()) diff --git a/core_settings/static/core_settings/css/admin_logo.css b/core_settings/static/core_settings/css/admin_logo.css new file mode 100644 index 0000000..ed825d5 --- /dev/null +++ b/core_settings/static/core_settings/css/admin_logo.css @@ -0,0 +1,12 @@ +.custom-admin-logo { + display: block; + max-height: 2.5rem; + max-width: 100%; + width: auto; + height: auto; +} + +.custom-admin-logo--login { + max-height: 4rem; + margin: 0 auto; +} diff --git a/core_settings/templates/wagtailadmin/base.html b/core_settings/templates/wagtailadmin/base.html new file mode 100644 index 0000000..4ad44ee --- /dev/null +++ b/core_settings/templates/wagtailadmin/base.html @@ -0,0 +1,5 @@ +{% extends "wagtailadmin/base.html" %} + +{% block branding_logo %} + {% include "wagtailadmin/includes/admin_logo.html" %} +{% endblock %} diff --git a/core_settings/templates/wagtailadmin/includes/admin_logo.html b/core_settings/templates/wagtailadmin/includes/admin_logo.html new file mode 100644 index 0000000..0669604 --- /dev/null +++ b/core_settings/templates/wagtailadmin/includes/admin_logo.html @@ -0,0 +1,9 @@ +{% if settings.core_settings.customsettings.admin_logo %} + +{% else %} + {% include "wagtailadmin/logo.html" %} +{% endif %} diff --git a/core_settings/templates/wagtailadmin/includes/admin_logo_login.html b/core_settings/templates/wagtailadmin/includes/admin_logo_login.html new file mode 100644 index 0000000..1dbf581 --- /dev/null +++ b/core_settings/templates/wagtailadmin/includes/admin_logo_login.html @@ -0,0 +1,9 @@ +{% if settings.core_settings.customsettings.admin_logo %} + +{% else %} + {% include "wagtailadmin/logo.html" with wordmark="True" %} +{% endif %} diff --git a/core_settings/templates/wagtailadmin/login.html b/core_settings/templates/wagtailadmin/login.html new file mode 100644 index 0000000..bcb41be --- /dev/null +++ b/core_settings/templates/wagtailadmin/login.html @@ -0,0 +1,7 @@ +{% extends "wagtailadmin/login.html" %} + +{% block branding_logo %} + +{% endblock %} diff --git a/core_settings/wagtail_hooks.py b/core_settings/wagtail_hooks.py new file mode 100644 index 0000000..04b82de --- /dev/null +++ b/core_settings/wagtail_hooks.py @@ -0,0 +1,11 @@ +from django.templatetags.static import static +from django.utils.html import format_html +from wagtail import hooks + + +@hooks.register("insert_global_admin_css") +def admin_logo_css(): + return format_html( + '', + static("core_settings/css/admin_logo.css"), + ) diff --git a/django_celery_beat/wagtail_hooks.py b/django_celery_beat/wagtail_hooks.py index 6601b67..429a804 100644 --- a/django_celery_beat/wagtail_hooks.py +++ b/django_celery_beat/wagtail_hooks.py @@ -7,12 +7,9 @@ from django.utils.translation import gettext_lazy as _ from kombu.utils.json import loads from wagtail import hooks -from wagtail_modeladmin.options import ( - ModelAdmin, - ModelAdminGroup, - modeladmin_register, -) +from wagtail_modeladmin.options import ModelAdmin, ModelAdminGroup, modeladmin_register +from config.menu import get_menu_order from django_celery_beat.models import ( ClockedSchedule, CrontabSchedule, @@ -24,7 +21,6 @@ from django_celery_beat.utils import is_database_scheduler from .button_helper import PeriodicTaskHelper -from config.menu import get_menu_order class PeriodicTaskAdmin(ModelAdmin): @@ -190,8 +186,9 @@ class SolarScheduleAdmin(ModelAdmin): class TasksModelsAdminGroup(ModelAdminGroup): - menu_label = _("Tasks") - menu_icon = "cogs" + menu_name = "django_celery_beat" + menu_label = _("Tarefas agendadas") + menu_icon = "time" menu_order = get_menu_order("django_celery_beat") items = ( PeriodicTaskAdmin, diff --git a/docs/pr/2026-05-15-reorder-menu-svg-admin-branding.md b/docs/pr/2026-05-15-reorder-menu-svg-admin-branding.md new file mode 100644 index 0000000..cbfecdb --- /dev/null +++ b/docs/pr/2026-05-15-reorder-menu-svg-admin-branding.md @@ -0,0 +1,82 @@ +# Menu admin RCT, SVG, indexação, logo e correções Wagtail + +**Data:** 2026-05-15 +**Branch:** `reorder_menu_enable_svg` + +## Mensagem de commit + +``` +Reorganiza admin Wagtail, SVG, logo e indexação de imagens + +Menu alinhado ao fluxo RCT; upload SVG; logo via admin_logo; corrige +title_text na indexação e imports em markup_doc/wagtail_hooks. +``` + +## O que esse PR faz? + +Conjunto de melhorias no admin Wagtail e na configuração editorial do markapi: + +### 1. Menu lateral (fluxo RCT) + +Ordem centralizada em `config/menu.py`: + +1. Marcação editorial (`markup_doc`) +2. Gestão de XML (`xml_manager`) +3. Referências bibliográficas (`reference`) +4. Rastreio de eventos (`tracker`) +5. Modelos de IA (`model_ai`) +6. Tarefas agendadas (`django_celery_beat`) + +Rótulos e ícones atualizados em todos os `wagtail_hooks.py` dos módulos. Grupo **Marcação editorial**: Coleções → Periódicos → Carregar DOCX → XML SPS marcado. Removidos `ModelAdmin` legados não registados em `markup_doc`. + +### 2. Upload de SVG + +`WAGTAILIMAGES_EXTENSIONS` em `config/settings/base.py` inclui `svg` (e formatos raster habituais). + +### 3. Logo do admin + +Templates em `core_settings/templates/wagtailadmin/` usam `settings.core_settings.customsettings.admin_logo` na sidebar e no login. CSS em `core_settings/static/core_settings/css/admin_logo.css`. Fallback para logo Wagtail se não houver imagem. + +### 4. Indexação de imagens (`title_text`) + +Migração `core/migrations/0002_wagtailsearch_indexentry_text_defaults.py`: preenche `NULL` e define `DEFAULT ''` em `title_text`/`body_text` quando as colunas existem (corrige `IntegrityError` ao indexar imagens com schema Wagtail 7 e código de indexação que omite esses campos). + +Signal em `core/wagtail_hooks.py`: define título da imagem a partir do nome do ficheiro quando vazio. + +### 5. Correções em `markup_doc/wagtail_hooks.py` + +Restaura imports (`path`, `format_html`, `static`, `TemplateResponse`, `update_xml`) e resolve conflito de merge. + +## Onde a revisão poderia começar? + +- [config/menu.py](config/menu.py) +- [markup_doc/wagtail_hooks.py](markup_doc/wagtail_hooks.py) +- [core_settings/templates/wagtailadmin/includes/admin_logo.html](core_settings/templates/wagtailadmin/includes/admin_logo.html) +- [core/migrations/0002_wagtailsearch_indexentry_text_defaults.py](core/migrations/0002_wagtailsearch_indexentry_text_defaults.py) + +## Como este poderia ser testado manualmente? + +1. `python manage.py migrate` +2. Reiniciar a aplicação e abrir `/admin/` +3. Confirmar ordem e rótulos do menu (Marcação editorial → … → Tarefas agendadas) +4. **Settings → Site configuration → Admin settings**: definir `admin_logo` (SVG) e recarregar admin — logo na sidebar e em `/admin/login/` +5. **Images**: upload de `.svg` sem erro +6. Se antes falhava indexação: repetir upload de logo e confirmar ausência de `IntegrityError` em `wagtailsearch_indexentry` + +## Algum cenário de contexto que queira dar? + +Alinhar versão instalada de `wagtail` com migrações já aplicadas na base (recomendado Wagtail 7.4 LTS se `wagtailsearch.0010_add_text_fields` existir). A migração em `core` mitiga desalinhamento entre schema e indexador. SVG em produção: restringir upload a utilizadores de confiança. + +## Screenshots + +N/A + +## Quais são tickets relevantes? + +N/A + +## Referências + +- SciELO RCT — `.cursor/rules/project-objectives.mdc` +- [Wagtail — customização do admin](https://docs.wagtail.org/en/stable/advanced_topics/customization/admin_templates.html) +- [Wagtail — SVG nas imagens](https://wagtail.org/blog/how-we-added-svg-support-to-wagtail-50/) diff --git a/markup_doc/wagtail_hooks.py b/markup_doc/wagtail_hooks.py index 356c10b..fc3abe7 100644 --- a/markup_doc/wagtail_hooks.py +++ b/markup_doc/wagtail_hooks.py @@ -13,17 +13,17 @@ CreateView, EditView, SnippetViewSet, - SnippetViewSetGroup + SnippetViewSetGroup, ) -from markup_doc.models import ( - ArticleDocx, - ArticleDocxMarkup, - UploadDocx, - MarkupXML, +from config.menu import get_menu_order +from markup_doc import views +from markup_doc.models import ( CollectionModel, JournalModel, - ProcessStatus + MarkupXML, + ProcessStatus, + UploadDocx, ) from markup_doc import views @@ -31,29 +31,29 @@ from markup_doc.tasks import get_labels, task_sync_journals_from_api, update_xml - -@hooks.register('register_admin_urls') +@hooks.register("register_admin_urls") def register_admin_urls(): return [ - path('download-xml//', views.generate_xml, name='generate_xml'), - path('extract-citation/', views.extract_citation, name='extract_citation'), - path('get_journal/', views.get_journal, name='get_journal'), - path('download-zip/', views.generate_zip, name='generate_zip'), - path('preview-html/', views.preview_html_post, name='preview_html_post'), - path('pretty-xml/', views.preview_xml_tree, name='preview_xml_tree'), + path( + "download-xml//", views.generate_xml, name="generate_xml" + ), + path("extract-citation/", views.extract_citation, name="extract_citation"), + path("get_journal/", views.get_journal, name="get_journal"), + path("download-zip/", views.generate_zip, name="generate_zip"), + path("preview-html/", views.preview_html_post, name="preview_html_post"), + path("pretty-xml/", views.preview_xml_tree, name="preview_xml_tree"), ] -@hooks.register('insert_editor_js') +@hooks.register("insert_editor_js") def xref_js(): return format_html( '', - static('js/xref-button.js') + static("js/xref-button.js"), ) class ArticleDocxCreateView(CreateView): - # def get_form_class(self): def dispatch(self, request, *args, **kwargs): if not CollectionModel.objects.exists(): messages.warning(request, "Debes seleccionar primero una colección.") @@ -69,7 +69,9 @@ def form_valid(self, form): self.object = form.save_all(self.request.user) self.object.estatus = ProcessStatus.PROCESSING self.object.save() - transaction.on_commit(lambda: get_labels.delay(self.object.title, self.request.user.id)) + transaction.on_commit( + lambda: get_labels.delay(self.object.title, self.request.user.id) + ) return HttpResponseRedirect(self.get_success_url()) @@ -77,65 +79,41 @@ class ArticleDocxEditView(EditView): def form_valid(self, form): form.instance.updated_by = self.request.user form.instance.save() - update_xml.delay(form.instance.id, form.instance.content.get_prep_value(), form.instance.content_body.get_prep_value(), form.instance.content_back.get_prep_value()) + update_xml.delay( + form.instance.id, + form.instance.content.get_prep_value(), + form.instance.content_body.get_prep_value(), + form.instance.content_back.get_prep_value(), + ) return HttpResponseRedirect(self.get_success_url()) -class ArticleDocxAdmin(ModelAdmin): - model = ArticleDocx - create_view_class = ArticleDocxCreateView - menu_label = _("Documents") - menu_icon = "folder" - menu_order = 1 - add_to_settings_menu = False # or True to add your model to the Settings sub-menu - exclude_from_explorer = ( - False # or True to exclude pages of this type from Wagtail's explorer view - ) - list_per_page = 20 - list_display = ("title", "get_estatus_display") - - class ArticleDocxMarkupCreateView(CreateView): def form_valid(self, form): self.object = form.save_all(self.request.user) return HttpResponseRedirect(self.get_success_url()) -class ArticleDocxMarkupAdmin(ModelAdmin): - model = ArticleDocxMarkup - create_view_class = ArticleDocxMarkupCreateView - menu_label = _("Documents Markup") - menu_icon = "folder" - menu_order = 1 - add_to_settings_menu = False # or True to add your model to the Settings sub-menu - exclude_from_explorer = ( - False # or True to exclude pages of this type from Wagtail's explorer view - ) - list_per_page = 20 - - class UploadDocxViewSet(SnippetViewSet): model = UploadDocx add_view_class = ArticleDocxCreateView menu_label = _("Carregar DOCX") - menu_icon = "folder" - menu_order = 1 - add_to_settings_menu = False + menu_icon = "upload" + add_to_admin_menu = False exclude_from_explorer = False list_per_page = 20 - list_display = ("title", "get_estatus_display") # Usar estatus, não status + list_display = ("title", "get_estatus_display") search_fields = ("title",) - list_filter = ("estatus",) # Usar estatus, não status + list_filter = ("estatus",) class MarkupXMLViewSet(SnippetViewSet): model = MarkupXML add_view_class = ArticleDocxMarkupCreateView edit_view_class = ArticleDocxEditView - menu_label = _("XML marcado") # Alterado de "MarkupXML" - menu_icon = "folder" - menu_order = 1 - add_to_settings_menu = False + menu_label = _("XML SPS marcado") + menu_icon = "code" + add_to_admin_menu = False exclude_from_explorer = False list_display = ("title",) list_per_page = 20 @@ -157,10 +135,9 @@ def form_valid(self, form): class CollectionModelViewSet(SnippetViewSet): model = CollectionModel add_view_class = CollectionModelCreateView - menu_label = _("Modelo de Coleções") # Alterado de "CollectionModel" - menu_icon = "folder" - menu_order = 1 - add_to_settings_menu = False + menu_label = _("Coleções SciELO") + menu_icon = "folder-inverse" + add_to_admin_menu = False exclude_from_explorer = False list_per_page = 20 list_display = ("collection",) @@ -175,10 +152,9 @@ def get_context_data(self, **kwargs): class JournalModelViewSet(SnippetViewSet): model = JournalModel - menu_label = _("Modelo de Revistas") # Alterado de "JournalModel" - menu_icon = "folder" - menu_order = 1 - add_to_settings_menu = False + menu_label = _("Periódicos") + menu_icon = "doc-empty" + add_to_admin_menu = False exclude_from_explorer = False list_per_page = 20 list_display = ("title",) @@ -206,15 +182,15 @@ def index_view(self, request): class MarkupSnippetViewSetGroup(SnippetViewSetGroup): - menu_name = "docx_files" # Renomeado de 'docx_processor' - menu_label = _("DOCX Files") - menu_icon = "folder-open-inverse" - menu_order = 0 # Mudado de 1 para 0 para ficar na primeira posição + menu_name = "markup_doc" + menu_label = _("Marcação editorial") + menu_icon = "edit" + menu_order = get_menu_order("markup_doc") items = ( - UploadDocxViewSet, - MarkupXMLViewSet, CollectionModelViewSet, JournalModelViewSet, + UploadDocxViewSet, + MarkupXMLViewSet, ) diff --git a/model_ai/wagtail_hooks.py b/model_ai/wagtail_hooks.py index a872d4f..f0476c3 100644 --- a/model_ai/wagtail_hooks.py +++ b/model_ai/wagtail_hooks.py @@ -1,21 +1,12 @@ # Third party imports +from django.contrib import messages from django.http import HttpResponseRedirect from django.utils.translation import gettext_lazy as _ -from django.contrib import messages - -from wagtail.snippets.views.snippets import ( - CreateView, - EditView, - SnippetViewSet, -) - from wagtail.snippets.models import register_snippet +from wagtail.snippets.views.snippets import CreateView, EditView, SnippetViewSet -# Local application imports -from model_ai.models import ( - LlamaModel, - DownloadStatus, -) +from config.menu import get_menu_order +from model_ai.models import DownloadStatus, LlamaModel from model_ai.tasks import download_model @@ -43,12 +34,14 @@ def form_valid(self, form): download_model.delay(form.instance.id) else: if not data.get("api_url") and not data.get("api_key_gemini"): - messages.error(self.request, _("API AI URL or API KEY GEMINI is required.")) + messages.error( + self.request, _("API AI URL or API KEY GEMINI is required.") + ) return self.form_invalid(form) self.object = form.save_all(self.request.user) messages.success(self.request, _("Model created, use API AI.")) - + return HttpResponseRedirect(self.get_success_url()) @@ -76,7 +69,9 @@ def form_valid(self, form): form.instance.save() messages.success(self.request, _("Model updated and download started.")) else: - messages.success(self.request, _("Model updated and already downloaded.")) + messages.success( + self.request, _("Model updated and already downloaded.") + ) else: if not data.get("api_url"): messages.error(self.request, _("API AI URL is required.")) @@ -92,17 +87,14 @@ class LlamaModelViewSet(SnippetViewSet): model = LlamaModel add_view_class = LlamaModelCreateView edit_view_class = LlamaModelEditView - menu_label = _("AI LLM Model") - menu_icon = "folder" - menu_order = 3 - exclude_from_explorer = ( - False # or True to exclude pages of this type from Wagtail's explorer view - ) + menu_name = "model_ai" + menu_label = _("Modelos de IA") + menu_icon = "cog" + menu_order = get_menu_order("model_ai") + exclude_from_explorer = False add_to_admin_menu = True list_per_page = 20 - list_display = ( - "display_name_model", - "get_download_status_display" - ) + list_display = ("display_name_model", "get_download_status_display") + register_snippet(LlamaModelViewSet) diff --git a/reference/wagtail_hooks.py b/reference/wagtail_hooks.py index 564dce3..1f770fb 100644 --- a/reference/wagtail_hooks.py +++ b/reference/wagtail_hooks.py @@ -2,21 +2,18 @@ from django.http import HttpResponseRedirect from django.utils.translation import gettext_lazy as _ from wagtail.snippets.models import register_snippet -from wagtail.snippets.views.snippets import ( - CreateView, - SnippetViewSet, -) +from wagtail.snippets.views.snippets import CreateView, SnippetViewSet # Local application imports +from config.menu import get_menu_order from reference.data_utils import get_reference from reference.models import Reference class ReferenceCreateView(CreateView): def form_valid(self, form): - # Obtener el contenido de mixed_citation del formulario - mixed_citation_text = form.cleaned_data['mixed_citation'].strip() + mixed_citation_text = form.cleaned_data["mixed_citation"].strip() lineas = mixed_citation_text.split("\n") # Dividir por saltos de línea # Crear un nuevo objeto Reference por cada línea válida @@ -33,19 +30,18 @@ def form_valid(self, form): # Redirigir después de la creación de los objetos return HttpResponseRedirect(self.get_success_url()) - + class ReferenceModelViewSet(SnippetViewSet): model = Reference add_view_class = ReferenceCreateView - menu_label = _("Reference") - menu_icon = "folder" - menu_order = 3 - exclude_from_explorer = ( - False - ) + menu_name = "reference" + menu_label = _("Referências bibliográficas") + menu_icon = "openquote" + menu_order = get_menu_order("reference") + exclude_from_explorer = False list_per_page = 20 add_to_admin_menu = True -register_snippet(ReferenceModelViewSet) \ No newline at end of file +register_snippet(ReferenceModelViewSet) diff --git a/tracker/wagtail_hooks.py b/tracker/wagtail_hooks.py index 1bd754d..fbca31e 100644 --- a/tracker/wagtail_hooks.py +++ b/tracker/wagtail_hooks.py @@ -1,21 +1,16 @@ from django.utils.translation import gettext_lazy as _ -from wagtail_modeladmin.options import ( - ModelAdmin, - ModelAdminGroup, - modeladmin_register, -) +from wagtail_modeladmin.options import ModelAdmin, ModelAdminGroup, modeladmin_register from config.menu import get_menu_order -from .models import XMLDocumentEvent, GeneralEvent +from .models import GeneralEvent, XMLDocumentEvent class XMLDocumentEventModelAdmin(ModelAdmin): model = XMLDocumentEvent inspect_view_enabled = True - menu_label = _("XML Document Events") - menu_icon = "warning" - menu_order = 100 + menu_label = _("Eventos de documento XML") + menu_icon = "history" add_to_settings_menu = False exclude_from_explorer = False list_per_page = 10 @@ -27,7 +22,7 @@ class XMLDocumentEventModelAdmin(ModelAdmin): "message", "created", ) - list_filter = ("error_type", ) + list_filter = ("error_type",) search_fields = ( "message", "data", @@ -44,9 +39,8 @@ class XMLDocumentEventModelAdmin(ModelAdmin): class GeneralEventModelAdmin(ModelAdmin): model = GeneralEvent inspect_view_enabled = True - menu_label = _("General Events") - menu_icon = "warning" - menu_order = 200 + menu_label = _("Eventos gerais") + menu_icon = "history" add_to_settings_menu = False exclude_from_explorer = False list_per_page = 10 @@ -58,7 +52,10 @@ class GeneralEventModelAdmin(ModelAdmin): "exception_msg", "created", ) - list_filter = ("action", "exception_type", ) + list_filter = ( + "action", + "exception_type", + ) search_fields = ( "exception_msg", "detail", @@ -77,8 +74,9 @@ class GeneralEventModelAdmin(ModelAdmin): class EventModelAdminGroup(ModelAdminGroup): - menu_icon = "warning" - menu_label = _("Unexpected Events") + menu_name = "tracker" + menu_icon = "history" + menu_label = _("Rastreio de eventos") menu_order = get_menu_order("tracker") items = (GeneralEventModelAdmin, XMLDocumentEventModelAdmin) diff --git a/xml_manager/wagtail_hooks.py b/xml_manager/wagtail_hooks.py index 1ba52e0..37c20b9 100644 --- a/xml_manager/wagtail_hooks.py +++ b/xml_manager/wagtail_hooks.py @@ -1,7 +1,6 @@ import os -from django.urls import path, include -from django.urls import reverse +from django.urls import include, path, reverse from django.utils.html import format_html from django.utils.translation import gettext_lazy as _ from wagtail import hooks @@ -11,14 +10,15 @@ from config.menu import get_menu_order -from .models import XMLDocument, XMLDocumentPDF, XMLDocumentHTML from . import urls +from .models import XMLDocument, XMLDocumentHTML, XMLDocumentPDF class FileNameColumn(Column): """ Coluna que mostra apenas o nome do arquivo de um FileField. """ + def get_value(self, instance): val = super().get_value(instance) if not val: @@ -31,6 +31,7 @@ class LinkColumn(Column): Column que recebe um FileField (FieldFile) e renderiza um . Cria '-' se não houver arquivo. """ + def get_value(self, instance): val = super().get_value(instance) if not val: @@ -57,8 +58,7 @@ class XMLDocumentSnippetViewSet(SnippetViewSet): verbose_name_plural = _("XML Documents") icon = "folder-open-inverse" menu_name = "xml_manager" - menu_label = _("XML Document") - menu_order = get_menu_order("xml_manager") + menu_label = _("Documentos XML") add_to_admin_menu = False list_display = ( @@ -78,8 +78,8 @@ class XMLDocumentPDFSnippetViewSet(SnippetViewSet): verbose_name_plural = _("XML Document PDFs") icon = "doc-full" menu_name = "xml_manager" - menu_label = _("XML Document PDF") - menu_order = get_menu_order("xml_manager") + menu_label = _("PDF derivados") + menu_icon = "doc-full" add_to_admin_menu = False list_display = ( @@ -87,7 +87,7 @@ class XMLDocumentPDFSnippetViewSet(SnippetViewSet): LinkColumn("pdf_file", "PDF file"), LinkColumn("docx_file", "DOCX file"), "language", - "uploaded_at" + "uploaded_at", ) search_fields = ("pdf_file",) @@ -99,8 +99,8 @@ class XMLDocumentHTMLSnippetViewSet(SnippetViewSet): verbose_name_plural = _("XML Document HTMLs") icon = "doc-full" menu_name = "xml_manager" - menu_label = _("XML Document HTML") - menu_order = get_menu_order("xml_manager") + menu_label = _("HTML derivados") + menu_icon = "doc-full-inverse" add_to_admin_menu = False list_display = ( @@ -114,22 +114,22 @@ class XMLDocumentHTMLSnippetViewSet(SnippetViewSet): class XMLDocumentSnippetViewSetGroup(SnippetViewSetGroup): - menu_name = 'xml_manager' - menu_label = _("XML Manager") - menu_icon = "folder-open-inverse" + menu_name = "xml_manager" + menu_label = _("Gestão de XML") + menu_icon = "code" menu_order = get_menu_order("xml_manager") items = ( XMLDocumentSnippetViewSet, - XMLDocumentHTMLSnippetViewSet, XMLDocumentPDFSnippetViewSet, + XMLDocumentHTMLSnippetViewSet, ) register_snippet(XMLDocumentSnippetViewSetGroup) -@hooks.register('register_admin_urls') +@hooks.register("register_admin_urls") def register_admin_urls(): return [ - path('xml-manager/', include(urls)), + path("xml-manager/", include(urls)), ]