You've already forked hotpocket
This commit is contained in:
215
services/backend/hotpocket_backend/apps/ui/forms/accounts.py
Normal file
215
services/backend/hotpocket_backend/apps/ui/forms/accounts.py
Normal file
@@ -0,0 +1,215 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from crispy_forms.bootstrap import FormActions
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Layout, Submit
|
||||
from django import forms
|
||||
from django.contrib.auth.forms import (
|
||||
AuthenticationForm as BaseAuthenticationForm,
|
||||
PasswordChangeForm as BasePasswordChangeForm,
|
||||
)
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .base import Form
|
||||
|
||||
|
||||
class LoginForm(BaseAuthenticationForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.helper = FormHelper(self)
|
||||
self.helper.attrs = {
|
||||
'id': self.__class__.__name__,
|
||||
'novalidate': '',
|
||||
}
|
||||
self.helper.layout = Layout(
|
||||
'username',
|
||||
'password',
|
||||
FormActions(
|
||||
Submit('submit', _('Log in'), css_class='btn btn-primary'),
|
||||
template='ui/ui/forms/formactions.html',
|
||||
css_class='mb-0',
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class ProfileForm(Form):
|
||||
INCLUDE_CANCEL = False
|
||||
|
||||
username = forms.CharField(
|
||||
label=_('Username'),
|
||||
disabled=True,
|
||||
required=False,
|
||||
)
|
||||
first_name = forms.CharField(
|
||||
label=_('First name'),
|
||||
max_length=150,
|
||||
required=True,
|
||||
)
|
||||
last_name = forms.CharField(
|
||||
label=_('Last name'),
|
||||
max_length=150,
|
||||
required=True,
|
||||
)
|
||||
email = forms.EmailField(
|
||||
label=_('E-mail address'),
|
||||
required=True,
|
||||
)
|
||||
|
||||
def get_layout_fields(self) -> list[str]:
|
||||
return [
|
||||
'username',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
]
|
||||
|
||||
|
||||
class FederatedProfileForm(ProfileForm):
|
||||
username = forms.CharField(
|
||||
label=_('Username'),
|
||||
disabled=True,
|
||||
required=False,
|
||||
)
|
||||
first_name = forms.CharField(
|
||||
label=_('First name'),
|
||||
disabled=True,
|
||||
required=False,
|
||||
)
|
||||
last_name = forms.CharField(
|
||||
label=_('Last name'),
|
||||
disabled=True,
|
||||
required=False,
|
||||
)
|
||||
email = forms.EmailField(
|
||||
label=_('E-mail address'),
|
||||
disabled=True,
|
||||
required=False,
|
||||
)
|
||||
|
||||
def get_submit_button(self) -> Submit:
|
||||
return Submit(
|
||||
'submit',
|
||||
_('Save'),
|
||||
css_class='btn btn-primary',
|
||||
disabled=True,
|
||||
)
|
||||
|
||||
def clean(self) -> dict:
|
||||
return {}
|
||||
|
||||
|
||||
class PasswordForm(BasePasswordChangeForm):
|
||||
def get_submit_button(self) -> Submit:
|
||||
return Submit(
|
||||
'submit',
|
||||
_('Save'),
|
||||
css_class='btn btn-primary',
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.helper = FormHelper(self)
|
||||
self.helper.form_class = 'form-horizontal'
|
||||
self.helper.label_class = 'col-md-3 col-form-label'
|
||||
self.helper.field_class = 'col-md-9'
|
||||
self.helper.attrs = {
|
||||
'id': self.__class__.__name__,
|
||||
'novalidate': '',
|
||||
}
|
||||
self.helper.layout = Layout(
|
||||
'old_password',
|
||||
'new_password1',
|
||||
'new_password2',
|
||||
FormActions(
|
||||
self.get_submit_button(),
|
||||
template='ui/ui/forms/formactions-horizontal.html',
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class FederatedPasswordForm(PasswordForm):
|
||||
current_password = forms.CharField(
|
||||
label=_('Old password'),
|
||||
disabled=True,
|
||||
required=False,
|
||||
)
|
||||
new_password = forms.CharField(
|
||||
label=_('New password'),
|
||||
disabled=True,
|
||||
required=False,
|
||||
)
|
||||
new_password_again = forms.CharField(
|
||||
label=_('New password confirmation'),
|
||||
disabled=True,
|
||||
required=False,
|
||||
)
|
||||
|
||||
def get_submit_button(self) -> Submit:
|
||||
return Submit(
|
||||
'submit',
|
||||
_('Save'),
|
||||
css_class='btn btn-primary disable',
|
||||
disabled=True,
|
||||
)
|
||||
|
||||
def clean(self) -> dict:
|
||||
return {}
|
||||
|
||||
|
||||
class SettingsForm(Form):
|
||||
INCLUDE_CANCEL = False
|
||||
|
||||
theme = forms.ChoiceField(
|
||||
label=_('Theme'),
|
||||
disabled=True,
|
||||
required=False,
|
||||
choices=[
|
||||
(None, _('Bootstrap')),
|
||||
('cosmo', _('Cosmo')),
|
||||
],
|
||||
show_hidden_initial=True,
|
||||
)
|
||||
auto_load_embeds = forms.ChoiceField(
|
||||
label=_('Auto load embedded content'),
|
||||
required=False,
|
||||
choices=[
|
||||
(None, _('---')),
|
||||
(True, _('Yes')),
|
||||
(False, _('No')),
|
||||
],
|
||||
help_text=_((
|
||||
'Auto loading embedded content (e.g. YouTube videos) means that '
|
||||
'you allow cookies from these sites.'
|
||||
)),
|
||||
)
|
||||
|
||||
def get_layout_fields(self) -> list[str]:
|
||||
return [
|
||||
'theme',
|
||||
'auto_load_embeds',
|
||||
]
|
||||
|
||||
def get_submit_button(self) -> Submit:
|
||||
return Submit(
|
||||
'submit',
|
||||
_('Save'),
|
||||
css_class='btn btn-primary',
|
||||
)
|
||||
|
||||
def clean(self) -> dict:
|
||||
result = super().clean()
|
||||
|
||||
theme = result.get('theme', None)
|
||||
if not theme:
|
||||
result['theme'] = None
|
||||
|
||||
auto_load_embeds = result.get('auto_load_embeds', None)
|
||||
if not auto_load_embeds:
|
||||
result['auto_load_embeds'] = None
|
||||
else:
|
||||
result['auto_load_embeds'] = (auto_load_embeds == 'True')
|
||||
|
||||
return result
|
||||
@@ -0,0 +1,95 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from crispy_forms.layout import Submit
|
||||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .base import Form
|
||||
|
||||
|
||||
class AssociationForm(Form):
|
||||
pass
|
||||
|
||||
|
||||
class ConfirmationForm(AssociationForm):
|
||||
canhazconfirm = forms.CharField(
|
||||
label='',
|
||||
required=True,
|
||||
widget=forms.HiddenInput,
|
||||
)
|
||||
title = forms.CharField(
|
||||
label=_('Title'),
|
||||
required=False,
|
||||
disabled=True,
|
||||
show_hidden_initial=True,
|
||||
)
|
||||
url = forms.CharField(
|
||||
label=_('URL'),
|
||||
required=False,
|
||||
disabled=True,
|
||||
show_hidden_initial=True,
|
||||
)
|
||||
|
||||
def get_layout_fields(self) -> list[str]:
|
||||
return [
|
||||
'canhazconfirm',
|
||||
'title',
|
||||
'url',
|
||||
]
|
||||
|
||||
def get_submit_button(self) -> Submit:
|
||||
return Submit('submit', _('Confirm'), css_class='btn btn-primary')
|
||||
|
||||
|
||||
class EditForm(AssociationForm):
|
||||
url = forms.CharField(
|
||||
label=_('URL'),
|
||||
required=False,
|
||||
disabled=True,
|
||||
show_hidden_initial=True,
|
||||
)
|
||||
target_title = forms.CharField(
|
||||
label=_('Title'),
|
||||
required=False,
|
||||
)
|
||||
target_description = forms.CharField(
|
||||
label=_('Description'),
|
||||
required=False,
|
||||
widget=forms.Textarea,
|
||||
)
|
||||
|
||||
def get_layout_fields(self) -> list[str]:
|
||||
return [
|
||||
'url',
|
||||
'target_title',
|
||||
'target_description',
|
||||
]
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
|
||||
result = {}
|
||||
|
||||
if cleaned_data['target_title']:
|
||||
result['target_title'] = cleaned_data['target_title']
|
||||
|
||||
if cleaned_data['target_description']:
|
||||
result['target_description'] = cleaned_data['target_description']
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class RefreshForm(ConfirmationForm):
|
||||
def get_submit_button(self) -> Submit:
|
||||
return Submit('submit', _('Refresh'), css_class='btn btn-warning')
|
||||
|
||||
|
||||
class ArchiveForm(ConfirmationForm):
|
||||
def get_submit_button(self) -> Submit:
|
||||
return Submit('submit', _('Archive'), css_class='btn btn-danger')
|
||||
|
||||
|
||||
class DeleteForm(ConfirmationForm):
|
||||
def get_submit_button(self) -> Submit:
|
||||
return Submit('submit', _('Delete'), css_class='btn btn-danger')
|
||||
63
services/backend/hotpocket_backend/apps/ui/forms/base.py
Normal file
63
services/backend/hotpocket_backend/apps/ui/forms/base.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import typing
|
||||
|
||||
from crispy_forms.bootstrap import FormActions
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Layout, Submit
|
||||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .layout import CancelButton
|
||||
|
||||
|
||||
class Form(forms.Form):
|
||||
HORIZONTAL = True
|
||||
INCLUDE_CANCEL = True
|
||||
|
||||
def get_layout_fields(self) -> list[str]:
|
||||
return []
|
||||
|
||||
def get_submit_button(self) -> Submit:
|
||||
return Submit('submit', _('Save'), css_class='btn btn-primary')
|
||||
|
||||
def get_extra_actions(self) -> typing.Any:
|
||||
result = []
|
||||
|
||||
if self.INCLUDE_CANCEL is True:
|
||||
result.append(CancelButton(_('Cancel')))
|
||||
|
||||
return result
|
||||
|
||||
def get_form_actions_template(self) -> str:
|
||||
if self.HORIZONTAL is True:
|
||||
return 'ui/ui/forms/formactions-horizontal.html'
|
||||
|
||||
return 'ui/ui/forms/formactions.html'
|
||||
|
||||
def get_form_helper_form_class(self) -> str:
|
||||
if self.HORIZONTAL is True:
|
||||
return 'form-horizontal'
|
||||
|
||||
return ''
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.helper = FormHelper(self)
|
||||
self.helper.form_class = self.get_form_helper_form_class()
|
||||
self.helper.label_class = 'col-md-3 col-form-label'
|
||||
self.helper.field_class = 'col-md-9'
|
||||
self.helper.attrs = {
|
||||
'id': self.__class__.__name__,
|
||||
'novalidate': '',
|
||||
}
|
||||
self.helper.layout = Layout(
|
||||
*self.get_layout_fields(),
|
||||
FormActions(
|
||||
self.get_submit_button(),
|
||||
*self.get_extra_actions(),
|
||||
template=self.get_form_actions_template(),
|
||||
),
|
||||
)
|
||||
21
services/backend/hotpocket_backend/apps/ui/forms/imports.py
Normal file
21
services/backend/hotpocket_backend/apps/ui/forms/imports.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from crispy_forms.layout import Submit
|
||||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .base import Form
|
||||
|
||||
|
||||
class PocketImportForm(Form):
|
||||
csv = forms.FileField(
|
||||
label=_('Export CSV'),
|
||||
required=True,
|
||||
)
|
||||
|
||||
def get_layout_fields(self) -> list[str]:
|
||||
return ['csv']
|
||||
|
||||
def get_submit_button(self) -> Submit:
|
||||
return Submit('submit', _('Import'), css_class='btn btn-primary')
|
||||
41
services/backend/hotpocket_backend/apps/ui/forms/layout.py
Normal file
41
services/backend/hotpocket_backend/apps/ui/forms/layout.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from crispy_forms.utils import TEMPLATE_PACK
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
|
||||
class CancelButton:
|
||||
CSS_CLASS = 'btn btn-secondary ui-form-cancel-button'
|
||||
|
||||
def __init__(self,
|
||||
label: str,
|
||||
*,
|
||||
css_id: str | None = None,
|
||||
css_class: str | None = None,
|
||||
**attributes,
|
||||
):
|
||||
self.label = label
|
||||
self.css_id = css_id
|
||||
self.css_class = css_class
|
||||
self.attributes = attributes
|
||||
|
||||
def render(self, form, context, template_pack: TEMPLATE_PACK, **kwargs):
|
||||
final_attributes = {
|
||||
'class': self.css_class or self.CSS_CLASS,
|
||||
**self.attributes,
|
||||
'type': 'button',
|
||||
'value': self.label,
|
||||
}
|
||||
|
||||
if self.css_id:
|
||||
final_attributes['id'] = self.css_id
|
||||
|
||||
context = {
|
||||
'attributes': final_attributes,
|
||||
}
|
||||
|
||||
return render_to_string(
|
||||
'ui/ui/forms/cancel_button.html',
|
||||
context=context,
|
||||
)
|
||||
21
services/backend/hotpocket_backend/apps/ui/forms/saves.py
Normal file
21
services/backend/hotpocket_backend/apps/ui/forms/saves.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from django import forms
|
||||
from django.core import validators
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .base import Form
|
||||
|
||||
|
||||
class CreateForm(Form):
|
||||
url = forms.CharField(
|
||||
label=_('URL'),
|
||||
required=True,
|
||||
validators=[
|
||||
validators.URLValidator(schemes=['http', 'https']),
|
||||
],
|
||||
)
|
||||
|
||||
def get_layout_fields(self) -> list[str]:
|
||||
return ['url']
|
||||
Reference in New Issue
Block a user