341 lines
12 KiB
Python
341 lines
12 KiB
Python
# combo - content management system
|
|
# Copyright (C) 2014-2015 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from django import forms
|
|
from django.db.models.fields import BLANK_CHOICE_DASH
|
|
from django.utils.translation import gettext_lazy as _
|
|
from gadjo.forms.widgets import MultiSelectWidget
|
|
|
|
from combo.data.widgets import MultipleSelect2Widget
|
|
from combo.utils.forms import MultiSortWidget
|
|
|
|
from .models import (
|
|
WcsCardCell,
|
|
WcsCareFormsCell,
|
|
WcsCategoryCell,
|
|
WcsCurrentDraftsCell,
|
|
WcsCurrentFormsCell,
|
|
WcsFormCell,
|
|
WcsFormsOfCategoryCell,
|
|
)
|
|
from .utils import get_wcs_options, get_wcs_services
|
|
|
|
|
|
class WcsFormCellForm(forms.ModelForm):
|
|
class Meta:
|
|
model = WcsFormCell
|
|
fields = ('formdef_reference',)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
formdef_references = get_wcs_options('/api/formdefs/')
|
|
self.fields['formdef_reference'].widget = forms.Select(choices=formdef_references)
|
|
|
|
|
|
class WcsFormForLinkListCellForm(WcsFormCellForm):
|
|
class Meta:
|
|
model = WcsFormCell
|
|
fields = ('formdef_reference', 'extra_css_class')
|
|
|
|
|
|
class WcsCardCellForm(forms.ModelForm):
|
|
with_user = forms.BooleanField(
|
|
label=_('Restrict to cards accessible to the user'), required=False, initial=True
|
|
)
|
|
related_card_path = forms.ChoiceField(label=_('Card(s) to display'), required=False, initial='__all__')
|
|
|
|
class Meta:
|
|
model = WcsCardCell
|
|
fields = (
|
|
'carddef_reference',
|
|
'related_card_path',
|
|
'card_ids',
|
|
'only_for_user',
|
|
)
|
|
widgets = {
|
|
'card_ids': forms.TextInput(attrs={'class': 'text-wide'}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
instance = kwargs['instance']
|
|
initial = kwargs.pop('initial', {})
|
|
initial['with_user'] = not instance.without_user
|
|
super().__init__(initial=initial, *args, **kwargs)
|
|
card_models = get_wcs_options('/api/cards/@list', include_custom_views=True)
|
|
self.fields['carddef_reference'].widget = forms.Select(choices=card_models)
|
|
|
|
self.fields['related_card_path'].choices = [
|
|
('__all__', _('All cards')),
|
|
]
|
|
with_sub_slug = any(p.sub_slug for p in self.instance.page.get_parents_and_self())
|
|
if with_sub_slug:
|
|
self.fields['related_card_path'].choices += [
|
|
('--', _('Card whose identifier is in the URL')),
|
|
]
|
|
if not self.instance.card_ids and not self.instance.related_card_path:
|
|
self.initial['related_card_path'] = '--'
|
|
self.fields['related_card_path'].choices += self.instance.get_related_card_paths() + [
|
|
('', _('Template')),
|
|
]
|
|
self.fields['card_ids'].label = ''
|
|
self.fields['card_ids'].help_text = _('Card identifiers, separated by commas.')
|
|
|
|
def save(self, *args, **kwargs):
|
|
super().save(*args, **kwargs)
|
|
if self.instance.related_card_path:
|
|
self.instance.card_ids = ''
|
|
if self.instance.related_card_path == '--':
|
|
self.instance.related_card_path = ''
|
|
self.instance.without_user = not self.cleaned_data['with_user']
|
|
self.instance.save()
|
|
return self.instance
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
|
|
if not cleaned_data.get('related_card_path') and not cleaned_data.get('card_ids'):
|
|
self.add_error('card_ids', _('This field is required.'))
|
|
|
|
return cleaned_data
|
|
|
|
|
|
class WcsCardCellAppearanceBaseForm(forms.ModelForm):
|
|
def save(self, *args, **kwargs):
|
|
super().save(*args, **kwargs)
|
|
if self.instance.title_type != 'manual':
|
|
self.instance.custom_title = ''
|
|
self.instance.save()
|
|
return self.instance
|
|
|
|
|
|
class WcsCardCellDisplayForm(forms.ModelForm):
|
|
customize_display = forms.BooleanField(label=_('Customize display'), required=False)
|
|
filters = forms.MultipleChoiceField(label=_('Filters'), required=False, widget=MultiSelectWidget)
|
|
|
|
class Meta:
|
|
model = WcsCardCell
|
|
fields = (
|
|
'limit',
|
|
'filters',
|
|
'display_mode',
|
|
'custom_schema',
|
|
)
|
|
widgets = {
|
|
'custom_schema': forms.HiddenInput(),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
if kwargs.get('data'):
|
|
kwargs['data'] = kwargs['data'].copy() # QueryDict -> dict
|
|
# make sure there's a value for custom_schema as postgres.forms.jsonb
|
|
# would crash on None.
|
|
custom_schema_name = '%s-custom_schema' % kwargs.get('prefix')
|
|
if custom_schema_name not in kwargs['data']:
|
|
kwargs['data'][custom_schema_name] = '{}'
|
|
super().__init__(*args, **kwargs)
|
|
if callable(self.fields['custom_schema'].initial):
|
|
self.fields['custom_schema'].initial = {}
|
|
if self.instance.custom_schema:
|
|
self.initial['customize_display'] = True
|
|
self.initial['custom_schema'] = self.instance.get_custom_schema()
|
|
if not self.instance.cached_json:
|
|
del self.fields['customize_display']
|
|
del self.fields['custom_schema']
|
|
del self.fields['filters']
|
|
else:
|
|
choices = BLANK_CHOICE_DASH + [('status', _('Status'))]
|
|
self.fields['filters'].choices = choices + [
|
|
(x['varname'], x['label'])
|
|
for x in self.instance.cached_json['fields']
|
|
if x['type'] in ('item', 'items') and x.get('varname')
|
|
]
|
|
|
|
def save(self, *args, **kwargs):
|
|
super().save(*args, **kwargs)
|
|
if not self.cleaned_data.get('customize_display'):
|
|
self.instance.custom_schema = {}
|
|
self.instance.save()
|
|
return self.instance
|
|
|
|
|
|
class WcsCardCellFiltersForm(forms.Form):
|
|
def __init__(self, cell, card_objects):
|
|
super().__init__()
|
|
if not cell.cached_json:
|
|
return
|
|
|
|
for filter_id in cell.filters:
|
|
if filter_id == 'status' and 'workflow' in cell.cached_json:
|
|
options = [(x['id'], x['name']) for x in cell.cached_json['workflow']['statuses']]
|
|
self.fields[filter_id] = forms.MultipleChoiceField(
|
|
label=_('Status'), choices=options, widget=MultipleSelect2Widget
|
|
)
|
|
continue
|
|
|
|
field_schemas = [x for x in cell.cached_json['fields'] if x.get('varname') == filter_id]
|
|
if not field_schemas:
|
|
continue
|
|
field_schema = field_schemas[0]
|
|
|
|
options = {}
|
|
for card in card_objects:
|
|
value = card.get('fields', {}).get(filter_id + '_raw')
|
|
if not value:
|
|
continue
|
|
|
|
display_value = card['fields'][filter_id]
|
|
if field_schema['type'] == 'item':
|
|
options[value] = display_value
|
|
else:
|
|
for option_key, option_label in zip(value, display_value.split(', ')):
|
|
options[option_key] = option_label
|
|
|
|
self.fields[filter_id] = forms.MultipleChoiceField(
|
|
label=field_schema['label'],
|
|
choices=sorted(options.items(), key=lambda x: x[1]),
|
|
widget=MultipleSelect2Widget,
|
|
)
|
|
|
|
|
|
class WcsCategoryCellForm(forms.ModelForm):
|
|
class Meta:
|
|
model = WcsCategoryCell
|
|
fields = ('category_reference',)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
references = get_wcs_options('/api/categories/')
|
|
self.fields['category_reference'].widget = forms.Select(choices=references)
|
|
|
|
|
|
class WcsFormsOfCategoryCellForm(forms.ModelForm):
|
|
class Meta:
|
|
model = WcsFormsOfCategoryCell
|
|
fields = ('category_reference', 'ordering', 'manual_order', 'limit')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
references = get_wcs_options('/api/categories/')
|
|
formdef_references = get_wcs_options('/api/formdefs/', include_category_slug=True)
|
|
self.fields['ordering'].widget = forms.Select(
|
|
choices=self.fields['ordering'].choices, attrs={'class': 'ordering-select'}
|
|
)
|
|
self.fields['category_reference'].widget = forms.Select(
|
|
choices=references, attrs={'class': 'category-select'}
|
|
)
|
|
self.fields['manual_order'].widget = MultiSortWidget(choices=formdef_references)
|
|
|
|
|
|
class WcsFormsMixin:
|
|
def _init_wcs_site(self):
|
|
if len(get_wcs_services()) == 1:
|
|
self.fields['wcs_site'].widget = forms.HiddenInput()
|
|
else:
|
|
combo_wcs_sites = [('', _('All'))]
|
|
wcs_sites = [(x, y.get('title')) for x, y in get_wcs_services().items()]
|
|
wcs_sites.sort(key=lambda x: x[1])
|
|
combo_wcs_sites.extend(wcs_sites)
|
|
self.fields['wcs_site'].widget = forms.Select(
|
|
choices=combo_wcs_sites, attrs={'class': 'wcs-site-select'}
|
|
)
|
|
|
|
def _init_categories(self):
|
|
categories = get_wcs_options('/api/categories/')
|
|
self.fields['categories'] = forms.MultipleChoiceField(
|
|
choices=categories,
|
|
help_text=_('By default forms from all categories are displayed.'),
|
|
widget=forms.SelectMultiple(attrs={'class': 'categories-select'}),
|
|
initial=self.instance.categories.get('data') or [],
|
|
required=False,
|
|
)
|
|
if self.field_order:
|
|
self.order_fields(self.field_order)
|
|
|
|
def save(self, *args, **kwargs):
|
|
super().save(commit=False)
|
|
self.instance.categories = {'data': self.cleaned_data.get('categories') or []}
|
|
self.instance.save()
|
|
return self.instance
|
|
|
|
|
|
class WcsCurrentFormsCellForm(WcsFormsMixin, forms.ModelForm):
|
|
field_order = [
|
|
'wcs_site',
|
|
'categories',
|
|
'current_forms',
|
|
'done_forms',
|
|
'include_drafts',
|
|
'include_forms_user_can_access',
|
|
]
|
|
|
|
class Meta:
|
|
model = WcsCurrentFormsCell
|
|
fields = [
|
|
'wcs_site',
|
|
'current_forms',
|
|
'done_forms',
|
|
'include_drafts',
|
|
'include_forms_user_can_access',
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self._init_wcs_site()
|
|
self._init_categories()
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
|
|
if not cleaned_data.get('current_forms') and not cleaned_data.get('done_forms'):
|
|
raise forms.ValidationError(
|
|
_('Please choose at least one option among the following: Current Forms, Done Forms')
|
|
)
|
|
|
|
return cleaned_data
|
|
|
|
|
|
class WcsCurrentDraftsCellForm(WcsFormsMixin, forms.ModelForm):
|
|
class Meta:
|
|
model = WcsCurrentDraftsCell
|
|
fields = ['wcs_site']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self._init_wcs_site()
|
|
self._init_categories()
|
|
|
|
|
|
class WcsCareFormsCellForm(WcsFormsMixin, forms.ModelForm):
|
|
class Meta:
|
|
model = WcsCareFormsCell
|
|
fields = ['wcs_site']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self._init_wcs_site()
|
|
self._init_categories()
|
|
|
|
|
|
class BackofficeSubmissionCellForm(WcsFormsMixin, forms.ModelForm):
|
|
class Meta:
|
|
model = WcsCurrentDraftsCell
|
|
fields = ['wcs_site']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self._init_wcs_site()
|
|
self._init_categories()
|