Commit 8056ec16 authored by Ayush Tiwari's avatar Ayush Tiwari

Historical Revision: Use DiffTool to show differences in Historical Revisions

/reviewed-on nexedi/erp5!747
parents a2747dde 15a041c4
<?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>testHistoricalDiff</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></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test History Available from edit_workflow</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test History and edit_workflow</td></tr>
</thead><tbody>
<tr>
<td>store</td>
<td tal:content="python:here.getPortalObject().absolute_url()">http://example.com/erp5</td>
<td>base_url</td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/Zuite_waitForActivities</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/FooModule_createObjects?portal_type=Bar&amp;num:int=1</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/0</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 1</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 2</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 3</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=History</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number x0_listbox-current-page-total-number"]</td>
<td>4 records</td> <!-- Creation + edited 3 times -->
</tr>
<!-- First modification -->
<tr>
<td>clickAndWait</td>
<td>//tr[@class='x0_listbox-data-line-1 DataB']/td[4]/a</td>
<td></td>
</tr>
<tr>
<td>assertTitle</td>
<td>Historical Comparison - Version 3*</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number"]</td>
<td>1 records</td> <!-- Only one property changed. -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[1]</td>
<td>title</td>
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]</td>
<td>Title 0</td> <!-- before -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]</td>
<td>Version 1</td> <!-- after -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]</td>
<td>Version 3</td> <!-- now -->
</tr>
<tr>
<td>clickAndWait</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]//a</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[1]</td>
<td>title</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td>
<td></td>
</tr>
<tr>
<td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td>
<td>_data_gadget_value</td>
</tr>
<tr>
<td>verifyEval</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>---+++@@-1+1@@-Title0+Version1</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=History</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number x0_listbox-current-page-total-number"]</td>
<td>4 records</td> <!-- Creation + edited 3 times -->
</tr>
<!-- First modification -->
<tr>
<td>clickAndWait</td>
<td>//tr[@class='x0_listbox-data-line-1 DataB']/td[4]/a</td>
<td></td>
</tr>
<tr>
<td>assertTitle</td>
<td>Historical Comparison - Version 3*</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]//a</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[1]</td>
<td>title</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td>
<td></td>
</tr>
<tr>
<td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td>
<td>_data_gadget_value</td>
</tr>
<tr>
<td>verifyEval</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>---+++@@-1+1@@-Version1+Version3</td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?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>testHistoricalDiffNoLinkForCurrentChange</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></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test History Available from edit_workflow</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test Historical Diff For Links</td></tr>
</thead><tbody>
<tr>
<td>store</td>
<td tal:content="python:here.getPortalObject().absolute_url()">http://example.com/erp5</td>
<td>base_url</td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/Zuite_waitForActivities</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/FooModule_createObjects?portal_type=Bar&amp;num:int=1</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/0</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 1</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 2</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 3</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=History</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number x0_listbox-current-page-total-number"]</td>
<td>4 records</td> <!-- Creation + edited 3 times -->
</tr>
<!-- First modification -->
<tr>
<td>clickAndWait</td>
<td>//tr[@class='x0_listbox-data-line-3 DataB']/td[4]/a</td>
<td></td>
</tr>
<tr>
<td>assertTitle</td>
<td>Historical Comparison - Version 3*</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number"]</td>
<td>1 records</td> <!-- Only one property changed. -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[1]</td>
<td>title</td>
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]</td>
<td>Version 2</td> <!-- before -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]</td>
<td>Version 3</td> <!-- after -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]</td>
<td>Version 3</td> <!-- now -->
</tr>
<tr>
<td>clickAndWait</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]//a</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[1]</td>
<td>title</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td>
<td></td>
</tr>
<tr>
<td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td>
<td>_data_gadget_value</td>
</tr>
<tr>
<td>verifyEval</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>---+++@@-1+1@@-Version2+Version3</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=History</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number x0_listbox-current-page-total-number"]</td>
<td>4 records</td> <!-- Creation + edited 3 times -->
</tr>
<!-- First modification -->
<tr>
<td>clickAndWait</td>
<td>//tr[@class='x0_listbox-data-line-3 DataB']/td[4]/a</td>
<td></td>
</tr>
<tr>
<td>assertTitle</td>
<td>Historical Comparison - Version 3*</td>
<td></td>
</tr>
<tr>
<td>assertElementNotPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]//a</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
...@@ -130,21 +130,20 @@ ...@@ -130,21 +130,20 @@
<td>title</td> <td>title</td>
</tr> </tr>
<tr> <tr>
<td>assertElementPresent</td> <td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td> <td>//tr[@class='listbox-data-line-0 DataA']/td[2]</td>
<td></td> <td>Title 0</td> <!-- before -->
</tr> </tr>
<tr> <tr>
<td>storeEval</td> <td>assertText</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td> <td>//tr[@class='listbox-data-line-0 DataA']/td[3]</td>
<td>_data_gadget_value</td> <td>Version 1</td> <!-- after -->
</tr> </tr>
<tr> <tr>
<td>verifyEval</td> <td>assertText</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td> <td>//tr[@class='listbox-data-line-0 DataA']/td[4]</td>
<td>---+++@@-1+1@@-Title0+Version1</td> <td>Version 3</td> <!-- now -->
</tr> </tr>
</tal:block> </tal:block>
<tal:block tal:condition="python: context.TestTool_getSkinName()=='Mobile'"> <tal:block tal:condition="python: context.TestTool_getSkinName()=='Mobile'">
...@@ -191,21 +190,20 @@ ...@@ -191,21 +190,20 @@
<td>title</td> <td>title</td>
</tr> </tr>
<tr> <tr>
<td>assertElementPresent</td> <td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td> <td>//tr[@class='listbox-data-line-0 DataA']/td[2]</td>
<td></td> <td>Version 1</td> <!-- before -->
</tr> </tr>
<tr> <tr>
<td>storeEval</td> <td>assertText</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td> <td>//tr[@class='listbox-data-line-0 DataA']/td[3]</td>
<td>_data_gadget_value</td> <td>Version 2</td> <!-- after -->
</tr> </tr>
<tr> <tr>
<td>verifyEval</td> <td>assertText</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td> <td>//tr[@class='listbox-data-line-0 DataA']/td[4]</td>
<td>---+++@@-1+1@@-Version1+Version2</td> <td>Version 3</td> <!-- now -->
</tr> </tr>
</tal:block> </tal:block>
<tal:block tal:condition="python: context.TestTool_getSkinName()=='Mobile'"> <tal:block tal:condition="python: context.TestTool_getSkinName()=='Mobile'">
...@@ -270,21 +268,20 @@ ...@@ -270,21 +268,20 @@
<td>title</td> <td>title</td>
</tr> </tr>
<tr> <tr>
<td>assertElementPresent</td> <td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td> <td>//tr[@class='listbox-data-line-0 DataA']/td[2]</td>
<td></td> <td>Version 2</td> <!-- before -->
</tr> </tr>
<tr> <tr>
<td>storeEval</td> <td>assertText</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td> <td>//tr[@class='listbox-data-line-0 DataA']/td[3]</td>
<td>_data_gadget_value</td> <td>Version 3</td> <!-- after -->
</tr> </tr>
<tr> <tr>
<td>verifyEval</td> <td>assertText</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td> <td>//tr[@class='listbox-data-line-0 DataA']/td[4]</td>
<td>---+++@@-1+1@@-Version2+Version3</td> <td>Version 3</td> <!-- now -->
</tr> </tr>
</tal:block> </tal:block>
<tal:block tal:condition="python: context.TestTool_getSkinName()=='Mobile'"> <tal:block tal:condition="python: context.TestTool_getSkinName()=='Mobile'">
......
...@@ -64,6 +64,21 @@ ...@@ -64,6 +64,21 @@
<td>A new foo</td> <td>A new foo</td>
</tr> </tr>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@name='field_my_lines_list']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea[@name='field_my_lines_list']</td>
<td>
Foo
Bar
</td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/save" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/save" />
<!-- Go to History tab --> <!-- Go to History tab -->
...@@ -130,9 +145,56 @@ ...@@ -130,9 +145,56 @@
<tr> <tr>
<td>verifyText</td> <td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[2]</td> <td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[2]</td>
<td>Diff Viewer</td> <td>Old Value</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[3]</td>
<td>New Value</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[4]</td>
<td>Current Value</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[3]</td>
<td>New Value</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[4]</td>
<td>Current Value</td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[1]/td[1]</td>
<td>short_title</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[1]/td[2]</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[1]/td[3]</td>
<td>A new foo</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[1]/td[4]</td>
<td>A new foo</td>
</tr> </tr>
<!-- Click on the link to see the diff between old and new value -->
<tr>
<td>click</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[1]/td[3]/a</td>
<td></td>
</tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[2]/td[2]//iframe</td> <td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[2]/td[2]//iframe</td>
...@@ -143,7 +205,7 @@ ...@@ -143,7 +205,7 @@
<td>1000</td> <td>1000</td>
<td></td> <td></td>
</tr> </tr>
<!-- Check for the value of diff in Iframe --> <!-- Check for the value of diff in IFrame -->
<tr> <tr>
<td>storeEval</td> <td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//div[@data-gadget-scope='field_listbox']//table/tbody/tr[2]/td[2]//iframe", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.contentWindow.document.body.textContent</td> <td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//div[@data-gadget-scope='field_listbox']//table/tbody/tr[2]/td[2]//iframe", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.contentWindow.document.body.textContent</td>
...@@ -153,7 +215,7 @@ ...@@ -153,7 +215,7 @@
<td>verifyEval</td> <td>verifyEval</td>
<!-- Verify the value after removing the spaces and line breaks --> <!-- Verify the value after removing the spaces and line breaks -->
<td>storedVars['diff_content'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td> <td>storedVars['diff_content'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>1-1+Anewfoo</td> <td>1-1+('Foo','Bar')</td>
</tr> </tr>
</tbody></table> </tbody></table>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_hidden</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view_historical_diff</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>108.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View Historical Diff</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>python: object.absolute_url() + \'/Base_viewHistoricalComparisonDiff\'</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""
This URL script is used for Historical comparison list
to show the diff between the new value and current value.
In case there new value is the current value, there is no
need to show the diff link.
"""
request = context.REQUEST
# In this case, the second serial should be the current value, i.e, 0.0.0.0
first_serial = getattr(brain, 'next_serial', '0.0.0.0')
second_serial = '0.0.0.0'
time = getattr(brain, 'time', '')
action = getattr(brain, 'action', '')
actor = getattr(brain, 'actor', '')
# There is no need to compare revisions in case its the
# first version.
if first_serial != second_serial:
if url_dict:
return {'command': 'index',
'options': {
# XXX: This shouldn't be the referred way to get
# relative URL, but if we directly use context here
# to get the relative URL, it will return us the
# URL of tempbase object of list, which is not
# what we desire, thus taking the approach to
# get it via REQUEST
'jio_key': request.get('relative_url'),
},
'view_kw': {
'view': 'view_historical_diff',
'jio_key': request.get('relative_url'),
'extra_param_json': {
'first_serial': first_serial,
'second_serial': second_serial,
'time': time,
'action': action,
'actor': actor,
}
}
}
return 'Base_viewHistoricalComparisonDiff?first_serial=%s&amp;second_serial=%s&amp;time=%s&amp;action=%s&amp;actor=%s'\
% ( first_serial, second_serial, time, action, actor )
elif url_dict:
return {}
<?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>brain, url_dict=False, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getCurrentDiffUrl</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""
This URL script is used for Historical comparison list
to get diff between old and new value
"""
request = context.REQUEST
first_serial = getattr(brain, 'serial', '0.0.0.0')
second_serial = getattr(brain, 'next_serial', '0.0.0.0')
time = getattr(brain, 'time', '')
action = getattr(brain, 'action', '')
actor = getattr(brain, 'actor', '')
# There is no need to compare revisions in case its the
# first version.
if url_dict:
return {'command': 'index',
'options': {
# XXX: This shouldn't be the referred way to get
# relative URL, but if we directly use context here
# to get the relative URL, it will return us the
# URL of tempbase object of list, which is not
# what we desire, thus taking the approach to
# get it via REQUEST
'jio_key': request.get('relative_url'),
},
'view_kw': {
'view': 'view_historical_diff',
'jio_key': request.get('relative_url'),
'extra_param_json': {
'first_serial': first_serial,
'second_serial': second_serial,
'time': time,
'action': action,
'actor': actor,
}
}
}
return 'Base_viewHistoricalComparisonDiff?first_serial=%s&amp;second_serial=%s&amp;time=%s&amp;action=%s&amp;actor=%s'\
% ( first_serial, second_serial, time, action, actor )
<?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>brain, url_dict=False, serial=None, next_serial=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getDiffUrl</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from Products.ERP5Type.Document import newTempBase from Products.PythonScripts.standard import Object
from ZODB.POSException import ConflictError from ZODB.POSException import ConflictError
from zExceptions import Unauthorized from zExceptions import Unauthorized
from Products.ERP5Type.Document import newTempBase
Base_translateString = context.Base_translateString Base_translateString = context.Base_translateString
portal = context.getPortalObject()
portal_diff = portal.portal_diff
try: try:
context.HistoricalRevisions[serial] context.HistoricalRevisions[serial]
except (ConflictError, Unauthorized): except (ConflictError, Unauthorized):
raise raise
except Exception: except Exception: # POSKeyError
return [newTempBase(portal, Base_translateString('Historical revisions are' return [Object(property_name=Base_translateString('Historical revisions are'
' not available, maybe the database has been packed'))] ' not available, maybe the database has been packed'))]
if next_serial == '0.0.0.0': if next_serial == '0.0.0.0':
# In case the next serial is 0.0.0.0, we should always be considering the
# new object as the current context
new_getProperty = context.getProperty new_getProperty = context.getProperty
new = context
else: else:
new = context.HistoricalRevisions[next_serial] new = context.HistoricalRevisions[next_serial]
new_getProperty = new.getProperty new_getProperty = new.getProperty
old = context.HistoricalRevisions[serial] old = context.HistoricalRevisions[serial]
result = [] result = []
# XXX: Instead of creating a separate property list here, we can use DiffTool binary_data_explanation = Base_translateString("Binary data can't be displayed")
# to directly find out the beautified diff and send it to the listbox base_error_message = Base_translateString('(value retrieval failed)')
diff = portal_diff.diffPortalObject(old, new).asBeautifiedJSONDiff() for prop_dict in context.getPropertyMap():
prop = prop_dict['id']
tempbase_list = [] error = False
uid = 900 try:
for x in diff: current_value = context.getProperty(prop)
temp_obj = newTempBase(portal, except TypeError:
x['path'], error = True
current_value = base_error_message
try:
old_value = old.getProperty(prop)
except TypeError:
error = True
old_value = base_error_message
try:
new_value = new_getProperty(prop)
except TypeError:
error = True
new_value = base_error_message
if new_value != old_value or error:
# check if values are unicode convertible (binary are not)
if isinstance(new_value, (str, unicode)):
try:
unicode(str(new_value), 'utf-8')
except UnicodeDecodeError:
new_value = binary_data_explanation
if isinstance(old_value, (str, unicode)):
try:
unicode(str(old_value), 'utf-8')
except UnicodeDecodeError:
old_value = binary_data_explanation
if isinstance(current_value, (str, unicode)):
try:
unicode(str(current_value), 'utf-8')
except UnicodeDecodeError:
current_value = binary_data_explanation
x = {'property_name': prop,
'new_value': new_value,
'old_value': old_value,
'current_value': current_value,
}
tmp_obj = newTempBase(context,
'',
**x) **x)
temp_obj.setUid('new_%s' % uid) tmp_obj.setProperty('serial', serial)
uid = uid + 1 tmp_obj.setProperty('next_serial', next_serial)
tempbase_list.append(temp_obj) tmp_obj.setProperty('action', action)
tmp_obj.setProperty('actor', actor)
return tempbase_list tmp_obj.setProperty('time', time)
result.append(tmp_obj)
return result
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>serial, next_serial, **kw</string> </value> <value> <string>serial, next_serial, action, actor, time, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -11,6 +11,9 @@ request = context.REQUEST ...@@ -11,6 +11,9 @@ request = context.REQUEST
serial = getattr(brain, 'serial', '0.0.0.0') serial = getattr(brain, 'serial', '0.0.0.0')
next_serial = getattr(brain, 'next_serial', '0.0.0.0') next_serial = getattr(brain, 'next_serial', '0.0.0.0')
time = getattr(brain, 'time', '')
action = getattr(brain, 'action', '')
actor = getattr(brain, 'actor', '')
# There is no need to compare revisions in case its the # There is no need to compare revisions in case its the
# first version. # first version.
...@@ -32,12 +35,14 @@ if serial != '0.0.0.0': ...@@ -32,12 +35,14 @@ if serial != '0.0.0.0':
'extra_param_json': { 'extra_param_json': {
'serial': serial, 'serial': serial,
'next_serial': next_serial, 'next_serial': next_serial,
'time': brain.time 'time': time,
'action': action,
'actor': actor,
} }
} }
} }
return 'Base_viewHistoricalComparison?serial=%s&amp;next_serial=%s&amp;time=%s'\ return 'Base_viewHistoricalComparison?serial=%s&amp;next_serial=%s&amp;time=%s&amp;action=%s&amp;actor=%s'\
% ( serial, next_serial, brain.time ) % ( serial, next_serial, time, action, actor )
elif url_dict: elif url_dict:
return {} return {}
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
<value> <string>bar</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>edit_order</string> </key> <key> <string>edit_order</string> </key>
...@@ -90,9 +90,7 @@ ...@@ -90,9 +90,7 @@
<item> <item>
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <value>
<list> <list/>
<string>listbox_diff</string>
</list>
</value> </value>
</item> </item>
<item> <item>
...@@ -146,6 +144,10 @@ ...@@ -146,6 +144,10 @@
<key> <string>update_action</string> </key> <key> <string>update_action</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
...@@ -2,24 +2,10 @@ ...@@ -2,24 +2,10 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/> <global name="ListBox" module="Products.ERP5Form.ListBox"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>columns</string>
<string>count_method</string>
<string>lines</string>
<string>list_method</string>
<string>selection_name</string>
<string>title</string>
<string>url_columns</string>
</list>
</value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>listbox</string> </value> <value> <string>listbox</string> </value>
...@@ -32,6 +18,10 @@ ...@@ -32,6 +18,10 @@
<key> <string>external_validator_failed</string> </key> <key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value> <value> <string>The input failed the external validator.</string> </value>
</item> </item>
<item>
<key> <string>required_not_found</string> </key>
<value> <string>Input is required but no input given.</string> </value>
</item>
</dictionary> </dictionary>
</value> </value>
</item> </item>
...@@ -40,11 +30,171 @@ ...@@ -40,11 +30,171 @@
<value> <value>
<dictionary> <dictionary>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>all_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>anchor</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>count_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_display_style</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_style_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>domain_root_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>domain_tree</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_attributes</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_search_column</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hide_rows_on_no_search_criterion</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>list_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>meta_types</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>page_navigation_template</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>page_template</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>report_root_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>report_tree</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>row_css_method</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>form_id</string> </key> <key> <string>search</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>search_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>select</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>sort</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>sort_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>stat_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>stat_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>style_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>untranslatable_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>url_columns</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -55,11 +205,173 @@ ...@@ -55,11 +205,173 @@
<value> <value>
<dictionary> <dictionary>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>all_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>anchor</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>count_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_display_style</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_style_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>domain_root_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>domain_tree</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_attributes</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_search_column</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hide_rows_on_no_search_criterion</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>list_action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>list_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>meta_types</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>page_navigation_template</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>page_template</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>report_root_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>report_tree</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>row_css_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>search</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>search_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>select</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>sort</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>sort_columns</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>form_id</string> </key> <key> <string>stat_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>stat_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>style_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>untranslatable_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>url_columns</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -69,17 +381,39 @@ ...@@ -69,17 +381,39 @@
<key> <string>values</string> </key> <key> <string>values</string> </key>
<value> <value>
<dictionary> <dictionary>
<item>
<key> <string>all_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>anchor</string> </key>
<value> <int>0</int> </value>
</item>
<item> <item>
<key> <string>columns</string> </key> <key> <string>columns</string> </key>
<value> <value>
<list> <list>
<tuple> <tuple>
<string>path</string> <string>property_name</string>
<string>Property Name</string> <string>Property Name</string>
</tuple> </tuple>
<tuple> <tuple>
<string>diff</string> <string>old_value</string>
<string>Diff Viewer</string> <string>Old Value</string>
</tuple>
<tuple>
<string>new_value</string>
<string>New Value</string>
</tuple>
<tuple>
<string>current_value</string>
<string>Current Value</string>
</tuple> </tuple>
</list> </list>
</value> </value>
...@@ -89,43 +423,199 @@ ...@@ -89,43 +423,199 @@
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>css_class</string> </key>
<value> <string>my_view_mode_listbox</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>form_id</string> </key> <key> <string>default_display_style</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value> <value> <string>table</string> </value>
</item> </item>
<item> <item>
<key> <string>lines</string> </key> <key> <string>default_params</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_style_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>domain_root_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>domain_tree</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>editable</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_attributes</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>global_search_column</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>hide_rows_on_no_search_criterion</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value> <int>20</int> </value>
</item>
<item>
<key> <string>list_action</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>list_method</string> </key> <key> <string>list_method</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>meta_types</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>page_navigation_template</string> </key>
<value> <string>ListBox_viewSliderPageNavigationRenderer</string> </value>
</item>
<item>
<key> <string>page_template</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>report_root_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>report_tree</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>row_css_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>search</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>search_columns</string> </key>
<value>
<list/>
</value> </value>
</item> </item>
<item>
<key> <string>select</string> </key>
<value> <int>0</int> </value>
</item>
<item> <item>
<key> <string>selection_name</string> </key> <key> <string>selection_name</string> </key>
<value> <string>historical_comparison_selection</string> </value>
</item>
<item>
<key> <string>sort</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>sort_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>stat_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>stat_method</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>style_columns</string> </key>
<value>
<list/>
</value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Differences</string> </value> <value> <string>Differences</string> </value>
</item> </item>
<item>
<key> <string>untranslatable_columns</string> </key>
<value>
<list/>
</value>
</item>
<item> <item>
<key> <string>url_columns</string> </key> <key> <string>url_columns</string> </key>
<value> <value>
<list> <list>
<tuple> <tuple>
<string>path</string> <string>property_name</string>
<string></string> <string></string>
</tuple> </tuple>
<tuple> <tuple>
<string>diff</string> <string>old_value</string>
<string></string> <string></string>
</tuple> </tuple>
<tuple>
<string>new_value</string>
<string>Base_getDiffUrl</string>
</tuple>
<tuple>
<string>current_value</string>
<string>Base_getCurrentDiffUrl</string>
</tuple>
</list> </list>
</value> </value>
</item> </item>
...@@ -136,6 +626,19 @@ ...@@ -136,6 +626,19 @@
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>string:${here/getRelativeUrl}/HistoricalRevisions/${request/serial}/view?portal_status_message=Version%20from%20${request/time}</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="Method" module="Products.Formulator.MethodField"/> <global name="Method" module="Products.Formulator.MethodField"/>
</pickle> </pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list>
<string>listbox_diff</string>
</list>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_action</string>
<string>my_actor</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list>
<string>my_datetime</string>
</list>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_viewHistoricalComparisonDiff</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Base_viewHistoricalComparisonDiff</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_view</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Historical Differences</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>selection_name</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</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>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>ERP5Site_viewDiffTwoObjectDialog</string> </value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_diff</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>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>listbox_diff</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>ERP5Site_viewDiffTwoObjectDialog</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_action</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>
</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>title</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> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Action</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: request.get(\'action\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_actor</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>
</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Actor</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: request.get(\'actor\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -10,17 +10,16 @@ ...@@ -10,17 +10,16 @@
<key> <string>delegated_list</string> </key> <key> <string>delegated_list</string> </key>
<value> <value>
<list> <list>
<string>css_class</string> <string>date_only</string>
<string>default</string> <string>default</string>
<string>gadget_url</string> <string>editable</string>
<string>js_sandbox</string>
<string>title</string> <string>title</string>
</list> </list>
</value> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>listbox_diff</string> </value> <value> <string>my_datetime</string> </value>
</item> </item>
<item> <item>
<key> <string>message_values</string> </key> <key> <string>message_values</string> </key>
...@@ -53,7 +52,7 @@ ...@@ -53,7 +52,7 @@
<value> <value>
<dictionary> <dictionary>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>date_only</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
...@@ -63,24 +62,16 @@ ...@@ -63,24 +62,16 @@
</value> </value>
</item> </item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>editable</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>form_id</string> </key> <key> <string>field_id</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>gadget_url</string> </key> <key> <string>form_id</string> </key>
<value> <value> <string></string> </value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>js_sandbox</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
...@@ -94,32 +85,30 @@ ...@@ -94,32 +85,30 @@
<value> <value>
<dictionary> <dictionary>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>date_only</string> </key>
<value> <string>listbox-gadget</string> </value> <value> <int>0</int> </value>
</item> </item>
<item> <item>
<key> <string>default</string> </key> <key> <string>default</string> </key>
<value> <string></string> </value> <value>
<none/>
</value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item> </item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>field_id</string> </key>
<value> <string>my_gadget_field</string> </value> <value> <string>my_date_time_field</string> </value>
</item> </item>
<item> <item>
<key> <string>form_id</string> </key> <key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value> <value> <string>Base_viewFieldLibrary</string> </value>
</item> </item>
<item>
<key> <string>gadget_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>js_sandbox</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Diff Viewer</string> </value> <value> <string>Date Time</string> </value>
</item> </item>
</dictionary> </dictionary>
</value> </value>
...@@ -135,33 +124,7 @@ ...@@ -135,33 +124,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: cell.diff</string> </value> <value> <string>python: request.get(\'time\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: field.restrictedTraverse(\'gadget_erp5_side_by_side_diff.html\').absolute_url()</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: context.Base_getDiffGadgetSandbox()</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
""" """
Script that returns the list of diff of 2 historical states of ERP5 object(s). This script gets 2 ERP5 objects based on the parameters provided, either by
using path and datetime or by using context and serial and then creates a
diff between the 2 objects.
This should is used as a 'list method' as it returns a list of temp base object The diff returned is a list of Tempbase object with properties `path` and `diff`.
which have its properties as : `path` and `diff`.
""" """
from Products.ERP5Type.Document import newTempBase from Products.ERP5Type.Document import newTempBase
from ZODB.POSException import ConflictError
from zExceptions import Unauthorized
portal = context.getPortalObject() portal = context.getPortalObject()
portal_diff = portal.portal_diff portal_diff = portal.portal_diff
...@@ -12,6 +15,9 @@ request = context.REQUEST ...@@ -12,6 +15,9 @@ request = context.REQUEST
object_revision_list = [] object_revision_list = []
history_size = portal.portal_preferences.getPreferredHtmlStyleZodbHistorySize() history_size = portal.portal_preferences.getPreferredHtmlStyleZodbHistorySize()
first_object = None
second_object = None
# In case the request has been made via action on any ERP5 object, we get the # In case the request has been made via action on any ERP5 object, we get the
# paths as `your_<field_name>` as this is what use as field in dialog. Hence, # paths as `your_<field_name>` as this is what use as field in dialog. Hence,
# its better to check for path in the request also. # its better to check for path in the request also.
...@@ -20,69 +26,100 @@ if first_path is None: ...@@ -20,69 +26,100 @@ if first_path is None:
if second_path is None: if second_path is None:
second_path = request.get('your_second_path', None) second_path = request.get('your_second_path', None)
# Case I: When we try to access the dialog directly from `portal_diff` or from # If first_path and second_path exists, get their current revision from ZODB
# selections in a module. If the paths are None, then return an empty list if first_path not in (None, ''):
# or try to get the paths from selection and then return the diff. first_object = portal.restrictedTraverse(first_path)
if first_path is None and second_path is None: if second_path not in (None, ''):
list_selection_name = request.get('list_selection_name', None) second_object = portal.restrictedTraverse(second_path)
# In case the list_selection_name is there, it can be the case of selection
# from the module, hence we get the paths from the selection and use them to # Try to get the objects from the serials.
# create diff. if first_serial:
if list_selection_name is not None: if not first_object:
selected_obj_list = portal.portal_selections.getSelectionCheckedValueList(selection_name=list_selection_name) first_object = context
object_revision_list.extend(selected_obj_list) try:
first_object = first_object.HistoricalRevisions[first_serial]
except (ConflictError, Unauthorized):
raise
except Exception:
return [newTempBase(portal, context.Base_translateString('Historical revisions are'
' not available, maybe the database has been packed'))]
if second_serial:
if second_serial == '0.0.0.0':
# In case the second serial is 0.0.0.0, we should consider the second object as
# the current version of context
second_object = context
else: else:
# Return an empty list here. This would be the case when we first access if not second_object:
# the dialog and then it try to get list of items to dipslay on the listbox second_object = context
return [] try:
second_object = second_object.HistoricalRevisions[second_serial]
except (ConflictError, Unauthorized):
raise
except Exception:
return [newTempBase(portal, context.Base_translateString('Historical revisions are'
' not available, maybe the database has been packed'))]
# Case II: Get object revision from the date of the revisions. # Here if the datetime and the paths exist in params, we always give priority
# The default dates for revision are the 1st and 2nd # to get the objects via these params.
# revision dates.
if first_date not in (None, ''):
first_obj = portal.restrictedTraverse(first_path)
old_state_revision = context.Base_getRevisionFromDate(first_obj, first_date)
object_revision_list.append(old_state_revision)
if second_date not in (None, ''):
second_obj = portal.restrictedTraverse(second_path)
new_state_revision = context.Base_getRevisionFromDate(second_obj, second_date)
object_revision_list.append(new_state_revision)
# Case III: When the paths exist, but there is no revision given if (first_object is not None and (first_object == second_object)):
# for the paths, we diff the current revision # If both the objects are same, diff between the current version
if first_path != second_path:
# Diff the current verison if both the paths are different
if first_path is not None and first_date in (None, ''):
object_revision_list.append(portal.restrictedTraverse(first_path))
if second_path is not None and second_date in (None, ''):
object_revision_list.append(portal.restrictedTraverse(second_path))
else:
# If both the paths are same, diff between the current version
# and the last version(if it exists) # and the last version(if it exists)
# Get the historical revisions for the object and check if there # Get the historical revisions for the object and check if there
# is more than one revision # is more than one revision
obj = portal.restrictedTraverse(first_path) revision_date_list = first_object.Base_getRevisionDateList(first_object, size=history_size)
revision_date_list = obj.Base_getRevisionDateList(obj, size=history_size)
if len(revision_date_list) > 1: if len(revision_date_list) > 1:
object_revision_list.append(obj.Base_getRevisionFromDate(obj, revision_date_list[1])) first_object = first_object.Base_getRevisionFromDate(first_object, revision_date_list[1])
object_revision_list.append(obj.Base_getRevisionFromDate(obj, revision_date_list[0])) second_object = second_object.Base_getRevisionFromDate(second_object, revision_date_list[0])
# Get object revision from the date of the revisions.
# The default dates for revision are the 1st and 2nd
# revision dates.
if first_date not in (None, ''):
if isinstance(first_object, dict):
# If the object type is dictionary because historical revisions are present
# as dictionaries, then we get the object using restrictedTraverse
first_object = portal.restrictedTraverse(first_path)
first_object = context.Base_getRevisionFromDate(first_object, first_date)
if second_date not in (None, ''):
if isinstance(second_object, dict):
second_object = portal.restrictedTraverse(second_path)
second_object = context.Base_getRevisionFromDate(second_object, second_date)
# When we try to access the dialog directly from `portal_diff` or from
# selections in a module. If the paths are None, then return an empty list
# or try to get the paths from selection and then return the diff.
if ((first_path is None and second_path is None) and
(first_object is None and second_object is None)):
# Make sure to always check if the first_object and second_object is empty, because this script
# is used outside of Diff Tool also, where we might have list_selection_name which will
# end up getting useless selection.
list_selection_name = request.get('list_selection_name', None)
# In case the list_selection_name is there, it can be the case of selection
# from the module, hence we get the paths from the selection and use them to
# create diff.
if list_selection_name is not None:
selected_object_list = portal.portal_selections.getSelectionCheckedValueList(
selection_name=list_selection_name)
first_object = selected_object_list[0]
second_object = selected_object_list[1]
# Use DiffTool to get the diff between the 2 objects in object_revision_list List. # Use DiffTool to get the diff between the 2 objects in object_revision_list List.
# These 2 objects can be revisions of same object, 2 different revisions of # These 2 objects can be revisions of same object, 2 different revisions of
# different objects or 2 current ERP5 object. # different objects or 2 current ERP5 object.
if len(object_revision_list) > 1: if first_object and second_object:
# Using this last 2 Historical revision dicts, create a Diff diff_list = portal_diff.diffPortalObject(first_object, second_object).asBeautifiedJSONDiff()
diff_list = portal_diff.diffPortalObject(object_revision_list[0], object_revision_list[1]).asBeautifiedJSONDiff()
# Return a list of TempBase objects which can be displayed in a listbox # Return a list of TempBase objects which can be displayed in a listbox
uid = 1 uid = 1
tempbase_list = [] tempbase_list = []
for diff_unit in diff_list: for diff_unit in diff_list:
temp_obj = newTempBase(portal, temp_object = newTempBase(portal,
diff_unit['path'], diff_unit['path'],
**diff_unit) **diff_unit)
temp_obj.setUid(uid) temp_object.setUid(uid)
uid = uid + 1 uid = uid + 1
tempbase_list.append(temp_obj) tempbase_list.append(temp_object)
return tempbase_list return tempbase_list
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>first_date=None, second_date=None, first_path=None, second_path=None, **kw</string> </value> <value> <string>first_date=None, second_date=None, first_path=None, second_path=None, first_serial=None, second_serial=None, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -172,6 +172,7 @@ portal_actions | search ...@@ -172,6 +172,7 @@ portal_actions | search
portal_actions | sort_on portal_actions | sort_on
portal_actions | types_tool portal_actions | types_tool
portal_actions | view_historical_comparison portal_actions | view_historical_comparison
portal_actions | view_historical_diff
portal_membership | login portal_membership | login
portal_membership | logout portal_membership | logout
portal_membership | preferences portal_membership | preferences
......
...@@ -239,7 +239,9 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional): ...@@ -239,7 +239,9 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
'object_action': [{'id': 'post_query', 'title': 'Post a Query'}, 'object_action': [{'id': 'post_query', 'title': 'Post a Query'},
{'id': 'diff_object_action', 'title': 'Diff Object'}], {'id': 'diff_object_action', 'title': 'Diff Object'}],
'object_hidden': [{'id': 'view_historical_comparison', 'object_hidden': [{'id': 'view_historical_comparison',
'title': 'View Historical Comparison'}], 'title': 'View Historical Comparison'},
{'id': 'view_historical_diff',
'title': 'View Historical Diff'}],
'object_jump': [{'id': 'jump_related_object', 'title': 'Related Objects'}, 'object_jump': [{'id': 'jump_related_object', 'title': 'Related Objects'},
{'id': 'jump_query', 'title': 'Queries'}], {'id': 'jump_query', 'title': 'Queries'}],
'object_search': [{'title': 'Search', 'id': 'search'}], 'object_search': [{'title': 'Search', 'id': 'search'}],
...@@ -263,7 +265,9 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional): ...@@ -263,7 +265,9 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
'object': [], 'object': [],
'object_action': [{'id': 'diff_object_action', 'title': 'Diff Object'}], 'object_action': [{'id': 'diff_object_action', 'title': 'Diff Object'}],
'object_hidden': [{'id': 'view_historical_comparison', 'object_hidden': [{'id': 'view_historical_comparison',
'title': 'View Historical Comparison'}], 'title': 'View Historical Comparison'},
{'id': 'view_historical_diff',
'title': 'View Historical Diff'}],
'object_jump': [{'id': 'jump_related_object', 'title': 'Related Objects'}], 'object_jump': [{'id': 'jump_related_object', 'title': 'Related Objects'}],
'object_search': [{'title': 'Search', 'id': 'search'}], 'object_search': [{'title': 'Search', 'id': 'search'}],
'object_sort': [{'title': 'Sort', 'id': 'sort_on'}], 'object_sort': [{'title': 'Sort', 'id': 'sort_on'}],
...@@ -282,7 +286,9 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional): ...@@ -282,7 +286,9 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
'object': [], 'object': [],
'object_action': [{'id': 'diff_object_action', 'title': 'Diff Object'}], 'object_action': [{'id': 'diff_object_action', 'title': 'Diff Object'}],
'object_hidden': [{'id': 'view_historical_comparison', 'object_hidden': [{'id': 'view_historical_comparison',
'title': 'View Historical Comparison'}], 'title': 'View Historical Comparison'},
{'id': 'view_historical_diff',
'title': 'View Historical Diff'}],
'object_jump': [{'id': 'jump_related_object', 'title': 'Related Objects'}], 'object_jump': [{'id': 'jump_related_object', 'title': 'Related Objects'}],
'object_search': [{'title': 'Search', 'id': 'search'}], 'object_search': [{'title': 'Search', 'id': 'search'}],
'object_sort': [{'title': 'Sort', 'id': 'sort_on'}], 'object_sort': [{'title': 'Sort', 'id': 'sort_on'}],
......
...@@ -50,7 +50,7 @@ class TestXHTMLMixin(ERP5TypeTestCase): ...@@ -50,7 +50,7 @@ class TestXHTMLMixin(ERP5TypeTestCase):
# some forms have intentionally empty listbox selections like RSS generators # some forms have intentionally empty listbox selections like RSS generators
FORM_LISTBOX_EMPTY_SELECTION_PATH_LIST = ['erp5_web_widget_library/WebSection_viewContentListAsRSS', FORM_LISTBOX_EMPTY_SELECTION_PATH_LIST = ['erp5_web_widget_library/WebSection_viewContentListAsRSS',
'erp5_core/Base_viewHistoricalComparison', 'erp5_core/Base_viewHistoricalComparisonDiff',
'erp5_diff/ERP5Site_viewDiffTwoObjectDialog',] 'erp5_diff/ERP5Site_viewDiffTwoObjectDialog',]
JSL_IGNORE_FILE_LIST = ( JSL_IGNORE_FILE_LIST = (
'diff2html.js', 'diff2html.js',
......
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