appy.gen: removed fields Tool.showWorkflowCommentFieldForxx (workflow comment may not be entered into the confirm popup); appy.gen: security-related bugfixes.

This commit is contained in:
Gaetan Delannay 2012-03-19 17:00:44 +01:00
parent cbb8d5cd12
commit f6a828bc13
12 changed files with 67 additions and 32 deletions

View file

@ -564,11 +564,6 @@ class ToolClassDescriptor(ClassDescriptor):
fieldType = gen.Boolean(default=defaultValue, page='userInterface',
group=groupName)
self.addField(fieldName, fieldType)
# Adds the boolean field for showing or not the field "enter comments".
fieldName = 'showWorkflowCommentFieldFor%s' % className
fieldType = gen.Boolean(default=defaultValue, page='userInterface',
group=groupName)
self.addField(fieldName, fieldType)
# Adds the boolean field for showing all states in current state or not.
# If this boolean is True but the current phase counts only one state,
# we will not show the state at all: the fact of knowing in what phase

View file

@ -417,6 +417,8 @@ class ZopeInstaller:
self.configureSessions()
self.installBaseObjects()
self.installCatalog()
# The following line cleans and rebuilds the catalog entirely.
#self.app.config.appy().refreshCatalog()
self.installTool()
self.installUi()
# Perform migrations if required

View file

@ -896,7 +896,11 @@ class BaseMixin:
self.log('Wrong workflow info for a "%s"; is not in state "%s".' % \
(self.meta_type, stateName))
# Update permission attributes on the object if required
return state.updatePermissions(wf, self)
updated = state.updatePermissions(wf, self)
if updated:
# Reindex the object because security-related info is indexed.
self.reindex()
return updated
def hasHistory(self):
'''Has this object an history?'''

View file

