Commit bab963e4 authored by Jérome Perrin's avatar Jérome Perrin

Support Request: "Comment {Date,Author}" on frontpage

Originally, there was a regression introduce in my recent changes that "Comment Author" column was always empty.

This MR contains some more refactoring for "Comment Date" and "Comment Author" columns:

![image](/uploads/7b07a6a5610d533f1435af45b3716104/image.png)

On the visible side, "Comment Date" column has been simplified, it used to show "hour:minutes" if the message was posted today, and "year/month/day" if the post was older. It's now a simple date time field (using `Base_viewCRMFieldLibrary/my_event_start_date`), for consistency.

On the implementation side, they now use existing `SupportRequest_getCommentPostListAsJson` script, which simplified code a lot. That script was also renamed as `SupportRequest_getCommentPostList`, because it's no longer returning JSON.

/reviewed-on nexedi/erp5!804
parents e19743d7 4fcbb0f3
......@@ -93,9 +93,8 @@
<string>listbox_destination_decision_language</string>
<string>listbox_causality_translated_portal_type</string>
<string>listbox_delivery_start_date</string>
<string>listbox_post_start_date_hidden</string>
<string>listbox_post_user</string>
<string>listbox_post_start_date</string>
<string>listbox_post_user</string>
</list>
</value>
</item>
......
......@@ -10,8 +10,10 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>date_only</string>
<string>default</string>
<string>editable</string>
<string>input_order</string>
</list>
</value>
</item>
......@@ -71,6 +73,10 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>input_order</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
......@@ -82,9 +88,15 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>date_only</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>editable</string> </key>
......@@ -92,11 +104,15 @@
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
<value> <string>my_event_start_date</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
<value> <string>Base_viewCRMFieldLibrary</string> </value>
</item>
<item>
<key> <string>input_order</string> </key>
<value> <string>ymd</string> </value>
</item>
<item>
<key> <string>target</string> </key>
......@@ -116,7 +132,7 @@
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: cell.SupportRequest_getLastPostDate()</string> </value>
<value> <string>cell/SupportRequest_getLastPostDate</string> </value>
</item>
</dictionary>
</pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>default</string>
<string>editable</string>
<string>input_order</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_post_start_date_hidden</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>input_order</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_date</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>input_order</string> </key>
<value> <string>ymd</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: cell.SupportRequest_getLastPostDate(is_pure_date=True)</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
document_type_list = portal.getPortalDocumentTypeList()
event_list = portal.portal_simulation.getMovementHistoryList(
security_query=portal.portal_catalog.getSecurityQuery(),
portal_type=portal.getPortalEventTypeList(),
strict_follow_up_uid=context.getUid(),
simulation_state=('started', 'stopped', 'delivered', ),
only_accountable=False,
omit_input=True,
sort_on=(('date', 'asc'), ('uid', 'asc',),)
)
comment_list = []
for event in event_list:
event = event.getObject()
attachment_link = attachment_name = None
attachment = event.getDefaultAggregateValue(portal_type=document_type_list)
if attachment is not None:
attachment_link, attachment_name = attachment.getRelativeUrl(), attachment.getFilename()
comment_list.append((dict(
user=event.getSourceTitle(),
date=event.getStartDate().ISO8601(),
text=event.asStrippedHTML(),
attachment_link=attachment_link,
attachment_name=attachment_name,
message_id=event.getSourceReference(),
)))
just_posted_comment = portal.portal_sessions[
'%s.latest_comment' % context.getRelativeUrl()].pop(
'comment_post_list', None)
if just_posted_comment is not None:
# make sure not to display twice if it was already ingested in the meantime.
if just_posted_comment['message_id'] not in [comment['message_id'] for comment in comment_list]:
comment_list.append(just_posted_comment)
return comment_list
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SupportRequest_getCommentPostList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from json import dumps
portal = context.getPortalObject()
document_type_list = portal.getPortalDocumentTypeList()
event_list = portal.portal_simulation.getMovementHistoryList(
security_query=portal.portal_catalog.getSecurityQuery(),
portal_type=portal.getPortalEventTypeList(),
strict_follow_up_uid=context.getUid(),
simulation_state=('started', 'stopped', 'delivered', ),
only_accountable=False,
omit_input=True,
sort_on=(('date', 'asc'), ('uid', 'asc',),)
)
comment_list = []
for event in event_list:
event = event.getObject()
attachment_link = attachment_name = None
attachment = event.getDefaultAggregateValue(portal_type=document_type_list)
if attachment is not None:
attachment_link, attachment_name = attachment.getRelativeUrl(), attachment.getFilename()
comment_list.append((dict(
user=event.getSourceTitle(),
date=event.getStartDate().ISO8601(),
text=event.asStrippedHTML(),
attachment_link=attachment_link,
attachment_name=attachment_name,
message_id=event.getSourceReference(),
)))
just_posted_comment = portal.portal_sessions[
'%s.latest_comment' % context.getRelativeUrl()].pop(
'comment_post_list', None)
if just_posted_comment is not None:
# make sure not to display twice if it was already ingested in the meantime.
if just_posted_comment['message_id'] not in [comment['message_id'] for comment in comment_list]:
comment_list.append(just_posted_comment)
return dumps(comment_list)
return dumps(context.SupportRequest_getCommentPostList())
portal = context.getPortalObject()
# get the related Support Request, this should not be None
support_request_list = portal.portal_catalog(portal_type="Support Request", id=context.getId()) # with id keyword, this function will return a sequence data type which contains one element.
support_request_object = support_request_list[0].getObject()
# get the all HTML Posts which related to this Support Request
post_list = portal.portal_catalog(portal_type="HTML Post", strict_follow_up_uid=support_request_object.getUid(), sort_on=(('modification_date', 'descending'),), limit=1, validation_state="published") # with id keyword, this function will return a sequence data type which contains one element.
if len(post_list):
return post_list[0].Base_getOwnerTitle()
else:
return None
comment_list = context.SupportRequest_getCommentPostList()
if comment_list:
return comment_list[-1]['user']
portal = context.getPortalObject()
# get the related Support Request, this should not be None
support_request_list = portal.portal_catalog(portal_type="Support Request", id=context.getId()) # with id keyword, this function will return a sequence data type which contains one element.
support_request_object = support_request_list[0].getObject()
# get the all HTML Posts which related to this Support Request
post_list = portal.portal_catalog(portal_type="HTML Post", strict_follow_up_uid=support_request_object.getUid()) # with id keyword, this function will return a sequence data type which contains one element.
post_list = sorted(post_list, key=lambda x:x.getStartDate(), reverse=True)
preferred_date_order = portal.portal_preferences.getPreferredDateOrder()
if post_list:
# raise NotImplementedError(post_list[0].getStartDate())
post_date = post_list[0].getStartDate()
if is_pure_date:
return post_date
# raise NotImplementedError(post_date.strftime("%H:%M:%S"))
if post_date.isCurrentDay():
return post_date.strftime("%H:%M:%S")
else:
if preferred_date_order == 'dmy':
return "%s/%s/%s" % (post_date.dd(), post_date.mm(), post_date.year())
if preferred_date_order == 'mdy':
return "%s/%s/%s" % (post_date.mm(), post_date.dd(), post_date.year())
# ymd
return "%s/%s/%s" % (post_date.year(), post_date.mm(), post_date.dd())
else:
return None
from DateTime import DateTime
comment_list = context.SupportRequest_getCommentPostList()
if comment_list:
return DateTime(comment_list[-1]['date'])
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>is_pure_date=False</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testLatestPostOnFrontPage</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode>Test "Comment Date" and "Comment Author" on Front Page</unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head>
<title tal:content="template/title">The title</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3" tal:content="template/title">Support Request Zuite</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_SupportRequestUITemplate/macros/init" />
<tr><td colspan="3"><b>Post a new SR message</b></td></tr>
<tr><td>open</td>
<td>${base_url}/web_site_module/erp5_officejs_support_request_ui/</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//input[@data-i18n='[value]Submit New Support Request']</td><td></td></tr>
<tr><td>click</td>
<td>//input[@data-i18n='[value]Submit New Support Request']</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//input[@data-i18n="[value]Proceed"]</td><td></td></tr>
<tr><td>type</td>
<td>//input[@name='field_your_title']</td>
<td>testLatestPostOnFrontPage</td></tr>
<tr><td>select</td>
<td>field_your_project</td>
<td>RobotMaking</td></tr>
<tr><td>waitForTextPresent</td>
<td>FeatureRequire</td></tr>
<tr><td>select</td>
<td>field_your_resource</td>
<td>FeatureRequire</td></tr>
<tal:block tal:define="text_content string:Post test">
<tal:block metal:use-macro="container/Zuite_CommonTemplateForRenderjsUi/macros/type_ckeditor_text_content"/></tal:block>
<tr><td>click</td>
<td>//input[@data-i18n='[value]Proceed']</td><td></td></tr>
<tr><td>waitForText</td>
<td>//ol[@id="post_list"]//li/p</td>
<td>Post test</td></tr>
<tr><td colspan="3"><b>Go back ot front page and check "latest post" columns</b></td></tr>
<tr><td>openAndWait</td>
<td>${base_url}/Zuite_waitForActivities</td><td></td></tr>
<tr><td>waitForTextPresent</td>
<td>Done.</td><td></td></tr>
<tr><td>open</td>
<td>${base_url}/web_site_module/erp5_officejs_support_request_ui/</td><td></td></tr>
<tr><td>waitForText</td>
<td>//div[@class="document_table"]//tr[1]/td[1]</td>
<td>testLatestPostOnFrontPage</td></tr>
<tr><td>assertText</td>
<td>//div[@class="document_table"]//tr[1]/td[5]</td>
<td tal:content="python: 'glob:*{}*'.format(modules['DateTime'].DateTime().year())"></td></tr>
<tr><td>assertText</td>
<td>//div[@class="document_table"]//tr[1]/td[6]</td>
<td>A1 Corporation</td></tr><!-- because this test run as a ZODB user, the post author is the organisation -->
</tbody></table>
</body>
</html>
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment