[gen] For Strings with validator=String.URL, an HTML link is rendered in view layouts; added a 'real' 'state' field to any Appy class, allowing to use it in search screens for example; added 2 hook methods: getIcons and getSubTitles, allowing to add, in lists of objects (Refs or queries), icons besides the title and anything below it; optimized query.pt: for every new query, 1 server request is done (previously, one standard request + one ajax request were done); removed columns 'actions' (Refs, query): action icons are not included in the column containing the title (we avoid having empty columns whhen no action is available).
|  | @ -1157,6 +1157,7 @@ class String(Type): | ||||||
|         # field of format CAPTCHA by page, because the captcha challenge is |         # field of format CAPTCHA by page, because the captcha challenge is | ||||||
|         # stored in the session at some global key. |         # stored in the session at some global key. | ||||||
|         self.format = format |         self.format = format | ||||||
|  |         self.isUrl = validator == String.URL | ||||||
|         # When format is XHTML, the list of styles that the user will be able to |         # When format is XHTML, the list of styles that the user will be able to | ||||||
|         # select in the styles dropdown is defined hereafter. |         # select in the styles dropdown is defined hereafter. | ||||||
|         self.styles = styles |         self.styles = styles | ||||||
|  | @ -1225,6 +1226,8 @@ class String(Type): | ||||||
|             return {'view': 'l-f', 'edit': 'lrv-f'} |             return {'view': 'l-f', 'edit': 'lrv-f'} | ||||||
| 
 | 
 | ||||||
|     def getValue(self, obj): |     def getValue(self, obj): | ||||||
|  |         # Cheat if this field represents p_obj's state | ||||||
|  |         if self.name == 'state': return obj.State() | ||||||
|         value = Type.getValue(self, obj) |         value = Type.getValue(self, obj) | ||||||
|         if not value: |         if not value: | ||||||
|             if self.isMultiValued(): return emptyTuple |             if self.isMultiValued(): return emptyTuple | ||||||
|  |  | ||||||
|  | @ -404,7 +404,6 @@ class ZopeGenerator(Generator): | ||||||
|             msg('modified_field',       '', msg.MODIFIED_FIELD), |             msg('modified_field',       '', msg.MODIFIED_FIELD), | ||||||
|             msg('previous_value',       '', msg.PREVIOUS_VALUE), |             msg('previous_value',       '', msg.PREVIOUS_VALUE), | ||||||
|             msg('phase',                '', msg.PHASE), |             msg('phase',                '', msg.PHASE), | ||||||
|             msg('root_type',            '', msg.ROOT_TYPE), |  | ||||||
|             msg('workflow_comment',     '', msg.WORKFLOW_COMMENT), |             msg('workflow_comment',     '', msg.WORKFLOW_COMMENT), | ||||||
|             msg('choose_a_value',       '', msg.CHOOSE_A_VALUE), |             msg('choose_a_value',       '', msg.CHOOSE_A_VALUE), | ||||||
|             msg('choose_a_doc',         '', msg.CHOOSE_A_DOC), |             msg('choose_a_doc',         '', msg.CHOOSE_A_DOC), | ||||||
|  | @ -412,7 +411,6 @@ class ZopeGenerator(Generator): | ||||||
|             msg('max_ref_violated',     '', msg.MAX_REF_VIOLATED), |             msg('max_ref_violated',     '', msg.MAX_REF_VIOLATED), | ||||||
|             msg('no_ref',               '', msg.REF_NO), |             msg('no_ref',               '', msg.REF_NO), | ||||||
|             msg('add_ref',              '', msg.REF_ADD), |             msg('add_ref',              '', msg.REF_ADD), | ||||||
|             msg('ref_actions',          '', msg.REF_ACTIONS), |  | ||||||
|             msg('action_ok',            '', msg.ACTION_OK), |             msg('action_ok',            '', msg.ACTION_OK), | ||||||
|             msg('action_ko',            '', msg.ACTION_KO), |             msg('action_ko',            '', msg.ACTION_KO), | ||||||
|             msg('move_up',              '', msg.REF_MOVE_UP), |             msg('move_up',              '', msg.REF_MOVE_UP), | ||||||
|  |  | ||||||
|  | @ -545,6 +545,11 @@ class ToolMixin(BaseMixin): | ||||||
|         appyType = self.getAppyType(name, className=className) |         appyType = self.getAppyType(name, className=className) | ||||||
|         if appyType: return appyType.isSortable(usage=usage) |         if appyType: return appyType.isSortable(usage=usage) | ||||||
| 
 | 
 | ||||||
|  |     def subTitleIsUsed(self, className): | ||||||
|  |         '''Does class named p_className define a method "getSubTitle"?''' | ||||||
|  |         klass = self.getAppyClass(className) | ||||||
|  |         return hasattr(klass, 'getSubTitle') | ||||||
|  | 
 | ||||||
