class Meta: model = Global fields = ("name", "value") widgets = { "name": InputWidget(attrs={"name": _("Name"), "widget_only": False}), "value": InputWidget(attrs={"name": _("Value"), "widget_only": False, "textarea": True}), }
def customize_form_field(self, name, field): attrs = field.widget.attrs if field.widget.attrs else {} # don't replace the widget if it is already one of us if isinstance(field.widget, (forms.widgets.HiddenInput, CheckboxWidget, InputWidget, SelectWidget, SelectMultipleWidget)): return field if isinstance(field.widget, (forms.widgets.Textarea, )): attrs["textarea"] = True field.widget = InputWidget(attrs=attrs) elif isinstance( field.widget, (forms.widgets.PasswordInput, )): # pragma: needs cover attrs["password"] = True field.widget = InputWidget(attrs=attrs) elif isinstance( field.widget, (forms.widgets.TextInput, forms.widgets.EmailInput, forms.widgets.URLInput, forms.widgets.NumberInput), ): field.widget = InputWidget(attrs=attrs) elif isinstance(field.widget, (forms.widgets.Select, )): if isinstance(field, (forms.models.ModelMultipleChoiceField, )): field.widget = SelectMultipleWidget( attrs) # pragma: needs cover else: field.widget = SelectWidget(attrs) field.widget.choices = field.choices elif isinstance(field.widget, (forms.widgets.CheckboxInput, )): field.widget = CheckboxWidget(attrs) return field
class ExportForm(Form): LABEL_CHOICES = ((0, _("Just this label")), (1, _("All messages"))) SYSTEM_LABEL_CHOICES = ((0, _("Just this folder")), (1, _("All messages"))) export_all = forms.ChoiceField( choices=(), label=_("Selection"), initial=0, widget=SelectWidget(attrs={"widget_only": True}) ) start_date = forms.DateField( required=False, help_text=_("Leave blank for the oldest message"), widget=InputWidget(attrs={"datepicker": True, "hide_label": True, "placeholder": _("Start Date")}), ) end_date = forms.DateField( required=False, help_text=_("Leave blank for the latest message"), widget=InputWidget(attrs={"datepicker": True, "hide_label": True, "placeholder": _("End Date")}), ) groups = forms.ModelMultipleChoiceField( queryset=ContactGroup.user_groups.none(), required=False, label=_("Groups"), widget=SelectMultipleWidget( attrs={"widget_only": True, "placeholder": _("Optional: Choose groups to show in your export")} ), ) def __init__(self, user, label, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user self.fields["export_all"].choices = self.LABEL_CHOICES if label else self.SYSTEM_LABEL_CHOICES self.fields["groups"].queryset = ContactGroup.user_groups.filter(org=self.user.get_org(), is_active=True) self.fields["groups"].help_text = _( "Export only messages from these contact groups. " "(Leave blank to export all messages)." ) def clean(self): cleaned_data = super().clean() start_date = cleaned_data.get("start_date") end_date = cleaned_data.get("end_date") if start_date and start_date > date.today(): # pragma: needs cover raise forms.ValidationError(_("Start date can't be in the future.")) if end_date and start_date and end_date < start_date: # pragma: needs cover raise forms.ValidationError(_("End date can't be before start date")) return cleaned_data
class ScheduleForm(BaseScheduleForm, forms.ModelForm): repeat_period = forms.ChoiceField(choices=Schedule.REPEAT_CHOICES) repeat_days_of_week = forms.MultipleChoiceField( choices=Schedule.REPEAT_DAYS_CHOICES, label="Repeat Days", required=False, widget=SelectMultipleWidget( attrs=({ "placeholder": _("Select days to repeat on") })), ) start_datetime = forms.DateTimeField( required=False, label=_(" "), widget=InputWidget( attrs={ "datetimepicker": True, "placeholder": "Select a time to send the message" }), ) def __init__(self, org, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["start_datetime"].help_text = _("%s Time Zone" % org.timezone) def clean_repeat_days_of_week(self): return "".join(self.cleaned_data["repeat_days_of_week"]) class Meta: model = Schedule fields = "__all__"
class RegisterTriggerForm(BaseTriggerForm): """ Wizard form that creates keyword trigger which starts contacts in a newly created flow which adds them to a group """ class AddNewGroupChoiceField(forms.ModelChoiceField): def clean(self, value): if value.startswith("[_NEW_]"): # pragma: needs cover value = value[7:] # we must get groups for this org only group = ContactGroup.get_user_group_by_name( self.user.get_org(), value) if not group: group = ContactGroup.create_static(self.user.get_org(), self.user, name=value) return group return super().clean(value) keyword = forms.CharField( max_length=16, required=True, help_text=_("The first word of the message text"), widget=InputWidget()) action_join_group = AddNewGroupChoiceField( ContactGroup.user_groups.filter(pk__lt=0), required=True, label=_("Group to Join"), help_text=_( "The group the contact will join when they send the above keyword" ), widget=SelectWidget(), ) response = forms.CharField( widget=CompletionTextarea( attrs={"placeholder": _("Hi @contact.name!")}), required=False, label=_("Response"), help_text= _("The message to send in response after they join the group (optional)" ), ) def __init__(self, user, *args, **kwargs): flows = Flow.get_triggerable_flows(user.get_org()) super().__init__(user, flows, *args, **kwargs) self.fields["flow"].required = False group_field = self.fields["action_join_group"] group_field.queryset = ContactGroup.user_groups.filter( org=self.user.get_org(), is_active=True).order_by("name") group_field.user = user class Meta(BaseTriggerForm.Meta): fields = ("keyword", "action_join_group", "response", "flow")
class RegisterTriggerForm(BaseTriggerForm): """ Wizard form that creates keyword trigger which starts contacts in a newly created flow which adds them to a group """ class AddNewGroupChoiceField(TembaChoiceField): def clean(self, value): if value.startswith("[_NEW_]"): # pragma: needs cover value = value[7:] # we must get groups for this org only group = ContactGroup.get_user_group_by_name(self.user.get_org(), value) if not group: group = ContactGroup.create_static(self.user.get_org(), self.user, name=value) return group return super().clean(value) keyword = forms.CharField( max_length=16, required=True, label=_("Join Keyword"), help_text=_("The first word of the message"), widget=InputWidget(), ) action_join_group = AddNewGroupChoiceField( ContactGroup.user_groups.none(), required=True, label=_("Group to Join"), help_text=_("The group the contact will join when they send the above keyword"), widget=SelectWidget(), ) response = forms.CharField( widget=CompletionTextarea(attrs={"placeholder": _("Hi @contact.name!")}), required=False, label=ngettext_lazy("Response", "Responses", 1), help_text=_("The message to send in response after they join the group (optional)"), ) def __init__(self, user, *args, **kwargs): super().__init__(user, Trigger.TYPE_KEYWORD, *args, **kwargs) # on this form flow becomes the flow to be triggered from the generated flow and is optional self.fields["flow"].required = False self.fields["action_join_group"].queryset = ContactGroup.user_groups.filter( org=self.org, is_active=True ).order_by("name") self.fields["action_join_group"].user = user def get_conflicts_kwargs(self, cleaned_data): kwargs = super().get_conflicts_kwargs(cleaned_data) kwargs["keyword"] = cleaned_data.get("keyword") or "" return kwargs class Meta(BaseTriggerForm.Meta): fields = ("keyword", "action_join_group", "response") + BaseTriggerForm.Meta.fields
class FolderForm(BaseLabelForm): name = forms.CharField( label=_("Name"), help_text=_("Choose a name for your folder"), widget=InputWidget(attrs={"widget_only": False}) ) def __init__(self, *args, **kwargs): self.org = kwargs.pop("org") self.existing = kwargs.pop("object", None) super().__init__(*args, **kwargs)
class NoteForm(forms.ModelForm): note = forms.CharField( max_length=2048, required=True, widget=InputWidget({"hide_label": True, "textarea": True}), help_text=_("Notes can only be seen by the support team"), ) class Meta: model = Ticket fields = ("note",)
class ScheduleFormMixin(forms.Form): start_datetime = forms.DateTimeField( label=_("Start Time"), widget=InputWidget(attrs={ "datetimepicker": True, "placeholder": _("Select a date and time") }), ) repeat_period = forms.ChoiceField(choices=Schedule.REPEAT_CHOICES, label=_("Repeat"), widget=SelectWidget()) repeat_days_of_week = forms.MultipleChoiceField( choices=Schedule.REPEAT_DAYS_CHOICES, label=_("Repeat On Days"), help_text=_("The days of the week to repeat on for weekly schedules"), required=False, widget=SelectMultipleWidget(attrs=({ "placeholder": _("Select days") })), ) def set_user(self, user): """ Because this mixin is mixed with other forms it can't have a __init__ constructor that takes non standard Django forms args and kwargs, so we have to customize based on user after the form has been created. """ tz = user.get_org().timezone self.fields["start_datetime"].help_text = _( "First time this should happen in the %s timezone.") % tz def clean_repeat_days_of_week(self): value = self.cleaned_data["repeat_days_of_week"] # sort by Monday to Sunday value = sorted(value, key=lambda c: Schedule.DAYS_OF_WEEK_OFFSET.index(c)) return "".join(value) def clean(self): cleaned_data = super().clean() if self.is_valid(): if cleaned_data[ "repeat_period"] == Schedule.REPEAT_WEEKLY and not cleaned_data.get( "repeat_days_of_week"): self.add_error("repeat_days_of_week", _("Must specify at least one day of the week.")) return cleaned_data class Meta: fields = ("start_datetime", "repeat_period", "repeat_days_of_week")
class Meta: model = Label fields = "__all__" widgets = {"name": InputWidget()}
class Meta(BaseTriggerForm.Meta): fields = ("keyword", "match_type", "flow", "groups") widgets = {"keyword": InputWidget(), "match_type": SelectWidget()}
class Meta(BaseTriggerForm.Meta): fields = ("keyword", "match_type") + BaseTriggerForm.Meta.fields widgets = {"keyword": InputWidget(), "match_type": SelectWidget()}
class Meta: model = Campaign fields = ("name", "group") labels = {"name": _("Name")} widgets = {"name": InputWidget()}
class Meta: model = Global fields = ("value",) widgets = { "value": InputWidget(attrs={"name": _("Value"), "widget_only": False}), }
class ScheduleTriggerForm(BaseScheduleForm, forms.ModelForm): repeat_period = forms.ChoiceField(choices=Schedule.REPEAT_CHOICES, label="Repeat", required=False, widget=SelectWidget()) repeat_days_of_week = forms.MultipleChoiceField( choices=Schedule.REPEAT_DAYS_CHOICES, label="Repeat Days", required=False, widget=SelectMultipleWidget( attrs=({ "placeholder": _("Select days to repeat on") })), ) start_datetime = forms.DateTimeField( required=False, label=_("Start Time"), widget=InputWidget( attrs={ "datetimepicker": True, "placeholder": "Select a time to start the flow" }), ) flow = forms.ModelChoiceField( Flow.objects.filter(pk__lt=0), label=_("Flow"), required=True, widget=SelectWidget(attrs={ "placeholder": _("Select a flow"), "searchable": True }), empty_label=None, ) omnibox = JSONField( label=_("Contacts"), required=True, help_text=_("The groups and contacts the flow will be broadcast to"), widget=OmniboxChoice( attrs={ "placeholder": _("Recipients, enter contacts or groups"), "groups": True, "contacts": True }), ) def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user org = user.get_org() flows = Flow.get_triggerable_flows(org) self.fields["start_datetime"].help_text = _("%s Time Zone" % org.timezone) self.fields["flow"].queryset = flows def clean_repeat_days_of_week(self): return "".join(self.cleaned_data["repeat_days_of_week"]) def clean_omnibox(self): return omnibox_deserialize(self.user.get_org(), self.cleaned_data["omnibox"]) class Meta: model = Trigger fields = ("flow", "omnibox", "repeat_period", "repeat_days_of_week", "start_datetime")
class Meta: model = Campaign fields = ("name", "group") widgets = {"name": InputWidget()}
class Meta: model = CampaignEvent fields = "__all__" widgets = {"offset": InputWidget(attrs={"widget_only": True})}
class Meta: model = Label fields = ("name", ) labels = {"name": _("Name")} widgets = {"name": InputWidget()}