diff --git a/tests/admin_pages/test_block.py b/tests/admin_pages/test_block.py index 98080ac14..c0246e468 100644 --- a/tests/admin_pages/test_block.py +++ b/tests/admin_pages/test_block.py @@ -257,6 +257,55 @@ def test_block_delete(pub): assert 'This block is still used' in resp +def test_block_export_overwrite(pub): + create_superuser(pub) + BlockDef.wipe() + block = BlockDef() + block.name = 'foobar' + block.fields = [fields.StringField(id='123', required=True, label='Test')] + block.store() + + app = login(get_app(pub)) + resp = app.get('/backoffice/forms/blocks/%s/' % block.id) + resp = resp.click(href=re.compile('^export$')) + xml_export = resp.text + + block.slug = 'new-slug' + block.name = 'New foobar' + block.fields = [fields.StringField(id='123', required=True, label='Test bebore overwrite')] + block.store() + + resp = app.get('/backoffice/forms/blocks/%s/' % block.id) + resp = resp.click('Overwrite') + resp = resp.form.submit('cancel').follow() + resp = resp.click('Overwrite') + resp = resp.form.submit() + assert 'There were errors processing your form.' in resp + + resp.form['file'] = Upload('block', xml_export.encode('utf-8')) + resp = resp.form.submit() + resp = resp.follow() + assert BlockDef.count() == 1 + + block.refresh_from_storage() + assert block.fields[0].label == 'Test' + assert block.name == 'foobar' + assert block.slug == 'new-slug' # not overwritten + + # unknown reference + block.fields = [fields.StringField(id='1', data_source={'type': 'foobar'})] + block.store() + resp = app.get('/backoffice/forms/blocks/%s/' % block.id) + resp = resp.click(href=re.compile('^export$')) + xml_export = resp.text + resp = app.get('/backoffice/forms/blocks/%s/' % block.id) + resp = resp.click('Overwrite') + resp.form['file'] = Upload('block', xml_export.encode('utf-8')) + resp = resp.form.submit() + assert 'Invalid File (Unknown referenced objects)' in resp + assert '' in resp + + def test_block_edit_duplicate_delete_field(pub): create_superuser(pub) BlockDef.wipe() @@ -453,14 +502,14 @@ def test_block_edit_field_warnings(pub): blockdef.store() resp = app.get('/backoffice/forms/blocks/%s/' % blockdef.id) assert 'more than 30 fields' not in resp.text - assert '

New Field

' in resp.text + assert resp.pyquery('#new-field') assert resp.pyquery('#fields-list a[title="Duplicate"]').length blockdef.fields.extend([fields.StringField(id='%d' % i, label='field %d' % i) for i in range(21, 51)]) blockdef.store() resp = app.get('/backoffice/forms/blocks/%s/' % blockdef.id) assert 'This block of fields contains 60 fields.' in resp.text - assert '

New Field

' not in resp.text + assert not resp.pyquery('#new-field') assert not resp.pyquery('#fields-list a[title="Duplicate"]').length diff --git a/tests/admin_pages/test_card.py b/tests/admin_pages/test_card.py index 473945591..ea3ef2749 100644 --- a/tests/admin_pages/test_card.py +++ b/tests/admin_pages/test_card.py @@ -1035,7 +1035,7 @@ def test_card_edit_field_warnings(pub): resp = app.get('/backoffice/cards/%s/fields/' % carddef.id) assert 'more than 200 fields' not in resp.text assert 'first field should be of type "page"' in resp.text - assert '

New Field

' in resp.text + assert resp.pyquery('#new-field') carddef.fields.extend([fields.StringField(id='%d' % i, label='field %d' % i) for i in range(10, 210)]) carddef.store() @@ -1049,7 +1049,7 @@ def test_card_edit_field_warnings(pub): resp = app.get('/backoffice/cards/%s/fields/' % carddef.id) assert 'This card model contains 410 fields.' in resp.text assert 'first field should be of type "page"' in resp.text - assert '

New Field

' not in resp.text + assert not resp.pyquery('#new-field') assert '>Duplicate<' not in resp.text diff --git a/tests/admin_pages/test_form.py b/tests/admin_pages/test_form.py index 7760472e2..8480e59eb 100644 --- a/tests/admin_pages/test_form.py +++ b/tests/admin_pages/test_form.py @@ -3600,7 +3600,7 @@ def test_form_edit_field_warnings(pub): resp = app.get('/backoffice/forms/%s/fields/' % formdef.id) assert 'more than 200 fields' not in resp.text assert 'first field should be of type "page"' in resp.text - assert '

New Field

' in resp.text + assert resp.pyquery('#new-field') formdef.fields.extend([fields.StringField(id='%d' % i, label='field %d' % i) for i in range(10, 210)]) formdef.store() @@ -3615,7 +3615,7 @@ def test_form_edit_field_warnings(pub): assert 'This form contains 410 fields.' in resp.text assert 'no new fields can be added.' in resp.text assert 'first field should be of type "page"' in resp.text - assert '

New Field

