150 lines
5.2 KiB
Python
150 lines
5.2 KiB
Python
from django import forms
|
|
from django.contrib.auth.models import User
|
|
from django.utils.translation import gettext_lazy as _
|
|
from common.models import UserConfig
|
|
|
|
from .models import Notification, Team
|
|
|
|
|
|
class MultipleFileInput(forms.FileInput):
|
|
"""Widget FileInput autorisant la sélection de plusieurs fichiers."""
|
|
allow_multiple_selected = True
|
|
|
|
def __init__(self, attrs=None):
|
|
super().__init__(attrs={'multiple': True, 'class': 'form-control', **(attrs or {})})
|
|
|
|
|
|
class MultipleFileField(forms.FileField):
|
|
"""Champ fichier acceptant plusieurs fichiers."""
|
|
widget = MultipleFileInput
|
|
|
|
def clean(self, data, initial=None):
|
|
# data may be a list (multiple files) or a single file
|
|
if not data:
|
|
return []
|
|
if not isinstance(data, list):
|
|
data = [data]
|
|
return [super(MultipleFileField, self).clean(d, initial) for d in data]
|
|
|
|
|
|
class NotificationCreateForm(forms.Form):
|
|
"""Formulaire de création manuelle d'une notification."""
|
|
|
|
title = forms.CharField(
|
|
max_length=255,
|
|
label=_("Titre"),
|
|
widget=forms.TextInput(attrs={'class': 'form-control'}),
|
|
)
|
|
content = forms.CharField(
|
|
required=False,
|
|
label=_("Contenu"),
|
|
widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4}),
|
|
)
|
|
notification_type = forms.ChoiceField(
|
|
choices=Notification.TYPES,
|
|
initial=Notification.TYPE_MESSAGE,
|
|
label=_("Type"),
|
|
widget=forms.Select(attrs={'class': 'form-select'}),
|
|
)
|
|
action_url = forms.CharField(
|
|
required=False,
|
|
max_length=500,
|
|
label=_("Lien d'action (URL)"),
|
|
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '/example/path/'}),
|
|
)
|
|
action_label = forms.CharField(
|
|
required=False,
|
|
max_length=100,
|
|
label=_("Libellé du lien"),
|
|
widget=forms.TextInput(attrs={'class': 'form-control'}),
|
|
)
|
|
expires_at = forms.DateTimeField(
|
|
required=False,
|
|
label=_("Expire le"),
|
|
widget=forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}),
|
|
)
|
|
attachments = MultipleFileField(
|
|
required=False,
|
|
label=_("Pièces jointes"),
|
|
help_text=_("Photos ou documents (plusieurs fichiers possibles)."),
|
|
)
|
|
|
|
# Recipients
|
|
recipient_users = forms.ModelMultipleChoiceField(
|
|
queryset=User.objects.filter(is_active=True).order_by('first_name', 'last_name', 'username'),
|
|
required=False,
|
|
label=_("Destinataires individuels"),
|
|
widget=forms.SelectMultiple(attrs={'class': 'form-select', 'size': '6'}),
|
|
)
|
|
recipient_teams = forms.ModelMultipleChoiceField(
|
|
queryset=Team.objects.all(),
|
|
required=False,
|
|
label=_("Équipes destinataires"),
|
|
widget=forms.SelectMultiple(attrs={'class': 'form-select', 'size': '4'}),
|
|
)
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
users = cleaned_data.get('recipient_users')
|
|
teams = cleaned_data.get('recipient_teams')
|
|
if not users and not teams:
|
|
raise forms.ValidationError(
|
|
_("Veuillez sélectionner au moins un destinataire ou une équipe.")
|
|
)
|
|
return cleaned_data
|
|
|
|
|
|
class TeamForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Team
|
|
fields = ['name', 'description', 'members']
|
|
widgets = {
|
|
'name': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
|
|
'members': forms.SelectMultiple(attrs={'class': 'form-select', 'size': '8'}),
|
|
}
|
|
|
|
|
|
class NotificationReminderSettingsForm(forms.ModelForm):
|
|
class Meta:
|
|
model = UserConfig
|
|
fields = [
|
|
'notification_reminder_enabled',
|
|
'notification_reminder_emails',
|
|
'notification_reminder_delay_hours',
|
|
]
|
|
widgets = {
|
|
'notification_reminder_enabled': forms.CheckboxInput(
|
|
attrs={'class': 'form-check-input', 'role': 'switch'}
|
|
),
|
|
'notification_reminder_emails': forms.TextInput(
|
|
attrs={
|
|
'class': 'form-control rounded-3',
|
|
'placeholder': _("Ex: email1@exemple.com, email2@exemple.com"),
|
|
}
|
|
),
|
|
'notification_reminder_delay_hours': forms.NumberInput(
|
|
attrs={'class': 'form-control rounded-3', 'min': 1, 'max': 720}
|
|
),
|
|
}
|
|
|
|
def clean_notification_reminder_emails(self):
|
|
emails_raw = self.cleaned_data.get('notification_reminder_emails', '')
|
|
if not emails_raw:
|
|
return ''
|
|
import re
|
|
from django.core.validators import validate_email
|
|
from django.core.exceptions import ValidationError
|
|
|
|
cleaned_emails = []
|
|
for email in re.split(r'[;,]', emails_raw):
|
|
email = email.strip()
|
|
if email:
|
|
try:
|
|
validate_email(email)
|
|
cleaned_emails.append(email)
|
|
except ValidationError:
|
|
raise forms.ValidationError(
|
|
_("L'adresse e-mail '%(email)s' n'est pas valide.") % {'email': email}
|
|
)
|
|
return ', '.join(cleaned_emails)
|