wagtail-enap-designsystem 1.2.1.174__py3-none-any.whl → 1.2.1.176__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.

Potentially problematic release.


This version of wagtail-enap-designsystem might be problematic. Click here for more details.

Files changed (20) hide show
  1. enap_designsystem/blocks/html_blocks.py +142 -27
  2. enap_designsystem/migrations/0445_alter_areaaluno_body_alter_cursoeadpage_curso_and_more.py +70889 -0
  3. enap_designsystem/migrations/0446_alter_areaaluno_body_alter_enapcomponentes_body_and_more.py +55314 -0
  4. enap_designsystem/migrations/0447_alter_areaaluno_body_alter_enapcomponentes_body_and_more.py +55294 -0
  5. enap_designsystem/models.py +1 -0
  6. enap_designsystem/static/enap_designsystem/blocks/banner.css +1 -1
  7. enap_designsystem/static/enap_designsystem/blocks/btn.css +11 -5
  8. enap_designsystem/static/enap_designsystem/blocks/capsulas.css +662 -690
  9. enap_designsystem/static/enap_designsystem/blocks/carousel_images.css +0 -2
  10. enap_designsystem/static/enap_designsystem/blocks/suap/suap_courses_block.css +1 -0
  11. enap_designsystem/templates/enap_designsystem/blocks/card_block.html +4 -2
  12. enap_designsystem/templates/enap_designsystem/blocks/suap/apisuap_courses_block.html +224 -208
  13. enap_designsystem/templates/enap_designsystem/blocks/texto_imagem.html +1 -1
  14. enap_designsystem/templates/enap_designsystem/pages/capsula_index_page.html +67 -755
  15. enap_designsystem/templates/enap_designsystem/pages/quiz_rota_page.html +425 -389
  16. {wagtail_enap_designsystem-1.2.1.174.dist-info → wagtail_enap_designsystem-1.2.1.176.dist-info}/METADATA +1 -1
  17. {wagtail_enap_designsystem-1.2.1.174.dist-info → wagtail_enap_designsystem-1.2.1.176.dist-info}/RECORD +20 -17
  18. {wagtail_enap_designsystem-1.2.1.174.dist-info → wagtail_enap_designsystem-1.2.1.176.dist-info}/WHEEL +0 -0
  19. {wagtail_enap_designsystem-1.2.1.174.dist-info → wagtail_enap_designsystem-1.2.1.176.dist-info}/licenses/LICENSE +0 -0
  20. {wagtail_enap_designsystem-1.2.1.174.dist-info → wagtail_enap_designsystem-1.2.1.176.dist-info}/top_level.txt +0 -0
@@ -136,6 +136,8 @@ FONTAWESOME_ICON_CHOICES = [
136
136
  ('fa-solid fa-calendar', 'Calendário'),
137
137
  ('fa-solid fa-clock', 'Relógio'),
138
138
  ('fa-solid fa-users', 'Usuários'),
139
+ ('fa-solid fa-house-user', 'Usuário em uma casa'),
140
+ ('fa-solid fa-user-gear', 'Usuário com uma engrenagem'),
139
141
  ('fa-solid fa-user', 'Usuário'),
140
142
  ('fa-solid fa-chalkboard-user', 'Usuário em frente a um quadro'),
141
143
  ('fa-solid fa-circle-user', 'Usuário rodeado por um circulo'),
@@ -716,8 +718,6 @@ class SuapCourseBlock(StructBlock):
716
718
  label = "Cursos do SUAP"
717
719
 
718
720
 
719
-
720
-
721
721
  class APISuapCourseBlock(StructBlock):
722
722
  title = CharBlock(required=False, label="Título")
723
723
  cor_title = CharBlock(required=False, label="Cor do Título em HEX (opcional)")
@@ -732,35 +732,135 @@ class APISuapCourseBlock(StructBlock):
732
732
  label="Posição do Título",
733
733
  required=False
734
734
  )
735
+ estilo_cards = blocks.ChoiceBlock(
736
+ choices=[
737
+ ('eventos', 'Eventos'),
738
+ ('cursos', 'Cursos'),
739
+ ],
740
+ default='eventos',
741
+ help_text="Escolha o tipo dos cards",
742
+ label="Tipo dos cards",
743
+ required=True
744
+ )
735
745
  description = CharBlock(required=False, label="Descrição")