|     def _searchValueIsEmpty(self, key): |     def _searchValueIsEmpty(self, key): | ||||||
|         '''Returns True if request value in key p_key can be considered as |         '''Returns True if request value in key p_key can be considered as | ||||||
|            empty.''' |            empty.''' | ||||||
|  |  | ||||||
|  | @ -687,17 +687,11 @@ class BaseMixin: | ||||||
|         '''Gets the Appy types named p_fieldNames.''' |         '''Gets the Appy types named p_fieldNames.''' | ||||||
|         res = [] |         res = [] | ||||||
|         for name in fieldNames: |         for name in fieldNames: | ||||||
|             if name == 'state': |             appyType = self.getAppyType(name, asDict) | ||||||
|                 # We do not return a appyType if the attribute is not a *real* |             if appyType: res.append(appyType) | ||||||
|                 # attribute, but the workfow state. |  | ||||||
|                 res.append({'name': name, 'labelId': 'workflow_state', |  | ||||||
|                             'filterable': False}) |  | ||||||
|             else: |             else: | ||||||
|                 appyType = self.getAppyType(name, asDict) |                 self.log('Field "%s", used as shownInfo in a Ref, ' \ | ||||||
|                 if appyType: res.append(appyType) |                          'was not found.' % name, type='warning') | ||||||
|                 else: |  | ||||||
|                     self.log('Field "%s", used as shownInfo in a Ref, ' \ |  | ||||||
|                              'was not found.' % name, type='warning') |  | ||||||
|         return res |         return res | ||||||
| 
 | 
 | ||||||
|     def getAppyStates(self, phase, currentOnly=False): |     def getAppyStates(self, phase, currentOnly=False): | ||||||
|  | @ -820,6 +814,18 @@ class BaseMixin: | ||||||
|         else: |         else: | ||||||
|             return res |             return res | ||||||
| 
 | 
 | ||||||
|  |     def getIcons(self): | ||||||
|  |         '''Gets the icons that can be shown besides the title of an object.''' | ||||||
|  |         appyObj = self.appy() | ||||||
|  |         if hasattr(appyObj, 'getIcons'): return appyObj.getIcons() | ||||||
|  |         return '' | ||||||
|  | 
 | ||||||
|  |     def getSubTitle(self): | ||||||
|  |         '''Gets the content that must appear below the title of an object.''' | ||||||
|  |         appyObj = self.appy() | ||||||
|  |         if hasattr(appyObj, 'getSubTitle'): return appyObj.getSubTitle() | ||||||
|  |         return '' | ||||||
|  | 
 | ||||||
