[gen] Improved performance of the Ref field and added an icon for dissociating referred objects.
This commit is contained in:
parent
872b77208b
commit
9954edf71a
|
@ -1757,11 +1757,11 @@ class Ref(Type):
|
||||||
|
|
||||||
def __init__(self, klass=None, attribute=None, validator=None,
|
def __init__(self, klass=None, attribute=None, validator=None,
|
||||||
multiplicity=(0,1), index=None, default=None, optional=False,
|
multiplicity=(0,1), index=None, default=None, optional=False,
|
||||||
editDefault=False, add=False, addConfirm=False, noForm=False,
|
editDefault=False, add=False, addConfirm=False, delete=None,
|
||||||
link=True, unlink=False, back=None, show=True, page='main',
|
noForm=False, link=True, unlink=None, back=None, show=True,
|
||||||
group=None, layouts=None, showHeaders=False, shownInfo=(),
|
page='main', group=None, layouts=None, showHeaders=False,
|
||||||
select=None, maxPerPage=30, move=0, indexed=False,
|
shownInfo=(), select=None, maxPerPage=30, move=0,
|
||||||
searchable=False, specificReadPermission=False,
|
indexed=False, searchable=False, specificReadPermission=False,
|
||||||
specificWritePermission=False, width=None, height=5,
|
specificWritePermission=False, width=None, height=5,
|
||||||
maxChars=None, colspan=1, master=None, masterValue=None,
|
maxChars=None, colspan=1, master=None, masterValue=None,
|
||||||
focus=False, historized=False, mapping=None, label=None,
|
focus=False, historized=False, mapping=None, label=None,
|
||||||
|
@ -1773,6 +1773,12 @@ class Ref(Type):
|
||||||
self.add = add
|
self.add = add
|
||||||
# When the user adds a new object, must a confirmation popup be shown?
|
# When the user adds a new object, must a confirmation popup be shown?
|
||||||
self.addConfirm = addConfirm
|
self.addConfirm = addConfirm
|
||||||
|
# May the user delete objects via this Ref?
|
||||||
|
self.delete = delete
|
||||||
|
if delete == None:
|
||||||
|
# By default, one may delete objects via a Ref for which one can
|
||||||
|
# add objects.
|
||||||
|
self.delete = bool(self.add)
|
||||||
# If noForm is True, when clicking to create an object through this ref,
|
# If noForm is True, when clicking to create an object through this ref,
|
||||||
# the object will be created automatically, and no creation form will
|
# the object will be created automatically, and no creation form will
|
||||||
# be presented to the user.
|
# be presented to the user.
|
||||||
|
@ -1781,6 +1787,10 @@ class Ref(Type):
|
||||||
self.link = link
|
self.link = link
|
||||||
# May the user unlink existing objects?
|
# May the user unlink existing objects?
|
||||||
self.unlink = unlink
|
self.unlink = unlink
|
||||||
|
if unlink == None:
|
||||||
|
# By default, one may unlink objects via a Ref for which one can
|
||||||
|
# link objects.
|
||||||
|
self.unlink = bool(self.link)
|
||||||
self.back = None
|
self.back = None
|
||||||
if back:
|
if back:
|
||||||
# It is a forward reference
|
# It is a forward reference
|
||||||
|
|
|
@ -448,8 +448,11 @@ class ZopeGenerator(Generator):
|
||||||
msg('no_elem_selected', '', msg.NO_SELECTION),
|
msg('no_elem_selected', '', msg.NO_SELECTION),
|
||||||
msg('object_edit', '', msg.EDIT),
|
msg('object_edit', '', msg.EDIT),
|
||||||
msg('object_delete', '', msg.DELETE),
|
msg('object_delete', '', msg.DELETE),
|
||||||
|
msg('object_unlink', '', msg.UNLINK),
|
||||||
msg('delete_confirm', '', msg.DELETE_CONFIRM),
|
msg('delete_confirm', '', msg.DELETE_CONFIRM),
|
||||||
|
msg('unlink_confirm', '', msg.UNLINK_CONFIRM),
|
||||||
msg('delete_done', '', msg.DELETE_DONE),
|
msg('delete_done', '', msg.DELETE_DONE),
|
||||||
|
msg('unlink_done', '', msg.UNLINK_DONE),
|
||||||
msg('goto_first', '', msg.GOTO_FIRST),
|
msg('goto_first', '', msg.GOTO_FIRST),
|
||||||
msg('goto_previous', '', msg.GOTO_PREVIOUS),
|
msg('goto_previous', '', msg.GOTO_PREVIOUS),
|
||||||
msg('goto_next', '', msg.GOTO_NEXT),
|
msg('goto_next', '', msg.GOTO_NEXT),
|
||||||
|
|
|
@ -16,7 +16,7 @@ except ImportError:
|
||||||
_noroles = []
|
_noroles = []
|
||||||
|
|
||||||
# Errors -----------------------------------------------------------------------
|
# Errors -----------------------------------------------------------------------
|
||||||
jsMessages = ('no_elem_selected', 'delete_confirm')
|
jsMessages = ('no_elem_selected', 'delete_confirm', 'unlink_confirm')
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class ToolMixin(BaseMixin):
|
class ToolMixin(BaseMixin):
|
||||||
|
|
|
@ -106,6 +106,7 @@ class BaseMixin:
|
||||||
self.getParentNode().manage_delObjects([self.id])
|
self.getParentNode().manage_delObjects([self.id])
|
||||||
|
|
||||||
def onDelete(self):
|
def onDelete(self):
|
||||||
|
'''Called when an object deletion is triggered from the ui.'''
|
||||||
rq = self.REQUEST
|
rq = self.REQUEST
|
||||||
self.delete()
|
self.delete()
|
||||||
if self.getUrl(rq['HTTP_REFERER'],mode='raw') ==self.getUrl(mode='raw'):
|
if self.getUrl(rq['HTTP_REFERER'],mode='raw') ==self.getUrl(mode='raw'):
|
||||||
|
@ -117,6 +118,18 @@ class BaseMixin:
|
||||||
self.say(self.translate('delete_done'))
|
self.say(self.translate('delete_done'))
|
||||||
self.goto(urlBack)
|
self.goto(urlBack)
|
||||||
|
|
||||||
|
def onUnlink(self):
|
||||||
|
'''Called when an object unlinking is triggered from the ui.'''
|
||||||
|
rq = self.REQUEST
|
||||||
|
tool = self.getTool()
|
||||||
|
sourceObject = tool.getObject(rq['sourceUid'])
|
||||||
|
targetObject = tool.getObject(rq['targetUid'])
|
||||||
|
field = sourceObject.getAppyType(rq['fieldName'])
|
||||||
|
field.unlinkObject(sourceObject, targetObject)
|
||||||
|
urlBack = self.getUrl(rq['HTTP_REFERER'])
|
||||||
|
self.say(self.translate('unlink_done'))
|
||||||
|
self.goto(urlBack)
|
||||||
|
|
||||||
def onCreate(self):
|
def onCreate(self):
|
||||||
'''This method is called when a user wants to create a root object in
|
'''This method is called when a user wants to create a root object in
|
||||||
the "data" folder or an object through a reference field. A temporary
|
the "data" folder or an object through a reference field. A temporary
|
||||||
|
@ -1006,7 +1019,7 @@ class BaseMixin:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def mayDelete(self):
|
def mayDelete(self):
|
||||||
'''May the currently logged user delete this object?.'''
|
'''May the currently logged user delete this object?'''
|
||||||
res = self.allows('Delete objects')
|
res = self.allows('Delete objects')
|
||||||
if not res: return
|
if not res: return
|
||||||
# An additional, user-defined condition, may refine the base permission.
|
# An additional, user-defined condition, may refine the base permission.
|
||||||
|
@ -1014,9 +1027,10 @@ class BaseMixin:
|
||||||
if hasattr(appyObj, 'mayDelete'): return appyObj.mayDelete()
|
if hasattr(appyObj, 'mayDelete'): return appyObj.mayDelete()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def mayEdit(self):
|
def mayEdit(self, permission='Modify portal content'):
|
||||||
'''May the currently logged user edit this object?.'''
|
'''May the currently logged user edit this object? p_perm can be a
|
||||||
res = self.allows('Modify portal content')
|
field-specific permission.'''
|
||||||
|
res = self.allows(permission)
|
||||||
if not res: return
|
if not res: return
|
||||||
# An additional, user-defined condition, may refine the base permission.
|
# An additional, user-defined condition, may refine the base permission.
|
||||||
appyObj = self.appy()
|
appyObj = self.appy()
|
||||||
|
|
|
@ -94,8 +94,11 @@ class PoMessage:
|
||||||
NO_SELECTION = 'You must select at least one element.'
|
NO_SELECTION = 'You must select at least one element.'
|
||||||
EDIT = 'Edit'
|
EDIT = 'Edit'
|
||||||
DELETE = 'Delete'
|
DELETE = 'Delete'
|
||||||
|
UNLINK = 'Unlink'
|
||||||
DELETE_CONFIRM = 'Are you sure you want to delete this element?'
|
DELETE_CONFIRM = 'Are you sure you want to delete this element?'
|
||||||
|
UNLINK_CONFIRM = 'Are you sure you want to unlink this element?'
|
||||||
DELETE_DONE = 'The element has been deleted.'
|
DELETE_DONE = 'The element has been deleted.'
|
||||||
|
UNLINK_DONE = 'The element has been unlinked.'
|
||||||
GOTO_FIRST = 'Go to top'
|
GOTO_FIRST = 'Go to top'
|
||||||
GOTO_PREVIOUS = 'Go to previous'
|
GOTO_PREVIOUS = 'Go to previous'
|
||||||
GOTO_NEXT = 'Go to next'
|
GOTO_NEXT = 'Go to next'
|
||||||
|
|
|
@ -318,6 +318,14 @@ function onDeleteObject(objectUid) {
|
||||||
askConfirm('form', 'deleteForm', delete_confirm);
|
askConfirm('form', 'deleteForm', delete_confirm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onUnlinkObject(sourceUid, fieldName, targetUid) {
|
||||||
|
f = document.getElementById('unlinkForm');
|
||||||
|
f.sourceUid.value = sourceUid;
|
||||||
|
f.fieldName.value = fieldName;
|
||||||
|
f.targetUid.value = targetUid;
|
||||||
|
askConfirm('form', 'unlinkForm', unlink_confirm);
|
||||||
|
}
|
||||||
|
|
||||||
function createCookie(name, value, days) {
|
function createCookie(name, value, days) {
|
||||||
if (days) {
|
if (days) {
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
|
|
|
@ -18,6 +18,13 @@
|
||||||
<input type="hidden" name="action" value="Delete"/>
|
<input type="hidden" name="action" value="Delete"/>
|
||||||
<input type="hidden" name="objectUid"/>
|
<input type="hidden" name="objectUid"/>
|
||||||
</form>
|
</form>
|
||||||
|
<tal:comment replace="nothing">Global form for unlinking an object</tal:comment>
|
||||||
|
<form id="unlinkForm" method="post" action="do">
|
||||||
|
<input type="hidden" name="action" value="Unlink"/>
|
||||||
|
<input type="hidden" name="sourceUid"/>
|
||||||
|
<input type="hidden" name="fieldName"/>
|
||||||
|
<input type="hidden" name="targetUid"/>
|
||||||
|
</form>
|
||||||
<tal:comment replace="nothing">Global form for generating a document from a pod template</tal:comment>
|
<tal:comment replace="nothing">Global form for generating a document from a pod template</tal:comment>
|
||||||
<form name="podTemplateForm" method="post"
|
<form name="podTemplateForm" method="post"
|
||||||
tal:attributes="action python: tool.absolute_url() + '/generateDocument'">
|
tal:attributes="action python: tool.absolute_url() + '/generateDocument'">
|
||||||
|
|
BIN
gen/ui/unlink.png
Normal file
BIN
gen/ui/unlink.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 239 B |
|
@ -19,10 +19,11 @@
|
||||||
<metal:objectActions define-macro="objectActions">
|
<metal:objectActions define-macro="objectActions">
|
||||||
<tal:comment replace="nothing">Displays icons for triggering actions on a given
|
<tal:comment replace="nothing">Displays icons for triggering actions on a given
|
||||||
referenced object (edit, delete, etc).</tal:comment>
|
referenced object (edit, delete, etc).</tal:comment>
|
||||||
<table class="noStyle">
|
<table class="noStyle"
|
||||||
<tr>
|
tal:define="isBack appyType/isBack">
|
||||||
|
<tr>
|
||||||
<tal:comment replace="nothing">Arrows for moving objects up or down</tal:comment>
|
<tal:comment replace="nothing">Arrows for moving objects up or down</tal:comment>
|
||||||
<td tal:condition="python: not appyType['isBack'] and (len(objs)>1) and changeOrder and context.allows('Modify portal content')">
|
<td tal:condition="python: not isBack and (len(objs)>1) and changeOrder and canWrite">
|
||||||
<tal:moveRef define="objectIndex python: contextObj.getAppyRefIndex(fieldName, obj);
|
<tal:moveRef define="objectIndex python: contextObj.getAppyRefIndex(fieldName, obj);
|
||||||
ajaxBaseCall python: navBaseCall.replace('**v**', '\'%s\',\'ChangeRefOrder\', {\'refObjectUid\':\'%s\', \'move\':\'**v**\'}' % (startNumber, obj.UID()))">
|
ajaxBaseCall python: navBaseCall.replace('**v**', '\'%s\',\'ChangeRefOrder\', {\'refObjectUid\':\'%s\', \'move\':\'**v**\'}' % (startNumber, obj.UID()))">
|
||||||
<tal:comment replace="nothing">Move up</tal:comment>
|
<tal:comment replace="nothing">Move up</tal:comment>
|
||||||
|
@ -39,23 +40,29 @@
|
||||||
style="cursor:pointer"/>
|
style="cursor:pointer"/>
|
||||||
</tal:moveRef>
|
</tal:moveRef>
|
||||||
</td>
|
</td>
|
||||||
<tal:comment replace="nothing">Edit the element</tal:comment>
|
<tal:comment replace="nothing">Edit</tal:comment>
|
||||||
<td tal:condition="python: not appyType['noForm'] and obj.mayEdit()">
|
<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);"
|
||||||
tal:attributes="href python: obj.getUrl(mode='edit', page='main', nav=navInfo)">
|
tal:attributes="href python: obj.getUrl(mode='edit', page='main', nav=navInfo)">
|
||||||
<img tal:attributes="src string: $appUrl/ui/edit.gif;
|
<img tal:attributes="src string: $appUrl/ui/edit.gif;
|
||||||
title python: _('object_edit')"/>
|
title python: _('object_edit')"/>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<tal:comment replace="nothing">Delete the element</tal:comment>
|
<tal:comment replace="nothing">Delete</tal:comment>
|
||||||
<td>
|
<td tal:condition="python: not isBack and appyType['delete'] and canWrite and obj.mayDelete()">
|
||||||
<img style="cursor:pointer"
|
<img style="cursor:pointer"
|
||||||
tal:condition="python: not appyType['isBack'] and obj.mayDelete()"
|
|
||||||
tal:attributes="src string: $appUrl/ui/delete.png;
|
tal:attributes="src string: $appUrl/ui/delete.png;
|
||||||
onClick python:'onDeleteObject(\'%s\')' % obj.UID();
|
onClick python:'onDeleteObject(\'%s\')' % obj.UID();
|
||||||
title python: _('object_delete')"/>
|
title python: _('object_delete')"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
<tal:comment replace="nothing">Unlink</tal:comment>
|
||||||
|
<td tal:condition="python: not isBack and appyType['unlink'] and canWrite">
|
||||||
|
<img style="cursor:pointer"
|
||||||
|
tal:attributes="src string: $appUrl/ui/unlink.png;
|
||||||
|
onClick python:'onUnlinkObject(\'%s\',\'%s\',\'%s\')' % (contextObj.UID(), appyType['name'], obj.UID());
|
||||||
|
title python: _('object_unlink')"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</metal:objectActions>
|
</metal:objectActions>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue