backoffice: add action to duplicate blocks (#67594)

This commit is contained in:
Frédéric Péters 2022-08-03 00:00:09 +02:00
parent 1a85d14ff5
commit 575050dec8
2 changed files with 74 additions and 2 deletions

View File

@ -436,7 +436,7 @@ def test_block_edit_field_warnings(pub):
resp = app.get('/backoffice/forms/blocks/%s/' % blockdef.id)
assert 'more than 30 fields' not in resp.text
assert '<div id="new-field"><h3>New Field</h3>' in resp.text
assert '>Duplicate<' in resp.text
assert resp.pyquery('#fields-list a[title="Duplicate"]').length
blockdef.fields.extend(
[fields.StringField(id='%d' % i, label='field %d' % i, type='string') for i in range(21, 51)]
@ -445,7 +445,7 @@ def test_block_edit_field_warnings(pub):
resp = app.get('/backoffice/forms/blocks/%s/' % blockdef.id)
assert 'This block of fields contains 60 fields.' in resp.text
assert '<div id="new-field"><h3>New Field</h3>' not in resp.text
assert '>Duplicate<' not in resp.text
assert not resp.pyquery('#fields-list a[title="Duplicate"]').length
def test_block_inspect(pub):
@ -463,3 +463,41 @@ def test_block_inspect(pub):
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click('Inspector')
assert resp.pyquery('#inspect-fields .inspect-field').length == 2
def test_block_duplicate(pub):
create_superuser(pub)
BlockDef.wipe()
block = BlockDef()
block.name = 'Foobar'
block.fields = [
fields.StringField(id='123', required=True, label='Test', type='string'),
fields.StringField(id='124', required=True, label='Test2', type='string'),
]
block.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^duplicate$'))
assert resp.form['name'].value == 'Foobar (copy)'
resp = resp.form.submit('cancel').follow()
assert BlockDef.count() == 1
resp = resp.click(href=re.compile('^duplicate$'))
assert resp.form['name'].value == 'Foobar (copy)'
resp = resp.form.submit('submit').follow()
assert BlockDef.count() == 2
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^duplicate$'))
assert resp.form['name'].value == 'Foobar (copy 2)'
resp.form['name'].value = 'other copy'
resp = resp.form.submit('submit').follow()
assert BlockDef.count() == 3
assert {x.name for x in BlockDef.select()} == {'Foobar', 'Foobar (copy)', 'other copy'}
assert {x.slug for x in BlockDef.select()} == {'foobar', 'foobar_copy', 'other_copy'}
block_copy = BlockDef.get_by_slug('other_copy')
assert len(block_copy.fields) == 2

View File

@ -45,6 +45,7 @@ class BlockDirectory(FieldsDirectory):
'export',
'settings',
'inspect',
'duplicate',
('history', 'snapshots_dir'),
]
field_def_page_class = BlockFieldDefPage
@ -101,6 +102,7 @@ class BlockDirectory(FieldsDirectory):
r = TemplateIO(html=True)
r += htmltext('<ul id="sidebar-actions">')
r += htmltext('<li><a href="delete" rel="popup">%s</a></li>') % _('Delete')
r += htmltext('<li><a href="duplicate" rel="popup">%s</a></li>') % _('Duplicate')
r += htmltext('<li><a href="export">%s</a></li>') % _('Export')
if get_publisher().snapshot_class:
r += htmltext('<li><a rel="popup" href="history/save">%s</a></li>') % _('Save snapshot')
@ -136,6 +138,38 @@ class BlockDirectory(FieldsDirectory):
self.objectdef.remove_self()
return redirect('..')
def duplicate(self):
form = Form(enctype='multipart/form-data')
name_widget = form.add(StringWidget, 'name', title=_('Name'), required=True, size=30)
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
if form.get_widget('cancel').parse():
return redirect('.')
if not form.is_submitted():
original_name = self.objectdef.name
new_name = '%s %s' % (original_name, _('(copy)'))
names = [x.name for x in BlockDef.select()]
no = 2
while new_name in names:
new_name = _('%(name)s (copy %(no)d)') % {'name': original_name, 'no': no}
no += 1
name_widget.set_value(new_name)
if not form.is_submitted() or form.has_errors():
html_top(self.section, title=_('Duplicate Fields Block'))
r = TemplateIO(html=True)
get_response().breadcrumb.append(('duplicate', _('Duplicate')))
r += htmltext('<h2>%s</h2>') % _('Duplicate Fields Block')
r += form.render()
return r.getvalue()
self.objectdef.id = None
self.objectdef.slug = None
self.objectdef.name = form.get_widget('name').parse()
self.objectdef.store()
return redirect('../%s/' % self.objectdef.id)
def export(self):
return misc.xml_response(
self.objectdef,