' not in resp.text + assert not resp.pyquery('#new-field') assert '>Duplicate<' not in resp.text assert resp.pyquery('aside .errornotice') assert not resp.pyquery('aside form[action=new]') @@ -3628,7 +3628,7 @@ def test_form_edit_field_warnings(pub): resp = app.get('/backoffice/forms/%s/fields/' % formdef.id) assert 'no new fields should be added.' in resp.text - assert '

New Field

' in resp.text + assert resp.pyquery('#new-field') assert '>Duplicate<' in resp.text assert not resp.pyquery('aside .errornotice') assert resp.pyquery('aside form[action=new]') diff --git a/wcs/admin/blocks.py b/wcs/admin/blocks.py index ab68f5fd7..7aeab5ba3 100644 --- a/wcs/admin/blocks.py +++ b/wcs/admin/blocks.py @@ -54,6 +54,7 @@ class BlockDirectory(FieldsDirectory): 'inspect', 'duplicate', ('history', 'snapshots_dir'), + 'overwrite', ] field_def_page_class = BlockFieldDefPage blacklisted_types = ['page', 'table', 'table-select', 'tablerows', 'ranked-items', 'blocks', 'computed'] @@ -106,6 +107,14 @@ class BlockDirectory(FieldsDirectory): r = TemplateIO(html=True) r += htmltext('
') r += htmltext('

%s

') % self.objectdef.name + r += htmltext('') + r += htmltext('') + r += htmltext('
    ') + r += htmltext('
  • %s
  • ') % _('Export') + r += htmltext('
  • %s
  • ') % _('Delete') + r += htmltext('
') + r += htmltext('%s') % _('Settings') + r += htmltext('
') r += htmltext('
') r += utils.last_modification_block(obj=self.objectdef) r += get_session().display_message() @@ -132,17 +141,25 @@ class BlockDirectory(FieldsDirectory): def get_new_field_form_sidebar(self, page_id): r = TemplateIO(html=True) - r += htmltext('') r += super().get_new_field_form_sidebar(page_id=page_id) + r += htmltext('

%s

') % _('Actions') + r += htmltext('') + r += htmltext('

%s

') % _('Navigation') + r += htmltext('') return r.getvalue() def delete(self): @@ -209,6 +226,41 @@ class BlockDirectory(FieldsDirectory): content_type='application/x-wcs-form', ) + def overwrite(self): + form = Form(enctype='multipart/form-data') + form.widgets.append( + HtmlWidget( + '

%s

' + % _('Field data will be lost if overwriting with an incompatible block.') + ) + ) + form.add(FileWidget, 'file', title=_('File'), required=True) + form.add_submit('submit', _('Submit')) + form.add_submit('cancel', _('Cancel')) + if form.get_widget('cancel').parse(): + return redirect('.') + + if form.is_submitted() and not form.has_errors(): + try: + return self.overwrite_submit(form) + except ValueError: + pass + + get_response().breadcrumb.append(('overwrite', _('Overwrite'))) + get_response().set_title(title=_('Overwrite')) + r = TemplateIO(html=True) + r += htmltext('

%s

') % _('Overwrite') + r += form.render() + return r.getvalue() + + def overwrite_submit(self, form): + blockdef = BlocksDirectory.import_blockdef(form) + self.objectdef.name = blockdef.name + self.objectdef.digest_template = blockdef.digest_template + self.objectdef.fields = blockdef.fields + self.objectdef.store(comment=_('Overwritten')) + return redirect('.') + def settings(self): get_response().breadcrumb.append(('settings', _('Settings'))) form = Form() @@ -409,7 +461,8 @@ class BlocksDirectory(Directory): r += form.render() return r.getvalue() - def import_submit(self, form): + @classmethod + def import_blockdef(cls, form): fp = form.get_widget('file').parse().fp error, reason = False, None @@ -433,6 +486,10 @@ class BlocksDirectory(Directory): form.set_error('file', msg) raise ValueError() + return blockdef + + def import_submit(self, form): + blockdef = self.import_blockdef(form) initial_blockdef_name = blockdef.name blockdef_names = [x.name for x in BlockDef.select()] copy_no = 1 diff --git a/wcs/admin/fields.py b/wcs/admin/fields.py index 73ac78902..d5e63b604 100644 --- a/wcs/admin/fields.py +++ b/wcs/admin/fields.py @@ -527,8 +527,8 @@ class FieldsDirectory(Directory): ) return r.getvalue() - r += htmltext('
') r += htmltext('

%s

') % _('New Field') + r += htmltext('
') get_request().form = None # ignore the eventual ?page=x form = self.get_new_field_form(page_id) r += form.render() diff --git a/wcs/qommon/static/css/dc2/admin.scss b/wcs/qommon/static/css/dc2/admin.scss index 4056d7618..05c38a511 100644 --- a/wcs/qommon/static/css/dc2/admin.scss +++ b/wcs/qommon/static/css/dc2/admin.scss @@ -222,13 +222,8 @@ div#new-action, div#new-trigger, div#new-field { } } -div#new-field { - margin: 2em 0 4px 0; - padding: 5px 5px; -} - -div#new-field form { - margin-bottom: 2em; +form#import-fields { + margin-top: 1em; } aside#sidebar div.news h3,