general: expand blocks in form_details (#44804)
gitea/wcs/pipeline/head This commit looks good
Details
gitea/wcs/pipeline/head This commit looks good
Details
This commit is contained in:
parent
aa070498e4
commit
0c7f2ea925
|
@ -1648,14 +1648,12 @@ def test_block_card_item_link(pub):
|
|||
# check cards are links in backoffice
|
||||
resp = app.get('/backoffice/management' + resp.request.path)
|
||||
assert (
|
||||
'<div class="value"><a href="http://example.net/backoffice/data/foo/%s/">card plop</a></div></div>'
|
||||
% card.id
|
||||
in resp
|
||||
resp.pyquery('div.value > a[href="http://example.net/backoffice/data/foo/%s/"]' % card.id).text()
|
||||
== 'card plop'
|
||||
)
|
||||
assert (
|
||||
'<div class="value"><a href="http://example.net/backoffice/data/foo/%s/">card plop2</a></div></div>'
|
||||
% card2.id
|
||||
in resp
|
||||
resp.pyquery('div.value > a[href="http://example.net/backoffice/data/foo/%s/"]' % card2.id).text()
|
||||
== 'card plop2'
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1741,10 +1741,10 @@ def test_block_subfields_display_locations(pub):
|
|||
block = BlockDef()
|
||||
block.name = 'foobar'
|
||||
block.fields = [
|
||||
fields.StringField(id='123', required=True, label='Test'),
|
||||
fields.TitleField(id='234', label='Blah Title'),
|
||||
fields.SubtitleField(id='345', label='Blah Subtitle'),
|
||||
fields.CommentField(id='456', label='Blah Comment'),
|
||||
fields.StringField(id='123', required=True, label='Test'),
|
||||
]
|
||||
block.store()
|
||||
|
||||
|
@ -1849,7 +1849,6 @@ def test_block_block_counter(pub):
|
|||
block = BlockDef()
|
||||
block.name = 'foobar'
|
||||
block.fields = [
|
||||
fields.StringField(id='123', required=True, label='Test'),
|
||||
fields.TitleField(
|
||||
id='234', label='Blah Title #{{ block_counter.index }} #{{ block_counter.index0 }}'
|
||||
),
|
||||
|
@ -1859,6 +1858,7 @@ def test_block_block_counter(pub):
|
|||
fields.CommentField(
|
||||
id='456', label='Blah Comment #{{ block_counter.index }} #{{ block_counter.index0 }}'
|
||||
),
|
||||
fields.StringField(id='123', required=True, label='Test'),
|
||||
]
|
||||
block.store()
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ def test_blocks_in_form_details(pub):
|
|||
assert 'test1' not in details
|
||||
assert 'test empty block' not in details
|
||||
assert 'test2' in details
|
||||
assert 'bar' in details
|
||||
assert 'plop:\n foo\n' in details
|
||||
|
||||
|
||||
def test_block_migrate(pub):
|
||||
|
|
|
@ -5619,7 +5619,9 @@ def test_rst_form_details_all_fields(pub):
|
|||
assert '**Subtitle**\n\n' in rst
|
||||
assert 'Text:\n para1\n para2' in rst
|
||||
assert 'File:\n test.jpeg' in rst
|
||||
assert 'Block Field:\n XfooY, Xfoo2Y' in rst
|
||||
assert 'Block Field:\n' in rst
|
||||
assert 'Test:\n foo\n' in rst
|
||||
assert 'Test:\n foo2\n' in rst
|
||||
assert 'Map:\n 2;4\n\n' in rst
|
||||
|
||||
|
||||
|
|
|
@ -491,8 +491,12 @@ def test_export_to_model_form_details_section(pub, filename):
|
|||
assert '>2015-05-12<' in new_content
|
||||
assert 'Invisible' not in new_content
|
||||
assert new_content.count('/table:table-cell') == 8
|
||||
assert 'XfooY, Xfoo2Y' in new_content
|
||||
assert '>14.4<' in new_content
|
||||
# block sub fields
|
||||
assert '>foo<' in new_content
|
||||
assert '>bar<' in new_content
|
||||
assert '>foo2<' in new_content
|
||||
assert '>bar2<' in new_content
|
||||
|
||||
if filename == 'template-form-details-no-styles.odt':
|
||||
with open(formdata.evolution[0].parts[-1].get_file_path(), 'rb') as fd:
|
||||
|
|
|
@ -15,17 +15,13 @@
|
|||
# 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.blocks import BlockDef, BlockWidget
|
||||
from wcs.qommon import _
|
||||
from wcs.qommon.form import CheckboxWidget, IntWidget, SingleSelectWidget, StringWidget
|
||||
from wcs.qommon.ods import NS as OD_NS
|
||||
from wcs.qommon.ods import clean_text as od_clean_text
|
||||
|
||||
from .base import SetValueError, WidgetField
|
||||
from .item import UnknownCardValueError
|
||||
|
@ -200,67 +196,25 @@ class BlockField(WidgetField):
|
|||
parts.append(self.block.get_display_value(subvalue) or '')
|
||||
return ', '.join(parts)
|
||||
|
||||
def get_view_value(self, value, summary=False, include_unset_required_fields=False, **kwargs):
|
||||
from wcs.workflows import template_on_formdata
|
||||
|
||||
if 'value_id' not in kwargs:
|
||||
# when called from get_rst_view_value()
|
||||
return str(value or '')
|
||||
value = kwargs['value_id']
|
||||
if value is None:
|
||||
return ''
|
||||
r = TemplateIO(html=True)
|
||||
for i, row_value in enumerate(value['data']):
|
||||
def get_value_details(self, formdata, value, include_unset_required_fields):
|
||||
for i, row_value in enumerate((value or {}).get('data') or []):
|
||||
try:
|
||||
block = self.block
|
||||
except KeyError:
|
||||
# block was deleted, ignore
|
||||
continue
|
||||
context = block.get_substitution_counter_variables(i)
|
||||
for field in block.fields:
|
||||
if summary and not field.include_in_summary_page:
|
||||
continue
|
||||
if not hasattr(field, 'get_value_info'):
|
||||
# inert field
|
||||
if field.include_in_summary_page:
|
||||
with get_publisher().substitutions.temporary_feed(context):
|
||||
if field.key == 'title':
|
||||
label = template_on_formdata(None, field.label, autoescape=False)
|
||||
r += htmltext('<div class="title %s"><h3>%s</h3></div>') % (
|
||||
field.extra_css_class or '',
|
||||
label,
|
||||
)
|
||||
elif field.key == 'subtitle':
|
||||
label = template_on_formdata(None, field.label, autoescape=False)
|
||||
r += htmltext('<div class="subtitle %s"><h4>%s</h4></div>') % (
|
||||
field.extra_css_class or '',
|
||||
label,
|
||||
)
|
||||
elif field.key == 'comment':
|
||||
r += htmltext(
|
||||
'<div class="comment-field %s">%s</div>'
|
||||
% (field.extra_css_class or '', field.get_text())
|
||||
)
|
||||
continue
|
||||
css_classes = ['field', 'field-type-%s' % field.key]
|
||||
if field.extra_css_class:
|
||||
css_classes.append(field.extra_css_class)
|
||||
sub_value, sub_value_details = field.get_value_info(row_value)
|
||||
if sub_value is None and not (field.required and include_unset_required_fields):
|
||||
continue
|
||||
label_id = f'form-field-label-f{self.id}-r{i}-s{field.id}'
|
||||
r += htmltext('<div class="%s">' % ' '.join(css_classes))
|
||||
r += htmltext('<p id="%s" class="label">%s</p> ') % (label_id, field.label)
|
||||
if sub_value is None:
|
||||
r += htmltext('<div class="value"><i>%s</i></div>') % _('Not set')
|
||||
else:
|
||||
r += htmltext('<div class="value">')
|
||||
kwargs = {'parent_field': self, 'parent_field_index': i, 'label_id': label_id}
|
||||
kwargs.update(**sub_value_details)
|
||||
r += field.get_view_value(sub_value, **kwargs)
|
||||
r += htmltext('</div>')
|
||||
r += htmltext('</div>\n')
|
||||
return r.getvalue()
|
||||
with get_publisher().substitutions.temporary_feed(context):
|
||||
yield from formdata.get_summary_field_details(
|
||||
fields=block.fields,
|
||||
include_unset_required_fields=include_unset_required_fields,
|
||||
data=row_value,
|
||||
parent_field=self,
|
||||
parent_field_index=i,
|
||||
)
|
||||
|
||||
def get_view_value(self, value, summary=False, include_unset_required_fields=False, **kwargs):
|
||||
return str(value or '')
|
||||
|
||||
def get_value_info(self, data):
|
||||
value = data.get(self.id)
|
||||
|
@ -338,11 +292,6 @@ class BlockField(WidgetField):
|
|||
|
||||
return {'data': result, 'schema': {x.id: x.key for x in self.block.fields}}
|
||||
|
||||
def get_opendocument_node_value(self, value, formdata=None, **kwargs):
|
||||
node = ET.Element('{%s}span' % OD_NS['text'])
|
||||
node.text = od_clean_text(force_str(value))
|
||||
return node
|
||||
|
||||
def __getstate__(self):
|
||||
# do not store _block cache
|
||||
odict = super().__getstate__()
|
||||
|
|
|
@ -1755,10 +1755,20 @@ class FormData(StorableObject):
|
|||
for field in self.formdef.fields:
|
||||
field.feed_session(self.data.get(field.id), self.data.get('%s_display' % field.id))
|
||||
|
||||
def get_summary_field_details(self, fields=None, include_unset_required_fields=False):
|
||||
def get_summary_field_details(
|
||||
self,
|
||||
fields=None,
|
||||
include_unset_required_fields=False,
|
||||
data=None,
|
||||
parent_field=None,
|
||||
parent_field_index=None,
|
||||
):
|
||||
if fields is None:
|
||||
fields = self.formdef.fields
|
||||
|
||||
if data is None:
|
||||
data = self.data
|
||||
|
||||
on_page = False
|
||||
current_page_fields = []
|
||||
pages = []
|
||||
|
@ -1820,10 +1830,14 @@ class FormData(StorableObject):
|
|||
if not f.include_in_summary_page:
|
||||
continue
|
||||
|
||||
value, value_details = f.get_value_info(self.data)
|
||||
value, value_details = f.get_value_info(data)
|
||||
if value is None and not (f.required and include_unset_required_fields):
|
||||
continue
|
||||
|
||||
if parent_field:
|
||||
value_details['parent_field'] = parent_field
|
||||
value_details['parent_field_index'] = parent_field_index
|
||||
|
||||
current_page_fields.append({'field': f, 'value': value, 'value_details': value_details})
|
||||
has_contents_since_latest_subtitle = True
|
||||
has_contents_since_latest_title = True
|
||||
|
@ -1960,15 +1974,23 @@ class FormData(StorableObject):
|
|||
)
|
||||
|
||||
def get_summary_display_actions(self, fields=None, form_url='', include_unset_required_fields=False):
|
||||
from wcs.workflows import template_on_formdata
|
||||
|
||||
field_details = self.get_summary_field_details(
|
||||
fields, include_unset_required_fields=include_unset_required_fields
|
||||
)
|
||||
yield from self.iter_summary_display_actions(
|
||||
field_details,
|
||||
form_url=form_url,
|
||||
include_unset_required_fields=include_unset_required_fields,
|
||||
)
|
||||
|
||||
def iter_summary_display_actions(self, field_details, form_url='', include_unset_required_fields=False):
|
||||
from wcs.workflows import template_on_formdata
|
||||
|
||||
on_page = None
|
||||
for field_value_info in field_details:
|
||||
f = field_value_info['field']
|
||||
parent_field = field_value_info.get('value_details', {}).get('parent_field')
|
||||
parent_field_index = field_value_info.get('value_details', {}).get('parent_field_index')
|
||||
if f.key == 'page':
|
||||
if on_page:
|
||||
yield {'action': 'close-page'}
|
||||
|
@ -1995,6 +2017,8 @@ class FormData(StorableObject):
|
|||
css_classes.append(f.extra_css_class)
|
||||
css_classes = ' '.join(css_classes)
|
||||
label_id = f'form-field-label-f{f.id}'
|
||||
if parent_field:
|
||||
label_id = f'form-field-label-f{parent_field.id}-r{parent_field_index}-s{f.id}'
|
||||
yield {'action': 'open-field', 'css': css_classes}
|
||||
if f.key == 'block' and f.label_display == 'subtitle':
|
||||
yield {
|
||||
|
@ -2015,6 +2039,19 @@ class FormData(StorableObject):
|
|||
if value is None:
|
||||
if not (f.key == 'block' and f.label_display == 'hidden'):
|
||||
yield {'action': 'value', 'value': None}
|
||||
elif f.key == 'block':
|
||||
block_field_details = f.get_value_details(
|
||||
formdata=self,
|
||||
value=value_details.get('value_id'),
|
||||
include_unset_required_fields=include_unset_required_fields,
|
||||
)
|
||||
yield {'action': 'open-block-value'}
|
||||
yield from self.iter_summary_display_actions(
|
||||
block_field_details,
|
||||
form_url=form_url,
|
||||
include_unset_required_fields=include_unset_required_fields,
|
||||
)
|
||||
yield {'action': 'close-block-value'}
|
||||
else:
|
||||
s = f.get_view_value(
|
||||
value,
|
||||
|
|
|
@ -581,6 +581,10 @@ class FormStatusPage(Directory, FormTemplateMixin):
|
|||
r += htmltext('<div class="page">')
|
||||
r += htmltext('<h3>%s</h3>') % field_action['value']
|
||||
r += htmltext('<div>')
|
||||
elif field_action['action'] == 'open-block-value':
|
||||
r += htmltext('<div class="value value--block">')
|
||||
elif field_action['action'] == 'close-block-value':
|
||||
r += htmltext('</div>')
|
||||
elif field_action['action'] == 'title':
|
||||
r += htmltext('<div class="title %s"><h3>%s</h3></div>') % (
|
||||
field_action['css'],
|
||||
|
|
Loading…
Reference in New Issue