[gen] A page can now be visible on edit but not on view (ie, the new User page containing only fields 'password' and 'retype password'. Default User class has now 2 pages: the 2 password fields are on a separate page. Zone containing user name in the user strip has evolved.

This commit is contained in:
Gaetan Delannay 2014-10-24 15:55:45 +02:00
parent c316ab896b
commit 412d9f939f
20 changed files with 150 additions and 106 deletions

View file

@ -21,6 +21,7 @@ from appy import Object
class Page:
'''Used for describing a page, its related phase, show condition, etc.'''
subElements = ('save', 'cancel', 'previous', 'next', 'edit')
def __init__(self, name, phase='main', show=True, showSave=True,
showCancel=True, showPrevious=True, showNext=True,
showEdit=True, label=None):
@ -61,9 +62,8 @@ class Page:
res = Page(pageData[0], phase=pageData[1])
return res
def isShowable(self, obj, elem='page'):
'''Must this page be shown for p_obj? The method can return True, False
or 'view' (page is available only in "view" mode).
def isShowable(self, obj, layoutType, elem='page'):
'''Is this page showable for p_obj on p_layoutType ("view" or "edit")?
If p_elem is not "page", this method returns the fact that a
sub-element is viewable or not (buttons "save", "cancel", etc).'''
@ -72,16 +72,14 @@ class Page:
# Get the value of the show attribute as identified above.
res = getattr(self, attr)
if callable(res): res = res(obj.appy())
if isinstance(res, str): return res == layoutType
return res
def getInfo(self, obj, layoutType):
'''Gets information about this page, for p_obj, as an object.'''
res = Object()
for elem in Page.subElements:
showable = self.isShowable(obj, elem)
# "showable" can be True, False or "view"
if layoutType == 'edit': showable = showable==True
else: showable = bool(showable)
showable = self.isShowable(obj, layoutType, elem)
setattr(res, 'show%s' % elem.capitalize(), showable)
return res

View file

@ -33,8 +33,11 @@ class Phase:
class=":(aPage == page) and 'currentPage' or ''">
<!-- First line: page name and icons -->
<span if="not (singlePhase and singlePage)">
<a href=":zobj.getUrl(page=aPage, \
inPopup=inPopup)">::aPageInfo.page.getLabel(zobj)</a>
<x var="label=aPageInfo.page.getLabel(zobj)">
<a if="aPageInfo.showOnView"
href=":zobj.getUrl(page=aPage, inPopup=inPopup)">::label</a>
<x if="not aPageInfo.showOnView">:label</x>
</x>
<x var="locked=zobj.isLocked(user, aPage);
editable=mayEdit and aPageInfo.showOnEdit and \
aPageInfo.showEdit">
@ -136,13 +139,14 @@ class Phase:
if (field.page.name in self.pages) or \
(field.page.name in self.hiddenPages): return
# Add the page only if it must be shown.
showable = field.page.isShowable(obj)
if showable:
showOnView = field.page.isShowable(obj, 'view')
showOnEdit = field.page.isShowable(obj, 'edit')
if showOnView or showOnEdit:
# The page must be added
self.pages.append(field.page.name)
# Create the dict about page information and add it in self.pageInfo
pageInfo = Object(page=field.page, showOnView=bool(showable),
showOnEdit=showable==True, links=None)
pageInfo = Object(page=field.page, showOnView=showOnView,
showOnEdit=showOnEdit, links=None)
pageInfo.update(field.page.getInfo(obj, layoutType))
self.pagesInfo[field.page.name] = pageInfo
else:
@ -203,4 +207,18 @@ class Phase:
return res, nextPhase.pagesInfo[res]
else:
return None, None
def getPageInfo(self, page, layoutType):
'''Return the page info corresponding to the given p_page. If this page
cannot be shown on p_layoutType, this method returns page info about
the first showable page on p_layoutType, or None if no page is
showable at all.'''
res = self.pagesInfo[page]
showAttribute = 'showOn%s' % layoutType.capitalize()
if getattr(res, showAttribute): return res
# Find the first showable page in this phase on p_layoutType.
for pageName in self.pages:
if pageName == page: continue
pageInfo = self.pagesInfo[pageName]
if getattr(pageInfo, showAttribute): return pageInfo
# ------------------------------------------------------------------------------

View file

@ -17,6 +17,7 @@
import types, string
from group import Group
from appy.px import Px
from appy.gen.utils import User
from appy.gen.mail import sendNotification
# Default Appy permissions -----------------------------------------------------
@ -568,6 +569,11 @@ class WorkflowOwner:
active = State({r:(ma, o), w:(ma, o), d:ma}, initial=True)
inactive = State({r:(ma, o), w:ma, d:ma})
# Transitions
deactivate = Transition( (active, inactive), condition=ma)
def doDeactivate(self, obj):
'''Prevent user "admin" from being deactivated.'''
if isinstance(obj, User) and (obj.login == 'admin'):
raise Exception('Cannot deactivate admin.')
deactivate = Transition( (active, inactive), condition=ma,
action=doDeactivate)
reactivate = Transition( (inactive, active), condition=ma)
# ------------------------------------------------------------------------------