|     def getPreviousPage(self, phase, page): |     def getPreviousPage(self, phase, page): | ||||||
|         '''Returns the page that precedes p_page which is in p_phase.''' |         '''Returns the page that precedes p_page which is in p_phase.''' | ||||||
|         try: |         try: | ||||||
|  |  | ||||||
|  | @ -40,7 +40,6 @@ class PoMessage: | ||||||
|     POD_ASKACTION = 'Trigger related action' |     POD_ASKACTION = 'Trigger related action' | ||||||
|     REF_NO = 'No object.' |     REF_NO = 'No object.' | ||||||
|     REF_ADD = 'Add a new one' |     REF_ADD = 'Add a new one' | ||||||
|     REF_ACTIONS = 'Actions' |  | ||||||
|     REF_MOVE_UP = 'Move up' |     REF_MOVE_UP = 'Move up' | ||||||
|     REF_MOVE_DOWN = 'Move down' |     REF_MOVE_DOWN = 'Move down' | ||||||
|     REF_INVALID_INDEX = 'No move occurred: please specify a valid number.' |     REF_INVALID_INDEX = 'No move occurred: please specify a valid number.' | ||||||
|  | @ -69,7 +68,6 @@ class PoMessage: | ||||||
|     MODIFIED_FIELD = 'Modified field' |     MODIFIED_FIELD = 'Modified field' | ||||||
|     PREVIOUS_VALUE = 'Previous value' |     PREVIOUS_VALUE = 'Previous value' | ||||||
|     PHASE = 'phase' |     PHASE = 'phase' | ||||||
|     ROOT_TYPE = 'type' |  | ||||||
|     CHOOSE_A_VALUE = ' - ' |     CHOOSE_A_VALUE = ' - ' | ||||||
|     CHOOSE_A_DOC = '[ Documents ]' |     CHOOSE_A_DOC = '[ Documents ]' | ||||||
|     MIN_REF_VIOLATED = 'You must choose more elements here.' |     MIN_REF_VIOLATED = 'You must choose more elements here.' | ||||||
|  |  | ||||||
|  | @ -92,11 +92,12 @@ img { border: 0; vertical-align: middle} | ||||||
| .list { border: 1px solid grey; margin-bottom: 3px;} | .list { border: 1px solid grey; margin-bottom: 3px;} | ||||||
| .list td, .list th { border: 1px solid grey; | .list td, .list th { border: 1px solid grey; | ||||||
|                      padding-left: 5px; padding-right: 5px; padding-top: 3px;} |                      padding-left: 5px; padding-right: 5px; padding-top: 3px;} | ||||||
| .list th { background-color: #d7dee4; font-style: italic; font-weight: normal;} | .list th { background-color: #d7dee4; font-style: italic; font-weight: normal; | ||||||
|  |            text-align: left } | ||||||
| .grid th { font-style: italic; font-weight: normal; | .grid th { font-style: italic; font-weight: normal; | ||||||
|            border-bottom: 2px solid grey; padding: 2px 2px;} |            border-bottom: 2px solid grey; padding: 2px 2px } | ||||||
| .grid td { padding-right: 5px; } | .grid td { padding-right: 5px } | ||||||
| .cellGap { padding-right: 0.4em; } | .cellGap { padding-right: 0.4em } | ||||||
| .cellDashed { border: 1px dashed grey !important } | .cellDashed { border: 1px dashed grey !important } | ||||||
| .noStyle { border: 0 !important; padding: 0 !important; margin: 0 !important; } | .noStyle { border: 0 !important; padding: 0 !important; margin: 0 !important; } | ||||||
| .noStyle td { border:0 !important; padding:0 !important; margin:0 !important; } | .noStyle td { border:0 !important; padding:0 !important; margin:0 !important; } | ||||||
|  |  | ||||||
|  | @ -200,6 +200,26 @@ function toggleCheckbox(visibleCheckbox, hiddenBoolean) { | ||||||
|   else hidden.value = 'False'; |   else hidden.value = 'False'; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Function that sets a value for showing/hiding sub-titles.
 | ||||||
|  | function setSubTitles(value) { | ||||||
|  |   createCookie('showSubTitles', value); | ||||||
|  |   // Get the sub-titles
 | ||||||
|  |   var subTitles = document.getElementsByName('subTitle'); | ||||||
|  |   if (subTitles.length == 0) return; | ||||||
|  |   for (var i=0; i < subTitles.length; i++) { | ||||||
|  |     if (value == 'true') subTitles[i].style.display = 'block'; | ||||||
|  |     else subTitles[i].style.display = 'none'; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Function that toggles the value for showing/hiding sub-titles.
 | ||||||
|  | function toggleSubTitles() { | ||||||
|  |   var value = readCookie('showSubTitles'); | ||||||
|  |   var newValue = 'true'; | ||||||
|  |   if (value == 'true') newValue = 'false'; | ||||||
|  |   setSubTitles(newValue); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Functions used for master/slave relationships between widgets
 | // Functions used for master/slave relationships between widgets
 | ||||||
| function getSlaveInfo(slave, infoType) { | function getSlaveInfo(slave, infoType) { | ||||||
|   // Returns the appropriate info about slavery, depending on p_infoType.
 |   // Returns the appropriate info about slavery, depending on p_infoType.
 | ||||||
|  |  | ||||||
| Before Width: | Height: | Size: 232 B After Width: | Height: | Size: 234 B | 
| Before Width: | Height: | Size: 232 B After Width: | Height: | Size: 234 B | 
| Before Width: | Height: | Size: 239 B After Width: | Height: | Size: 231 B | 
							
								
								
									
										
											BIN
										
									
								
								gen/ui/edit.gif
									
										
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 476 B After Width: | Height: | Size: 470 B | 
|  | @ -70,11 +70,11 @@ | ||||||
|              style="cursor:pointer" onClick="toggleViewableElements()" align="left" /> |              style="cursor:pointer" onClick="toggleViewableElements()" align="left" /> | ||||||
|         <span tal:replace="columnHeader"/> |         <span tal:replace="columnHeader"/> | ||||||
|       </th> |       </th> | ||||||
|       <th tal:content="python: _('ref_actions')"></th> |       <th></th> | ||||||
|       <th width="20px"><img |       <th width="20px"><img | ||||||
|         tal:attributes="src string: $appUrl/ui/select_elems.png; |         tal:attributes="src string: $appUrl/ui/select_elems.png; | ||||||
|                         title python: _('select_delesect')" |                         title python: _('select_delesect')" | ||||||
|         onClick="toggleCheckboxes()" style="cursor:pointer"/> |         onClick="toggleCheckboxes()" style="cursor:pointer"></th> | ||||||
|     </tr> |     </tr> | ||||||
|     <tal:row repeat="row python: importElems[1]"> |     <tal:row repeat="row python: importElems[1]"> | ||||||
|     <tr tal:define="alreadyImported python: tool.isAlreadyImported(className, row[0]); |     <tr tal:define="alreadyImported python: tool.isAlreadyImported(className, row[0]); | ||||||
|  |  | ||||||
|  | @ -115,3 +115,9 @@ | ||||||
|          style="cursor:pointer"/> |          style="cursor:pointer"/> | ||||||
|   </tal:filter> |   </tal:filter> | ||||||
| </metal:sortAndFilter> | </metal:sortAndFilter> | ||||||
|  | 
 | ||||||
|  | <tal:comment replace="nothing">Icon for hiding/showing details below the title</tal:comment> | ||||||
|  | <metal:details define-macro="showDetails" tal:condition="python: tool.subTitleIsUsed(className)"> | ||||||
|  |   <img tal:condition="python: widget['name'] == 'title'" style="cursor:pointer" | ||||||
|  |        tal:attributes="src string: $appUrl/ui/toggleDetails.png" onClick="toggleSubTitles()"/> | ||||||
|  | </metal:details> | ||||||
|  |  | ||||||
|  | @ -206,8 +206,10 @@ | ||||||
|     <table width="100%" class="summary"> |     <table width="100%" class="summary"> | ||||||
|       <tr> |       <tr> | ||||||
|         <tal:comment replace="nothing">Title</tal:comment> |         <tal:comment replace="nothing">Title</tal:comment> | ||||||
|         <td colspan="2" class="objectTitle" |         <td colspan="2" class="objectTitle"> | ||||||
|             tal:content="python: contextObj.getFieldValue('title', layoutType='view')"></td> |          <tal:icons replace="structure contextObj/getIcons"/> | ||||||
|  |          <span tal:content="python: contextObj.getFieldValue('title', layoutType='view')"></span> | ||||||
|  |         </td> | ||||||
|       </tr> |       </tr> | ||||||
|       <tr class="underTitle"> |       <tr class="underTitle"> | ||||||
|         <td colspan="2" class="by"> |         <td colspan="2" class="by"> | ||||||
|  |  | ||||||
|  | @ -3,15 +3,8 @@ | ||||||
|  <metal:fill fill-slot="content" |  <metal:fill fill-slot="content" | ||||||
|    tal:define="className request/className; |    tal:define="className request/className; | ||||||
|                searchName request/search|python:''"> |                searchName request/search|python:''"> | ||||||
| 
 |  | ||||||
|   <div metal:use-macro="context/ui/page/macros/prologue"/> |   <div metal:use-macro="context/ui/page/macros/prologue"/> | ||||||
|   <tal:comment replace="nothing">Query result</tal:comment> |   <metal:result use-macro="tool/ui/result/macros/queryResult"/> | ||||||
|   <div id="queryResult"></div> |  | ||||||
| 
 |  | ||||||
|   <script type="text/javascript" |  | ||||||
|     tal:define="ajaxUrl python: tool.getQueryUrl(className, searchName)" |  | ||||||
|     tal:content="python: 'askQueryResult(\'queryResult\', \'%s\',\'%s\',\'%s\',0)' % (tool.absolute_url(), className, searchName)"> |  | ||||||
|   </script> |  | ||||||
|  </metal:fill> |  </metal:fill> | ||||||
| </html> | </html> | ||||||
| </tal:main> | </tal:main> | ||||||
|  |  | ||||||
							
								
								
									
										113
									
								
								gen/ui/result.pt
									
										
									
									
									
								
							
							
						
						|  | @ -1,31 +1,30 @@ | ||||||
| <metal:queryResults define-macro="queryResult" | <div id="queryResult" metal:define-macro="queryResult" | ||||||
|    tal:define="_            python: tool.translate; |    tal:define="_             python: tool.translate; | ||||||
|                className    request/className; |                className     request/className; | ||||||
|                refInfo      tool/getRefInfo; |                refInfo       tool/getRefInfo; | ||||||
|                refObject    python: refInfo[0]; |                refObject     python: refInfo[0]; | ||||||
|                refField     python: refInfo[1]; |                refField      python: refInfo[1]; | ||||||
|                refUrlPart   python: refObject and ('&ref=%s:%s' % (refObject.UID(), refField))  or ''; |                refUrlPart    python: refObject and ('&ref=%s:%s' % (refObject.UID(), refField))  or ''; | ||||||
|                startNumber  request/startNumber|python:'0'; |                startNumber   request/startNumber|python:'0'; | ||||||
|                startNumber  python: int(startNumber); |                startNumber   python: int(startNumber); | ||||||
|                searchName   request/search; |                searchName    request/search; | ||||||
|                labelId      python: searchName and ('%s_search_%s' % (className, searchName)) or ''; |                labelId       python: searchName and ('%s_search_%s' % (className, searchName)) or ''; | ||||||
|                labelId      python: (searchName == '_advanced') and 'search_results' or labelId; |                labelId       python: (searchName == '_advanced') and 'search_results' or labelId; | ||||||
|                searchLabel  python: labelId and _(labelId) or ''; |                searchLabel   python: labelId and _(labelId) or ''; | ||||||
|                severalTypes python: className and (className.find(',') != -1); |                sortKey       request/sortKey| python:''; | ||||||
|                sortKey      request/sortKey| python:''; |                sortOrder     request/sortOrder| python:'asc'; | ||||||
|                sortOrder    request/sortOrder| python:'asc'; |                filterKey     request/filterKey| python:''; | ||||||
|                filterKey    request/filterKey| python:''; |                filterValue   request/filterValue | python:''; | ||||||
|                filterValue  request/filterValue | python:''; |                queryResult   python: tool.executeQuery(className, searchName, startNumber, remember=True, sortBy=sortKey, sortOrder=sortOrder, filterKey=filterKey, filterValue=filterValue, refObject=refObject, refField=refField); | ||||||
|                queryResult  python: tool.executeQuery(className, searchName, startNumber, remember=True, sortBy=sortKey, sortOrder=sortOrder, filterKey=filterKey, filterValue=filterValue, refObject=refObject, refField=refField); |                objs          queryResult/objects; | ||||||
|                objs         queryResult/objects; |                totalNumber   queryResult/totalNumber; | ||||||
|                totalNumber  queryResult/totalNumber; |                batchSize     queryResult/batchSize; | ||||||
|                batchSize    queryResult/batchSize; |                ajaxHookId    python:'queryResult'; | ||||||
|                ajaxHookId   python:'queryResult'; |                navBaseCall   python: 'askQueryResult(\'%s\',\'%s\',\'%s\',\'%s\',**v**)' % (ajaxHookId, tool.absolute_url(), className, searchName); | ||||||
|                navBaseCall  python: 'askQueryResult(\'%s\',\'%s\',\'%s\',\'%s\',**v**)' % (ajaxHookId, tool.absolute_url(), className, searchName); |                newSearchUrl  python: '%s/ui/search?className=%s%s' % (tool.absolute_url(), className, refUrlPart); | ||||||
|                newSearchUrl python: '%s/ui/search?className=%s%s' % (tool.absolute_url(), className, refUrlPart)"> |                showSubTitles python: request.get('showSubTitles', 'true') == 'true'"> | ||||||
| 
 | 
 | ||||||
|  <tal:result condition="objs"> |  <tal:result condition="objs"> | ||||||
| 
 |  | ||||||
|   <tal:comment replace="nothing">Display here POD templates if required.</tal:comment> |   <tal:comment replace="nothing">Display here POD templates if required.</tal:comment> | ||||||
|   <table tal:define="widgets python: tool.getResultPodFields(className); |   <table tal:define="widgets python: tool.getResultPodFields(className); | ||||||
|                      layoutType python:'view'" |                      layoutType python:'view'" | ||||||
|  | @ -40,7 +39,7 @@ | ||||||
| 
 | 
 | ||||||
|   <tal:comment replace="nothing">The title of the search.</tal:comment> |   <tal:comment replace="nothing">The title of the search.</tal:comment> | ||||||
|   <p> |   <p> | ||||||
|    <span tal:replace="structure python: test(searchName, searchLabel, test(severalTypes, _(tool.getAppName()), _('%s_plural' % className)))"/> |    <span tal:replace="structure python: test(searchName, searchLabel, _('%s_plural' % className))"/> | ||||||
|     (<span tal:replace="totalNumber"/>) |     (<span tal:replace="totalNumber"/>) | ||||||
|       <tal:newSearch condition="python: searchName == '_advanced'"> |       <tal:newSearch condition="python: searchName == '_advanced'"> | ||||||
|          — <i><a tal:attributes="href newSearchUrl" |          — <i><a tal:attributes="href newSearchUrl" | ||||||
|  | @ -72,37 +71,42 @@ | ||||||
|                        filterable widget/filterable|nothing;"> |                        filterable widget/filterable|nothing;"> | ||||||
|         <span tal:replace="structure python: tool.truncateText(_(widget['labelId']))"/> |         <span tal:replace="structure python: tool.truncateText(_(widget['labelId']))"/> | ||||||
|         <metal:icons use-macro="context/ui/navigate/macros/sortAndFilter"/> |         <metal:icons use-macro="context/ui/navigate/macros/sortAndFilter"/> | ||||||
|  |         <metal:details use-macro="context/ui/navigate/macros/showDetails"/> | ||||||
|        </th> |        </th> | ||||||
|       </tal:header> |       </tal:header> | ||||||
|       <tal:comment replace="nothing">Object type, shown if instances of several types are shown</tal:comment> |  | ||||||
|       <th tal:condition="severalTypes"> |  | ||||||
|         <span tal:replace="python: _('root_type')"></span> |  | ||||||
|       </th> |  | ||||||
|       <tal:comment replace="nothing">Actions</tal:comment> |  | ||||||
|       <th tal:content="python: _('ref_actions')"></th> |  | ||||||
|     </tr> |     </tr> | ||||||
| 
 | 
 | ||||||
|     <tal:comment replace="nothing">Results</tal:comment> |     <tal:comment replace="nothing">Results</tal:comment> | ||||||
|     <tal:row repeat="obj objs"> |     <tal:row repeat="obj objs"> | ||||||
|     <tr id="query_row" tal:define="odd repeat/obj/odd" |     <tr id="query_row" valign="top" tal:define="odd repeat/obj/odd" | ||||||
|         tal:attributes="class python:test(odd, 'even', 'odd')"> |         tal:attributes="class python:test(odd, 'even', 'odd')"> | ||||||
| 
 | 
 | ||||||
|       <tal:fields repeat="widget widgets"> |       <tal:fields repeat="widget widgets"> | ||||||
|       <tal:comment replace="nothing">Title</tal:comment> |       <tal:comment replace="nothing">Title</tal:comment> | ||||||
|       <td id="field_title" |       <td id="field_title" | ||||||
|           tal:condition="python: widget['name'] == 'title'"> |           tal:condition="python: widget['name'] == 'title'"> | ||||||
|  |         <tal:icons replace="structure obj/getIcons"/> | ||||||
|         <a tal:define="navInfo python:'search.%s.%s.%d.%d' % (className, searchName, repeat['obj'].number()+startNumber, totalNumber);" |         <a tal:define="navInfo python:'search.%s.%s.%d.%d' % (className, searchName, repeat['obj'].number()+startNumber, totalNumber);" | ||||||
|            tal:content="obj/Title" tal:attributes="href python: obj.getUrl(nav=navInfo, page=obj.getDefaultViewPage())"></a> |            tal:content="obj/Title" tal:attributes="href python: obj.getUrl(nav=navInfo, page=obj.getDefaultViewPage())"></a> | ||||||
|       </td> |         <div name="subTitle" tal:content="structure obj/getSubTitle" | ||||||
|  |              tal:attributes="style python: showSubTitles and 'display:block' or 'display:none'"></div> | ||||||
| 
 | 
 | ||||||
|       <tal:comment replace="nothing">Workflow state</tal:comment> |         <tal:comment replace="nothing">Actions: edit, delete</tal:comment> | ||||||
|       <td id="field_workflow_state" |         <div tal:attributes="align dright" tal:condition="obj/mayAct"> | ||||||
|           tal:condition="python: widget['name'] == 'state'" |          <a tal:define="navInfo python:'search.%s.%s.%d.%d' % (className, searchName, repeat['obj'].number()+startNumber, totalNumber);" | ||||||
|           tal:content="python: _(obj.getWorkflowLabel())"> |             tal:attributes="href python: obj.getUrl(mode='edit', page=obj.getDefaultEditPage(), nav=navInfo)" | ||||||
|  |             tal:condition="obj/mayEdit"> | ||||||
|  |           <img tal:attributes="src string: $appUrl/ui/edit.gif; | ||||||
|  |                                title python: _('object_edit')"/></a><img | ||||||
|  |             tal:condition="obj/mayDelete" style="cursor:pointer" | ||||||
|  |             tal:attributes="src string: $appUrl/ui/delete.png; | ||||||
|  |                             title python: _('object_delete'); | ||||||
|  |                             onClick python:'onDeleteObject(\'%s\')' % obj.UID()"/> | ||||||
|  |         </div> | ||||||
|       </td> |       </td> | ||||||
| 
 | 
 | ||||||
|       <tal:comment replace="nothing">Any other field</tal:comment> |       <tal:comment replace="nothing">Any other field</tal:comment> | ||||||
|       <td tal:condition="python: widget['name'] not in ('title', 'state')" |       <td tal:condition="python: widget['name'] != 'title'" | ||||||
|           tal:attributes="id python:'field_%s' % widget['name']"> |           tal:attributes="id python:'field_%s' % widget['name']"> | ||||||
|         <tal:field define="contextObj python:obj; |         <tal:field define="contextObj python:obj; | ||||||
|                            layoutType python:'cell'; |                            layoutType python:'cell'; | ||||||
|  | @ -112,33 +116,6 @@ | ||||||
|          </tal:field> |          </tal:field> | ||||||
|       </td> |       </td> | ||||||
|       </tal:fields> |       </tal:fields> | ||||||
| 
 |  | ||||||
|       <tal:comment replace="nothing">Column "Object type", shown if instances of several types are shown</tal:comment> |  | ||||||
|       <td tal:condition="severalTypes" id="field_root_type" |  | ||||||
|           tal:content="python: _(obj.portal_type)"></td> |  | ||||||
| 
 |  | ||||||
|       <tal:comment replace="nothing">Column "Actions"</tal:comment> |  | ||||||
|       <td tal:attributes="align dright"> |  | ||||||
|         <table class="noStyle" tal:condition="obj/mayAct"> |  | ||||||
|           <tr> |  | ||||||
|             <tal:comment replace="nothing">Edit the element</tal:comment> |  | ||||||
|             <td> |  | ||||||
|               <a tal:define="navInfo python:'search.%s.%s.%d.%d' % (className, searchName, repeat['obj'].number()+startNumber, totalNumber);" |  | ||||||
|                  tal:attributes="href python: obj.getUrl(mode='edit', page=obj.getDefaultEditPage(), nav=navInfo)" |  | ||||||
|                  tal:condition="obj/mayEdit"> |  | ||||||
|                 <img tal:attributes="src string: $appUrl/ui/edit.gif; |  | ||||||
|                                      title python: _('object_edit')"/> |  | ||||||
|             </a></td> |  | ||||||
|             <tal:comment replace="nothing">Delete the element</tal:comment> |  | ||||||
|             <td> |  | ||||||
|               <img tal:condition="obj/mayDelete" style="cursor:pointer" |  | ||||||
|                    tal:attributes="src string: $appUrl/ui/delete.png; |  | ||||||
|                                    title python: _('object_delete'); |  | ||||||
|                                    onClick python:'onDeleteObject(\'%s\')' % obj.UID()"/> |  | ||||||
|             </td> |  | ||||||
|           </tr> |  | ||||||
|         </table> |  | ||||||
|       </td> |  | ||||||
|     </tr> |     </tr> | ||||||
|     </tal:row> |     </tal:row> | ||||||
|   </table> |   </table> | ||||||
|  | @ -154,4 +131,4 @@ | ||||||
|         tal:content="python: _('search_new')"></a></i> |         tal:content="python: _('search_new')"></a></i> | ||||||
|       </tal:newSearch> |       </tal:newSearch> | ||||||
|   </tal:noResult> |   </tal:noResult> | ||||||
| </metal:queryResults> | </div> | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								gen/ui/toggleDetails.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 250 B | 
| Before Width: | Height: | Size: 239 B After Width: | Height: | Size: 231 B | 
|  | @ -8,6 +8,7 @@ | ||||||
|     allows to reach the correct page where the forward reference is defined. If we are |     allows to reach the correct page where the forward reference is defined. If we are | ||||||
|     on a forward reference, the "nav" parameter is added to the URL for allowing to navigate |     on a forward reference, the "nav" parameter is added to the URL for allowing to navigate | ||||||
|     from one object to the next/previous on ui/view.</tal:comment> |     from one object to the next/previous on ui/view.</tal:comment> | ||||||
|  |   <tal:icons replace="structure obj/getIcons"/> | ||||||
|   <a tal:define="includeShownInfo includeShownInfo | python:False; |   <a tal:define="includeShownInfo includeShownInfo | python:False; | ||||||
|                  navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['pageName'], repeat['obj'].number()+startNumber, totalNumber); |                  navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['pageName'], repeat['obj'].number()+startNumber, totalNumber); | ||||||
|                  navInfo python: test(appyType['isBack'], '', navInfo); |                  navInfo python: test(appyType['isBack'], '', navInfo); | ||||||
|  | @ -22,24 +23,6 @@ | ||||||
|   <table class="noStyle" |   <table class="noStyle" | ||||||
|          tal:define="isBack appyType/isBack"> |          tal:define="isBack appyType/isBack"> | ||||||
|    <tr> |    <tr> | ||||||
|     <tal:comment replace="nothing">Arrows for moving objects up or down</tal:comment> |  | ||||||
|     <td tal:condition="python: not isBack and (len(objs)>1) and changeOrder and canWrite"> |  | ||||||
|       <tal:moveRef define="objectIndex  python: contextObj.getAppyRefIndex(fieldName, obj); |  | ||||||
|                            ajaxBaseCall python: navBaseCall.replace('**v**', '\'%s\',\'ChangeRefOrder\', {\'refObjectUid\':\'%s\', \'move\':\'**v**\'}' % (startNumber, obj.UID()))"> |  | ||||||
|       <tal:comment replace="nothing">Move up</tal:comment> |  | ||||||
|       <img tal:condition="python: objectIndex > 0" |  | ||||||
|         tal:attributes="src string: $appUrl/ui/arrowUp.png; |  | ||||||
|                         title python: _('move_up'); |  | ||||||
|                         onClick python: ajaxBaseCall.replace('**v**', 'up')" |  | ||||||
|         style="cursor:pointer"/> |  | ||||||
|       <tal:comment replace="nothing">Move down</tal:comment> |  | ||||||
|       <img tal:condition="python: objectIndex < (totalNumber-1)" |  | ||||||
|         tal:attributes="src string: $appUrl/ui/arrowDown.png; |  | ||||||
|                         title python: _('move_down'); |  | ||||||
|                         onClick python: ajaxBaseCall.replace('**v**', 'down')" |  | ||||||
|         style="cursor:pointer"/> |  | ||||||
|       </tal:moveRef> |  | ||||||
|     </td> |  | ||||||
|     <tal:comment replace="nothing">Edit</tal:comment> |     <tal:comment replace="nothing">Edit</tal:comment> | ||||||
|     <td tal:condition="python: not appyType['noForm'] and obj.mayEdit() and appyType['delete']"> |     <td tal:condition="python: not appyType['noForm'] and obj.mayEdit() and appyType['delete']"> | ||||||
|        <a tal:define="navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['pageName'], repeat['obj'].number()+startNumber, totalNumber);" |        <a tal:define="navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['pageName'], repeat['obj'].number()+startNumber, totalNumber);" | ||||||
|  | @ -62,6 +45,20 @@ | ||||||
|                            onClick python:'onUnlinkObject(\'%s\',\'%s\',\'%s\')' % (contextObj.UID(), appyType['name'], obj.UID()); |                            onClick python:'onUnlinkObject(\'%s\',\'%s\',\'%s\')' % (contextObj.UID(), appyType['name'], obj.UID()); | ||||||
|                            title python: _('object_unlink')"/> |                            title python: _('object_unlink')"/> | ||||||
|     </td> |     </td> | ||||||
|  |     <tal:comment replace="nothing">Arrows for moving objects up or down</tal:comment> | ||||||
|  |     <td tal:condition="python: not isBack and (len(objs)>1) and changeOrder and canWrite"> | ||||||
|  |       <tal:moveRef define="objectIndex  python: contextObj.getAppyRefIndex(fieldName, obj); | ||||||
|  |                            ajaxBaseCall python: navBaseCall.replace('**v**', '\'%s\',\'ChangeRefOrder\', {\'refObjectUid\':\'%s\', \'move\':\'**v**\'}' % (startNumber, obj.UID()))"> | ||||||
|  |        <img tal:condition="python: objectIndex > 0" style="cursor:pointer" | ||||||
|  |             tal:attributes="src string: $appUrl/ui/arrowUp.png; | ||||||
|  |                             title python: _('move_up'); | ||||||
|  |                             onClick python: ajaxBaseCall.replace('**v**', 'up')"/><img style="cursor:pointer" | ||||||
|  |             tal:condition="python: objectIndex < (totalNumber-1)" | ||||||
|  |             tal:attributes="src string: $appUrl/ui/arrowDown.png; | ||||||
|  |                             title python: _('move_down'); | ||||||
|  |                             onClick python: ajaxBaseCall.replace('**v**', 'down')"/> | ||||||
|  |       </tal:moveRef> | ||||||
|  |     </td> | ||||||
|    </tr> |    </tr> | ||||||
|   </table> |   </table> | ||||||
| </metal:objectActions> | </metal:objectActions> | ||||||
|  | @ -125,7 +122,8 @@ | ||||||
|                  atMostOneRef python: (appyType['multiplicity'][1] == 1) and (len(objs)<=1); |                  atMostOneRef python: (appyType['multiplicity'][1] == 1) and (len(objs)<=1); | ||||||
|                  addConfirmMsg python: appyType['addConfirm'] and _('%s_addConfirm' % appyType['labelId']) or ''; |                  addConfirmMsg python: appyType['addConfirm'] and _('%s_addConfirm' % appyType['labelId']) or ''; | ||||||
|                  navBaseCall python: 'askRefField(\'%s\',\'%s\',\'%s\',\'%s\',**v**)' % (ajaxHookId, contextObj.absolute_url(), fieldName, innerRef); |                  navBaseCall python: 'askRefField(\'%s\',\'%s\',\'%s\',\'%s\',**v**)' % (ajaxHookId, contextObj.absolute_url(), fieldName, innerRef); | ||||||
|                  changeOrder python: contextObj.callField(fieldName, 'changeOrderEnabled', contextObj)" |                  changeOrder python: contextObj.callField(fieldName, 'changeOrderEnabled', contextObj); | ||||||
|  |                  showSubTitles python: request.get('showSubTitles', 'true') == 'true'" | ||||||
|     tal:attributes="id ajaxHookId"> |     tal:attributes="id ajaxHookId"> | ||||||
| 
 | 
 | ||||||
|   <tal:comment replace="nothing">This macro displays the Reference widget on a "view" page. |   <tal:comment replace="nothing">This macro displays the Reference widget on a "view" page. | ||||||
|  | @ -181,21 +179,25 @@ | ||||||
|         <th tal:repeat="widget widgets"> |         <th tal:repeat="widget widgets"> | ||||||
|           <span tal:content="python: _(widget['labelId'])"></span> |           <span tal:content="python: _(widget['labelId'])"></span> | ||||||
|           <metal:sortIcons use-macro="app/ui/widgets/ref/macros/sortIcons" /> |           <metal:sortIcons use-macro="app/ui/widgets/ref/macros/sortIcons" /> | ||||||
|  |           <tal:sd define="className linkedPortalType"> | ||||||
|  |            <metal:details use-macro="context/ui/navigate/macros/showDetails"/> | ||||||
|  |           </tal:sd> | ||||||
|         </th> |         </th> | ||||||
|         <th tal:content="python: _('ref_actions')"></th> |  | ||||||
|       </tr> |       </tr> | ||||||
|       <tal:row repeat="obj objs"> |       <tal:row repeat="obj objs"> | ||||||
|        <tr valign="middle" tal:define="odd repeat/obj/odd" |        <tr valign="top" tal:define="odd repeat/obj/odd" | ||||||
|           tal:attributes="class python:test(odd, 'even', 'odd')"> |           tal:attributes="class python:test(odd, 'even', 'odd')"> | ||||||
|         <td tal:repeat="widget widgets" |         <td tal:repeat="widget widgets" | ||||||
|             tal:attributes="width python: appyType['shownInfoWidths'][repeat['widget'].index]"> |             tal:attributes="width python: appyType['shownInfoWidths'][repeat['widget'].index]"> | ||||||
|           <tal:title condition="python: widget['name'] == 'title'"> |           <tal:title condition="python: widget['name'] == 'title'"> | ||||||
|             <metal:showObjectTitle use-macro="app/ui/widgets/ref/macros/objectTitle"/> |             <metal:showObjectTitle use-macro="app/ui/widgets/ref/macros/objectTitle"/> | ||||||
|  |             <div name="subTitle" tal:content="structure obj/getSubTitle" | ||||||
|  |                  tal:attributes="style python: showSubTitles and 'display:block' or 'display:none'"></div> | ||||||
|  |             <div tal:attributes="align dright" tal:condition="obj/mayAct"> | ||||||
|  |              <metal:showObjectActions use-macro="app/ui/widgets/ref/macros/objectActions" /> | ||||||
|  |             </div> | ||||||
|           </tal:title> |           </tal:title> | ||||||
|           <tal:state condition="python: widget['name'] == 'state'" |           <tal:other condition="python: widget['name'] != 'title'"> | ||||||
|                      content="python: _(obj.getWorkflowLabel())"> |  | ||||||
|           </tal:state> |  | ||||||
|           <tal:other condition="python: widget['name'] not in ('title', 'state')"> |  | ||||||
|             <tal:field define="contextObj python:obj; |             <tal:field define="contextObj python:obj; | ||||||
|                                layoutType python: 'cell'; |                                layoutType python: 'cell'; | ||||||
|                                innerRef python:True"> |                                innerRef python:True"> | ||||||
|  | @ -203,12 +205,6 @@ | ||||||
|             </tal:field> |             </tal:field> | ||||||
|           </tal:other> |           </tal:other> | ||||||
|         </td> |         </td> | ||||||
|         <tal:comment replace="nothing">Actions</tal:comment> |  | ||||||
|         <td tal:attributes="align dright"> |  | ||||||
|           <tal:show condition="obj/mayAct"> |  | ||||||
|            <metal:showObjectActions use-macro="app/ui/widgets/ref/macros/objectActions" /> |  | ||||||
|           </tal:show> |  | ||||||
|         </td> |  | ||||||
|        </tr> |        </tr> | ||||||
|       </tal:row> |       </tal:row> | ||||||
|       </tal:widgets> |       </tal:widgets> | ||||||
|  |  | ||||||
|  | @ -1,13 +1,19 @@ | ||||||
| <tal:comment replace="nothing">View macro for a String.</tal:comment> | <tal:comment replace="nothing">View macro for a String.</tal:comment> | ||||||
| <metal:view define-macro="view" | <metal:view define-macro="view" | ||||||
|        tal:define="fmt widget/format"> |        tal:define="fmt widget/format; isUrl widget/isUrl"> | ||||||
|   <span tal:condition="python: fmt in (0, 3)"> |   <span tal:condition="python: fmt in (0, 3)"> | ||||||
|     <ul tal:condition="python: value and isMultiple"> |     <ul tal:condition="python: value and isMultiple"> | ||||||
|       <li tal:repeat="sv value"><i tal:content="structure sv"></i></li> |       <li tal:repeat="sv value"><i tal:content="structure sv"></i></li> | ||||||
|     </ul> |     </ul> | ||||||
|     <tal:singleValue condition="python: value and not isMultiple"> |     <tal:singleValue condition="python: value and not isMultiple"> | ||||||
|       <span tal:condition="python: fmt != 3" tal:replace="structure value"/> |       <tal:comment replace="nothing">A password</tal:comment> | ||||||
|       <span tal:condition="python: fmt == 3">********</span> |       <span tal:condition="python: fmt == 3">********</span> | ||||||
|  |       <tal:comment replace="nothing">A URL</tal:comment> | ||||||
|  |       <a tal:condition="python: (fmt != 3) and isUrl" target="_blank" | ||||||
|  |          tal:attributes="href value" tal:content="value"></a> | ||||||
|  |       <tal:comment replace="nothing">Any other value</tal:comment> | ||||||
|  |       <span tal:condition="python: (fmt != 3) and not isUrl" | ||||||
|  |             tal:replace="structure value"/> | ||||||
|     </tal:singleValue> |     </tal:singleValue> | ||||||
|   </span> |   </span> | ||||||
|   <tal:comment replace="nothing">Text</tal:comment> |   <tal:comment replace="nothing">Text</tal:comment> | ||||||
|  |  | ||||||
 Gaetan Delannay
						Gaetan Delannay