-
Notifications
You must be signed in to change notification settings - Fork 98
Issue#3828 Refatorar Mesa Diretora #3829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 3.1.x
Are you sure you want to change the base?
Changes from all commits
799f0ec
652e74f
7acb516
2b55d6d
b32959c
106847a
08c5eb6
2e894ca
52240ba
799d0e0
958e83f
cfdfd69
65e50bc
76dec7b
7a14c1e
507cc4a
c9e55dc
3d62955
a6ee8d3
29c9dc0
f36970c
5faefcb
fcb2de6
f777e02
98e687f
1b144e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -183,6 +183,7 @@ small { | |
| hyphens: auto;*/ | ||
| } | ||
|
|
||
|
|
||
| @media print { | ||
| a[href]:after { | ||
| content: none !important; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| @import "~bootstrap/scss/variables"; | ||
|
|
||
| // Estilização do tab-content conectado ao nav-tabs (substitui inline style) | ||
| .nav-tabs + .tab-content { | ||
| border: 1px solid $nav-tabs-border-color; | ||
| border-top: 0; | ||
| border-radius: 0 0 $border-radius $border-radius; | ||
| } | ||
|
|
||
| @media (max-width: 992px) { | ||
| .nav-tabs { | ||
| position: relative; | ||
| flex-direction: column; | ||
| border: 1px solid $nav-tabs-border-color; | ||
| border-radius: $border-radius; // Totalmente arredondado — parece um botão/select | ||
| background-color: $white; | ||
| overflow: hidden; // Recorta filhos nas bordas arredondadas | ||
|
|
||
| // Seta indicando dropdown | ||
| &::after { | ||
| content: "▾"; | ||
| position: absolute; | ||
| right: 0.75rem; | ||
| top: 0.6rem; | ||
| font-size: 1rem; | ||
| color: $secondary; | ||
| pointer-events: none; | ||
| transition: transform 0.2s ease; | ||
| } | ||
|
|
||
| // Oculta todos os itens por padrão | ||
| .nav-item { | ||
| display: none; | ||
| width: 100%; | ||
|
|
||
| .nav-link { | ||
| border: none; | ||
| border-bottom: 1px solid $nav-tabs-border-color; | ||
| border-radius: 0; | ||
| width: 100%; | ||
| text-align: left; | ||
| padding-right: 2rem; | ||
| margin-bottom: 0; | ||
|
|
||
| &.active { | ||
| background-color: $nav-tabs-link-active-bg; | ||
| color: $nav-tabs-link-active-color; | ||
| border-color: transparent; | ||
| } | ||
|
|
||
| &:hover:not(.active) { | ||
| background-color: $light; | ||
| } | ||
| } | ||
|
|
||
| &:last-child .nav-link { | ||
| border-bottom: none; | ||
| } | ||
| } | ||
|
|
||
| // CSS nativo: exibe somente o item ativo (browsers com suporte a :has) | ||
| .nav-item:has(.nav-link.active) { | ||
| display: block; | ||
| } | ||
|
|
||
| // Estado expandido: via :focus-within (nativo) ou .nav-tabs--open (fallback JS) | ||
| &:focus-within, | ||
| &.nav-tabs--open { | ||
| border-radius: $border-radius $border-radius 0 0; // Arredonda apenas topo quando aberto | ||
| overflow: visible; | ||
| z-index: $zindex-dropdown; | ||
|
|
||
| &::after { | ||
| transform: rotate(180deg); | ||
| } | ||
|
|
||
| .nav-item { | ||
| display: block; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Em mobile, tab-content é visualmente independente do nav-tabs (que vira um select) | ||
| .nav-tabs + .tab-content { | ||
| border-top: 1px solid $nav-tabs-border-color; | ||
| border-radius: $border-radius; // Rounding completo — desconectado do nav-tabs | ||
| margin-top: 0.5rem; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| @import "./bootstrap/nav_navbar"; | ||
| @import "./bootstrap/nav_tabs"; | ||
| @import "./bootstrap/table"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| from datetime import timedelta | ||
| import logging | ||
|
|
||
| from crispy_forms.layout import Fieldset, Layout | ||
| from crispy_forms.layout import Fieldset, Layout, Field | ||
| from django import forms | ||
| from django.contrib.auth import get_user_model | ||
| from django.contrib.auth.models import Group, User | ||
|
|
@@ -19,10 +19,10 @@ | |
| from sapl.crispy_layout_mixin import SaplFormHelper | ||
| from sapl.crispy_layout_mixin import form_actions, to_row | ||
| from sapl.rules import SAPL_GROUP_VOTANTE | ||
| from sapl.utils import FileFieldCheckMixin | ||
| from sapl.utils import FileFieldCheckMixin, SelectSubmitChangeWidget | ||
|
|
||
| from .models import (Coligacao, ComposicaoColigacao, Filiacao, Frente, Legislatura, | ||
| Mandato, Parlamentar, Partido, Votante, Bloco, FrenteParlamentar, BlocoMembro) | ||
| from .models import (Coligacao, ComposicaoColigacao, ComposicaoMesa, Filiacao, Frente, Legislatura, | ||
| Mandato, MesaDiretora, Parlamentar, Partido, Votante, Bloco, FrenteParlamentar, BlocoMembro) | ||
|
|
||
|
|
||
| class CustomImageCropWidget(ImageCropWidget): | ||
|
|
@@ -752,3 +752,49 @@ def clean(self): | |
| _("Parlamentar já é membro do bloco parlamentar.")) | ||
|
|
||
| return cd | ||
|
|
||
| class MesaDiretoraFilterSet(django_filters.FilterSet): | ||
|
|
||
| legislatura = django_filters.ModelChoiceFilter( | ||
| label='', | ||
| queryset=Legislatura.objects.all(), | ||
| widget=SelectSubmitChangeWidget) | ||
|
|
||
| class Meta: | ||
| model = MesaDiretora | ||
| fields = ['legislatura'] | ||
|
|
||
| def __init__(self, *args, **kwargs): | ||
| super(MesaDiretoraFilterSet, self).__init__(*args, **kwargs) | ||
|
|
||
| row0 = to_row([('legislatura', 5)]) | ||
|
|
||
| self.form.helper = SaplFormHelper() | ||
| self.form.helper.form_method = 'GET' | ||
| self.form.helper.layout = Layout( | ||
| Fieldset(_('Escolha da Legislatura'), | ||
| row0,) | ||
| ) | ||
|
|
||
|
|
||
| class MesaDiretoraForm(ModelForm): | ||
|
|
||
| class Meta: | ||
| model = MesaDiretora | ||
| fields = '__all__' | ||
|
|
||
|
|
||
| class ComposicaoMesaForm(ModelForm): | ||
|
|
||
| class Meta: | ||
| model = ComposicaoMesa | ||
| fields = ( | ||
| 'parlamentar', | ||
| 'cargo' | ||
| ) | ||
|
|
||
| def __init__(self, *args, **kwargs): | ||
| super(ComposicaoMesaForm, self).__init__(*args, **kwargs) | ||
| self.instance.mesa_diretora = self.initial.get('mesa_diretora') | ||
| self.fields['parlamentar'].queryset = self.fields['parlamentar'].queryset.filter( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Se o form for instanciado sem Hoje as views CRUD sempre passam mesa = self.initial.get('mesa_diretora')
if mesa is not None:
self.instance.mesa_diretora = mesa
self.fields['parlamentar'].queryset = (
self.fields['parlamentar'].queryset
.filter(mandato__legislatura=mesa.legislatura)
) |
||
| mandato__legislatura=self.initial.get('mesa_diretora').legislatura) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Generated by Django 2.2.28 on 2026-04-13 01:48 | ||
|
|
||
| from django.db import migrations, models | ||
| import django.db.models.deletion | ||
| from datetime import date | ||
|
|
||
| def add_legislatura_to_mesa_diretora(apps, schema_editor): | ||
| schema_editor.execute(""" | ||
| UPDATE parlamentares_mesadiretora md | ||
| SET | ||
| legislatura_id = sl.legislatura_id, | ||
| data_inicio = sl.data_inicio, | ||
| data_fim = sl.data_fim | ||
| FROM | ||
| parlamentares_sessaolegislativa sl | ||
| WHERE | ||
| sl.id = md.sessao_legislativa_id | ||
| """) | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ('parlamentares', '0045_auto_20251201_1531'), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.AddField( | ||
| model_name='mesadiretora', | ||
| name='legislatura', | ||
| field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='parlamentares.Legislatura', verbose_name='Legislatura'), | ||
| ), | ||
| migrations.RunPython(add_legislatura_to_mesa_diretora), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Generated by Django 2.2.28 on 2026-04-13 01:56 | ||
|
|
||
| from django.db import migrations, models | ||
| import django.db.models.deletion | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ('parlamentares', '0046_mesadiretora_legislatura'), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.AlterField( | ||
| model_name='mesadiretora', | ||
| name='legislatura', | ||
| field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='parlamentares.Legislatura', verbose_name='Legislatura'), | ||
| ), | ||
| migrations.RemoveField( | ||
| model_name='mesadiretora', | ||
| name='sessao_legislativa', | ||
| ), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| # Generated by Django 2.2.28 on 2026-04-13 13:49 | ||
|
|
||
| from django.db import migrations, models | ||
| import django.db.models.deletion | ||
|
|
||
| def preencher_titulo_mesa_diretora(apps, schema_editor): | ||
| schema_editor.execute(""" | ||
| UPDATE parlamentares_mesadiretora | ||
| SET titulo = 'Mesa Diretora' || | ||
| CASE WHEN EXTRACT(YEAR FROM data_fim)::integer - EXTRACT(YEAR FROM data_inicio)::integer = 1 | ||
| THEN ' Biênio' | ||
| ELSE '' | ||
| END || ' ' || | ||
| EXTRACT(YEAR FROM data_inicio)::integer::text || '/' || | ||
| EXTRACT(YEAR FROM data_fim)::integer::text | ||
| WHERE data_inicio IS NOT NULL AND data_fim IS NOT NULL | ||
| """) | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ('parlamentares', '0047_auto_20260412_2256'), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.AlterModelOptions( | ||
| name='mesadiretora', | ||
| options={'ordering': ('-legislatura', '-data_inicio'), 'verbose_name': 'Mesa Diretora', 'verbose_name_plural': 'Mesas Diretoras'}, | ||
| ), | ||
| migrations.AddField( | ||
| model_name='mesadiretora', | ||
| name='titulo', | ||
| field=models.CharField(default='', max_length=100, verbose_name='Título da Mesa Diretora'), | ||
| ), | ||
| migrations.AlterField( | ||
| model_name='composicaomesa', | ||
| name='mesa_diretora', | ||
| field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='composicaomesa_set', to='parlamentares.MesaDiretora'), | ||
| ), | ||
| migrations.RunPython(preencher_titulo_mesa_diretora), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # Generated by Django 2.2.28 on 2026-04-17 22:17 | ||
|
|
||
| from django.db import migrations, models | ||
| import django.db.models.deletion | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ('parlamentares', '0048_auto_20260413_1049'), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.AlterField( | ||
| model_name='composicaomesa', | ||
| name='cargo', | ||
| field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='parlamentares.CargoMesa', verbose_name='Cargo'), | ||
| ), | ||
| migrations.AlterField( | ||
| model_name='composicaomesa', | ||
| name='mesa_diretora', | ||
| field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='composicaomesa_set', to='parlamentares.MesaDiretora', verbose_name='Mesa Diretora'), | ||
| ), | ||
| migrations.AlterField( | ||
| model_name='composicaomesa', | ||
| name='parlamentar', | ||
| field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='parlamentares.Parlamentar', verbose_name='Parlamentar'), | ||
| ), | ||
| migrations.AlterField( | ||
| model_name='mesadiretora', | ||
| name='data_fim', | ||
| field=models.DateField(verbose_name='Data Fim'), | ||
| ), | ||
| migrations.AlterField( | ||
| model_name='mesadiretora', | ||
| name='data_inicio', | ||
| field=models.DateField(verbose_name='Data Início'), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Migration pode falhar em bases legadas O modelo antigo permitia
Se houver
|
||
| ), | ||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # Generated by Django 2.2.28 on 2026-04-18 01:35 | ||
|
|
||
| from django.db import migrations, models | ||
| import django.db.models.deletion | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ('parlamentares', '0049_auto_20260417_1917'), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.AlterField( | ||
| model_name='mesadiretora', | ||
| name='legislatura', | ||
| field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='mesadiretora_set', to='parlamentares.Legislatura', verbose_name='Legislatura'), | ||
| ), | ||
| ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import
Fieldadicionado mas não usado em nenhum lugar do diff.fix_qa.sh(isort/autopep8) deveria limpar.