From 7c6f32ca1b9c2bc590e68d52c0d89767271aee71 Mon Sep 17 00:00:00 2001 From: rangelbruno Date: Sat, 18 Oct 2025 23:08:45 -0300 Subject: [PATCH] =?UTF-8?q?Modal=20de=20explica=C3=A7=C3=A3o=20na=20cria?= =?UTF-8?q?=C3=A7=C3=A3o=20de=20Tipo=20de=20Proposi=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/urls.py | 3 +- sapl/base/views.py | 151 ++++ sapl/materia/urls.py | 4 + sapl/parlamentares/urls.py | 9 +- sapl/parlamentares/views.py | 158 ++++ sapl/templates/404.html | 159 +--- sapl/templates/500.html | 127 +-- sapl/templates/auth/user_form.html | 756 ++++++++++++++++++ sapl/templates/fluxo_proposicoes.html | 166 +++- sapl/templates/materia/proposicao_form.html | 9 +- .../materia/tipomaterialegislativa_form.html | 349 ++++++++ .../materia/tipoproposicao_form.html | 627 ++++++++++++++- .../parlamentares/vincular_parlamentar.html | 465 ++++++++++- 13 files changed, 2706 insertions(+), 277 deletions(-) create mode 100644 sapl/templates/materia/tipomaterialegislativa_form.html diff --git a/sapl/base/urls.py b/sapl/base/urls.py index 1fd8fe23c..787ac44e3 100644 --- a/sapl/base/urls.py +++ b/sapl/base/urls.py @@ -8,7 +8,7 @@ from django.views.generic.base import RedirectView, TemplateView from sapl.base.views import (AutorCrud, ConfirmarEmailView, TipoAutorCrud, get_estatistica, RecuperarSenhaEmailView, RecuperarSenhaFinalizadoView, RecuperarSenhaConfirmaView, RecuperarSenhaCompletoView, IndexView, UserCrud, - GuiaProjetoView, FluxoProposicoesView) + GuiaProjetoView, FluxoProposicoesView, CriarAutorAjaxView) from sapl.settings import MEDIA_URL, LOGOUT_REDIRECT_URL from .apps import AppConfig from .views import (LoginSapl, AlterarSenha, AppConfigCrud, CasaLegislativaCrud, @@ -50,6 +50,7 @@ urlpatterns = [ url(r'^$', IndexView.as_view(template_name='index.html'), name='sapl_index'), url(r'^sistema/autor/tipo/', include(TipoAutorCrud.get_urls())), + url(r'^sistema/autor/criar-ajax/$', CriarAutorAjaxView.as_view(), name='criar_autor_ajax'), url(r'^sistema/autor/', include(AutorCrud.get_urls())), url(r'^sistema/guia-projeto/$', GuiaProjetoView.as_view(), diff --git a/sapl/base/views.py b/sapl/base/views.py index 07a1097f4..10024940e 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -1587,3 +1587,154 @@ def pesquisa_textual(request): json_dict['resultados'].append(sec_dict) return JsonResponse(json_dict) + + +@method_decorator(ratelimit(key=ratelimit_ip, + rate=RATE_LIMITER_RATE, + method='POST', + block=True), name='dispatch') +class CriarAutorAjaxView(PermissionRequiredMixin, FormView): + """ + View AJAX para criar Autor rapidamente na tela de edição de usuário. + Suporta tanto autores com content_type (Parlamentar, Comissão, etc) + quanto autores genéricos (nome e cargo). + """ + permission_required = ('base.add_autor',) + logger = logging.getLogger(__name__) + + def get(self, request, *args, **kwargs): + """ + Retorna lista de usuários ativos para seleção no modal. + """ + User = get_user_model() + + usuarios = User.objects.filter(is_active=True).order_by('first_name', 'username') + + usuarios_data = [] + for user in usuarios: + nome_completo = f"{user.first_name} {user.last_name}".strip() if user.first_name else user.username + usuarios_data.append({ + 'id': user.id, + 'username': user.username, + 'first_name': user.first_name, + 'last_name': user.last_name, + 'nome_completo': nome_completo + }) + + return JsonResponse({ + 'success': True, + 'count': len(usuarios_data), + 'results': usuarios_data + }) + + def post(self, request, *args, **kwargs): + from django.contrib.contenttypes.models import ContentType + + try: + tipo_autor_id = request.POST.get('tipo_autor') + autor_related_id = request.POST.get('autor_related') + nome = request.POST.get('nome', '').strip() + cargo = request.POST.get('cargo', '').strip() + + if not tipo_autor_id: + return JsonResponse({ + 'success': False, + 'error': 'Tipo de Autor é obrigatório.' + }, status=400) + + # Buscar TipoAutor + try: + tipo_autor = TipoAutor.objects.get(pk=tipo_autor_id) + except TipoAutor.DoesNotExist: + return JsonResponse({ + 'success': False, + 'error': 'Tipo de Autor não encontrado.' + }, status=404) + + # Verificar se tipo tem content_type + if tipo_autor.content_type: + # Tipo com content_type (Parlamentar, Comissão, etc) + if not autor_related_id: + return JsonResponse({ + 'success': False, + 'error': f'Selecione um registro de {tipo_autor.descricao}.' + }, status=400) + + # Buscar o registro relacionado + model_class = tipo_autor.content_type.model_class() + try: + related_obj = model_class.objects.get(pk=autor_related_id) + except model_class.DoesNotExist: + return JsonResponse({ + 'success': False, + 'error': f'Registro de {tipo_autor.descricao} não encontrado.' + }, status=404) + + # Verificar se já existe autor para este registro + if Autor.objects.filter( + content_type=tipo_autor.content_type, + object_id=autor_related_id + ).exists(): + return JsonResponse({ + 'success': False, + 'error': f'Já existe um autor cadastrado para "{related_obj}".' + }, status=400) + + # Criar autor com content_type + autor = Autor.objects.create( + tipo=tipo_autor, + content_type=tipo_autor.content_type, + object_id=autor_related_id, + nome=str(related_obj) + ) + + self.logger.info( + f"user={request.user.username}. Autor '{autor.nome}' criado " + f"via AJAX vinculado a {tipo_autor.descricao} (ID: {autor.id})" + ) + + else: + # Tipo genérico (sem content_type) + if not nome: + return JsonResponse({ + 'success': False, + 'error': 'Nome do Autor é obrigatório.' + }, status=400) + + # Verificar se já existe autor com este nome + if Autor.objects.filter(nome=nome).exists(): + return JsonResponse({ + 'success': False, + 'error': f'Já existe um autor com o nome "{nome}".' + }, status=400) + + # Criar autor genérico + autor = Autor.objects.create( + tipo=tipo_autor, + nome=nome, + cargo=cargo if cargo else '' + ) + + self.logger.info( + f"user={request.user.username}. Autor genérico '{autor.nome}' " + f"criado via AJAX (ID: {autor.id})" + ) + + return JsonResponse({ + 'success': True, + 'autor': { + 'id': autor.id, + 'nome': autor.nome, + 'tipo': str(autor.tipo), + 'cargo': autor.cargo if autor.cargo else '' + } + }) + + except Exception as e: + self.logger.error( + f"user={request.user.username}. Erro ao criar autor via AJAX: {str(e)}" + ) + return JsonResponse({ + 'success': False, + 'error': f'Erro ao criar autor: {str(e)}' + }, status=500) diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index 80d909e79..abf15cb20 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -166,9 +166,13 @@ urlpatterns_sistema = [ include(AssuntoMateriaCrud.get_urls())), url(r'^sistema/proposicao/tipo/', include(TipoProposicaoCrud.get_urls())), + url(r'^sistema/materia/tipoproposicao/', + include(TipoProposicaoCrud.get_urls())), url(r'^sistema/materia/tipo/', include(TipoMateriaCrud.get_urls())), url(r'^sistema/materia/regime-tramitacao/', include(RegimeTramitacaoCrud.get_urls())), + url(r'^sistema/materia/regimetramitacao/', + include(RegimeTramitacaoCrud.get_urls())), url(r'^sistema/materia/tipo-documento/', include(TipoDocumentoCrud.get_urls())), url(r'^sistema/materia/tipo-fim-relatoria/', diff --git a/sapl/parlamentares/urls.py b/sapl/parlamentares/urls.py index d67a1f6b1..b3fd32fd5 100644 --- a/sapl/parlamentares/urls.py +++ b/sapl/parlamentares/urls.py @@ -23,7 +23,8 @@ from sapl.parlamentares.views import (CargoMesaCrud, ColigacaoCrud, PesquisarParlamentarView, VincularParlamentarView, get_sessoes_legislatura, FrenteCargoCrud, FrenteParlamentarCrud, get_parlamentar_frentes, PesquisarColigacaoView, PesquisarPartidoView, - BlocoCargoCrud, BlocoMembroCrud) + BlocoCargoCrud, BlocoMembroCrud, criar_parlamentar_ajax, + criar_legislatura_ajax) from .apps import AppConfig @@ -56,6 +57,12 @@ urlpatterns = [ url(r'^parlamentar/vincular-parlamentar/$', VincularParlamentarView.as_view(), name='vincular_parlamentar'), + url(r'^parlamentar/criar-parlamentar-ajax/$', + criar_parlamentar_ajax, name='criar_parlamentar_ajax'), + + url(r'^parlamentar/criar-legislatura-ajax/$', + criar_legislatura_ajax, name='criar_legislatura_ajax'), + url(r'^parlamentar/coligacao-legislatura/', coligacao_legislatura, name="coligacao_legislatura"), url(r'^sistema/coligacao/', include(ColigacaoCrud.get_urls() + diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index a46ce2b84..fda75cca2 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -3,6 +3,7 @@ import json import logging from django.contrib import messages +from django.contrib.auth.decorators import permission_required from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType @@ -1470,6 +1471,163 @@ class VincularParlamentarView(PermissionRequiredMixin, FormView): return HttpResponseRedirect(self.get_success_url()) +@permission_required('parlamentares.add_parlamentar') +def criar_parlamentar_ajax(request): + """View AJAX para criar parlamentar via modal""" + if request.method == 'POST': + try: + nome_completo = request.POST.get('nome_completo', '').strip() + nome_parlamentar = request.POST.get('nome_parlamentar', '').strip() + sexo = request.POST.get('sexo', '').strip() + + # Validações básicas dos campos obrigatórios + if not nome_completo or not nome_parlamentar or not sexo: + return JsonResponse({ + 'success': False, + 'error': 'Nome Completo, Nome Parlamentar e Sexo são obrigatórios.' + }) + + if sexo not in ['F', 'M']: + return JsonResponse({ + 'success': False, + 'error': 'Sexo inválido. Use F (Feminino) ou M (Masculino).' + }) + + # Campos opcionais + cpf = request.POST.get('cpf', '').strip() + rg = request.POST.get('rg', '').strip() + data_nascimento = request.POST.get('data_nascimento', '').strip() + email = request.POST.get('email', '').strip() + telefone = request.POST.get('telefone', '').strip() + telefone_celular = request.POST.get('telefone_celular', '').strip() + + # Processar data de nascimento se fornecida + data_nascimento_obj = None + if data_nascimento: + try: + data_nascimento_obj = datetime.strptime(data_nascimento, '%d/%m/%Y').date() + except ValueError: + return JsonResponse({ + 'success': False, + 'error': 'Formato de data de nascimento inválido. Use DD/MM/AAAA.' + }) + + # Criar parlamentar com todos os campos + parlamentar = Parlamentar.objects.create( + nome_completo=nome_completo, + nome_parlamentar=nome_parlamentar, + sexo=sexo, + cpf=cpf, + rg=rg, + data_nascimento=data_nascimento_obj, + email=email, + telefone=telefone, + telefone_celular=telefone_celular, + ativo=True # Por padrão, marcar como ativo + ) + + return JsonResponse({ + 'success': True, + 'parlamentar': { + 'id': parlamentar.id, + 'nome': str(parlamentar) + } + }) + + except Exception as e: + return JsonResponse({ + 'success': False, + 'error': f'Erro ao criar parlamentar: {str(e)}' + }) + + return JsonResponse({'success': False, 'error': 'Método não permitido'}) + + +@permission_required('parlamentares.add_parlamentar') +def criar_legislatura_ajax(request): + """View AJAX para criar legislatura via modal""" + if request.method == 'POST': + try: + numero = request.POST.get('numero', '').strip() + data_inicio = request.POST.get('data_inicio', '').strip() + data_fim = request.POST.get('data_fim', '').strip() + data_eleicao = request.POST.get('data_eleicao', '').strip() + + # Validações básicas + if not numero or not data_inicio or not data_fim or not data_eleicao: + return JsonResponse({ + 'success': False, + 'error': 'Todos os campos são obrigatórios.' + }) + + try: + numero = int(numero) + if numero <= 0: + raise ValueError + except ValueError: + return JsonResponse({ + 'success': False, + 'error': 'Número deve ser um valor inteiro positivo.' + }) + + # Converter datas do formato brasileiro (DD/MM/YYYY) para YYYY-MM-DD + from datetime import datetime + + try: + data_inicio_obj = datetime.strptime(data_inicio, '%d/%m/%Y').date() + data_fim_obj = datetime.strptime(data_fim, '%d/%m/%Y').date() + data_eleicao_obj = datetime.strptime(data_eleicao, '%d/%m/%Y').date() + except ValueError: + return JsonResponse({ + 'success': False, + 'error': 'Formato de data inválido. Use DD/MM/YYYY.' + }) + + # Validar ordem das datas + if data_inicio_obj >= data_fim_obj: + return JsonResponse({ + 'success': False, + 'error': 'Data de Início deve ser anterior à Data Fim.' + }) + + if data_eleicao_obj >= data_inicio_obj: + return JsonResponse({ + 'success': False, + 'error': 'Data de Eleição deve ser anterior à Data de Início.' + }) + + # Verificar se já existe legislatura com esse número + if Legislatura.objects.filter(numero=numero).exists(): + return JsonResponse({ + 'success': False, + 'error': f'Já existe uma legislatura com o número {numero}.' + }) + + # Criar legislatura + legislatura = Legislatura.objects.create( + numero=numero, + data_inicio=data_inicio_obj, + data_fim=data_fim_obj, + data_eleicao=data_eleicao_obj + ) + + return JsonResponse({ + 'success': True, + 'legislatura': { + 'id': legislatura.id, + 'nome': str(legislatura) + } + }) + + except Exception as e: + return JsonResponse({ + 'success': False, + 'error': f'Erro ao criar legislatura: {str(e)}' + }) + + return JsonResponse({'success': False, 'error': 'Método não permitido'}) + + class BlocoCrud(CrudAux): model = Bloco public = [RP_DETAIL, RP_LIST] diff --git a/sapl/templates/404.html b/sapl/templates/404.html index 82a3dee5e..b174f7a4f 100644 --- a/sapl/templates/404.html +++ b/sapl/templates/404.html @@ -1,147 +1,12 @@ -{% load i18n menus %} -{% load common_tags %} -{% load render_bundle from webpack_loader %} -{% load webpack_static from webpack_loader %} - - - - - - - - - {% block head_title %}{% trans 'SAPL - Sistema de Apoio ao Processo Legislativo' %}{% endblock %} - - {% block head_content %} - - - {% render_chunk_vendors 'css' %} - {% render_bundle 'global' 'css' %} - - {% endblock %} - - - -
- - {% if not request|has_iframe %} - {% block navigation %} - - {% endblock navigation %} - - {# Header #} - {% block main_header %} -
- -
- {% endblock main_header %} - {% else %} -
- -
-
-
-
- {% subnav %} -
-
-
- {% endif %} -
- -

{% trans 'Página não encontrada! Erro 404' %}

-
-
- {% block base_content %} - {% endblock %} - {% if not request|has_iframe %} - {% block footer_container %} - -
- {% endblock footer_container %} - {% endif %} - - {% block foot_js %} - - {% render_chunk_vendors 'js' %} - {% render_bundle 'global' 'js' %} - - {% block extra_js %}{% endblock %} - - - - {% endblock foot_js %} - - +{% extends "base.html" %} +{% load i18n %} + +{% block head_title %}{% trans 'Página não encontrada! Erro 404' %}{% endblock %} + +{% block base_content %} +
+

{% trans 'Página não encontrada! Erro 404' %}

+

{% trans 'A página que você está procurando não foi encontrada.' %}

+ {% trans 'Voltar para a página inicial' %} +
+{% endblock %} diff --git a/sapl/templates/500.html b/sapl/templates/500.html index 868225132..3ca757620 100644 --- a/sapl/templates/500.html +++ b/sapl/templates/500.html @@ -1,115 +1,12 @@ -{% load i18n menus %} -{% load common_tags %} -{% load render_bundle from webpack_loader %} -{% load webpack_static from webpack_loader %} - - - - - - - - - {% block head_title %}{% trans 'SAPL - Sistema de Apoio ao Processo Legislativo' %}{% endblock %} - - {% block head_content %} - - - - {% render_chunk_vendors 'css' %} - {% render_bundle 'global' 'css' %} - - - {% endblock %} - - - -
- - {% block navigation %} - - {% endblock navigation %} - - {# Header #} - {% block main_header %} -
-
- -
- {% block sections_nav %} {% subnav %} {% endblock sections_nav %} -
-
-
- {% endblock main_header %} - -
- -

{% trans 'Ocorreu um erro inesperado! Erro 500' %}

-
-
- {% block base_content %} - {% endblock %} - {% block footer_container %} - -
- {% endblock footer_container %} - - {% block foot_js %} - - {% render_chunk_vendors 'js' %} - {% render_bundle 'global' 'js' %} - - {% block extra_js %}{% endblock %} - - {% endblock foot_js %} - - +{% extends "base.html" %} +{% load i18n %} + +{% block head_title %}{% trans 'Ocorreu um erro inesperado! Erro 500' %}{% endblock %} + +{% block base_content %} +
+

{% trans 'Ocorreu um erro inesperado! Erro 500' %}

+

{% trans 'Desculpe, ocorreu um erro interno no servidor. Tente novamente mais tarde.' %}

+ {% trans 'Voltar para a página inicial' %} +
+{% endblock %} diff --git a/sapl/templates/auth/user_form.html b/sapl/templates/auth/user_form.html index 7279f67ff..163428054 100644 --- a/sapl/templates/auth/user_form.html +++ b/sapl/templates/auth/user_form.html @@ -1,10 +1,332 @@ {% extends "crud/form.html" %} {% load i18n %} +{% block base_content %} + {{ block.super }} + + + + + + +{% endblock base_content %} + {% block extra_js %} diff --git a/sapl/templates/fluxo_proposicoes.html b/sapl/templates/fluxo_proposicoes.html index 76abcb190..a071f44a6 100644 --- a/sapl/templates/fluxo_proposicoes.html +++ b/sapl/templates/fluxo_proposicoes.html @@ -417,6 +417,9 @@
Conceitos Atores + + Permissões Necessárias + Estados Fluxo Visual Passo a Passo @@ -545,6 +548,111 @@
+ +

Permissões Necessárias para Criar Proposições

+ +
+

IMPORTANTE: Requisitos para Acesso

+

Para que um usuário possa acessar /proposicao/create e criar proposições, ele precisa atender DOIS requisitos obrigatórios:

+
+ +
+
+
+

1. Grupo "Autor"

+

O usuário precisa estar no grupo "Autor" do sistema.

+

Como adicionar:

+
+
+

Ir para Usuários

+
+ URL: /sistema/usuario/ + + Acessar + +
+
+
+

Editar o usuário desejado

+

Clique no nome do usuário (ex: helena)

+
+
+

Adicionar ao grupo

+

Na seção "Grupos", marque "Autor"

+

Clique em "Salvar"

+
+
+
+
+ +
+
+

2. Vínculo com Autor

+

O usuário precisa estar vinculado como operador de um Autor.

+

Como vincular:

+
+
+

Ir para Editar Usuário

+
+ URL: /sistema/usuario/{id}/edit + + Ver Lista + +
+
+
+

Selecionar o Autor

+

No campo "Autor", selecione o autor correspondente (ex: "Helena Silva")

+

Se não existir autor, crie um parlamentar primeiro

+
+
+

Salvar

+

Isso cria automaticamente o vínculo OperadorAutor

+
+ ✓ Pronto! Agora o usuário pode criar proposições. +
+
+
+
+
+
+ +
+

Exemplo de Erro Comum

+

Se o usuário helena possui os grupos:

+ +

Ela NÃO conseguirá criar proposições porque:

+ +

Solução: Adicionar ao grupo "Autor" E vincular a um Autor existente.

+
+ +
+

Atalho Rápido

+

Para vincular rapidamente um usuário e permitir criação de proposições:

+
    +
  1. Acesse /sistema/usuario/
  2. +
  3. Clique no usuário desejado
  4. +
  5. Clique em "Editar"
  6. +
  7. Marque o grupo "Autor"
  8. +
  9. No campo "Autor", selecione o autor correspondente
  10. +
  11. Salve
  12. +
+
+ Ir diretamente para: /sistema/usuario/ + + Configurar Agora + +
+
+

Estados de uma Proposição

@@ -825,6 +933,28 @@

PARLAMENTAR Criar e Enviar Proposição

+
+

ATENÇÃO: Verifique os Requisitos Primeiro!

+

Antes de tentar criar uma proposição, certifique-se de que o usuário possui:

+
    +
  • ✓ Grupo "Autor" atribuído
  • +
  • ✓ Vínculo com um Autor (parlamentar, comissão, etc.)
  • +
+

Se faltar algum requisito, você receberá:

+
+ ❌ Acesso Negado
+ Desculpe, você não tem permissão para acessar esta página ou recurso. +
+

+ + Ver Seção de Permissões + + + Configurar Usuário Agora + +

+
+

Login como Parlamentar

@@ -1065,10 +1195,44 @@
  • Regimes de Tramitação em /sistema/materia/regimetramitacao/
  • Parlamentares em /parlamentar/create
  • Usuários em /sistema/usuario/create
  • -
  • Vincular Usuários a Autores em /sistema/usuario/{id}/edit
  • +
    +

    CONFIGURAÇÃO CRÍTICA: Permissões para Criar Proposições

    +

    Para cada usuário que precisa criar proposições, você DEVE:

    +
      +
    1. + Adicionar ao grupo "Autor" + +
    2. +
    3. + Vincular a um Autor +
        +
      • Na mesma tela de edição do usuário
      • +
      • No campo "Autor", selecione o autor correspondente (parlamentar, comissão, etc.)
      • +
      • Salve
      • +
      +
    4. +
    +
    + Configurar agora: /sistema/usuario/ + + Configurar Permissões + +
    +

    Sem essas duas configurações, o usuário receberá "Acesso Negado" ao tentar acessar /proposicao/create.

    +

    + + Ver Detalhes das Permissões + +

    +
    +

    Resumo Executivo

    diff --git a/sapl/templates/materia/proposicao_form.html b/sapl/templates/materia/proposicao_form.html index 5a603d255..22e92f98f 100644 --- a/sapl/templates/materia/proposicao_form.html +++ b/sapl/templates/materia/proposicao_form.html @@ -13,6 +13,13 @@ $("#div_id_texto_original").addClass('hidden'); }); + // Adicionar botão ao lado do select de tipo + var $tipoSelect = $("select[name=tipo]"); + if ($tipoSelect.length > 0) { + var $btnNovoTipo = $(' Novo Tipo'); + $tipoSelect.parent().append($btnNovoTipo); + } + $("select[name=tipo]").change(function(event) { if (this.selectedOptions[0].getAttribute('data-has-perfil') === "True") { @@ -27,7 +34,7 @@ } if ($("input[name=tipo_texto]:checked").length == 0) { $("input[name=tipo_texto]").first().prop('checked', true); - $("input[name=tipo_texto]").first().closest('label').addClass('checked'); + $("input[name=tipo_texto]").first().closest('label').addClass('checked'); } }); diff --git a/sapl/templates/materia/tipomaterialegislativa_form.html b/sapl/templates/materia/tipomaterialegislativa_form.html new file mode 100644 index 000000000..2ef0b20cc --- /dev/null +++ b/sapl/templates/materia/tipomaterialegislativa_form.html @@ -0,0 +1,349 @@ +{% extends "crud/form.html" %} +{% load i18n %} + +{% block extra_css %} + +{% endblock %} + +{% block extra_js %} + +{% endblock %} diff --git a/sapl/templates/materia/tipoproposicao_form.html b/sapl/templates/materia/tipoproposicao_form.html index 3618869b8..e072bb776 100644 --- a/sapl/templates/materia/tipoproposicao_form.html +++ b/sapl/templates/materia/tipoproposicao_form.html @@ -1,39 +1,562 @@ {% extends "crud/form.html" %} {% load i18n %} +{% block extra_css %} + +{% endblock %} + {% block extra_js %} diff --git a/sapl/templates/parlamentares/vincular_parlamentar.html b/sapl/templates/parlamentares/vincular_parlamentar.html index 6ba8948dd..d5870e006 100644 --- a/sapl/templates/parlamentares/vincular_parlamentar.html +++ b/sapl/templates/parlamentares/vincular_parlamentar.html @@ -3,6 +3,465 @@ {% load crispy_forms_tags %} {% load common_tags %} -{% block detail_content %} - {% crispy form %} -{% endblock detail_content %} \ No newline at end of file +{% block base_content %} + {% crispy form %} + + + + + + + +{% endblock base_content %} + +{% block extra_js %} + +{% endblock extra_js %} \ No newline at end of file