Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 0 additions & 70 deletions core/middleware.py

This file was deleted.

16 changes: 13 additions & 3 deletions core/mixins.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
from django.urls import reverse_lazy
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.auth.mixins import PermissionRequiredMixin, AccessMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.utils.translation import gettext_lazy as _
from django.views.generic.edit import CreateView, DeleteView
from django.core.exceptions import ImproperlyConfigured
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.forms import inlineformset_factory


class SuperuserRequiredMixin(AccessMixin):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return self.handle_no_permission()
if not request.user.is_superuser:
raise PermissionDenied
return super().dispatch(request, *args, **kwargs)


class PageTitleMixin:
page_title = ""

Expand Down Expand Up @@ -46,9 +55,10 @@ def get_context_data(self, **kwargs):

class AutoPermissionRequiredMixin(PermissionRequiredMixin):
permission_action = "view"
permission_required = None

def get_permission_required(self):
if not self.permission_required:
if self.permission_required is None:
model = getattr(self, "model", None)
if model is None and hasattr(self, "get_queryset"):
model = self.get_queryset().model
Expand Down
15 changes: 13 additions & 2 deletions core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,22 @@ def get_fields(self):
no_check = not isinstance(self.fields, (list, tuple))
for field in self.object._meta.fields:
if no_check or field.name in self.fields:
value = getattr(self.object, field.name)
safe = field.name in self.safe_fields

# Format boolean fields with badges
if field.get_internal_type() == "BooleanField":
if value:
value = '<span class="badge bg-success"><i class="bi bi-check-circle"></i> Sim</span>'
else:
value = '<span class="badge bg-secondary"><i class="bi bi-x-circle"></i> Não</span>'
safe = True

selected_fields.append(
{
"label": field.verbose_name,
"value": getattr(self.object, field.name),
"safe": True if field.name in self.safe_fields else False,
"value": value,
"safe": safe,
}
)
return selected_fields
Expand Down
34 changes: 34 additions & 0 deletions presente/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,27 @@


class ActivityFilter(django_filters.FilterSet):
STATUS_CHOICES = [
("", "---------"),
("active", _("Ativa")),
("not_started", _("Não Iniciada")),
("expired", _("Encerrada")),
("not_enabled", _("Desabilitada")),
]

title = django_filters.CharFilter(
lookup_expr="icontains",
label=_("Título"),
widget=forms.TextInput(attrs={"class": "form-control"}),
)
status = django_filters.ChoiceFilter(
choices=STATUS_CHOICES,
label=_("Status"),
method="filter_status",
widget=forms.Select(
attrs={"class": "form-select", "data-tom-select": "simple"}
),
)
tags = django_filters.ModelChoiceFilter(
queryset=Tag.objects.all(),
label=_("Tags"),
Expand All @@ -35,10 +51,28 @@ class ActivityFilter(django_filters.FilterSet):
widget=forms.DateInput(attrs={"class": "form-control", "type": "date"}),
)

def filter_status(self, queryset, name, value):
from django.utils import timezone

now = timezone.now()

if value == "active":
return queryset.filter(
start_time__lte=now, end_time__gte=now, is_enabled=True
)
elif value == "not_started":
return queryset.filter(start_time__gt=now)
elif value == "expired":
return queryset.filter(end_time__lt=now)
elif value == "not_enabled":
return queryset.filter(is_enabled=False)
return queryset

class Meta:
model = Activity
fields = [
"title",
"status",
"tags",
"start_time__gte",
"start_time__lte",
Expand Down
5 changes: 4 additions & 1 deletion presente/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class Meta:
"end_time",
"qr_timeout",
"restrict_ip",
"is_enabled",
"allowed_networks",
"owners",
]
Expand All @@ -52,8 +53,9 @@ class Meta:
format="%Y-%m-%dT%H:%M",
),
"qr_timeout": forms.NumberInput(
attrs={"class": "form-control", "min": "10"}
attrs={"class": "form-control", "min": "0"}
),
"is_enabled": forms.CheckboxInput(attrs={"class": "form-check-input"}),
"restrict_ip": forms.CheckboxInput(attrs={"class": "form-check-input"}),
"allowed_networks": forms.CheckboxSelectMultiple(
attrs={"class": "form-check-input"}
Expand Down Expand Up @@ -93,6 +95,7 @@ def __init__(self, *args, **kwargs):
"start_time",
"end_time",
"qr_timeout",
"is_enabled",
"restrict_ip",
"allowed_networks",
"owners",
Expand Down
6 changes: 3 additions & 3 deletions presente/menus.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"presente",
MenuItem(
"Minhas Atividades",
reverse("presente:my_activities"),
reverse("presente:activity_list"),
icon="bi bi-list-check",
check=lambda r: r.user.has_perm("presente.view_activity"),
),
Expand All @@ -36,7 +36,7 @@
"presente",
MenuItem(
"Atividades",
reverse("presente:activity_list"),
reverse("presente:admin_activities"),
icon="bi bi-list-check",
check=lambda r: r.user.is_superuser,
),
Expand All @@ -48,6 +48,6 @@
"Usuários",
reverse("users:user_list"),
icon="bi bi-person",
check=lambda r: r.user.has_perm("users.view_user"),
check=lambda r: r.user.is_superuser,
),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 5.2.7 on 2025-11-29 23:45

from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('presente', '0012_remove_is_published'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.AddField(
model_name='activity',
name='is_enabled',
field=models.BooleanField(default=True, verbose_name='Habilitar?'),
),
migrations.AlterField(
model_name='activity',
name='owners',
field=models.ManyToManyField(related_name='owned_activities', to=settings.AUTH_USER_MODEL, verbose_name='Responsáveis'),
),
migrations.AlterField(
model_name='activity',
name='qr_timeout',
field=models.IntegerField(default=0, help_text='Tempo de validade de cada QR Code para registro de presença (em segundos). Use "0" para desabilitar.', verbose_name='Timeout do QR Code (segundos)'),
),
]
18 changes: 18 additions & 0 deletions presente/migrations/0014_alter_activity_is_enabled.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.2.7 on 2025-11-30 03:34

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('presente', '0013_activity_is_enabled_alter_activity_owners_and_more'),
]

operations = [
migrations.AlterField(
model_name='activity',
name='is_enabled',
field=models.BooleanField(default=True, help_text='Habilitar o registro de presença.', verbose_name='Habilitar?'),
),
]
Loading