blocks: add/manage post conditions attribute (#71778)
gitea/wcs/pipeline/head This commit looks good Details

This commit is contained in:
Frédéric Péters 2024-03-12 08:07:51 +01:00
parent d2e44d9ecb
commit 0732ebb1d0
4 changed files with 65 additions and 48 deletions

View File

@ -26,6 +26,7 @@ from wcs.backoffice.deprecations import DeprecationsDirectory
from wcs.backoffice.snapshots import SnapshotsDirectory
from wcs.blocks import BlockDef, BlockdefImportError
from wcs.categories import BlockCategory
from wcs.fields.page import PostConditionsTableWidget
from wcs.formdef import UpdateStatisticsDataAfterJob
from wcs.qommon import _, misc, template
from wcs.qommon.errors import AccessForbiddenError, TraversalError
@ -113,7 +114,7 @@ class BlockDirectory(FieldsDirectory):
r += htmltext('<li><a href="export">%s</a></li>') % _('Export')
r += htmltext('<li><a href="delete" rel="popup">%s</a></li>') % _('Delete')
r += htmltext('</ul>')
r += htmltext('<a href="settings" rel="popup" role="button">%s</a>') % _('Settings')
r += htmltext('<a href="settings" role="button">%s</a>') % _('Settings')
r += htmltext('</span>')
r += htmltext('</div>')
r += utils.last_modification_block(obj=self.objectdef)
@ -294,6 +295,13 @@ class BlockDirectory(FieldsDirectory):
size=50,
hint=_('Use block_var_... to refer to fields.'),
)
form.add(
PostConditionsTableWidget,
'post_conditions',
title=_('Validation conditions'),
value=self.objectdef.post_conditions,
)
if not self.objectdef.is_readonly():
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
@ -311,6 +319,7 @@ class BlockDirectory(FieldsDirectory):
form.get_widget('slug').set_error(_('This identifier is already used.'))
if form.get_widget('category_id'):
self.objectdef.category_id = form.get_widget('category_id').parse()
self.objectdef.post_conditions = form.get_widget('post_conditions').parse()
widget_template = form.get_widget('digest_template')
if widget_template.parse() and 'form_var_' in widget_template.parse():
widget_template.set_error(

View File

@ -33,6 +33,7 @@ from .qommon.form import CompositeWidget, SingleSelectHintWidget, WidgetList
from .qommon.storage import Equal, StorableObject
from .qommon.substitution import CompatibilityNamesDict
from .qommon.template import Template
from .qommon.xml_storage import PostConditionsXmlMixin
class BlockdefImportError(Exception):
@ -46,7 +47,7 @@ class BlockdefImportUnknownReferencedError(UnknownReferencedErrorMixin, Blockdef
pass
class BlockDef(StorableObject):
class BlockDef(StorableObject, PostConditionsXmlMixin):
_names = 'blockdefs'
_indexes = ['slug']
backoffice_class = 'wcs.admin.blocks.BlockDirectory'
@ -60,6 +61,7 @@ class BlockDef(StorableObject):
fields = None
digest_template = None
category_id = None
post_conditions = None
SLUG_DASH = '_'
@ -176,6 +178,8 @@ class BlockDef(StorableObject):
for field in self.fields or []:
fields.append(field.export_to_xml(include_id=True))
self.post_conditions_export_to_xml(root, include_id=include_id)
return root
@classmethod
@ -237,6 +241,9 @@ class BlockDef(StorableObject):
BlockCategory.object_category_xml_import(blockdef, tree, include_id=include_id)
post_conditions_node = tree.find('post_conditions')
blockdef.post_conditions_init_with_xml(post_conditions_node, include_id=include_id)
unknown_datasources = set()
if check_datasources:
from wcs.carddef import CardDef

View File

@ -15,16 +15,15 @@
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import copy
import xml.etree.ElementTree as ET
from django.utils.encoding import force_str
from quixote import get_publisher
from quixote.html import TemplateIO, htmltext
from wcs.conditions import Condition
from wcs.qommon import _
from wcs.qommon.form import CompositeWidget, ConditionWidget, StringWidget, VarnameWidget, WidgetListAsTable
from wcs.qommon.misc import get_dependencies_from_template, xml_node_text
from wcs.qommon.misc import get_dependencies_from_template
from wcs.qommon.xml_storage import PostConditionsXmlMixin
from .base import Field, register_field_class
@ -138,55 +137,13 @@ class PageCondition(Condition):
return data
class PageField(Field):
class PageField(Field, PostConditionsXmlMixin):
key = 'page'
description = _('Page')
is_no_data_field = True
post_conditions = None
def post_conditions_init_with_xml(self, node, include_id=False, snapshot=False):
if node is None:
return
self.post_conditions = []
for post_condition_node in node.findall('post_condition'):
if post_condition_node.findall('condition/type'):
condition = {
'type': xml_node_text(post_condition_node.find('condition/type')),
'value': xml_node_text(post_condition_node.find('condition/value')),
}
elif post_condition_node.find('condition').text:
condition = {
'type': 'python',
'value': xml_node_text(post_condition_node.find('condition')),
}
else:
continue
self.post_conditions.append(
{
'condition': condition,
'error_message': xml_node_text(post_condition_node.find('error_message')),
}
)
def post_conditions_export_to_xml(self, node, include_id=False):
if not self.post_conditions:
return
conditions_node = ET.SubElement(node, 'post_conditions')
for post_condition in self.post_conditions:
post_condition_node = ET.SubElement(conditions_node, 'post_condition')
condition_node = ET.SubElement(post_condition_node, 'condition')
ET.SubElement(condition_node, 'type').text = force_str(
(post_condition['condition'] or {}).get('type') or ''
)
ET.SubElement(condition_node, 'value').text = force_str(
(post_condition['condition'] or {}).get('value') or ''
)
ET.SubElement(post_condition_node, 'error_message').text = force_str(
post_condition['error_message'] or ''
)
def fill_admin_form(self, form):
form.add(StringWidget, 'label', title=_('Label'), value=self.label, required=True, size=50)
form.add(

View File

@ -156,3 +156,47 @@ class XmlStorableObject(StorableObject):
return get_publisher().role_class.select([Or(criterias)], order_by='name')
return lazy_roles
class PostConditionsXmlMixin:
def post_conditions_init_with_xml(self, node, include_id=False, snapshot=False):
if node is None:
return
self.post_conditions = []
for post_condition_node in node.findall('post_condition'):
if post_condition_node.findall('condition/type'):
condition = {
'type': xml_node_text(post_condition_node.find('condition/type')),
'value': xml_node_text(post_condition_node.find('condition/value')),
}
elif post_condition_node.find('condition').text:
condition = {
'type': 'python',
'value': xml_node_text(post_condition_node.find('condition')),
}
else:
continue
self.post_conditions.append(
{
'condition': condition,
'error_message': xml_node_text(post_condition_node.find('error_message')),
}
)
def post_conditions_export_to_xml(self, node, include_id=False):
if not self.post_conditions:
return
conditions_node = ET.SubElement(node, 'post_conditions')
for post_condition in self.post_conditions:
post_condition_node = ET.SubElement(conditions_node, 'post_condition')
condition_node = ET.SubElement(post_condition_node, 'condition')
ET.SubElement(condition_node, 'type').text = str(
(post_condition['condition'] or {}).get('type') or ''
)
ET.SubElement(condition_node, 'value').text = str(
(post_condition['condition'] or {}).get('value') or ''
)
ET.SubElement(post_condition_node, 'error_message').text = str(
post_condition['error_message'] or ''
)