@ -188,7 +188,7 @@ class Translation(ModelClass):
toolFieldPrefixes = ('defaultValue', 'podTemplate', 'formats', 'resultColumns',
'enableAdvancedSearch', 'numberOfSearchColumns',
'searchFields', 'optionalFields', 'showWorkflow',
'showWorkflowCommentField', 'showAllStatesInPhase')
'showAllStatesInPhase')
defaultToolFields = ('title', 'users', 'groups', 'translations',
'enableNotifications', 'unoEnabledPython','openOfficePort',
'numberOfResultsPerPage', 'listBoxesMaximumWidth',

View file

@ -38,9 +38,6 @@ class PoMessage:
MSG_searchFields = "Search fields"
MSG_optionalFields = 'Optional fields'
MSG_showWorkflow = 'Show workflow-related information'
MSG_showWorkflowCommentField = 'Show field allowing to enter a ' \
'comment every time a transition is ' \
'triggered'
MSG_showAllStatesInPhase = 'Show all states in phase'
POD_ASKACTION = 'Trigger related action'
REF_NO = 'No object.'

View file

@ -9,6 +9,7 @@ table { font-size: 100%; border-spacing: 0px; border-collapse:collapse;}
form { margin: 0; padding: 0;}
p { margin: 0;}
acronym {cursor: help;}
input { font: 92% Helvetica,Arial,sans-serif }
input[type=image] { border: 0; background: none; }
input[type=checkbox] { border: 0; background: none; cursor: pointer;}
input[type=radio] { border: 0; background: none; cursor: pointer;}
@ -44,6 +45,8 @@ img {border: 0}
border-top: 1px solid #5F7983; border-bottom: 1px solid #5F7983; }
.login { margin-top: 2px; margin-bottom: 2px; color: white;}
.buttons { margin-left: 4px;}
.fakeButton { border: 1px solid #D7DEE4; background-color: #fde8e0;
padding: 0px 8px 2px; font: italic 92% Helvetica,Arial,sans-serif}
.message { color: #fd9c03; position: absolute; top: -55px; left: 100px;
width: 700px; border: 1px black dashed; padding: 2px 6px;
background-color: #f4f5f6}

View file

@ -307,7 +307,7 @@ function triggerTransition(transitionId, msg) {
theForm.submit();
}
else { // Ask the user to confirm.
askConfirm('form', 'triggerTransitionForm', msg);
askConfirm('form', 'triggerTransitionForm', msg, true);
}
}
@ -409,13 +409,17 @@ function closePopup(popupId) {
}
// Function triggered when an action needs to be confirmed by the user
function askConfirm(actionType, action, msg) {
function askConfirm(actionType, action, msg, showComment) {
/* Store the actionType (send a form, call an URL or call a script) and the
related action, and shows the confirm popup. If the user confirms, we
will perform the action. */
will perform the action. If p_showComment is true, an input field allowing
to enter a comment will be shown in the popup. */
var confirmForm = document.getElementById('confirmActionForm');
confirmForm.actionType.value = actionType;
confirmForm.action.value = action;
var commentArea = document.getElementById('commentArea');
if (showComment) commentArea.style.display = "block";
else commentArea.style.display = "none";
openPopup("confirmActionPopup", msg);
}
@ -427,8 +431,14 @@ function doConfirm() {
var actionType = confirmForm.actionType.value;
var action = confirmForm.action.value;
if (actionType == 'form') {
// We must submit the form whose id is in "action"
document.getElementById(action).submit();
/* Submit the form whose id is in "action", and transmmit him the comment
from the popup when relevant */
var theForm = document.getElementById(action);
if ((confirmForm.comment.style.display != 'none') &&
(confirmForm.comment.value)) {
theForm.comment.value = confirmForm.comment.value;
}
theForm.submit();
}
else if (actionType == 'url') {
// We must go to the URL defined in "action"

View file

@ -88,8 +88,9 @@
<td tal:define="actorid python:event.get('actor');" tal:content="actorid"/>
<td tal:content="event/time"/>
<td tal:condition="not: isDataChange">
<tal:comment condition="rhComments" tal:content="structure rhComments"/>
<span tal:condition="not: rhComments">No comment.</span>
<tal:c condition="rhComments"
content="structure python: contextObj.formatText(rhComments)"/>
<span tal:condition="not: rhComments">-</span>
</td>
<td tal:condition="isDataChange">
<tal:comment replace="nothing">
@ -152,21 +153,16 @@
<input type="hidden" name="workflow_action"/>
<table>
<tr valign="middle">
<tal:comment replace="nothing">Input field allowing to enter a comment before triggering a transition</tal:comment>
<td tal:define="showCommentsField python:tool.getAttr('showWorkflowCommentFieldFor'+contextObj.meta_type)"
align="right" tal:condition="showCommentsField">
<span tal:content="python: tool.translate('workflow_comment')" class="discreet"></span>
<input type="text" id="comment" name="comment" size="30"/>
</td>
<tal:comment replace="nothing">Input field for storing comment</tal:comment>
<textarea id="comment" name="comment" cols="30" rows="3" style="display:none"></textarea>
<tal:comment replace="nothing">Buttons for triggering transitions</tal:comment>
<td align="right" tal:repeat="transition transitions">
<tal:comment replace="nothing">Real button</tal:comment>
<input type="button" class="appyButton" tal:condition="transition/may_trigger"
<input type="button" tal:condition="transition/may_trigger"
tal:attributes="value transition/title;
onClick python: 'triggerTransition(\'%s\',\'%s\')' % (transition['name'],transition['confirm']);"/>
<tal:comment replace="nothing">Fake button, explaining why the transition can't be triggered</tal:comment>
<div class="appyButton fakeButton" tal:condition="not: transition/may_trigger">
<div class="fakeButton" tal:condition="not: transition/may_trigger">
<acronym tal:content="transition/title"
tal:attributes="title transition/reason"></acronym>
</div>

View file

@ -74,6 +74,12 @@
<p id="appyConfirmText"></p>
<input type="hidden" name="actionType"/>
<input type="hidden" name="action"/>
<div id="commentArea" align="left"><br/>
<span tal:content="python: tool.translate('workflow_comment')" class="discreet"></span>
<textarea name="comment" cols="30" rows="3"></textarea>
<br/>
</div>
<br/>
<input type="button" onClick="doConfirm()"
tal:attributes="value python:_('yes')"/>
<input type="button" value="No" onClick="closePopup('confirmActionPopup')"

View file

@ -95,10 +95,6 @@ class ToolWrapper(AbstractWrapper):
Stores the boolean field indicating if we must show workflow-
related information for p_klass or not.
"showWorkflowCommentField"
Stores the boolean field indicating if we must show the field
allowing to enter a comment every time a transition is triggered.
"showAllStatesInPhase"
Stores the boolean field indicating if we must show all states
linked to the current phase or not. If this field is False, we
@ -133,4 +129,29 @@ class ToolWrapper(AbstractWrapper):
expression="ctx['nb'] += int(obj.o.refreshSecurity())")
msg = 'Security refresh: %d object(s) updated.' % context['nb']
self.log(msg)
def refreshCatalog(self, startObject=None):
'''Reindex all Appy objects. For some unknown reason, method
catalog.refreshCatalog is not able to recatalog Appy objects.'''
if not startObject:
# This is a global refresh. Clear the catallog completely, and then
# reindex all Appy-managed objects, ie those in folders "config"
# and "data".
# First, clear the catalog.
app = self.o.getParentNode()
app.catalog._catalog.clear()
app.config.reindex()
nb = 1
for obj in app.config.objectValues():
nb += self.refreshCatalog(startObject=obj)
# Then, refresh objects in the "data" folder.
for obj in app.data.objectValues():
nb += self.refreshCatalog(startObject=obj)
print '%d object(s) were reindexed.' % nb
else:
startObject.reindex()
nb = 1
for obj in startObject.objectValues():
nb += self.refreshCatalog(startObject=obj)
return nb
# ------------------------------------------------------------------------------

View file

@ -129,6 +129,7 @@ class ZopeUserPatches:
'''Returns the global roles that this user (or any of its groups)
possesses.'''
res = list(self.roles)
if 'Anonymous' not in res: res.append('Authenticated')
# Add group global roles
if not hasattr(aq_base(self), 'groups'): return res
for roles in self.groups.itervalues():

View file

@ -375,10 +375,10 @@ class Cortexer:
Once the "cortex.admin" folder and its content has been generated, in
order to push the app definition into Cortex, go in the folder where
"cortex.admin" lies and type (command-line tool "cortex-client" must
"cortex.admin" lies and type (command-line tool "cortex" must
be installed):
cortex-client sync push --api http://<cortex-host-ip>/api
cortex sync push --api http://<cortex-host-ip>/api
'''
def __init__(self, app, pythonVersions=('2.6',)):
self.appName = os.path.basename(app)