0001-admin-option-to-move-fields-when-a-page-is-moved-495.patch
tests/admin_pages/test_form.py | ||
---|---|---|
2049 | 2049 |
formdef.store() |
2050 | 2050 | |
2051 | 2051 |
app = login(get_app(pub)) |
2052 |
app.get('/backoffice/forms/%s/fields/update_order?order=0;3;1;2;' % formdef.id) |
|
2052 | ||
2053 |
# missing element in params: do nothing |
|
2054 |
resp = app.get('/backoffice/forms/%s/fields/update_order?order=0;3;1;2;' % formdef.id) |
|
2055 |
assert resp.json == {'success': 'ko'} |
|
2056 |
# missing order in params: do nothing |
|
2057 |
resp = app.get('/backoffice/forms/%s/fields/update_order?element=0' % formdef.id) |
|
2058 |
assert resp.json == {'success': 'ko'} |
|
2059 | ||
2060 |
resp = app.get('/backoffice/forms/%s/fields/update_order?order=0;3;1;2;&element=3' % formdef.id) |
|
2061 |
assert resp.json == {'success': 'ok'} |
|
2053 | 2062 |
formdef = FormDef.get(formdef.id) |
2054 | 2063 |
assert [x.id for x in formdef.fields] == ['0', '3', '1', '2'] |
2055 | 2064 | |
2056 | 2065 |
# unknown id: ignored |
2057 |
app.get('/backoffice/forms/%s/fields/update_order?order=0;1;2;3;4;' % formdef.id) |
|
2066 |
resp = app.get('/backoffice/forms/%s/fields/update_order?order=0;1;2;3;4;&element=3' % formdef.id) |
|
2067 |
assert resp.json == {'success': 'ok'} |
|
2058 | 2068 |
formdef = FormDef.get(formdef.id) |
2059 | 2069 |
assert [x.id for x in formdef.fields] == ['0', '1', '2', '3'] |
2060 | 2070 |
# missing id: do nothing |
2061 |
app.get('/backoffice/forms/%s/fields/update_order?order=0;3;1;' % formdef.id) |
|
2071 |
resp = app.get('/backoffice/forms/%s/fields/update_order?order=0;3;1;&element=3' % formdef.id) |
|
2072 |
assert resp.json == {'success': 'ko'} |
|
2073 |
formdef = FormDef.get(formdef.id) |
|
2074 |
assert [x.id for x in formdef.fields] == ['0', '1', '2', '3'] |
|
2075 | ||
2076 |
# move a page |
|
2077 |
resp = app.get('/backoffice/forms/%s/fields/update_order?order=2;0;1;3;&element=2' % formdef.id) |
|
2078 |
assert resp.json == {'success': 'ok', 'additional-action': { |
|
2079 |
'message': 'Also move the fields of the page', 'url': 'move_page_fields?fields=3&page=2'}} |
|
2080 |
# reset |
|
2081 |
resp = app.get('/backoffice/forms/%s/fields/update_order?order=0;1;2;3;&element=2' % formdef.id) |
|
2082 |
assert resp.json == {'success': 'ok'} |
|
2083 |
# move the first page |
|
2084 |
resp = app.get('/backoffice/forms/%s/fields/update_order?order=1;2;3;0;&element=0' % formdef.id) |
|
2085 |
assert resp.json == {'success': 'ok', 'additional-action': { |
|
2086 |
'message': 'Also move the fields of the page', 'url': 'move_page_fields?fields=1&page=0'}} |
|
2087 | ||
2088 | ||
2089 |
def test_form_move_page_fields(pub): |
|
2090 |
create_superuser(pub) |
|
2091 |
create_role() |
|
2092 | ||
2093 |
FormDef.wipe() |
|
2094 |
formdef = FormDef() |
|
2095 |
formdef.name = 'form title' |
|
2096 |
formdef.fields = [ |
|
2097 |
fields.PageField(id='2', label='2nd page', type='page'), |
|
2098 |
fields.PageField(id='0', label='1st page', type='page'), |
|
2099 |
fields.StringField(id='1', label='string', type='string'), |
|
2100 |
fields.StringField(id='3', label='string 2', type='string') |
|
2101 |
] |
|
2102 |
formdef.store() |
|
2103 | ||
2104 |
app = login(get_app(pub)) |
|
2105 |
# missing element in params: do nothing |
|
2106 |
app.get('/backoffice/forms/%s/fields/move_page_fields?fields=3' % formdef.id) |
|
2107 |
formdef = FormDef.get(formdef.id) |
|
2108 |
assert [x.id for x in formdef.fields] == ['2', '0', '1', '3'] |
|
2109 |
# missing order in params: do nothing |
|
2110 |
app.get('/backoffice/forms/%s/fields/move_page_fields?page=2' % formdef.id) |
|
2111 |
formdef = FormDef.get(formdef.id) |
|
2112 |
assert [x.id for x in formdef.fields] == ['2', '0', '1', '3'] |
|
2113 | ||
2114 |
# unknown id: do nothing |
|
2115 |
app.get('/backoffice/forms/%s/fields/move_page_fields?fields=4&page=2' % formdef.id) |
|
2116 |
formdef = FormDef.get(formdef.id) |
|
2117 |
assert [x.id for x in formdef.fields] == ['2', '0', '1', '3'] |
|
2118 | ||
2119 |
# move the fields of the page |
|
2120 |
app.get('/backoffice/forms/%s/fields/move_page_fields?fields=3&page=2' % formdef.id) |
|
2121 |
formdef = FormDef.get(formdef.id) |
|
2122 |
assert [x.id for x in formdef.fields] == ['2', '3', '0', '1'] |
|
2123 | ||
2124 |
# move the new first page |
|
2125 |
app.get('/backoffice/forms/%s/fields/update_order?order=3;0;1;2&element=2' % formdef.id) |
|
2126 |
formdef = FormDef.get(formdef.id) |
|
2127 |
assert [x.id for x in formdef.fields] == ['3', '0', '1', '2'] |
|
2128 |
# and the fields |
|
2129 |
app.get('/backoffice/forms/%s/fields/move_page_fields?fields=3&page=2' % formdef.id) |
|
2062 | 2130 |
formdef = FormDef.get(formdef.id) |
2063 | 2131 |
assert [x.id for x in formdef.fields] == ['0', '1', '2', '3'] |
2064 | 2132 |
wcs/admin/fields.py | ||
---|---|---|
17 | 17 |
# along with this program; if not, see <http://www.gnu.org/licenses/>. |
18 | 18 | |
19 | 19 |
import copy |
20 |
import json |
|
20 | 21 | |
21 | 22 |
from quixote import redirect |
22 | 23 |
from quixote.directory import Directory |
... | ... | |
213 | 214 | |
214 | 215 | |
215 | 216 |
class FieldsDirectory(Directory): |
216 |
_q_exports = ['', 'update_order', 'new', 'pages'] |
|
217 |
_q_exports = ['', 'update_order', 'move_page_fields', 'new', 'pages']
|
|
217 | 218 |
field_def_page_class = FieldDefPage |
218 | 219 |
blacklisted_types = [] |
219 | 220 |
page_id = None |
... | ... | |
395 | 396 |
pass |
396 | 397 | |
397 | 398 |
def update_order(self): |
399 |
get_response().set_content_type('application/json') |
|
398 | 400 |
request = get_request() |
401 | ||
402 |
if 'element' not in request.form: |
|
403 |
return json.dumps({'success': 'ko'}) |
|
404 |
if 'order' not in request.form: |
|
405 |
return json.dumps({'success': 'ko'}) |
|
406 | ||
407 |
dropped_element = request.form['element'] |
|
408 |
dropped_page_index = None |
|
409 | ||
399 | 410 |
new_order = request.form['order'].strip(';').split(';') |
400 | 411 |
new_fields = [] |
412 | ||
413 |
# build new ordered field list |
|
401 | 414 |
for y in new_order: |
402 |
for x in self.objectdef.fields: |
|
403 |
if x.id == y: |
|
404 |
new_fields.append(x) |
|
415 |
for i, x in enumerate(self.objectdef.fields): |
|
416 |
if x.id != y: |
|
417 |
continue |
|
418 |
new_fields.append(x) |
|
419 |
# if dropped field is a page, keep it's old index |
|
420 |
if x.id == dropped_element and x.type == 'page': |
|
421 |
dropped_page_index = i |
|
422 |
break |
|
423 | ||
424 |
# get the list of dropped page fields from old field list |
|
425 |
page_field_ids = [] |
|
426 |
if dropped_page_index is not None: |
|
427 |
for field in self.objectdef.fields[dropped_page_index + 1:]: |
|
428 |
if field.type == 'page': |
|
429 |
# next page found; break |
|
405 | 430 |
break |
431 |
page_field_ids.append(field.id) |
|
432 | ||
433 |
# check new field list composition |
|
434 |
if set(self.objectdef.fields) != set(new_fields): |
|
435 |
return json.dumps({'success': 'ko'}) |
|
436 | ||
437 |
self.objectdef.fields = new_fields |
|
438 |
self.objectdef.store(comment=_('Change in order of fields')) |
|
439 | ||
440 |
if not page_field_ids: |
|
441 |
return json.dumps({'success': 'ok'}) |
|
442 | ||
443 |
# propose to move also page fields |
|
444 |
return json.dumps({ |
|
445 |
'success': 'ok', |
|
446 |
'additional-action': { |
|
447 |
'message': _('Also move the fields of the page'), |
|
448 |
'url': 'move_page_fields?fields=%s&page=%s' % (';'.join(page_field_ids), dropped_element) |
|
449 |
} |
|
450 |
}) |
|
451 | ||
452 |
def move_page_fields(self): |
|
453 |
request = get_request() |
|
454 | ||
455 |
if 'fields' not in request.form: |
|
456 |
return redirect('.') |
|
457 |
if 'page' not in request.form: |
|
458 |
return redirect('.') |
|
459 | ||
460 |
field_ids = request.form['fields'].strip(';').split(';') |
|
461 |
# keep all fields except page fields |
|
462 |
new_fields = [f for f in self.objectdef.fields if f.id not in field_ids] |
|
463 |
# find page fields |
|
464 |
page_fields = [f for f in self.objectdef.fields if f.id in field_ids] |
|
465 |
# find page in new fields, and insert page_fields |
|
466 |
for i, field in enumerate(new_fields): |
|
467 |
if field.id != request.form['page']: |
|
468 |
continue |
|
469 |
new_fields = new_fields[:i+1] + page_fields + new_fields[i+1:] |
|
470 |
break |
|
471 | ||
472 |
# check new field list composition |
|
406 | 473 |
if set(self.objectdef.fields) != set(new_fields): |
407 |
return 'ko' |
|
474 |
return redirect('.') |
|
475 | ||
408 | 476 |
self.objectdef.fields = new_fields |
409 | 477 |
self.objectdef.store(comment=_('Change in order of fields')) |
410 |
return 'ok' |
|
478 | ||
479 |
return redirect('.') |
|
411 | 480 | |
412 | 481 |
def new(self): |
413 | 482 |
form = Form(enctype='multipart/form-data', action = 'new') |
wcs/qommon/static/js/biglist.js | ||
---|---|---|
8 | 8 |
$('ul.biglist.sortable li').each(function(i, elem) { |
9 | 9 |
$('<span class="handle">⣿</span>').prependTo(elem); |
10 | 10 |
}); |
11 | ||
12 |
const $move_page_field = $('<div class="move-page-field-content"></div>'); |
|
13 |
const $move_page_field_link = $('<a class="move-page-field-link"></a>').appendTo($move_page_field); |
|
14 |
$move_page_field.dialog({ |
|
15 |
autoOpen: false, |
|
16 |
minHeight: 0, |
|
17 |
dialogClass: "move-page-field oneline-dialog feedback-on-open", |
|
18 |
draggable: false, |
|
19 |
open: function() { |
|
20 |
$move_page_field.dialog('widget').removeClass('feedback-on-open'); |
|
21 |
}, |
|
22 |
close: function() { |
|
23 |
$move_page_field.dialog('widget').addClass('feedback-on-open'); |
|
24 |
} |
|
25 |
}); |
|
26 | ||
11 | 27 |
$('ul.biglist.sortable').sortable( |
12 | 28 |
{ |
13 | 29 |
handle: '.handle', |
... | ... | |
35 | 51 |
page_index += 1; |
36 | 52 |
} |
37 | 53 |
} |
54 |
$move_page_field.dialog('close'); |
|
38 | 55 |
var order_function = $(this).data('order-function') || 'update_order'; |
39 |
$.post(order_function, {'order': result}); |
|
56 |
$.post(order_function, {'order': result, 'element': $(ui.item)[0].id.substr(7, 50)}) |
|
57 |
.done(function(data) { |
|
58 |
if (data['success'] != "ok") return; |
|
59 |
if (!data['additional-action']) return; |
|
60 |
$move_page_field_link.attr('href', data['additional-action']['url']).html(data['additional-action']['message']); |
|
61 |
$move_page_field.dialog('option', 'position', { my: 'left top', at: 'left bottom', of: $(ui.item) }); |
|
62 |
$move_page_field.dialog('open'); |
|
63 |
}); |
|
40 | 64 |
}, |
41 | 65 |
} |
42 | 66 |
); |
43 |
- |