backoffice: add user selection support on edit page (#49812)
This commit is contained in:
parent
2be30c3668
commit
8ead3895a3
|
@ -2755,6 +2755,105 @@ def test_backoffice_wfedit_and_data_source_with_field_info(pub):
|
|||
resp = resp.follow()
|
||||
|
||||
|
||||
def test_backoffice_wfedit_and_user_selection(pub):
|
||||
user = create_user(pub)
|
||||
create_environment(pub)
|
||||
formdef = FormDef.get_by_urlname('form-title')
|
||||
form_class = formdef.data_class()
|
||||
|
||||
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
||||
number31.store()
|
||||
|
||||
# attach a custom workflow
|
||||
workflow = Workflow(name='wfedit')
|
||||
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
||||
|
||||
wfedit = EditableWorkflowStatusItem()
|
||||
wfedit.id = '_wfedit'
|
||||
wfedit.by = [user.roles[0]]
|
||||
st1.items.append(wfedit)
|
||||
wfedit.parent = st1
|
||||
workflow.store()
|
||||
|
||||
formdef.workflow_id = workflow.id
|
||||
formdef.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
|
||||
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
||||
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
||||
assert 'Associated User' not in resp
|
||||
resp = resp.form.submit('button_wfedit')
|
||||
resp = resp.follow()
|
||||
|
||||
assert resp.pyquery('.submit-user-selection')
|
||||
resp.form['user_id'] = str(user.id) # happens via javascript
|
||||
resp = resp.form.submit('submit')
|
||||
resp = resp.follow()
|
||||
assert 'Associated User' in resp
|
||||
assert formdef.data_class().get(number31.id).user_id == str(user.id)
|
||||
|
||||
|
||||
def test_backoffice_wfedit_and_user_selection_multi_page(pub):
|
||||
user = create_user(pub)
|
||||
create_environment(pub)
|
||||
formdef = FormDef.get_by_urlname('form-title')
|
||||
formdef.fields.insert(0, fields.PageField(id='0', label='1st page', type='page'))
|
||||
formdef.fields.append(fields.PageField(id='4', label='2nd page', type='page'))
|
||||
form_class = formdef.data_class()
|
||||
|
||||
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
||||
number31.store()
|
||||
|
||||
# attach a custom workflow
|
||||
workflow = Workflow(name='wfedit')
|
||||
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
||||
|
||||
wfedit = EditableWorkflowStatusItem()
|
||||
wfedit.id = '_wfedit'
|
||||
wfedit.by = [user.roles[0]]
|
||||
st1.items.append(wfedit)
|
||||
wfedit.parent = st1
|
||||
workflow.store()
|
||||
|
||||
formdef.workflow_id = workflow.id
|
||||
formdef.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
|
||||
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
||||
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
||||
assert 'Associated User' not in resp
|
||||
resp = resp.form.submit('button_wfedit')
|
||||
resp = resp.follow()
|
||||
|
||||
assert resp.pyquery('.submit-user-selection')
|
||||
resp.form['user_id'] = str(user.id) # happens via javascript
|
||||
resp = resp.form.submit('submit') # -> 2nd page
|
||||
assert resp.pyquery('.submit-user-selection')
|
||||
resp = resp.form.submit('submit') # -> save changes
|
||||
resp = resp.follow()
|
||||
assert 'Associated User' in resp
|
||||
assert formdef.data_class().get(number31.id).user_id == str(user.id)
|
||||
|
||||
number31.store() # save and lose associated user id
|
||||
|
||||
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
||||
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
||||
assert 'Associated User' not in resp
|
||||
resp = resp.form.submit('button_wfedit')
|
||||
resp = resp.follow()
|
||||
|
||||
assert resp.pyquery('.submit-user-selection')
|
||||
resp = resp.form.submit('submit') # -> 2nd page
|
||||
assert resp.pyquery('.submit-user-selection')
|
||||
resp.form['user_id'] = str(user.id) # happens via javascript
|
||||
resp = resp.form.submit('submit') # -> save changes
|
||||
resp = resp.follow()
|
||||
assert 'Associated User' in resp
|
||||
assert formdef.data_class().get(number31.id).user_id == str(user.id)
|
||||
|
||||
|
||||
def test_global_listing(pub):
|
||||
if not pub.is_using_postgresql():
|
||||
pytest.skip('this requires SQL')
|
||||
|
|
|
@ -603,3 +603,43 @@ def test_block_card_item_link(pub, blocks_feature):
|
|||
resp = app.get('/backoffice/management' + resp.request.path)
|
||||
assert '<div class="value"><a href="http://example.net/backoffice/data/foo/%s/">card plop</a></div></div>' % card.id in resp
|
||||
assert '<div class="value"><a href="http://example.net/backoffice/data/foo/%s/">card plop2</a></div></div>' % card2.id in resp
|
||||
|
||||
|
||||
def test_carddata_edit_user_selection(pub):
|
||||
CardDef.wipe()
|
||||
user = create_user(pub)
|
||||
carddef = CardDef()
|
||||
carddef.name = 'foo'
|
||||
carddef.fields = [
|
||||
fields.StringField(id='1', label='Test', type='string', varname='foo'),
|
||||
]
|
||||
carddef.backoffice_submission_roles = user.roles
|
||||
carddef.workflow_roles = {'_editor': user.roles[0]}
|
||||
carddef.store()
|
||||
carddef.data_class().wipe()
|
||||
|
||||
carddata = carddef.data_class()()
|
||||
carddata.data = {'1': 'plop'}
|
||||
carddata.just_created()
|
||||
carddata.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/data/foo/%s/' % carddata.id)
|
||||
assert 'Edit Card' in resp.text
|
||||
resp = resp.form.submit('button_editable')
|
||||
resp = resp.follow()
|
||||
assert 'Associated User' not in resp
|
||||
|
||||
carddef.user_support = 'optional'
|
||||
carddef.store()
|
||||
resp = app.get('/backoffice/data/foo/%s/' % carddata.id)
|
||||
assert 'Edit Card' in resp.text
|
||||
resp = resp.form.submit('button_editable')
|
||||
resp = resp.follow()
|
||||
assert 'Associated User' in resp
|
||||
assert resp.pyquery('.submit-user-selection')
|
||||
resp.form['user_id'] = str(user.id) # happens via javascript
|
||||
resp = resp.form.submit('submit') # -> save changes
|
||||
resp = resp.follow()
|
||||
assert 'Associated User' in resp
|
||||
assert carddef.data_class().get(carddata.id).user_id == str(user.id)
|
||||
|
|
|
@ -2549,7 +2549,7 @@ class FormBackOfficeStatusPage(FormStatusPage):
|
|||
|
||||
return response
|
||||
|
||||
def get_extra_context_bar(self):
|
||||
def get_extra_context_bar(self, parent=None):
|
||||
formdata = self.filled
|
||||
|
||||
r = TemplateIO(html=True)
|
||||
|
@ -2636,7 +2636,7 @@ class FormBackOfficeStatusPage(FormStatusPage):
|
|||
|
||||
r += self.get_extra_submission_context_bar()
|
||||
r += self.get_extra_submission_channel_bar()
|
||||
r += self.get_extra_submission_user_id_bar()
|
||||
r += self.get_extra_submission_user_id_bar(parent=parent)
|
||||
r += self.get_extra_geolocation_bar()
|
||||
if formdata.formdef.lateral_template:
|
||||
r += htmltext('<div data-async-url="%slateral-block"></div>' % formdata.get_url(backoffice=True))
|
||||
|
@ -2705,10 +2705,10 @@ class FormBackOfficeStatusPage(FormStatusPage):
|
|||
|
||||
return r.getvalue()
|
||||
|
||||
def get_extra_submission_user_id_bar(self):
|
||||
def get_extra_submission_user_id_bar(self, parent):
|
||||
formdata = self.filled
|
||||
r = TemplateIO(html=True)
|
||||
if formdata.user_id and formdata.get_user():
|
||||
if formdata and formdata.user_id and formdata.get_user():
|
||||
r += htmltext('<div class="extra-context">')
|
||||
r += htmltext('<h3>%s</h3>') % _('Associated User')
|
||||
users_cfg = get_cfg('users', {})
|
||||
|
@ -2722,6 +2722,24 @@ class FormBackOfficeStatusPage(FormStatusPage):
|
|||
else:
|
||||
r += htmltext('<p>%s</p>') % formdata.get_user().display_name
|
||||
r += htmltext('</div>')
|
||||
elif parent and parent.has_user_support and parent.edit_mode:
|
||||
r += self.get_extra_submission_user_selection_bar(parent=parent)
|
||||
return r.getvalue()
|
||||
|
||||
def get_extra_submission_user_selection_bar(self, parent=None):
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<div class="submit-user-selection" style="display: none;">')
|
||||
get_response().add_javascript(['select2.js'])
|
||||
r += htmltext('<h3>%s</h3>') % _('Associated User')
|
||||
r += htmltext('<select>')
|
||||
if parent and parent.selected_user_id:
|
||||
r += htmltext('<option value="%s">%s</option>') % (
|
||||
parent.selected_user_id,
|
||||
get_publisher().user_class.get(parent.selected_user_id, ignore_errors=True)
|
||||
)
|
||||
r += htmltext('</select>')
|
||||
r += htmltext('</div>')
|
||||
|
||||
return r.getvalue()
|
||||
|
||||
def get_extra_geolocation_bar(self):
|
||||
|
|
|
@ -227,7 +227,7 @@ class FormFillPage(PublicFormFillPage):
|
|||
from .management import FormBackOfficeStatusPage
|
||||
if self.on_validation_page or self.edit_mode:
|
||||
if formdata:
|
||||
r += FormBackOfficeStatusPage(self.formdef, formdata).get_extra_context_bar()
|
||||
r += FormBackOfficeStatusPage(self.formdef, formdata).get_extra_context_bar(parent=self)
|
||||
else:
|
||||
if formdata and formdata.submission_context and \
|
||||
set(formdata.submission_context.keys()) != {'return_url'}:
|
||||
|
@ -249,19 +249,10 @@ class FormFillPage(PublicFormFillPage):
|
|||
r += htmltext('</div>')
|
||||
|
||||
if formdata and formdata.user_id:
|
||||
r += FormBackOfficeStatusPage(self.formdef, formdata).get_extra_submission_user_id_bar()
|
||||
r += FormBackOfficeStatusPage(self.formdef, formdata).get_extra_submission_user_id_bar(parent=self)
|
||||
elif self.has_user_support:
|
||||
r += htmltext('<div class="submit-user-selection" style="display: none;">')
|
||||
get_response().add_javascript(['select2.js'])
|
||||
r += htmltext('<h3>%s</h3>') % _('Associated User')
|
||||
r += htmltext('<select>')
|
||||
if self.selected_user_id:
|
||||
r += htmltext('<option value="%s">%s</option>') % (
|
||||
self.selected_user_id,
|
||||
get_publisher().user_class.get(self.selected_user_id, ignore_errors=True)
|
||||
)
|
||||
r += htmltext('</select>')
|
||||
r += htmltext('</div>')
|
||||
r += FormBackOfficeStatusPage(self.formdef, formdata).get_extra_submission_user_selection_bar(parent=self)
|
||||
|
||||
if self.formdef.submission_lateral_template:
|
||||
r += htmltext('<div data-async-url="%slateral-block"></div>' % self.formdef.get_backoffice_submission_url())
|
||||
return r.getvalue()
|
||||
|
|
|
@ -156,7 +156,7 @@ class FormStatusPage(Directory, FormTemplateMixin):
|
|||
if not q in self._q_exports:
|
||||
self._q_exports.append(q)
|
||||
|
||||
if self.formdef.workflow and register_workflow_subdirs:
|
||||
if self.formdata and self.formdef.workflow and register_workflow_subdirs:
|
||||
for name, directory in self.formdef.workflow.get_subdirectories(self.filled):
|
||||
self._q_exports.append(name)
|
||||
setattr(self, name, directory)
|
||||
|
|
|
@ -1362,6 +1362,9 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
if k.startswith(WorkflowBackofficeFieldsFormDef.field_prefix):
|
||||
new_data[k] = v
|
||||
self.edited_data.data = new_data
|
||||
if getattr(self, 'selected_user_id', None):
|
||||
# user selection in backoffice
|
||||
self.edited_data.user_id = self.selected_user_id
|
||||
self.edited_data.store()
|
||||
# remove previous vars and formdata from substitution variables
|
||||
self.clean_submission_context()
|
||||
|
|
Loading…
Reference in New Issue