admin: option to move fields when a page is moved (#49585)
This commit is contained in:
parent
e833ab2ba0
commit
67abf4f379
|
@ -2049,16 +2049,84 @@ def test_form_fields_reorder(pub):
|
|||
formdef.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
app.get('/backoffice/forms/%s/fields/update_order?order=0;3;1;2;' % formdef.id)
|
||||
|
||||
# missing element in params: do nothing
|
||||
resp = app.get('/backoffice/forms/%s/fields/update_order?order=0;3;1;2;' % formdef.id)
|
||||
assert resp.json == {'success': 'ko'}
|
||||
# missing order in params: do nothing
|
||||
resp = app.get('/backoffice/forms/%s/fields/update_order?element=0' % formdef.id)
|
||||
assert resp.json == {'success': 'ko'}
|
||||
|
||||
resp = app.get('/backoffice/forms/%s/fields/update_order?order=0;3;1;2;&element=3' % formdef.id)
|
||||
assert resp.json == {'success': 'ok'}
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert [x.id for x in formdef.fields] == ['0', '3', '1', '2']
|
||||
|
||||
# unknown id: ignored
|
||||
app.get('/backoffice/forms/%s/fields/update_order?order=0;1;2;3;4;' % formdef.id)
|
||||
resp = app.get('/backoffice/forms/%s/fields/update_order?order=0;1;2;3;4;&element=3' % formdef.id)
|
||||
assert resp.json == {'success': 'ok'}
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert [x.id for x in formdef.fields] == ['0', '1', '2', '3']
|
||||
# missing id: do nothing
|
||||
app.get('/backoffice/forms/%s/fields/update_order?order=0;3;1;' % formdef.id)
|
||||
resp = app.get('/backoffice/forms/%s/fields/update_order?order=0;3;1;&element=3' % formdef.id)
|
||||
assert resp.json == {'success': 'ko'}
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert [x.id for x in formdef.fields] == ['0', '1', '2', '3']
|
||||
|
||||
# move a page
|
||||
resp = app.get('/backoffice/forms/%s/fields/update_order?order=2;0;1;3;&element=2' % formdef.id)
|
||||
assert resp.json == {'success': 'ok', 'additional-action': {
|
||||
'message': 'Also move the fields of the page', 'url': 'move_page_fields?fields=3&page=2'}}
|
||||
# reset
|
||||
resp = app.get('/backoffice/forms/%s/fields/update_order?order=0;1;2;3;&element=2' % formdef.id)
|
||||
assert resp.json == {'success': 'ok'}
|
||||
# move the first page
|
||||
resp = app.get('/backoffice/forms/%s/fields/update_order?order=1;2;3;0;&element=0' % formdef.id)
|
||||
assert resp.json == {'success': 'ok', 'additional-action': {
|
||||
'message': 'Also move the fields of the page', 'url': 'move_page_fields?fields=1&page=0'}}
|
||||
|
||||
|
||||
def test_form_move_page_fields(pub):
|
||||
create_superuser(pub)
|
||||
create_role()
|
||||
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'form title'
|
||||
formdef.fields = [
|
||||
fields.PageField(id='2', label='2nd page', type='page'),
|
||||
fields.PageField(id='0', label='1st page', type='page'),
|
||||
fields.StringField(id='1', label='string', type='string'),
|
||||
fields.StringField(id='3', label='string 2', type='string')
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
# missing element in params: do nothing
|
||||
app.get('/backoffice/forms/%s/fields/move_page_fields?fields=3' % formdef.id)
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert [x.id for x in formdef.fields] == ['2', '0', '1', '3']
|
||||
# missing order in params: do nothing
|
||||
app.get('/backoffice/forms/%s/fields/move_page_fields?page=2' % formdef.id)
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert [x.id for x in formdef.fields] == ['2', '0', '1', '3']
|
||||
|
||||
# unknown id: do nothing
|
||||
app.get('/backoffice/forms/%s/fields/move_page_fields?fields=4&page=2' % formdef.id)
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert [x.id for x in formdef.fields] == ['2', '0', '1', '3']
|
||||
|
||||
# move the fields of the page
|
||||
app.get('/backoffice/forms/%s/fields/move_page_fields?fields=3&page=2' % formdef.id)
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert [x.id for x in formdef.fields] == ['2', '3', '0', '1']
|
||||
|
||||
# move the new first page
|
||||
app.get('/backoffice/forms/%s/fields/update_order?order=3;0;1;2&element=2' % formdef.id)
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert [x.id for x in formdef.fields] == ['3', '0', '1', '2']
|
||||
# and the fields
|
||||
app.get('/backoffice/forms/%s/fields/move_page_fields?fields=3&page=2' % formdef.id)
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert [x.id for x in formdef.fields] == ['0', '1', '2', '3']
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
from quixote import redirect
|
||||
from quixote.directory import Directory
|
||||
|
@ -213,7 +214,7 @@ class FieldsPagesDirectory(Directory):
|
|||
|
||||
|
||||
class FieldsDirectory(Directory):
|
||||
_q_exports = ['', 'update_order', 'new', 'pages']
|
||||
_q_exports = ['', 'update_order', 'move_page_fields', 'new', 'pages']
|
||||
field_def_page_class = FieldDefPage
|
||||
blacklisted_types = []
|
||||
page_id = None
|
||||
|
@ -395,19 +396,87 @@ class FieldsDirectory(Directory):
|
|||
pass
|
||||
|
||||
def update_order(self):
|
||||
get_response().set_content_type('application/json')
|
||||
request = get_request()
|
||||
|
||||
if 'element' not in request.form:
|
||||
return json.dumps({'success': 'ko'})
|
||||
if 'order' not in request.form:
|
||||
return json.dumps({'success': 'ko'})
|
||||
|
||||
dropped_element = request.form['element']
|
||||
dropped_page_index = None
|
||||
|
||||
new_order = request.form['order'].strip(';').split(';')
|
||||
new_fields = []
|
||||
|
||||
# build new ordered field list
|
||||
for y in new_order:
|
||||
for x in self.objectdef.fields:
|
||||
if x.id == y:
|
||||
new_fields.append(x)
|
||||
for i, x in enumerate(self.objectdef.fields):
|
||||
if x.id != y:
|
||||
continue
|
||||
new_fields.append(x)
|
||||
# if dropped field is a page, keep it's old index
|
||||
if x.id == dropped_element and x.type == 'page':
|
||||
dropped_page_index = i
|
||||
break
|
||||
|
||||
# get the list of dropped page fields from old field list
|
||||
page_field_ids = []
|
||||
if dropped_page_index is not None:
|
||||
for field in self.objectdef.fields[dropped_page_index + 1:]:
|
||||
if field.type == 'page':
|
||||
# next page found; break
|
||||
break
|
||||
page_field_ids.append(field.id)
|
||||
|
||||
# check new field list composition
|
||||
if set(self.objectdef.fields) != set(new_fields):
|
||||
return 'ko'
|
||||
return json.dumps({'success': 'ko'})
|
||||
|
||||
self.objectdef.fields = new_fields
|
||||
self.objectdef.store(comment=_('Change in order of fields'))
|
||||
return 'ok'
|
||||
|
||||
if not page_field_ids:
|
||||
return json.dumps({'success': 'ok'})
|
||||
|
||||
# propose to move also page fields
|
||||
return json.dumps({
|
||||
'success': 'ok',
|
||||
'additional-action': {
|
||||
'message': _('Also move the fields of the page'),
|
||||
'url': 'move_page_fields?fields=%s&page=%s' % (';'.join(page_field_ids), dropped_element)
|
||||
}
|
||||
})
|
||||
|
||||
def move_page_fields(self):
|
||||
request = get_request()
|
||||
|
||||
if 'fields' not in request.form:
|
||||
return redirect('.')
|
||||
if 'page' not in request.form:
|
||||
return redirect('.')
|
||||
|
||||
field_ids = request.form['fields'].strip(';').split(';')
|
||||
# keep all fields except page fields
|
||||
new_fields = [f for f in self.objectdef.fields if f.id not in field_ids]
|
||||
# find page fields
|
||||
page_fields = [f for f in self.objectdef.fields if f.id in field_ids]
|
||||
# find page in new fields, and insert page_fields
|
||||
for i, field in enumerate(new_fields):
|
||||
if field.id != request.form['page']:
|
||||
continue
|
||||
new_fields = new_fields[:i+1] + page_fields + new_fields[i+1:]
|
||||
break
|
||||
|
||||
# check new field list composition
|
||||
if set(self.objectdef.fields) != set(new_fields):
|
||||
return redirect('.')
|
||||
|
||||
self.objectdef.fields = new_fields
|
||||
self.objectdef.store(comment=_('Change in order of fields'))
|
||||
|
||||
return redirect('.')
|
||||
|
||||
def new(self):
|
||||
form = Form(enctype='multipart/form-data', action = 'new')
|
||||
|
|
|
@ -8,6 +8,22 @@ $(document).ready(
|
|||
$('ul.biglist.sortable li').each(function(i, elem) {
|
||||
$('<span class="handle">⣿</span>').prependTo(elem);
|
||||
});
|
||||
|
||||
const $move_page_field = $('<div class="move-page-field-content"></div>');
|
||||
const $move_page_field_link = $('<a class="move-page-field-link"></a>').appendTo($move_page_field);
|
||||
$move_page_field.dialog({
|
||||
autoOpen: false,
|
||||
minHeight: 0,
|
||||
dialogClass: "move-page-field oneline-dialog feedback-on-open",
|
||||
draggable: false,
|
||||
open: function() {
|
||||
$move_page_field.dialog('widget').removeClass('feedback-on-open');
|
||||
},
|
||||
close: function() {
|
||||
$move_page_field.dialog('widget').addClass('feedback-on-open');
|
||||
}
|
||||
});
|
||||
|
||||
$('ul.biglist.sortable').sortable(
|
||||
{
|
||||
handle: '.handle',
|
||||
|
@ -35,8 +51,16 @@ $(document).ready(
|
|||
page_index += 1;
|
||||
}
|
||||
}
|
||||
$move_page_field.dialog('close');
|
||||
var order_function = $(this).data('order-function') || 'update_order';
|
||||
$.post(order_function, {'order': result});
|
||||
$.post(order_function, {'order': result, 'element': $(ui.item)[0].id.substr(7, 50)})
|
||||
.done(function(data) {
|
||||
if (data['success'] != "ok") return;
|
||||
if (!data['additional-action']) return;
|
||||
$move_page_field_link.attr('href', data['additional-action']['url']).html(data['additional-action']['message']);
|
||||
$move_page_field.dialog('option', 'position', { my: 'left top', at: 'left bottom', of: $(ui.item) });
|
||||
$move_page_field.dialog('open');
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue