from urllib.parse import urlencode from django import forms from django.contrib import admin from django.urls import reverse from django.utils.functional import cached_property from django.utils.translation import ugettext as _ from wagtail.contrib.modeladmin.forms import ParentChooserForm from wagtail.contrib.modeladmin.helpers import PageAdminURLHelper, PageButtonHelper, ButtonHelper from wagtail.contrib.modeladmin.views import ChooseParentView from wagtail.core.models import Page class VerboseLabelModelChoiceField(forms.ModelChoiceField): def label_from_instance(str, obj): return '[{}] {}'.format(obj._meta.verbose_name, obj.title) class FundChooserForm(ParentChooserForm): """Changes the default chooser to be fund orientated """ parent_page = VerboseLabelModelChoiceField( label=_('Fund or RFP'), required=True, empty_label=None, queryset=Page.objects.none(), widget=forms.RadioSelect(), ) class RoundFundChooserView(ChooseParentView): def get_form(self, request): parents = self.permission_helper.get_valid_parent_pages(request.user).specific() return FundChooserForm(parents, request.POST or None) class ButtonsWithPreview(PageButtonHelper): def preview_button(self, obj, classnames_add, classnames_exclude): classnames = self.copy_button_classnames + classnames_add cn = self.finalise_classname(classnames, classnames_exclude) return { 'url': reverse('wagtailadmin_pages:view_draft', args=(obj.id,)), 'label': 'Preview', 'classname': cn, 'title': 'Preview this %s' % self.verbose_name, } def get_buttons_for_obj(self, obj, exclude=list(), classnames_add=list(), classnames_exclude=list()): btns = super().get_buttons_for_obj(obj, exclude, classnames_add, classnames_exclude) # Put preview before delete btns.insert(-1, self.preview_button(obj, classnames_add, classnames_exclude)) return btns class FormsFundRoundListFilter(admin.SimpleListFilter): title = 'usage' parameter_name = 'form-usage' def lookups(self, request, model_admin): return ( ('applicationbase', _('Funds & RFP')), ('roundbase', _('Rounds and Sealed Rounds')), ('labbase', _('Labs')), ) def queryset(self, request, queryset): value = self.value() if value: query = {f'{value}form__isnull': False} return queryset.filter(**query).distinct() return queryset class RoundStateListFilter(admin.SimpleListFilter): title = 'state' parameter_name = 'form-state' def lookups(self, request, model_admin): return ( ('open', _('Open')), ('closed', _('Closed')), ) def queryset(self, request, queryset): value = self.value() if value == 'open': return queryset.open() elif value == 'closed': return queryset.closed() return queryset class ApplicationFormButtonHelper(ButtonHelper): def prepare_classnames(self, start=None, add=None, exclude=None): """Parse classname sets into final css classess list.""" classnames = start or [] classnames.extend(add or []) return self.finalise_classname(classnames, exclude or []) def copy_form_button(self, pk, form_name, **kwargs): classnames = self.prepare_classnames( start=self.edit_button_classnames, add=kwargs.get('classnames_add'), exclude=kwargs.get('classnames_exclude') ) return { 'classname': classnames, 'label': f'Copy', 'title': f'Copy {form_name}', 'url': self.url_helper.get_action_url('copy_form', admin.utils.quote(pk)), } def get_buttons_for_obj(self, obj, exclude=None, *args, **kwargs): """Override the getting of buttons, appending copy form button.""" buttons = super().get_buttons_for_obj(obj, *args, **kwargs) copy_form_button = self.copy_form_button( pk=getattr(obj, self.opts.pk.attname), form_name=getattr(obj, 'name'), **kwargs ) buttons.append(copy_form_button) return buttons class RoundAdminURLHelper(PageAdminURLHelper): @cached_property def index_url(self): # By default set open filter for Round listing page's index URL params = {'form-state': 'open'} return f"{self.get_action_url('index')}?{urlencode(params)}"