wagtail-enap-designsystem 1.2.1.140__py3-none-any.whl → 1.2.1.142__py3-none-any.whl
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.
- enap_designsystem/blocks/html_blocks.py +72 -6
- enap_designsystem/blocks/semana_blocks.py +10 -4
- enap_designsystem/migrations/0413_showcasecomponentespage_alter_areaaluno_body_and_more.py +54939 -0
- enap_designsystem/migrations/0414_showcasecomponentesdireto_and_more.py +52 -0
- enap_designsystem/models.py +238 -3
- enap_designsystem/static/enap_designsystem/blocks/cards.css +0 -1
- enap_designsystem/templates/enap_designsystem/base.html +14 -1
- enap_designsystem/templates/enap_designsystem/blocks/cards_titles.html +134 -114
- enap_designsystem/templates/enap_designsystem/blocks/logos_simple_block.html +9 -15
- enap_designsystem/templates/enap_designsystem/blocks/suap/apisuap_courses_block.html +1 -1
- enap_designsystem/templates/enap_designsystem/blocks/video_hero_banner.html +1 -1
- enap_designsystem/templates/enap_designsystem/pages/showcase_components.html +592 -0
- enap_designsystem/templates/enap_designsystem/semana_inovacao/blocks_menu_navigation.html +2 -2
- {wagtail_enap_designsystem-1.2.1.140.dist-info → wagtail_enap_designsystem-1.2.1.142.dist-info}/METADATA +1 -1
- {wagtail_enap_designsystem-1.2.1.140.dist-info → wagtail_enap_designsystem-1.2.1.142.dist-info}/RECORD +18 -15
- {wagtail_enap_designsystem-1.2.1.140.dist-info → wagtail_enap_designsystem-1.2.1.142.dist-info}/WHEEL +0 -0
- {wagtail_enap_designsystem-1.2.1.140.dist-info → wagtail_enap_designsystem-1.2.1.142.dist-info}/licenses/LICENSE +0 -0
- {wagtail_enap_designsystem-1.2.1.140.dist-info → wagtail_enap_designsystem-1.2.1.142.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Generated by Django 5.1.6 on 2025-09-16 16:36
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
import wagtail.fields
|
|
5
|
+
from django.db import migrations, models
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Migration(migrations.Migration):
|
|
9
|
+
|
|
10
|
+
dependencies = [
|
|
11
|
+
(
|
|
12
|
+
"enap_designsystem",
|
|
13
|
+
"0413_showcasecomponentespage_alter_areaaluno_body_and_more",
|
|
14
|
+
),
|
|
15
|
+
("wagtailcore", "0094_alter_page_locale"),
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
operations = [
|
|
19
|
+
migrations.CreateModel(
|
|
20
|
+
name="ShowcaseComponentesDireto",
|
|
21
|
+
fields=[
|
|
22
|
+
(
|
|
23
|
+
"page_ptr",
|
|
24
|
+
models.OneToOneField(
|
|
25
|
+
auto_created=True,
|
|
26
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
27
|
+
parent_link=True,
|
|
28
|
+
primary_key=True,
|
|
29
|
+
serialize=False,
|
|
30
|
+
to="wagtailcore.page",
|
|
31
|
+
),
|
|
32
|
+
),
|
|
33
|
+
(
|
|
34
|
+
"description",
|
|
35
|
+
wagtail.fields.RichTextField(
|
|
36
|
+
blank=True,
|
|
37
|
+
default="Showcase com renderização direta dos componentes usando valores padrão",
|
|
38
|
+
help_text="Descrição da biblioteca de componentes",
|
|
39
|
+
verbose_name="Descrição",
|
|
40
|
+
),
|
|
41
|
+
),
|
|
42
|
+
],
|
|
43
|
+
options={
|
|
44
|
+
"verbose_name": "Showcase Direto de Componentes",
|
|
45
|
+
"verbose_name_plural": "Showcases Diretos de Componentes",
|
|
46
|
+
},
|
|
47
|
+
bases=("wagtailcore.page",),
|
|
48
|
+
),
|
|
49
|
+
migrations.DeleteModel(
|
|
50
|
+
name="ShowcaseComponentesPage",
|
|
51
|
+
),
|
|
52
|
+
]
|
enap_designsystem/models.py
CHANGED
|
@@ -2187,7 +2187,7 @@ class EnapSearchElastic(Page):
|
|
|
2187
2187
|
def serve(self, request, *args, **kwargs):
|
|
2188
2188
|
if "tipo" not in request.GET:
|
|
2189
2189
|
query = request.GET.get("q", "")
|
|
2190
|
-
ordenacao = request.GET.get("ordenacao", "
|
|
2190
|
+
ordenacao = request.GET.get("ordenacao", "relevantes")
|
|
2191
2191
|
return redirect(f"{request.path}?q={query}&tipo=todos&ordenacao={ordenacao}")
|
|
2192
2192
|
|
|
2193
2193
|
return super().serve(request, *args, **kwargs)
|
|
@@ -2363,7 +2363,7 @@ class EnapSearchElastic(Page):
|
|
|
2363
2363
|
verify_ssl = not settings.DEBUG
|
|
2364
2364
|
query = request.GET.get("q", "").strip()
|
|
2365
2365
|
tipo = request.GET.get("tipo", "").strip()
|
|
2366
|
-
ordenacao = request.GET.get("ordenacao", "
|
|
2366
|
+
ordenacao = request.GET.get("ordenacao", "relevantes")
|
|
2367
2367
|
page = int(request.GET.get("page", 1))
|
|
2368
2368
|
if tipo == "cursos":
|
|
2369
2369
|
rows_per_page = 12
|
|
@@ -5020,4 +5020,239 @@ class SistemaVotacaoPage(Page):
|
|
|
5020
5020
|
|
|
5021
5021
|
if self.data_fim and now > self.data_fim:
|
|
5022
5022
|
return False
|
|
5023
|
-
return True
|
|
5023
|
+
return True
|
|
5024
|
+
|
|
5025
|
+
|
|
5026
|
+
|
|
5027
|
+
|
|
5028
|
+
|
|
5029
|
+
|
|
5030
|
+
|
|
5031
|
+
from wagtail.models import Page
|
|
5032
|
+
from wagtail.fields import RichTextField, StreamField
|
|
5033
|
+
from wagtail.admin.panels import FieldPanel
|
|
5034
|
+
|
|
5035
|
+
from .blocks import LAYOUT_STREAMBLOCKS
|
|
5036
|
+
|
|
5037
|
+
class ShowcaseComponentesDireto(Page):
|
|
5038
|
+
"""
|
|
5039
|
+
Showcase que renderiza componentes diretamente no template
|
|
5040
|
+
usando valores padrão dos componentes
|
|
5041
|
+
"""
|
|
5042
|
+
|
|
5043
|
+
description = RichTextField(
|
|
5044
|
+
verbose_name="Descrição",
|
|
5045
|
+
help_text="Descrição da biblioteca de componentes",
|
|
5046
|
+
blank=True,
|
|
5047
|
+
default="Showcase com renderização direta dos componentes usando valores padrão"
|
|
5048
|
+
)
|
|
5049
|
+
|
|
5050
|
+
content_panels = Page.content_panels + [
|
|
5051
|
+
FieldPanel('description'),
|
|
5052
|
+
]
|
|
5053
|
+
|
|
5054
|
+
template = 'enap_designsystem/pages/showcase_components.html'
|
|
5055
|
+
|
|
5056
|
+
class Meta:
|
|
5057
|
+
verbose_name = "Showcase Direto de Componentes"
|
|
5058
|
+
verbose_name_plural = "Showcases Diretos de Componentes"
|
|
5059
|
+
|
|
5060
|
+
def get_context(self, request):
|
|
5061
|
+
context = super().get_context(request)
|
|
5062
|
+
|
|
5063
|
+
try:
|
|
5064
|
+
# Organizar componentes por categoria
|
|
5065
|
+
categories_with_components = self.get_rendered_categories()
|
|
5066
|
+
|
|
5067
|
+
context.update({
|
|
5068
|
+
'categories_with_components': categories_with_components,
|
|
5069
|
+
'total_components': sum(len(cat['rendered_components']) for cat in categories_with_components.values()),
|
|
5070
|
+
'total_categories': len(categories_with_components),
|
|
5071
|
+
'page_title': 'Showcase Direto - Componentes ENAP',
|
|
5072
|
+
'page_description': 'Visualização direta dos componentes com valores padrão'
|
|
5073
|
+
})
|
|
5074
|
+
except Exception as e:
|
|
5075
|
+
context.update({
|
|
5076
|
+
'error_message': f'Erro ao carregar componentes: {str(e)}',
|
|
5077
|
+
'categories_with_components': {},
|
|
5078
|
+
'total_components': 0,
|
|
5079
|
+
'total_categories': 0,
|
|
5080
|
+
})
|
|
5081
|
+
|
|
5082
|
+
return context
|
|
5083
|
+
|
|
5084
|
+
def get_rendered_categories(self):
|
|
5085
|
+
"""Retorna categorias com componentes já renderizados"""
|
|
5086
|
+
categories = {}
|
|
5087
|
+
layout_streamblocks = LAYOUT_STREAMBLOCKS
|
|
5088
|
+
|
|
5089
|
+
# Mapeamento de ícones
|
|
5090
|
+
category_icons = {
|
|
5091
|
+
'banners': 'image',
|
|
5092
|
+
'galerias': 'images',
|
|
5093
|
+
'carousels': 'arrows-up-down',
|
|
5094
|
+
'dashboards': 'bar-chart',
|
|
5095
|
+
'formularios': 'form',
|
|
5096
|
+
'cursos': 'graduation-cap',
|
|
5097
|
+
'eventos': 'calendar',
|
|
5098
|
+
'navegacao': 'bars',
|
|
5099
|
+
'menus': 'list-ul',
|
|
5100
|
+
'botoes': 'mouse-pointer',
|
|
5101
|
+
'conteudo': 'file-text',
|
|
5102
|
+
'secoes': 'th-large',
|
|
5103
|
+
'cards': 'clone',
|
|
5104
|
+
'interativos': 'cogs',
|
|
5105
|
+
'midia': 'play-circle',
|
|
5106
|
+
'especialidades': 'puzzle-piece',
|
|
5107
|
+
}
|
|
5108
|
+
|
|
5109
|
+
# Descrições das categorias
|
|
5110
|
+
category_descriptions = {
|
|
5111
|
+
'banners': 'Componentes para banners, heroes e seções de destaque visual',
|
|
5112
|
+
'galerias': 'Componentes para exibição de imagens, galerias e portfolios',
|
|
5113
|
+
'carousels': 'Componentes de carrosséis, sliders e apresentações rotativas',
|
|
5114
|
+
'dashboards': 'Componentes para dashboards, KPIs, métricas e visualização de dados',
|
|
5115
|
+
'formularios': 'Componentes de formulários, campos de entrada e interação',
|
|
5116
|
+
'cursos': 'Componentes específicos para cursos, educação e capacitação',
|
|
5117
|
+
'eventos': 'Componentes para eventos, cronogramas, timelines e agenda',
|
|
5118
|
+
'navegacao': 'Componentes de navegação, menus e estrutura de site',
|
|
5119
|
+
'menus': 'Componentes de menu e navegação',
|
|
5120
|
+
'botoes': 'Componentes de botões, call-to-actions e elementos clicáveis',
|
|
5121
|
+
'conteudo': 'Componentes de conteúdo, texto rico, citações e mídia',
|
|
5122
|
+
'secoes': 'Componentes de seções, containers e estruturas de layout',
|
|
5123
|
+
'cards': 'Componentes de cards, grids e elementos organizacionais',
|
|
5124
|
+
'interativos': 'Componentes interativos, acordeões, modais e elementos dinâmicos',
|
|
5125
|
+
'midia': 'Componentes de vídeo, áudio, podcasts e conteúdo multimídia',
|
|
5126
|
+
'especialidades': 'Componentes especializados e funcionalidades específicas da ENAP',
|
|
5127
|
+
}
|
|
5128
|
+
|
|
5129
|
+
for stream_name, stream_block in layout_streamblocks:
|
|
5130
|
+
# Pular categorias complexas
|
|
5131
|
+
if stream_name in ['enap_section', 'recaptcha']:
|
|
5132
|
+
continue
|
|
5133
|
+
|
|
5134
|
+
if not hasattr(stream_block, 'child_blocks'):
|
|
5135
|
+
continue
|
|
5136
|
+
|
|
5137
|
+
category_info = {
|
|
5138
|
+
'name': stream_name,
|
|
5139
|
+
'display_name': self.get_category_display_name(stream_block, stream_name),
|
|
5140
|
+
'icon': category_icons.get(stream_name, 'cube'),
|
|
5141
|
+
'description': category_descriptions.get(stream_name, f'Componentes da categoria {stream_name}'),
|
|
5142
|
+
'rendered_components': []
|
|
5143
|
+
}
|
|
5144
|
+
|
|
5145
|
+
# Renderizar cada componente da categoria
|
|
5146
|
+
for component_name, component_block in stream_block.child_blocks.items():
|
|
5147
|
+
rendered_component = self.render_component_with_defaults(
|
|
5148
|
+
component_name, component_block, stream_name
|
|
5149
|
+
)
|
|
5150
|
+
if rendered_component:
|
|
5151
|
+
category_info['rendered_components'].append(rendered_component)
|
|
5152
|
+
|
|
5153
|
+
# Só adicionar categoria se tiver componentes renderizados
|
|
5154
|
+
if category_info['rendered_components']:
|
|
5155
|
+
categories[stream_name] = category_info
|
|
5156
|
+
|
|
5157
|
+
return categories
|
|
5158
|
+
|
|
5159
|
+
def get_category_display_name(self, stream_block, stream_name):
|
|
5160
|
+
"""Obtém nome de exibição da categoria"""
|
|
5161
|
+
try:
|
|
5162
|
+
category_meta = getattr(stream_block.__class__, 'Meta', None)
|
|
5163
|
+
if category_meta and hasattr(category_meta, 'label'):
|
|
5164
|
+
return category_meta.label
|
|
5165
|
+
except:
|
|
5166
|
+
pass
|
|
5167
|
+
|
|
5168
|
+
return stream_name.replace('_', ' ').title()
|
|
5169
|
+
|
|
5170
|
+
def render_component_with_defaults(self, component_name, component_block, category_name):
|
|
5171
|
+
"""Renderiza um componente usando valores padrão"""
|
|
5172
|
+
try:
|
|
5173
|
+
# Gerar dados padrão inteligentes
|
|
5174
|
+
default_data = self.get_smart_defaults(component_name, component_block)
|
|
5175
|
+
|
|
5176
|
+
# Tentar renderizar
|
|
5177
|
+
try:
|
|
5178
|
+
rendered_html = component_block.render(default_data)
|
|
5179
|
+
except Exception as render_error:
|
|
5180
|
+
# Se falhar com dados padrão, tentar sem dados
|
|
5181
|
+
try:
|
|
5182
|
+
rendered_html = component_block.render({})
|
|
5183
|
+
except:
|
|
5184
|
+
# Se ainda falhar, criar um placeholder
|
|
5185
|
+
rendered_html = f'<div style="padding: 1rem; background: #f3f4f6; border-radius: 8px; text-align: center; color: #6b7280;"><p>Componente {component_name}</p><small>Erro na renderização: {str(render_error)}</small></div>'
|
|
5186
|
+
|
|
5187
|
+
return {
|
|
5188
|
+
'name': component_name,
|
|
5189
|
+
'display_name': self.get_component_display_name(component_block),
|
|
5190
|
+
'class_name': component_block.__class__.__name__,
|
|
5191
|
+
'rendered_html': rendered_html,
|
|
5192
|
+
'category_name': category_name,
|
|
5193
|
+
'has_error': 'Erro na renderização' in rendered_html,
|
|
5194
|
+
'field_count': len(getattr(component_block, 'child_blocks', {}))
|
|
5195
|
+
}
|
|
5196
|
+
|
|
5197
|
+
except Exception as e:
|
|
5198
|
+
print(f"Erro ao processar componente {component_name}: {e}")
|
|
5199
|
+
return None
|
|
5200
|
+
|
|
5201
|
+
def get_component_display_name(self, component_block):
|
|
5202
|
+
"""Obtém nome de exibição do componente"""
|
|
5203
|
+
if hasattr(component_block, 'label') and component_block.label:
|
|
5204
|
+
label = component_block.label
|
|
5205
|
+
# Remove emojis do início
|
|
5206
|
+
if any(label.startswith(emoji) for emoji in ['🎯', '🎨', '🏢', '🚀', '🔍', '📑', '🖼️', '⭐', '🎬']):
|
|
5207
|
+
parts = label.split(' ', 1)
|
|
5208
|
+
if len(parts) > 1:
|
|
5209
|
+
return parts[1]
|
|
5210
|
+
return label
|
|
5211
|
+
|
|
5212
|
+
return component_block.__class__.__name__.replace('Block', '').replace('_', ' ')
|
|
5213
|
+
|
|
5214
|
+
def get_smart_defaults(self, component_name, component_block):
|
|
5215
|
+
"""Gera valores padrão inteligentes para o componente"""
|
|
5216
|
+
defaults = {}
|
|
5217
|
+
|
|
5218
|
+
if not hasattr(component_block, 'child_blocks'):
|
|
5219
|
+
return defaults
|
|
5220
|
+
|
|
5221
|
+
for field_name, field_block in component_block.child_blocks.items():
|
|
5222
|
+
field_type = field_block.__class__.__name__
|
|
5223
|
+
|
|
5224
|
+
# Usar valor padrão do campo se existir
|
|
5225
|
+
if hasattr(field_block, 'default') and field_block.default is not None:
|
|
5226
|
+
defaults[field_name] = field_block.default
|
|
5227
|
+
continue
|
|
5228
|
+
|
|
5229
|
+
# Gerar valores contextuais baseados no nome do campo
|
|
5230
|
+
field_lower = field_name.lower()
|
|
5231
|
+
|
|
5232
|
+
if 'title' in field_lower or 'titulo' in field_lower:
|
|
5233
|
+
defaults[field_name] = 'Escola Nacional de Administração Pública'
|
|
5234
|
+
elif 'subtitle' in field_lower or 'subtitulo' in field_lower:
|
|
5235
|
+
defaults[field_name] = 'Excelência em capacitação para o serviço público'
|
|
5236
|
+
elif 'text' in field_lower or 'texto' in field_lower:
|
|
5237
|
+
defaults[field_name] = 'A ENAP é responsável pela capacitação de servidores públicos federais, contribuindo para a modernização da administração pública.'
|
|
5238
|
+
elif 'description' in field_lower or 'descricao' in field_lower:
|
|
5239
|
+
defaults[field_name] = 'Componente do Design System ENAP para construção de interfaces modernas.'
|
|
5240
|
+
elif 'button' in field_lower or 'botao' in field_lower:
|
|
5241
|
+
defaults[field_name] = 'Saiba Mais'
|
|
5242
|
+
elif 'url' in field_lower or 'link' in field_lower:
|
|
5243
|
+
defaults[field_name] = 'https://www.enap.gov.br'
|
|
5244
|
+
elif 'email' in field_lower:
|
|
5245
|
+
defaults[field_name] = 'contato@enap.gov.br'
|
|
5246
|
+
elif field_type == 'BooleanBlock':
|
|
5247
|
+
defaults[field_name] = True
|
|
5248
|
+
elif field_type in ['IntegerBlock', 'FloatBlock']:
|
|
5249
|
+
defaults[field_name] = 42
|
|
5250
|
+
elif field_type == 'DateBlock':
|
|
5251
|
+
defaults[field_name] = '2024-03-15'
|
|
5252
|
+
elif field_type == 'RichTextBlock':
|
|
5253
|
+
defaults[field_name] = '<p>Conteúdo de <strong>exemplo</strong> para demonstração do componente.</p>'
|
|
5254
|
+
else:
|
|
5255
|
+
# Valor genérico baseado no nome do campo
|
|
5256
|
+
defaults[field_name] = f'Exemplo {field_name}'
|
|
5257
|
+
|
|
5258
|
+
return defaults
|
|
@@ -9,7 +9,15 @@
|
|
|
9
9
|
<meta name="author" content="ENAP - Escola Nacional de Administração Pública">
|
|
10
10
|
<meta name="theme-color" content="#0066cc">
|
|
11
11
|
{% block metadata %}{% endblock %}
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
<!-- Google Tag Manager -->
|
|
14
|
+
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
15
|
+
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
16
|
+
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
17
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
18
|
+
})(window,document,'script','dataLayer','GTM-WR2M7N2F');</script>
|
|
19
|
+
<!-- End Google Tag Manager -->
|
|
20
|
+
|
|
13
21
|
{% block title %}
|
|
14
22
|
<title>{% if page.page_title and page.page_title|length > 0 %}{{ page.page_title }}{% else %}ENAP - Escola Nacional de Administração Pública{% endif %}</title>
|
|
15
23
|
{% endblock %}
|
|
@@ -148,6 +156,11 @@
|
|
|
148
156
|
</head>
|
|
149
157
|
|
|
150
158
|
<body>
|
|
159
|
+
<!-- Google Tag Manager (noscript) -->
|
|
160
|
+
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WR2M7N2F"
|
|
161
|
+
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
|
162
|
+
<!-- End Google Tag Manager (noscript) -->
|
|
163
|
+
|
|
151
164
|
<a class="visually-hidden-focusable" href="#main-content">Pular para o conteúdo principal</a>
|
|
152
165
|
|
|
153
166
|
<section class="page-wrapper">
|