Browse Source

ajustes de scss para telas mobiles

3828_refatorar_mesa_diretora
LeandroJatai 14 hours ago
parent
commit
106847a244
  1. 1
      frontend/src/__global/scss/layouts/_globals.scss
  2. 89
      frontend/src/__global/scss/libs/bootstrap/_nav_tabs.scss
  3. 1
      frontend/src/__global/scss/libs/libs.scss
  4. 2
      sapl/parlamentares/forms.py
  5. 182
      sapl/templates/parlamentares/mesadiretora_filter.html

1
frontend/src/__global/scss/layouts/_globals.scss

@ -183,6 +183,7 @@ small {
hyphens: auto;*/
}
@media print {
a[href]:after {
content: none !important;

89
frontend/src/__global/scss/libs/bootstrap/_nav_tabs.scss

@ -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;
}
}

1
frontend/src/__global/scss/libs/libs.scss

@ -1,2 +1,3 @@
@import "./bootstrap/nav_navbar";
@import "./bootstrap/nav_tabs";
@import "./bootstrap/table";

2
sapl/parlamentares/forms.py

@ -772,6 +772,6 @@ class MesaDiretoraFilterSet(django_filters.FilterSet):
self.form.helper = SaplFormHelper()
self.form.helper.form_method = 'GET'
self.form.helper.layout = Layout(
Fieldset(_('Escolha da Legislatura e da Sessão Legislativa'),
Fieldset(_('Escolha da Legislatura'),
row0,)
)

182
sapl/templates/parlamentares/mesadiretora_filter.html

@ -5,58 +5,142 @@
{% if perms.add_mesadiretora %}
{{ block.super }}
{% else %}
<div>
<ul class="nav nav-tabs" role="tablist">
{% for md in object_list %}
{% if forloop.first %}
<li class="nav-item">
<a class="nav-link active" href="#tab-mesa-{{ md.id }}" data-toggle="tab" role="tab">{{ md }}</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="#tab-mesa-{{ md.id }}" data-toggle="tab" role="tab">{{ md }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
<div class="tab-content" style="border: 1px solid #dee2e6; border-top: 0; border-radius: 0 0 0.25rem 0.25rem;">
{% for md in object_list %}
{% if forloop.first or request.GET.mesadiretora == md.id|stringformat:"s" %}
<div class="tab-pane fade show active" id="tab-mesa-{{ md.id }}" role="tabpanel">
{% else %}
<div class="tab-pane fade" id="tab-mesa-{{ md.id }}" role="tabpanel">
{% endif %}
<i class="text-muted p-2 d-inline-block">(De {{md.data_inicio }} a {{ md.data_fim }})</i>
<table class="table table-striped table-hover table-link-ordering m-0 p-0">
<thead>
<tr>
<th>Nome do Parlamentar</th>
<th>Partido</th>
<th>Cargo</th>
</tr>
</thead>
<tbody>
{% for p in md.composicaomesa_set.all %}
<div class="row">
<div class="col-12">
<ul class="nav nav-tabs" role="tablist">
{% for md in object_list %}
{% if forloop.first %}
<li class="nav-item">
<a class="nav-link active" href="#tab-mesa-{{ md.id }}" data-toggle="tab" role="tab">{{ md }}</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="#tab-mesa-{{ md.id }}" data-toggle="tab" role="tab">{{ md }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
<div class="tab-content">
{% for md in object_list %}
{% if forloop.first or request.GET.mesadiretora == md.id|stringformat:"s" %}
<div class="tab-pane fade show active" id="tab-mesa-{{ md.id }}" role="tabpanel">
{% else %}
<div class="tab-pane fade" id="tab-mesa-{{ md.id }}" role="tabpanel">
{% endif %}
<i class="text-muted p-2 d-inline-block">(De {{md.data_inicio }} a {{ md.data_fim }})</i>
<table class="table table-striped table-hover table-link-ordering m-0 p-0">
<thead>
<tr>
<td>
<div id="d-flex">
{% if p.parlamentar.fotografia %}
<img class="img-fluid img-thumbnail" src="{% cropped_thumbnail p.parlamentar "cropping"%}">
{% endif %}
<a class="pl-2" href="{% url 'sapl.parlamentares:parlamentar_detail' p.parlamentar.pk %}">
{{p.parlamentar.nome_parlamentar}}</a>
</div>
</td>
<td>{{p.parlamentar.filiacao_atual}}</td>
<td>{{p.cargo}}</td>
<th>Nome do Parlamentar</th>
<th>Partido</th>
<th>Cargo</th>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
</thead>
<tbody>
{% for p in md.composicaomesa_set.all %}
<tr>
<td>
<div id="d-flex">
{% if p.parlamentar.fotografia %}
<img class="img-fluid img-thumbnail" src="{% cropped_thumbnail p.parlamentar "cropping"%}">
{% endif %}
<a class="pl-2" href="{% url 'sapl.parlamentares:parlamentar_detail' p.parlamentar.pk %}">
{{p.parlamentar.nome_parlamentar}}</a>
</div>
</td>
<td>{{p.parlamentar.filiacao_atual}}</td>
<td>{{p.cargo}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% endblock container_table_list %}
{% block extra_js %}
<script>
(function () {
// Suporte nativo a :has() — o CSS cuida de tudo, JS não é necessário
if (typeof CSS !== 'undefined' && CSS.supports && CSS.supports('selector(:has(*))')) return;
var mq = window.matchMedia('(max-width: 767px)');
function collapse(tabs) {
tabs.classList.remove('nav-tabs--open');
[].forEach.call(tabs.querySelectorAll('.nav-item'), function (item) {
item.style.display = item.querySelector('.nav-link.active') ? 'block' : 'none';
});
}
function expand(tabs) {
[].forEach.call(tabs.querySelectorAll('.nav-item'), function (item) {
item.style.display = 'block';
});
tabs.classList.add('nav-tabs--open');
}
function init() {
[].forEach.call(document.querySelectorAll('.nav-tabs'), function (tabs) {
if (tabs._dropdownBound) return;
tabs._dropdownBound = true;
// Expande ao clicar no container (apenas quando fechado)
tabs.addEventListener('click', function () {
if (!mq.matches || tabs.classList.contains('nav-tabs--open')) return;
expand(tabs);
setTimeout(function () {
document.addEventListener('click', function onOutside(ev) {
if (!tabs.contains(ev.target)) {
collapse(tabs);
document.removeEventListener('click', onOutside);
}
});
}, 0);
});
// Colapsa ao selecionar uma aba (apenas quando aberto)
[].forEach.call(tabs.querySelectorAll('.nav-link'), function (link) {
link.addEventListener('click', function () {
if (!tabs.classList.contains('nav-tabs--open')) return;
// Aguarda Bootstrap atualizar a classe .active
setTimeout(function () { collapse(tabs); }, 50);
});
});
});
// Estado inicial e ao redimensionar
function applyState(matches) {
[].forEach.call(document.querySelectorAll('.nav-tabs'), function (tabs) {
tabs.classList.remove('nav-tabs--open');
[].forEach.call(tabs.querySelectorAll('.nav-item'), function (item) {
item.style.display = '';
});
if (matches) collapse(tabs);
});
}
applyState(mq.matches);
if (mq.addEventListener) {
mq.addEventListener('change', function (e) { applyState(e.matches); });
} else {
mq.addListener(function (e) { applyState(e.matches); });
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
}());
</script>
{% endblock extra_js %}

Loading…
Cancel
Save