wagtail-enap-designsystem 1.2.1.204__py3-none-any.whl → 1.2.1.205__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/migrations/0475_alter_areaaluno_body_alter_cursoeadpage_curso_and_more.py +65052 -0
- enap_designsystem/migrations/0476_rotapage_capsulaordemrota.py +253 -0
- enap_designsystem/models.py +438 -195
- enap_designsystem/static/enap_designsystem/blocks/capsulas.css +3507 -52
- enap_designsystem/templates/admin/exportar_respostas.html +0 -9
- enap_designsystem/templates/enap_designsystem/blocks/formulario_snippet.html +0 -6
- enap_designsystem/templates/enap_designsystem/blocks/material_externo_block.html +211 -0
- enap_designsystem/templates/enap_designsystem/form_templates/form_report.html +0 -10
- enap_designsystem/templates/enap_designsystem/form_templates/submission_detail.html +0 -9
- enap_designsystem/templates/enap_designsystem/gerador_rotas_page.html +287 -0
- enap_designsystem/templates/enap_designsystem/pages/capsula_index_page.html +563 -464
- enap_designsystem/templates/enap_designsystem/rota_page.html +560 -0
- {wagtail_enap_designsystem-1.2.1.204.dist-info → wagtail_enap_designsystem-1.2.1.205.dist-info}/METADATA +1 -1
- {wagtail_enap_designsystem-1.2.1.204.dist-info → wagtail_enap_designsystem-1.2.1.205.dist-info}/RECORD +17 -12
- {wagtail_enap_designsystem-1.2.1.204.dist-info → wagtail_enap_designsystem-1.2.1.205.dist-info}/WHEEL +0 -0
- {wagtail_enap_designsystem-1.2.1.204.dist-info → wagtail_enap_designsystem-1.2.1.205.dist-info}/licenses/LICENSE +0 -0
- {wagtail_enap_designsystem-1.2.1.204.dist-info → wagtail_enap_designsystem-1.2.1.205.dist-info}/top_level.txt +0 -0
enap_designsystem/models.py
CHANGED
|
@@ -6685,227 +6685,470 @@ class CapsulaPage(Page):
|
|
|
6685
6685
|
|
|
6686
6686
|
|
|
6687
6687
|
|
|
6688
|
+
class GeradorRotasPage(Page):
|
|
6689
|
+
"""
|
|
6690
|
+
Página com perguntas que direcionam o usuário para uma rota específica.
|
|
6691
|
+
"""
|
|
6692
|
+
texto_introducao = RichTextField(
|
|
6693
|
+
verbose_name="Texto de Introdução",
|
|
6694
|
+
help_text="Texto explicativo sobre o gerador de rotas"
|
|
6695
|
+
)
|
|
6696
|
+
|
|
6697
|
+
texto_botao = models.CharField(
|
|
6698
|
+
verbose_name="Texto do Botão",
|
|
6699
|
+
max_length=255,
|
|
6700
|
+
default="Gerar Rota",
|
|
6701
|
+
help_text="Texto exibido no botão de comando"
|
|
6702
|
+
)
|
|
6703
|
+
|
|
6704
|
+
# Relações com as páginas de destino para cada rota
|
|
6705
|
+
rota_docente_presencial = models.ForeignKey(
|
|
6706
|
+
'wagtailcore.Page',
|
|
6707
|
+
null=True,
|
|
6708
|
+
blank=True,
|
|
6709
|
+
on_delete=models.SET_NULL,
|
|
6710
|
+
related_name='+',
|
|
6711
|
+
verbose_name="Rota Docente Presencial",
|
|
6712
|
+
help_text="Selecione a página da Rota Docente Presencial"
|
|
6713
|
+
)
|
|
6714
|
+
|
|
6715
|
+
rota_designer_instrucional = models.ForeignKey(
|
|
6716
|
+
'wagtailcore.Page',
|
|
6717
|
+
null=True,
|
|
6718
|
+
blank=True,
|
|
6719
|
+
on_delete=models.SET_NULL,
|
|
6720
|
+
related_name='+',
|
|
6721
|
+
verbose_name="Rota Designer Instrucional",
|
|
6722
|
+
help_text="Selecione a página da Rota Designer Instrucional"
|
|
6723
|
+
)
|
|
6724
|
+
|
|
6725
|
+
rota_multimidia = models.ForeignKey(
|
|
6726
|
+
'wagtailcore.Page',
|
|
6727
|
+
null=True,
|
|
6728
|
+
blank=True,
|
|
6729
|
+
on_delete=models.SET_NULL,
|
|
6730
|
+
related_name='+',
|
|
6731
|
+
verbose_name="Rota Multimídia",
|
|
6732
|
+
help_text="Selecione a página da Rota Multimídia"
|
|
6733
|
+
)
|
|
6734
|
+
|
|
6735
|
+
rota_equipe_tecnica = models.ForeignKey(
|
|
6736
|
+
'wagtailcore.Page',
|
|
6737
|
+
null=True,
|
|
6738
|
+
blank=True,
|
|
6739
|
+
on_delete=models.SET_NULL,
|
|
6740
|
+
related_name='+',
|
|
6741
|
+
verbose_name="Rota Equipe Técnica",
|
|
6742
|
+
help_text="Selecione a página da Rota Equipe Técnica"
|
|
6743
|
+
)
|
|
6744
|
+
|
|
6745
|
+
# Textos das perguntas e opções (personalizáveis no admin)
|
|
6746
|
+
pergunta = models.CharField(
|
|
6747
|
+
verbose_name="Pergunta",
|
|
6748
|
+
max_length=255,
|
|
6749
|
+
default="O que você quer aprender?",
|
|
6750
|
+
help_text="Pergunta principal para direcionamento da rota"
|
|
6751
|
+
)
|
|
6752
|
+
|
|
6753
|
+
opcao_docente = models.CharField(
|
|
6754
|
+
verbose_name="Opção Docente",
|
|
6755
|
+
max_length=255,
|
|
6756
|
+
default="Quero aprender a tornar minhas aulas e eventos presenciais mais acessíveis.",
|
|
6757
|
+
help_text="Texto para a opção Docente Presencial"
|
|
6758
|
+
)
|
|
6759
|
+
|
|
6760
|
+
opcao_designer = models.CharField(
|
|
6761
|
+
verbose_name="Opção Designer",
|
|
6762
|
+
max_length=255,
|
|
6763
|
+
default="Quero aprender a criar conteúdos digitais acessíveis, como documentos e apresentações.",
|
|
6764
|
+
help_text="Texto para a opção Designer Instrucional"
|
|
6765
|
+
)
|
|
6766
|
+
|
|
6767
|
+
opcao_multimidia = models.CharField(
|
|
6768
|
+
verbose_name="Opção Multimídia",
|
|
6769
|
+
max_length=255,
|
|
6770
|
+
default="Quero aprender a tornar vídeos e materiais multimídia acessíveis.",
|
|
6771
|
+
help_text="Texto para a opção Multimídia"
|
|
6772
|
+
)
|
|
6773
|
+
|
|
6774
|
+
opcao_tecnica = models.CharField(
|
|
6775
|
+
verbose_name="Opção Equipe Técnica",
|
|
6776
|
+
max_length=255,
|
|
6777
|
+
default="Quero aprender a aplicar boas práticas de acessibilidade em sistemas e plataformas digitais.",
|
|
6778
|
+
help_text="Texto para a opção Equipe Técnica"
|
|
6779
|
+
)
|
|
6780
|
+
|
|
6781
|
+
content_panels = Page.content_panels + [
|
|
6782
|
+
FieldPanel('texto_introducao'),
|
|
6783
|
+
FieldPanel('pergunta'),
|
|
6784
|
+
MultiFieldPanel([
|
|
6785
|
+
FieldPanel('opcao_docente'),
|
|
6786
|
+
FieldPanel('opcao_designer'),
|
|
6787
|
+
FieldPanel('opcao_multimidia'),
|
|
6788
|
+
FieldPanel('opcao_tecnica'),
|
|
6789
|
+
], heading="Opções de Resposta"),
|
|
6790
|
+
FieldPanel('texto_botao'),
|
|
6791
|
+
MultiFieldPanel([
|
|
6792
|
+
FieldPanel('rota_docente_presencial'),
|
|
6793
|
+
FieldPanel('rota_designer_instrucional'),
|
|
6794
|
+
FieldPanel('rota_multimidia'),
|
|
6795
|
+
FieldPanel('rota_equipe_tecnica'),
|
|
6796
|
+
], heading="Páginas de Destino das Rotas"),
|
|
6797
|
+
]
|
|
6798
|
+
|
|
6799
|
+
def serve(self, request):
|
|
6800
|
+
# Verifica se foi enviado um formulário para direcionar para uma rota
|
|
6801
|
+
if request.method == 'POST' and 'rota_selecionada' in request.POST:
|
|
6802
|
+
rota_selecionada = request.POST.get('rota_selecionada')
|
|
6803
|
+
|
|
6804
|
+
# Redireciona para a página da rota escolhida
|
|
6805
|
+
if rota_selecionada == 'docente_presencial' and self.rota_docente_presencial:
|
|
6806
|
+
return redirect(self.rota_docente_presencial.url)
|
|
6807
|
+
elif rota_selecionada == 'designer_instrucional' and self.rota_designer_instrucional:
|
|
6808
|
+
return redirect(self.rota_designer_instrucional.url)
|
|
6809
|
+
elif rota_selecionada == 'multimidia' and self.rota_multimidia:
|
|
6810
|
+
return redirect(self.rota_multimidia.url)
|
|
6811
|
+
elif rota_selecionada == 'equipe_tecnica' and self.rota_equipe_tecnica:
|
|
6812
|
+
return redirect(self.rota_equipe_tecnica.url)
|
|
6813
|
+
|
|
6814
|
+
# Se não houver rota selecionada, continua com a exibição normal da página
|
|
6815
|
+
return super().serve(request)
|
|
6816
|
+
|
|
6817
|
+
class Meta:
|
|
6818
|
+
verbose_name = "Página Geradora de Rotas"
|
|
6819
|
+
|
|
6688
6820
|
|
|
6689
|
-
from django.http import JsonResponse
|
|
6690
|
-
from django.views.decorators.csrf import csrf_exempt
|
|
6691
|
-
from django.utils.decorators import method_decorator
|
|
6692
|
-
import json
|
|
6693
6821
|
|
|
6694
6822
|
|
|
6695
6823
|
|
|
6696
|
-
|
|
6824
|
+
|
|
6825
|
+
|
|
6826
|
+
|
|
6827
|
+
from django.db import models
|
|
6828
|
+
from django.db.models.fields import TextField
|
|
6829
|
+
from modelcluster.fields import ParentalKey
|
|
6830
|
+
from wagtail.models import Orderable, Page
|
|
6831
|
+
from wagtail.admin.panels import (
|
|
6832
|
+
FieldPanel,
|
|
6833
|
+
InlinePanel,
|
|
6834
|
+
MultiFieldPanel,
|
|
6835
|
+
TabbedInterface,
|
|
6836
|
+
ObjectList
|
|
6837
|
+
)
|
|
6838
|
+
from wagtail.fields import RichTextField, StreamField
|
|
6839
|
+
from wagtail.blocks import StructBlock, CharBlock, TextBlock, ChoiceBlock, URLBlock
|
|
6840
|
+
from wagtail.images.blocks import ImageChooserBlock
|
|
6841
|
+
|
|
6842
|
+
|
|
6843
|
+
class MaterialExternoBlock(StructBlock):
|
|
6697
6844
|
"""
|
|
6698
|
-
|
|
6845
|
+
Bloco para materiais externos de aprofundamento.
|
|
6699
6846
|
"""
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6847
|
+
titulo = CharBlock(required=True, help_text="Título do material")
|
|
6848
|
+
descricao = TextBlock(required=False, help_text="Breve descrição do material")
|
|
6849
|
+
tipo = ChoiceBlock(
|
|
6850
|
+
choices=[
|
|
6851
|
+
('curso', 'Curso'),
|
|
6852
|
+
('publicacao', 'Publicação'),
|
|
6853
|
+
('video', 'Vídeo'),
|
|
6854
|
+
('guia', 'Guia'),
|
|
6855
|
+
('outro', 'Outro'),
|
|
6856
|
+
],
|
|
6857
|
+
help_text="Tipo de material"
|
|
6858
|
+
)
|
|
6859
|
+
url = URLBlock(required=True, help_text="Link para o material")
|
|
6860
|
+
imagem = ImageChooserBlock(required=False, help_text="Imagem ilustrativa (opcional)")
|
|
6861
|
+
|
|
6862
|
+
class Meta:
|
|
6863
|
+
template = 'enap_designsystem/blocks/material_externo_block.html'
|
|
6864
|
+
icon = 'link'
|
|
6865
|
+
label = 'Material Externo'
|
|
6866
|
+
|
|
6867
|
+
|
|
6868
|
+
class CapsulaOrdemRota(Orderable):
|
|
6869
|
+
"""
|
|
6870
|
+
Item ordenável para vincular e ordenar cápsulas em uma rota.
|
|
6871
|
+
"""
|
|
6872
|
+
page = ParentalKey('RotaPage', related_name='capsulas_vinculadas')
|
|
6873
|
+
capsula = models.ForeignKey(
|
|
6874
|
+
'wagtailcore.Page',
|
|
6875
|
+
on_delete=models.CASCADE,
|
|
6876
|
+
related_name='+',
|
|
6877
|
+
verbose_name="Cápsula",
|
|
6878
|
+
help_text="Selecione uma cápsula para vincular a esta rota"
|
|
6879
|
+
)
|
|
6880
|
+
destaque = models.BooleanField(
|
|
6881
|
+
default=False,
|
|
6882
|
+
verbose_name="Destaque",
|
|
6883
|
+
help_text="Marque para destacar esta cápsula como prioritária"
|
|
6884
|
+
)
|
|
6885
|
+
ordem = models.IntegerField(
|
|
6886
|
+
default=0,
|
|
6887
|
+
verbose_name="Ordem",
|
|
6888
|
+
help_text="Número para ordenar as cápsulas (menor = mais importante)"
|
|
6889
|
+
)
|
|
6890
|
+
texto_contextualizacao = models.TextField(
|
|
6891
|
+
blank=True,
|
|
6892
|
+
verbose_name="Texto de Contextualização",
|
|
6893
|
+
help_text="Texto explicando a relevância desta cápsula para esta rota específica"
|
|
6894
|
+
)
|
|
6895
|
+
|
|
6896
|
+
panels = [
|
|
6897
|
+
FieldPanel('capsula'),
|
|
6898
|
+
FieldPanel('destaque'),
|
|
6899
|
+
FieldPanel('ordem'),
|
|
6900
|
+
FieldPanel('texto_contextualizacao'),
|
|
6901
|
+
]
|
|
6902
|
+
|
|
6903
|
+
class Meta:
|
|
6904
|
+
ordering = ['ordem']
|
|
6905
|
+
|
|
6906
|
+
|
|
6907
|
+
class RotaPage(Page):
|
|
6908
|
+
"""
|
|
6909
|
+
Modelo de página para as rotas temáticas específicas.
|
|
6910
|
+
"""
|
|
6911
|
+
# Campo para identificar o tipo de rota (para filtragem e personalização)
|
|
6912
|
+
tipo_rota = models.CharField(
|
|
6913
|
+
max_length=100,
|
|
6914
|
+
choices=[
|
|
6915
|
+
('docente_presencial', 'Docente Presencial'),
|
|
6916
|
+
('designer_instrucional', 'Designer Instrucional'),
|
|
6917
|
+
('multimidia', 'Multimídia'),
|
|
6918
|
+
('equipe_tecnica', 'Equipe Técnica'),
|
|
6919
|
+
],
|
|
6920
|
+
verbose_name="Tipo de Rota",
|
|
6921
|
+
help_text="Selecione o tipo de rota"
|
|
6922
|
+
)
|
|
6923
|
+
|
|
6924
|
+
# Imagem de capa/banner da rota
|
|
6925
|
+
imagem_capa = models.ForeignKey(
|
|
6926
|
+
'wagtailimages.Image',
|
|
6704
6927
|
null=True,
|
|
6705
6928
|
blank=True,
|
|
6706
6929
|
on_delete=models.SET_NULL,
|
|
6707
|
-
related_name=
|
|
6930
|
+
related_name='+',
|
|
6931
|
+
verbose_name="Imagem de Capa",
|
|
6932
|
+
help_text="Imagem principal da rota (banner)"
|
|
6708
6933
|
)
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6934
|
+
|
|
6935
|
+
# Cor principal da rota (para personalização visual)
|
|
6936
|
+
cor_principal = models.CharField(
|
|
6937
|
+
max_length=20,
|
|
6938
|
+
default="#0066cc",
|
|
6939
|
+
verbose_name="Cor Principal",
|
|
6940
|
+
help_text="Código de cor hexadecimal (ex: #0066cc)"
|
|
6941
|
+
)
|
|
6942
|
+
|
|
6943
|
+
# Ícone representativo da rota
|
|
6944
|
+
icone = models.ForeignKey(
|
|
6945
|
+
'wagtailimages.Image',
|
|
6712
6946
|
null=True,
|
|
6713
6947
|
blank=True,
|
|
6714
6948
|
on_delete=models.SET_NULL,
|
|
6715
|
-
related_name=
|
|
6949
|
+
related_name='+',
|
|
6950
|
+
verbose_name="Ícone",
|
|
6951
|
+
help_text="Ícone representativo da rota"
|
|
6716
6952
|
)
|
|
6717
6953
|
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6954
|
+
# Descrição curta para uso em listagens e cards
|
|
6955
|
+
descricao_curta = models.CharField(
|
|
6956
|
+
max_length=255,
|
|
6957
|
+
blank=True,
|
|
6958
|
+
verbose_name="Descrição Curta",
|
|
6959
|
+
help_text="Breve descrição para uso em listagens (máx. 255 caracteres)"
|
|
6721
6960
|
)
|
|
6722
6961
|
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
verbose_name="
|
|
6726
|
-
help_text="
|
|
6962
|
+
# 1. Apresentação da Rota
|
|
6963
|
+
apresentacao = RichTextField(
|
|
6964
|
+
verbose_name="Apresentação da Rota",
|
|
6965
|
+
help_text="Texto introdutório explicando o foco da rota"
|
|
6966
|
+
)
|
|
6967
|
+
|
|
6968
|
+
# 2. Por onde começar?
|
|
6969
|
+
por_onde_comecar = RichTextField(
|
|
6970
|
+
verbose_name="Por onde começar?",
|
|
6971
|
+
help_text="Indicação dos conceitos ou conteúdos iniciais que ajudarão o usuário"
|
|
6972
|
+
)
|
|
6973
|
+
|
|
6974
|
+
# 3. Texto introdutório para as Cápsulas
|
|
6975
|
+
texto_capsulas = RichTextField(
|
|
6976
|
+
verbose_name="Texto sobre as Cápsulas",
|
|
6977
|
+
help_text="Texto explicativo sobre as cápsulas recomendadas para esta rota",
|
|
6978
|
+
blank=True
|
|
6727
6979
|
)
|
|
6728
6980
|
|
|
6981
|
+
# 4. Onde posso aprender mais?
|
|
6982
|
+
texto_materiais_extras = RichTextField(
|
|
6983
|
+
verbose_name="Introdução aos Materiais Extras",
|
|
6984
|
+
help_text="Texto introdutório para a seção de materiais de aprofundamento",
|
|
6985
|
+
blank=True
|
|
6986
|
+
)
|
|
6987
|
+
|
|
6988
|
+
# Materiais externos para aprofundamento
|
|
6989
|
+
materiais_externos = StreamField([
|
|
6990
|
+
('material', MaterialExternoBlock()),
|
|
6991
|
+
], blank=True, verbose_name="Materiais Externos", use_json_field=True)
|
|
6992
|
+
|
|
6993
|
+
# Painéis para o admin - Usamos FieldPanel para todos os campos, incluindo imagens
|
|
6729
6994
|
content_panels = Page.content_panels + [
|
|
6730
|
-
FieldPanel('
|
|
6731
|
-
FieldPanel('
|
|
6732
|
-
|
|
6733
|
-
|
|
6995
|
+
FieldPanel('descricao_curta'),
|
|
6996
|
+
FieldPanel('tipo_rota'),
|
|
6997
|
+
MultiFieldPanel([
|
|
6998
|
+
FieldPanel('imagem_capa'),
|
|
6999
|
+
FieldPanel('icone'),
|
|
7000
|
+
FieldPanel('cor_principal'),
|
|
7001
|
+
], heading="Identidade Visual"),
|
|
7002
|
+
MultiFieldPanel([
|
|
7003
|
+
FieldPanel('apresentacao'),
|
|
7004
|
+
FieldPanel('por_onde_comecar'),
|
|
7005
|
+
], heading="Conteúdo Introdutório"),
|
|
7006
|
+
MultiFieldPanel([
|
|
7007
|
+
FieldPanel('texto_capsulas'),
|
|
7008
|
+
InlinePanel('capsulas_vinculadas', label="Cápsulas"),
|
|
7009
|
+
], heading="Cápsulas Essenciais"),
|
|
7010
|
+
MultiFieldPanel([
|
|
7011
|
+
FieldPanel('texto_materiais_extras'),
|
|
7012
|
+
FieldPanel('materiais_externos'),
|
|
7013
|
+
], heading="Materiais de Aprofundamento"),
|
|
6734
7014
|
]
|
|
6735
7015
|
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
# Se tiver parâmetros de resposta na URL, salvar na sessão
|
|
6740
|
-
if request.GET.get('perfil') or request.GET.get('recurso') or request.GET.get('formato'):
|
|
6741
|
-
self.salvar_respostas_url(request)
|
|
6742
|
-
|
|
6743
|
-
# Se for requisição de resultado
|
|
6744
|
-
if request.GET.get('resultado') == '1':
|
|
6745
|
-
return self.servir_resultado(request)
|
|
6746
|
-
|
|
6747
|
-
# Renderização normal do quiz
|
|
6748
|
-
return super().serve(request)
|
|
7016
|
+
# Template
|
|
7017
|
+
template = 'enap_designsystem/rota_page.html'
|
|
6749
7018
|
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
respostas['perfil_profissional'] = {
|
|
6764
|
-
'valor': perfil_valores,
|
|
6765
|
-
'texto': request.GET.get('perfil_texto') # Manter o texto original com vírgulas
|
|
6766
|
-
}
|
|
6767
|
-
|
|
6768
|
-
# Tipo de recurso (múltiplos, separados por vírgula)
|
|
6769
|
-
if request.GET.get('recurso'):
|
|
6770
|
-
recurso_valores = request.GET.get('recurso').split(',')
|
|
6771
|
-
recurso_textos = request.GET.get('recurso_texto', '').split(', ')
|
|
6772
|
-
|
|
6773
|
-
# Garantir que temos o mesmo número de textos e valores
|
|
6774
|
-
if len(recurso_textos) < len(recurso_valores):
|
|
6775
|
-
recurso_textos.extend([recurso_valores[i] for i in range(len(recurso_textos), len(recurso_valores))])
|
|
6776
|
-
|
|
6777
|
-
respostas['tipo_recurso'] = {
|
|
6778
|
-
'valor': recurso_valores,
|
|
6779
|
-
'texto': request.GET.get('recurso_texto') # Manter o texto original com vírgulas
|
|
6780
|
-
}
|
|
6781
|
-
|
|
6782
|
-
# Formato de ação (múltiplos, separados por vírgula)
|
|
6783
|
-
if request.GET.get('formato'):
|
|
6784
|
-
formato_valores = request.GET.get('formato').split(',')
|
|
6785
|
-
formato_textos = request.GET.get('formato_texto', '').split(', ')
|
|
6786
|
-
|
|
6787
|
-
# Garantir que temos o mesmo número de textos e valores
|
|
6788
|
-
if len(formato_textos) < len(formato_valores):
|
|
6789
|
-
formato_textos.extend([formato_valores[i] for i in range(len(formato_textos), len(formato_valores))])
|
|
6790
|
-
|
|
6791
|
-
respostas['formato_acao'] = {
|
|
6792
|
-
'valor': formato_valores,
|
|
6793
|
-
'texto': request.GET.get('formato_texto') # Manter o texto original com vírgulas
|
|
6794
|
-
}
|
|
6795
|
-
|
|
6796
|
-
# Salvar na sessão
|
|
6797
|
-
request.session['quiz_respostas'] = respostas
|
|
7019
|
+
class Meta:
|
|
7020
|
+
verbose_name = "Página de Rota Temática"
|
|
7021
|
+
|
|
7022
|
+
|
|
7023
|
+
# Modelo para a página do Gerador de Rotas
|
|
7024
|
+
class GeradorRotasPage(Page):
|
|
7025
|
+
"""
|
|
7026
|
+
Página com perguntas que direcionam o usuário para uma rota específica.
|
|
7027
|
+
"""
|
|
7028
|
+
texto_introducao = RichTextField(
|
|
7029
|
+
verbose_name="Texto de Introdução",
|
|
7030
|
+
help_text="Texto explicativo sobre o gerador de rotas"
|
|
7031
|
+
)
|
|
6798
7032
|
|
|
6799
|
-
|
|
6800
|
-
"
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
if not respostas:
|
|
6806
|
-
return redirect(self.url)
|
|
6807
|
-
|
|
6808
|
-
# Buscar cápsulas baseadas nas respostas
|
|
6809
|
-
capsulas = self.filtrar_capsulas(respostas)
|
|
6810
|
-
|
|
6811
|
-
context = self.get_context(request)
|
|
6812
|
-
context.update({
|
|
6813
|
-
'e_resultado': True,
|
|
6814
|
-
'respostas': respostas,
|
|
6815
|
-
'capsulas_recomendadas': capsulas,
|
|
6816
|
-
'total_capsulas': len(capsulas),
|
|
6817
|
-
})
|
|
6818
|
-
|
|
6819
|
-
return render(request, self.get_template(request), context)
|
|
7033
|
+
texto_botao = models.CharField(
|
|
7034
|
+
verbose_name="Texto do Botão",
|
|
7035
|
+
max_length=255,
|
|
7036
|
+
default="Gerar Rota",
|
|
7037
|
+
help_text="Texto exibido no botão de comando"
|
|
7038
|
+
)
|
|
6820
7039
|
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
all_capsulas = list(CapsulaPage.objects.live().public())
|
|
6832
|
-
|
|
6833
|
-
# Lista resultante
|
|
6834
|
-
capsulas_filtradas = []
|
|
6835
|
-
|
|
6836
|
-
# Primeiro, filtrar por cada categoria separadamente
|
|
6837
|
-
perfis_filtrados = self._filtrar_por_categoria(
|
|
6838
|
-
all_capsulas,
|
|
6839
|
-
'perfil_profissional' in respostas,
|
|
6840
|
-
'perfis_profissionais',
|
|
6841
|
-
respostas.get('perfil_profissional', {}).get('valor', [])
|
|
6842
|
-
)
|
|
6843
|
-
|
|
6844
|
-
recursos_filtrados = self._filtrar_por_categoria(
|
|
6845
|
-
all_capsulas,
|
|
6846
|
-
'tipo_recurso' in respostas,
|
|
6847
|
-
'tipos_recurso',
|
|
6848
|
-
respostas.get('tipo_recurso', {}).get('valor', [])
|
|
6849
|
-
)
|
|
6850
|
-
|
|
6851
|
-
formatos_filtrados = self._filtrar_por_categoria(
|
|
6852
|
-
all_capsulas,
|
|
6853
|
-
'formato_acao' in respostas,
|
|
6854
|
-
'formatos_acao',
|
|
6855
|
-
respostas.get('formato_acao', {}).get('valor', [])
|
|
6856
|
-
)
|
|
6857
|
-
|
|
6858
|
-
# Intersecção das três listas para obter apenas cápsulas que atendem a todos os critérios
|
|
6859
|
-
# Para cada cápsula, verificamos se ela está presente em todas as listas filtradas relevantes
|
|
6860
|
-
for capsula in all_capsulas:
|
|
6861
|
-
deve_incluir = True
|
|
6862
|
-
|
|
6863
|
-
# Verificar se a cápsula está na lista de perfis filtrados (se houver filtro de perfil)
|
|
6864
|
-
if 'perfil_profissional' in respostas and capsula not in perfis_filtrados:
|
|
6865
|
-
deve_incluir = False
|
|
6866
|
-
|
|
6867
|
-
# Verificar se a cápsula está na lista de recursos filtrados (se houver filtro de recurso)
|
|
6868
|
-
if 'tipo_recurso' in respostas and capsula not in recursos_filtrados:
|
|
6869
|
-
deve_incluir = False
|
|
6870
|
-
|
|
6871
|
-
# Verificar se a cápsula está na lista de formatos filtrados (se houver filtro de formato)
|
|
6872
|
-
if 'formato_acao' in respostas and capsula not in formatos_filtrados:
|
|
6873
|
-
deve_incluir = False
|
|
6874
|
-
|
|
6875
|
-
# Se a cápsula atender a todos os critérios, inclua na lista final
|
|
6876
|
-
if deve_incluir:
|
|
6877
|
-
capsulas_filtradas.append(capsula)
|
|
6878
|
-
|
|
6879
|
-
# Ordenar por prioridade (obrigatório primeiro)
|
|
6880
|
-
capsulas_filtradas.sort(key=lambda c: (c.prioridade != 'obrigatorio', c.title))
|
|
6881
|
-
|
|
6882
|
-
return capsulas_filtradas
|
|
7040
|
+
# Relações com as páginas de destino para cada rota
|
|
7041
|
+
rota_docente_presencial = models.ForeignKey(
|
|
7042
|
+
'wagtailcore.Page',
|
|
7043
|
+
null=True,
|
|
7044
|
+
blank=True,
|
|
7045
|
+
on_delete=models.SET_NULL,
|
|
7046
|
+
related_name='+',
|
|
7047
|
+
verbose_name="Rota Docente Presencial",
|
|
7048
|
+
help_text="Selecione a página da Rota Docente Presencial"
|
|
7049
|
+
)
|
|
6883
7050
|
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
""
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
resultado = []
|
|
6895
|
-
|
|
6896
|
-
for capsula in capsulas:
|
|
6897
|
-
valores_capsula = getattr(capsula, campo_capsula, None)
|
|
6898
|
-
|
|
6899
|
-
if valores_capsula:
|
|
6900
|
-
# Verifica se há alguma correspondência entre os valores da cápsula
|
|
6901
|
-
# e os valores selecionados no filtro (lógica OR)
|
|
6902
|
-
if any(valor in valores_capsula for valor in valores_filtro):
|
|
6903
|
-
resultado.append(capsula)
|
|
6904
|
-
|
|
6905
|
-
return resultado
|
|
7051
|
+
rota_designer_instrucional = models.ForeignKey(
|
|
7052
|
+
'wagtailcore.Page',
|
|
7053
|
+
null=True,
|
|
7054
|
+
blank=True,
|
|
7055
|
+
on_delete=models.SET_NULL,
|
|
7056
|
+
related_name='+',
|
|
7057
|
+
verbose_name="Rota Designer Instrucional",
|
|
7058
|
+
help_text="Selecione a página da Rota Designer Instrucional"
|
|
7059
|
+
)
|
|
6906
7060
|
|
|
6907
|
-
|
|
7061
|
+
rota_multimidia = models.ForeignKey(
|
|
7062
|
+
'wagtailcore.Page',
|
|
7063
|
+
null=True,
|
|
7064
|
+
blank=True,
|
|
7065
|
+
on_delete=models.SET_NULL,
|
|
7066
|
+
related_name='+',
|
|
7067
|
+
verbose_name="Rota Multimídia",
|
|
7068
|
+
help_text="Selecione a página da Rota Multimídia"
|
|
7069
|
+
)
|
|
7070
|
+
|
|
7071
|
+
rota_equipe_tecnica = models.ForeignKey(
|
|
7072
|
+
'wagtailcore.Page',
|
|
7073
|
+
null=True,
|
|
7074
|
+
blank=True,
|
|
7075
|
+
on_delete=models.SET_NULL,
|
|
7076
|
+
related_name='+',
|
|
7077
|
+
verbose_name="Rota Equipe Técnica",
|
|
7078
|
+
help_text="Selecione a página da Rota Equipe Técnica"
|
|
7079
|
+
)
|
|
7080
|
+
|
|
7081
|
+
# Textos das perguntas e opções (personalizáveis no admin)
|
|
7082
|
+
pergunta = models.CharField(
|
|
7083
|
+
verbose_name="Pergunta",
|
|
7084
|
+
max_length=255,
|
|
7085
|
+
default="O que você quer aprender?",
|
|
7086
|
+
help_text="Pergunta principal para direcionamento da rota"
|
|
7087
|
+
)
|
|
7088
|
+
|
|
7089
|
+
opcao_docente = models.CharField(
|
|
7090
|
+
verbose_name="Opção Docente",
|
|
7091
|
+
max_length=255,
|
|
7092
|
+
default="Quero aprender a tornar minhas aulas e eventos presenciais mais acessíveis.",
|
|
7093
|
+
help_text="Texto para a opção Docente Presencial"
|
|
7094
|
+
)
|
|
7095
|
+
|
|
7096
|
+
opcao_designer = models.CharField(
|
|
7097
|
+
verbose_name="Opção Designer",
|
|
7098
|
+
max_length=255,
|
|
7099
|
+
default="Quero aprender a criar conteúdos digitais acessíveis, como documentos e apresentações.",
|
|
7100
|
+
help_text="Texto para a opção Designer Instrucional"
|
|
7101
|
+
)
|
|
6908
7102
|
|
|
7103
|
+
opcao_multimidia = models.CharField(
|
|
7104
|
+
verbose_name="Opção Multimídia",
|
|
7105
|
+
max_length=255,
|
|
7106
|
+
default="Quero aprender a tornar vídeos e materiais multimídia acessíveis.",
|
|
7107
|
+
help_text="Texto para a opção Multimídia"
|
|
7108
|
+
)
|
|
7109
|
+
|
|
7110
|
+
opcao_tecnica = models.CharField(
|
|
7111
|
+
verbose_name="Opção Equipe Técnica",
|
|
7112
|
+
max_length=255,
|
|
7113
|
+
default="Quero aprender a aplicar boas práticas de acessibilidade em sistemas e plataformas digitais.",
|
|
7114
|
+
help_text="Texto para a opção Equipe Técnica"
|
|
7115
|
+
)
|
|
7116
|
+
|
|
7117
|
+
content_panels = Page.content_panels + [
|
|
7118
|
+
FieldPanel('texto_introducao'),
|
|
7119
|
+
FieldPanel('pergunta'),
|
|
7120
|
+
MultiFieldPanel([
|
|
7121
|
+
FieldPanel('opcao_docente'),
|
|
7122
|
+
FieldPanel('opcao_designer'),
|
|
7123
|
+
FieldPanel('opcao_multimidia'),
|
|
7124
|
+
FieldPanel('opcao_tecnica'),
|
|
7125
|
+
], heading="Opções de Resposta"),
|
|
7126
|
+
FieldPanel('texto_botao'),
|
|
7127
|
+
MultiFieldPanel([
|
|
7128
|
+
FieldPanel('rota_docente_presencial'),
|
|
7129
|
+
FieldPanel('rota_designer_instrucional'),
|
|
7130
|
+
FieldPanel('rota_multimidia'),
|
|
7131
|
+
FieldPanel('rota_equipe_tecnica'),
|
|
7132
|
+
], heading="Páginas de Destino das Rotas"),
|
|
7133
|
+
]
|
|
7134
|
+
|
|
7135
|
+
def serve(self, request):
|
|
7136
|
+
# Verifica se foi enviado um formulário para direcionar para uma rota
|
|
7137
|
+
if request.method == 'POST' and 'rota_selecionada' in request.POST:
|
|
7138
|
+
rota_selecionada = request.POST.get('rota_selecionada')
|
|
7139
|
+
|
|
7140
|
+
# Redireciona para a página da rota escolhida
|
|
7141
|
+
if rota_selecionada == 'docente_presencial' and self.rota_docente_presencial:
|
|
7142
|
+
return redirect(self.rota_docente_presencial.url)
|
|
7143
|
+
elif rota_selecionada == 'designer_instrucional' and self.rota_designer_instrucional:
|
|
7144
|
+
return redirect(self.rota_designer_instrucional.url)
|
|
7145
|
+
elif rota_selecionada == 'multimidia' and self.rota_multimidia:
|
|
7146
|
+
return redirect(self.rota_multimidia.url)
|
|
7147
|
+
elif rota_selecionada == 'equipe_tecnica' and self.rota_equipe_tecnica:
|
|
7148
|
+
return redirect(self.rota_equipe_tecnica.url)
|
|
7149
|
+
|
|
7150
|
+
# Se não houver rota selecionada, continua com a exibição normal da página
|
|
7151
|
+
return super().serve(request)
|
|
7152
|
+
|
|
6909
7153
|
class Meta:
|
|
6910
|
-
verbose_name = "
|
|
6911
|
-
verbose_name_plural = "Quiz de Rotas"
|
|
7154
|
+
verbose_name = "Página Geradora de Rotas"
|