backoffice: duplicate page and subfields (#57036)
gitea-wip/wcs/pipeline/head There was a failure building this commit Details

This commit is contained in:
Lauréline Guérin 2021-10-08 10:57:26 +02:00
parent 0565ffe5d3
commit 5b19ab7fd9
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
2 changed files with 173 additions and 3 deletions

View File

@ -1453,8 +1453,7 @@ def test_form_duplicate_field(pub):
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='fields/')
resp = app.get('/backoffice/forms/1/fields/')
assert '1st field' in resp.text
resp = resp.click(href='1/duplicate')
@ -1465,6 +1464,120 @@ def test_form_duplicate_field(pub):
assert FormDef.get(1).fields[1].label == '1st field'
def test_form_duplicate_page_field(pub):
create_superuser(pub)
create_role(pub)
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.PageField(id='0', label='1st page', type='page'),
fields.StringField(id='1', label='1st field', type='string', varname='foobar'),
fields.PageField(id='2', label='2nd page', type='page'),
fields.StringField(id='3', label='2nd field', type='string', varname='baz'),
]
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/fields/')
# duplicate 1st page only
resp = resp.click(href='0/duplicate')
assert 'Also duplicate all fields of the page' in resp.text
resp = resp.form.submit().follow()
assert [f.label for f in FormDef.get(1).fields] == [
'1st page',
'1st field',
'1st page',
'2nd page',
'2nd field',
]
assert [str(f.id) for f in FormDef.get(1).fields] == ['0', '1', '4', '2', '3']
# duplicate 1st page and fields
resp = resp.click(href='0/duplicate')
assert 'Also duplicate all fields of the page' in resp.text
resp.form['duplicate_fields'] = True
resp = resp.form.submit().follow()
assert [f.label for f in FormDef.get(1).fields] == [
'1st page',
'1st field',
'1st page',
'1st field',
'1st page',
'2nd page',
'2nd field',
]
assert [str(f.id) for f in FormDef.get(1).fields] == ['0', '1', '5', '6', '4', '2', '3']
# duplicate copy of 1st page without fields
resp = resp.click(href='4/duplicate')
assert 'Also duplicate all fields of the page' not in resp.text
resp = resp.form.submit().follow()
assert [f.label for f in FormDef.get(1).fields] == [
'1st page',
'1st field',
'1st page',
'1st field',
'1st page',
'1st page',
'2nd page',
'2nd field',
]
assert [str(f.id) for f in FormDef.get(1).fields] == ['0', '1', '5', '6', '4', '7', '2', '3']
# duplicate last page and fields
resp = resp.click(href='2/duplicate')
assert 'Also duplicate all fields of the page' in resp.text
resp.form['duplicate_fields'] = True
resp = resp.form.submit().follow()
assert [f.label for f in FormDef.get(1).fields] == [
'1st page',
'1st field',
'1st page',
'1st field',
'1st page',
'1st page',
'2nd page',
'2nd field',
'2nd page',
'2nd field',
]
assert [str(f.id) for f in FormDef.get(1).fields] == ['0', '1', '5', '6', '4', '7', '2', '3', '8', '9']
# duplicate last page only
resp = resp.click(href='8/duplicate')
assert 'Also duplicate all fields of the page' in resp.text
resp = resp.form.submit().follow()
assert [f.label for f in FormDef.get(1).fields] == [
'1st page',
'1st field',
'1st page',
'1st field',
'1st page',
'1st page',
'2nd page',
'2nd field',
'2nd page',
'2nd field',
'2nd page',
]
assert [str(f.id) for f in FormDef.get(1).fields] == [
'0',
'1',
'5',
'6',
'4',
'7',
'2',
'3',
'8',
'9',
'10',
]
def test_form_duplicate_file_field(pub):
create_superuser(pub)
create_role(pub)

View File

@ -185,6 +185,8 @@ class FieldDefPage(Directory):
return self.redirect_field_anchor(above_field)
def duplicate(self):
if self.field.type == 'page':
return self.duplicate_page()
field_pos = self.objectdef.fields.index(self.field)
fields = self.objectdef.fields
new_field = copy.deepcopy(self.field)
@ -194,6 +196,61 @@ class FieldDefPage(Directory):
self.objectdef.store(comment=_('Duplication of field "%s"') % self.field.unhtmled_label)
return self.redirect_field_anchor(new_field)
def duplicate_page(self):
form = Form(enctype='multipart/form-data')
ellipsized_field_label = misc.ellipsize(self.field.unhtmled_label, 60)
duplicate_top_title = _('Duplicate Page')
duplicate_title = _('Duplicating Page: %s') % ellipsized_field_label
duplicate_message = _("You are about to duplicate the \"%s\" page.") % ellipsized_field_label
form.widgets.append(HtmlWidget('<p>%s</p>' % duplicate_message))
current_field_index = self.objectdef.fields.index(self.field)
page_fields = []
# get fields of the page
for index in range(current_field_index + 1, len(self.objectdef.fields)):
field = self.objectdef.fields[index]
if field.type == 'page':
# next page found; break
break
page_fields.append(field)
# add duplicate_fields checkbox only if the page has fields
if page_fields:
form.add(CheckboxWidget, 'duplicate_fields', title=_('Also duplicate all fields of the page'))
form.add_submit('submit', _('Duplicate'))
form.add_submit("cancel", _("Cancel"))
if form.get_widget('cancel').parse():
return self.redirect_field_anchor(self.field)
if not form.is_submitted() or form.has_errors():
get_response().breadcrumb.append(('duplicate', _('Duplicate')))
self.html_top(title=duplicate_top_title)
r = TemplateIO(html=True)
r += htmltext('<h2>%s</h2>') % duplicate_title
r += form.render()
return r.getvalue()
else:
duplicate_fields = form.get_widget('duplicate_fields')
to_be_duplicated = [self.field]
if duplicate_fields and duplicate_fields.parse():
# duplicate page fields if requested
to_be_duplicated += page_fields
new_fields = []
# duplicate fields
for field in to_be_duplicated:
new_field = copy.deepcopy(field)
# allocate a new id
new_field.id = self.objectdef.get_new_field_id()
new_fields.append(new_field)
# insert new fields
last_duplicated_field_index = self.objectdef.fields.index(([self.field] + page_fields)[-1])
self.objectdef.fields = (
self.objectdef.fields[: last_duplicated_field_index + 1]
+ new_fields
+ self.objectdef.fields[last_duplicated_field_index + 1 :]
)
# and store them
self.objectdef.store(comment=_('Duplication of field "%s"') % self.field.ellipsized_label)
# redirect to the new page field
return self.redirect_field_anchor(new_fields[0])
class FieldsPagesDirectory(Directory):
def __init__(self, parent):
@ -342,7 +399,7 @@ class FieldsDirectory(Directory):
)
r += command_icon('%s/' % field.id, 'edit')
if not self.objectdef.is_readonly():
r += command_icon('%s/duplicate' % field.id, 'duplicate')
r += command_icon('%s/duplicate' % field.id, 'duplicate', popup=(field.type == 'page'))
r += command_icon('%s/delete' % field.id, 'remove', popup=True)
r += htmltext('</p></li>')
r += htmltext('</ul>')