746
+ tag = CharBlock(required=False, label="Título", default="Curso")
736
747
  cor_description = CharBlock(required=False, label="Cor da Descrição em HEX (opcional)")
737
748
  button = CharBlock(required=False, label="Titulo do Botão")
738
749
  url_button = URLBlock(required=False, label="Link do Botão")
739
- api_url = blocks.URLBlock(
740
- default="https://suap.enap.gov.br/portal/api/v3/cursosAltosExecutivos?format=json",
741
- label="URL da API",
742
- help_text="URL da API para buscar os cursos/eventos"
750
+
751
+ # Configuração para múltiplas APIs
752
+ api_urls = blocks.ListBlock(
753
+ blocks.StructBlock([
754
+ ('url', blocks.URLBlock(label="URL da API")),
755
+ ('tipo', blocks.ChoiceBlock(
756
+ choices=[
757
+ ('curso', 'Curso'),
758
+ ('evento', 'Evento'),
759
+ ],
760
+ default='curso',
761
+ label="Tipo de conteúdo",
762
+ help_text="Identifica se esta API retorna cursos ou eventos"
763
+ )),
764
+ ('label', blocks.CharBlock(
765
+ required=False,
766
+ label="Label (opcional)",
767
+ help_text="Identificador para esta API (deixe vazio para usar o tipo)"
768
+ ))
769
+ ]),
770
+ default=[
771
+ {
772
+ 'url': 'https://suap.enap.gov.br/portal/api/v3/cursosAltosExecutivos?format=json',
773
+ 'tipo': 'curso',
774
+ 'label': ''
775
+ },
776
+ ],
777
+ label="URLs das APIs",
778
+ help_text="Adicione as APIs de cursos e eventos"
779
+ )
780
+
781
+ num_items = blocks.IntegerBlock(
782
+ default=3,
783
+ label=_("Máximo de cards por API"),
784
+ help_text="Número máximo de itens a buscar de cada API"
785
+ )
786
+
787
+ mesclar_resultados = blocks.BooleanBlock(
788
+ required=False,
789
+ default=True, # Alterado para True por padrão
790
+ label="Mesclar resultados das APIs",
791
+ help_text="Se marcado, os resultados de todas as APIs serão mesclados em uma única lista"
792
+ )
793
+
794
+ ordenar_por_data = blocks.BooleanBlock(
795
+ required=False,
796
+ default=True,
797
+ label="Ordenar por data",
798
+ help_text="Se marcado, ordena os resultados por data (mais recentes primeiro)"
743
799
  )
744
- num_items = blocks.IntegerBlock(default=3, label=_("Máximo de cursos apresentados"))
745
800
 
746
801
  def get_context(self, value, parent_context=None):
747
802
  context = super().get_context(value, parent_context)
748
803
  num = value.get("num_items", 3)
749
- api_url = value.get("api_url")
750
- cursos_suap = self.get_destaques(api_url, num)
751
- context.update({
752
- "bloco_suap": value,
753
- "cursos_suap": cursos_suap
754
- })
804
+ api_urls = value.get("api_urls", [])
805
+ mesclar = value.get("mesclar_resultados", True)
806
+ ordenar = value.get("ordenar_por_data", True)
807
+
808
+ if mesclar:
809
+ # Mesclar todos os resultados em uma única lista
810
+ todos_cursos = []
811
+ for api_config in api_urls:
812
+ cursos = self.get_destaques(
813
+ api_config['url'],
814
+ num,
815
+ api_config.get('tipo', 'curso')
816
+ )
817
+ todos_cursos.extend(cursos)
818
+
819
+ # Ordenar por data se solicitado
820
+ if ordenar:
821
+ todos_cursos.sort(
822
+ key=lambda x: getattr(x, 'data_inicio', None) or getattr(x, 'data_inicio_aula', None) or datetime.min.date(),
823
+ reverse=False # False = mais antigos primeiro (próximos eventos)
824
+ )
825
+
826
+ context.update({
827
+ "bloco_suap": value,
828
+ "cursos_suap": todos_cursos
829
+ })
830
+ else:
831
+ # Retornar resultados separados por API
832
+ resultados_por_api = []
833
+ for api_config in api_urls:
834
+ cursos = self.get_destaques(
835
+ api_config['url'],
836
+ num,
837
+ api_config.get('tipo', 'curso')
838
+ )
839
+
840
+ # Se label estiver vazio, usa o tipo como label
841
+ label = api_config.get('label', '')
842
+ if not label:
843
+ label = 'Cursos' if api_config.get('tipo') == 'curso' else 'Eventos'
844
+
845
+ resultados_por_api.append({
846
+ 'label': label,
847
+ 'cursos': cursos,
848
+ 'tipo': api_config.get('tipo', 'curso')
849
+ })
850
+
851
+ context.update({
852
+ "bloco_suap": value,
853
+ "resultados_por_api": resultados_por_api
854
+ })
855
+
755
856
  return context
756
857
 
757
- def get_destaques(self, api_url, limit=50):
758
-
858
+ def get_destaques(self, api_url, limit=50, tipo='curso'):
759
859
  try:
760
- resp = requests.get(api_url, timeout=500)
860
+ resp = requests.get(api_url, timeout=10)
761
861
  resp.raise_for_status()
762
862
  data = resp.json()
763
- data = data.get('results', [])
863
+ data = data.get('results', data)
764
864
 
765
865
  # Aplicar limite se especificado
766
866
  if limit:
@@ -769,14 +869,17 @@ class APISuapCourseBlock(StructBlock):
769
869
  # Processar os dados para converter datas
770
870
  processed_data = []
771
871
  for item in data:
772
- # Converter data_inicio de string para datetime se existir
872
+ # Adicionar o tipo ao item para uso no template
873
+ item['tipo_conteudo'] = tipo
874
+
875
+ # Converter data_inicio
773
876
  if 'data_inicio' in item and item['data_inicio']:
774
877
  try:
775
878
  item['data_inicio'] = datetime.strptime(item['data_inicio'], '%Y-%m-%d').date()
776
879
  except (ValueError, TypeError):
777
880
  pass
778
881
 
779
- # Converter data_inicio_aula de string para datetime se existir
882
+ # Converter data_inicio_aula
780
883
  if 'data_inicio_aula' in item and item['data_inicio_aula']:
781
884
  try:
782
885
  item['data_inicio_aula'] = datetime.strptime(item['data_inicio_aula'], '%Y-%m-%d').date()
@@ -784,18 +887,18 @@ class APISuapCourseBlock(StructBlock):
784
887
  pass
785
888
 
786
889
  processed_data.append(SimpleNamespace(**item))
787
-
788
- print(processed_data)
890
+
789
891
  return processed_data
790
892
  except Exception as e:
791
- # Log do erro para debug (opcional)
792
- print(f"Erro ao buscar eventos de {api_url}: {e}")
893
+ print(f"Erro ao buscar dados de {api_url}: {e}")
793
894
  return []
794
895
 
795
896
  class Meta:
796
897
  template = "enap_designsystem/blocks/suap/apisuap_courses_block.html"
797
898
  icon = "list-ul"
798
- label = "Cursos do SUAP com API"
899
+ label = "Cursos e Eventos do SUAP"
900
+
901
+
799
902
 
800
903
  class APIRPSUltimaEdicaoBlock(StructBlock):
801
904
  title = CharBlock(required=False, label="Título")
@@ -3972,9 +4075,9 @@ class TextoImagemBlock(blocks.StructBlock):
3972
4075
 
3973
4076
  estilo_botao = blocks.ChoiceBlock(
3974
4077
  choices=[
3975
- ('primary', 'Primário (destaque)'),
3976
- ('secondary', 'Secundário'),
3977
- ('terciary', 'Terciário'),
4078
+ ('primary', 'Tipo primário'),
4079
+ ('secondary', 'Tipo secundário'),
4080
+ ('terciary', 'Tipo terciário'),
3978
4081
  ],
3979
4082
  default='primario',
3980
4083
  required=False,
@@ -3982,6 +4085,18 @@ class TextoImagemBlock(blocks.StructBlock):
3982
4085
  verbose_name="Estilo do botão"
3983
4086
  )
3984
4087
 
4088
+ tamanho_botao = blocks.ChoiceBlock(
4089
+ choices=[
4090
+ ('small', 'Pequeno'),
4091
+ ('medium', 'Médio'),
4092
+ ('large', 'Grande'),
4093
+ ('extra-large', 'Extra grande'),
4094
+ ],
4095
+ default='large',
4096
+ help_text="Escolha o tamanho do botão",
4097
+ label="Tamanho"
4098
+ )
4099
+
3985
4100
  # Coluna de imagem
3986
4101
  imagem = ImageChooserBlock(
3987
4102
  required=True,