misc: anchor user at action form after submit (#40421)

This commit is contained in:
Frédéric Péters 2020-03-03 17:43:58 +01:00
parent 45554f40b0
commit d763b18b60
5 changed files with 124 additions and 15 deletions

View File

@ -33,7 +33,7 @@ from wcs.qommon.form import PicklableUpload
from wcs.qommon.ident.password_accounts import PasswordAccount
from wcs.qommon.http_request import HTTPRequest
from wcs.qommon.substitution import CompatibilityNamesDict
from wcs.roles import Role
from wcs.roles import Role, logged_users_role
from wcs.workflows import (Workflow, CommentableWorkflowStatusItem,
ChoiceWorkflowStatusItem, EditableWorkflowStatusItem,
DisplayMessageWorkflowStatusItem,
@ -6144,3 +6144,48 @@ def test_backoffice_create_carddata_from_formdata(pub, studio):
resp = app.get(formdata.get_url(backoffice=True))
resp = resp.form.submit(name='button_createcard').follow()
assert 'Card nr. 1-1 created' in resp
def test_backoffice_after_submit_location(pub):
create_superuser(pub)
create_environment(pub)
workflow = Workflow(name='test')
st1 = workflow.add_status('Status1', 'st1')
commentable = CommentableWorkflowStatusItem()
commentable.id = '_commentable'
commentable.by = [logged_users_role().id]
commentable.required = True
st1.items.append(commentable)
commentable.parent = st1
workflow.store()
formdef = FormDef.get_by_urlname('form-title')
formdef.store()
formdef.workflow_id = workflow.id
formdef.store()
for formdata in formdef.data_class().select():
formdata.status = 'wf-%s' % st1.id
formdata.store()
app = login(get_app(pub))
resp = app.get(formdata.get_url(backoffice=True))
resp.form['comment'] = 'plop'
resp = resp.form.submit('submit')
assert resp.location == 'http://example.net/backoffice/management/form-title/%s/#action-zone' % formdata.id
resp = resp.follow()
display = DisplayMessageWorkflowStatusItem()
display.message = 'message-to-all'
display.to = []
st1.items.append(display)
display.parent = st1
workflow.store()
resp.form['comment'] = 'plop'
resp = resp.form.submit('submit')
assert resp.location == 'http://example.net/backoffice/management/form-title/%s/#' % formdata.id

View File

@ -3500,7 +3500,7 @@ def test_formdata_generated_document_download(pub):
resp = login(get_app(pub), username='foo', password='foo').get(form_location)
resp = resp.form.submit('button_export_to')
assert resp.location == form_location
assert resp.location == form_location + '#action-zone'
resp = resp.follow() # back to form page
resp = resp.click('test.rtf')
@ -3520,7 +3520,7 @@ def test_formdata_generated_document_download(pub):
resp = login(get_app(pub), username='foo', password='foo').get(form_location)
resp = resp.form.submit('button_export_to')
assert resp.location == form_location
assert resp.location == form_location + '#action-zone'
resp = resp.follow() # back to form page
assert resp.click('test.rtf', index=0).follow().text == 'HELLO WORLD'
@ -3536,7 +3536,7 @@ def test_formdata_generated_document_download(pub):
resp = login(get_app(pub), username='foo', password='foo').get(form_location)
resp = resp.form.submit('button_export_to')
assert resp.location == form_location
assert resp.location == form_location + '#action-zone'
resp = resp.follow()
assert resp.click('test.rtf', index=2).follow().text == 'HELLO {{DJANGO}} WORLD {\\uc1{test}}'
@ -3607,7 +3607,7 @@ def test_formdata_generated_document_odt_download(pub, odt_template):
resp = login(get_app(pub), username='foo', password='foo').get(form_location)
resp = resp.form.submit('button_export_to')
assert resp.location == form_location
assert resp.location == form_location + '#action-zone'
resp = resp.follow() # back to form page
resp = resp.click(odt_template)
@ -3627,7 +3627,7 @@ def test_formdata_generated_document_odt_download(pub, odt_template):
resp = login(get_app(pub), username='foo', password='foo').get(form_location)
resp = resp.form.submit('button_export_to')
assert resp.location == form_location
assert resp.location == form_location + '#action-zone'
resp = resp.follow() # back to form page
with open(os.path.join(os.path.dirname(__file__), 'template-out.odt'), 'rb') as f:
@ -3685,7 +3685,7 @@ def test_formdata_generated_document_odt_download_with_substitution_variable(pub
resp = login(get_app(pub), username='foo', password='foo').get(form_location)
resp = resp.form.submit('button_export_to')
assert resp.location == form_location
assert resp.location == form_location + '#action-zone'
resp = resp.follow() # back to form page
resp = resp.click('template.odt')
@ -3705,7 +3705,7 @@ def test_formdata_generated_document_odt_download_with_substitution_variable(pub
resp = login(get_app(pub), username='foo', password='foo').get(form_location)
resp = resp.form.submit('button_export_to')
assert resp.location == form_location
assert resp.location == form_location + '#action-zone'
resp = resp.follow() # back to form page
with open(os.path.join(os.path.dirname(__file__), 'template-out.odt'), 'rb') as f:
@ -3804,7 +3804,7 @@ def test_formdata_generated_document_odt_to_pdf_download(pub):
resp = login(get_app(pub), username='foo', password='foo').get(form_location)
resp = resp.form.submit('button_export_to')
assert resp.location == form_location
assert resp.location == form_location + '#action-zone'
resp = resp.follow() # back to form page
resp = resp.click('template.pdf')
@ -3905,7 +3905,7 @@ def test_formdata_generated_document_odt_to_pdf_download_push_to_portfolio(pub,
assert payload['origin'] == 'example.net'
assert base64.decodestring(force_bytes(payload['file_b64_content'])).startswith(b'%PDF')
assert caplog.records[-1].message.startswith("file 'template.pdf' pushed to portfolio of 'Foo")
assert resp.location == form_location
assert resp.location == form_location + '#action-zone'
resp = resp.follow() # back to form page
resp = resp.click('template.pdf')
@ -4161,7 +4161,7 @@ def test_formdata_form_file_download(pub):
formdata = formdef.data_class().select()[0]
assert 'xxx_var_yyy_raw' in formdata.workflow_data
download = resp.test_app.get(resp.location + 'files/form-xxx-yyy/test.txt')
download = resp.test_app.get(urlparse.urljoin(resp.location, 'files/form-xxx-yyy/test.txt'))
assert download.content_type == 'text/plain'
assert download.body == b'foobar'
@ -7829,3 +7829,49 @@ def test_field_live_locked_error_prefilled_field(pub, http_requests):
resp = app.get('/foo/')
assert 'readonly' in resp.form['f2'].attrs
assert not resp.form['f2'].attrs.get('value')
def test_after_submit_location(pub):
create_user(pub)
workflow = Workflow(name='test')
st1 = workflow.add_status('Status1', 'st1')
commentable = CommentableWorkflowStatusItem()
commentable.id = '_commentable'
commentable.by = [logged_users_role().id]
commentable.required = True
st1.items.append(commentable)
commentable.parent = st1
workflow.store()
formdef = create_formdef()
formdef.fields = []
formdef.store()
formdef.workflow_id = workflow.id
formdef.store()
formdef.data_class().wipe()
app = login(get_app(pub), username='foo', password='foo')
resp = app.get('/test/')
resp = resp.forms[0].submit('submit') # form page
resp = resp.forms[0].submit('submit') # confirmation page
resp = resp.follow()
resp.form['comment'] = 'plop'
resp = resp.form.submit('submit')
assert resp.location == 'http://example.net/test/1/#action-zone'
resp = resp.follow()
display = DisplayMessageWorkflowStatusItem()
display.message = 'message-to-all'
display.to = []
st1.items.append(display)
display.parent = st1
workflow.store()
resp.form['comment'] = 'plop'
resp = resp.form.submit('submit')
assert resp.location == 'http://example.net/test/1/#'

View File

@ -328,7 +328,6 @@ class FormStatusPage(Directory, FormTemplateMixin):
form.attrs['data-live-url'] = self.filled.get_url() + 'live'
return form
def check_submitted_form(self, form):
if form and form.is_submitted():
submit_button_name = form.get_submit()
@ -341,6 +340,17 @@ class FormStatusPage(Directory, FormTemplateMixin):
url = self.submit(form)
if url is None:
url = get_request().get_frontoffice_url()
status = self.filled.get_status()
top_alert = False
for item in status.items or []:
if item.key == 'displaymsg' and item.position == 'top' and item.is_for_current_user(self.filled):
top_alert = True
break
if top_alert:
# prevent an existing anchor client side to take effect
url += '#'
else:
url += '#action-zone'
response = get_response()
response.set_status(303)
response.headers[str('location')] = url
@ -591,7 +601,11 @@ class FormStatusPage(Directory, FormTemplateMixin):
r += self.history()
r += htmltext(self.bottom_workflow_messages())
bottom_workflow_messages = self.bottom_workflow_messages()
if bottom_workflow_messages or form:
r += htmltext('<span id="action-zone"></span>')
r += htmltext(bottom_workflow_messages)
locked = False
if form:

View File

@ -23,7 +23,11 @@
{{ view.receipt|safe }}
{{ view.history|safe }}
{{ view.bottom_workflow_messages|safe }}
{% with workflow_messages=view.bottom_workflow_messages %}
{% if workflow_messages or workflow_form %}<span id="action-zone"></span>{% endif %}
{{ workflow_messages|safe }}
{% endwith %}
{% if workflow_form %}
{{ view.actions_workflow_messages|safe }}
{{ workflow_form.render|safe }}

View File

@ -229,7 +229,7 @@ class ExportToModel(WorkflowStatusItem):
self.perform_real(formdata, evo)
in_backoffice = get_request() and get_request().is_in_backoffice()
if self.attach_to_history:
return formdata.get_url(backoffice=in_backoffice)
return
base_url = formdata.get_url(backoffice=in_backoffice)
return base_url + self.get_directory_name()