From 7adbc7e4bc0f1f0cefb471cae06d064d8e66a578 Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Tue, 29 Apr 2014 19:02:06 +0200 Subject: [PATCH] [gen] Fixed groups with style 'tabs'; reused the same tabs for representing phases; pages and phases are now outside the portlet, rendered horizontally below the breadcrumb; methods getSupBreadCrumb and getSubBreadCrumb can now be defined on every gen-class to customize what is shown above and below the breadcrumb (=title with a prefix) on view layouts (those methods are similar to getSubTitle and getSupTitle when displaying lists of objects). --- fields/group.py | 24 ++++++------ fields/phase.py | 76 +++++++++++++++++++++++++++--------- fields/search.py | 2 +- gen/mixins/ToolMixin.py | 8 ++++ gen/mixins/__init__.py | 22 +++++++++-- gen/model.py | 7 ++-- gen/ui/appy.css | 29 ++++++++------ gen/ui/tabBg.png | Bin 174 -> 176 bytes gen/ui/tabBgu.png | Bin 172 -> 167 bytes gen/ui/tabLeft.png | Bin 217 -> 213 bytes gen/ui/tabLeftu.png | Bin 184 -> 176 bytes gen/ui/tabRight.png | Bin 223 -> 214 bytes gen/ui/tabRightu.png | Bin 197 -> 185 bytes gen/wrappers/ToolWrapper.py | 20 +++------- gen/wrappers/__init__.py | 30 +++++++++----- 15 files changed, 143 insertions(+), 75 deletions(-) diff --git a/fields/group.py b/fields/group.py index 9fefec0..42a6854 100644 --- a/fields/group.py +++ b/fields/group.py @@ -257,17 +257,16 @@ class UiGroup: -
- - +
+ + var2="nb = loop.row.nb + 1; + suffix='%s_%d_%d' % (field.name, nb, lenFields); + tabId='tab_%s' % suffix"> - @@ -277,8 +276,9 @@ class UiGroup: + var2="nb=loop.row.nb + 1" + id=":'tabcontent_%s_%d_%d' % (field.name, nb, lenFields)" + style=":(nb == 1) and 'display:table-row' or 'display:none'">
- :_('%s_col%d' % (field.labelId, rowNb)) + + :_('%s_col%d' % (field.labelId, nb))
:field.pxView :field.pxRender @@ -286,7 +286,7 @@ class UiGroup:
''') diff --git a/fields/phase.py b/fields/phase.py index 5d78edd..8858167 100644 --- a/fields/phase.py +++ b/fields/phase.py @@ -23,19 +23,16 @@ class Phase: '''A group of pages.''' pxView = Px(''' -
- - -
::_(label)
- + + - + - ''') + + +
-
+ ::aPageInfo.page.getLabel(zobj) + onclick=":'onUnlockPage(%s,%s)' % (q(zobj.id), q(aPage))"/> -
+ - + - -
''') + + # "Static" PX that displays all phases of a given object. + pxAllPhases = Px(''' + + :phase.pxView + + + + + + + + + +
+ + + + + + + + +
+ :_('%s_phase_%s' % (zobj.meta_type, \ + phase.name)) +
+
:phase.pxView
+ +
+
''') def __init__(self, name, obj): self.name = name diff --git a/fields/search.py b/fields/search.py index d5571fe..4e1ba26 100644 --- a/fields/search.py +++ b/fields/search.py @@ -148,7 +148,7 @@ class UiSearch: ''') diff --git a/gen/mixins/ToolMixin.py b/gen/mixins/ToolMixin.py index 7e04e2f..8cf2d5c 100644 --- a/gen/mixins/ToolMixin.py +++ b/gen/mixins/ToolMixin.py @@ -749,6 +749,14 @@ class ToolMixin(BaseMixin): # advanced search. return klass.searchAdvanced.isShowable(klass, self.appy()) + def portletBottom(self, klass): + '''Is there a custom zone to display at the bottom of the portlet zone + for p_klass?''' + if not hasattr(klass, 'getPortletBottom'): return '' + res = klass.getPortletBottom(self.appy()) + if not res: return '' + return res + def getQueryUrl(self, contentType, searchName, startNumber=None): '''This method creates the URL that allows to perform a (non-Ajax) request for getting queried objects from a search named p_searchName diff --git a/gen/mixins/__init__.py b/gen/mixins/__init__.py index b96fd83..e2c5c28 100644 --- a/gen/mixins/__init__.py +++ b/gen/mixins/__init__.py @@ -896,14 +896,28 @@ class BaseMixin: def getSupTitle(self, navInfo=''): '''Gets the html code (icons,...) that can be shown besides the title of an object.''' - appyObj = self.appy() - if hasattr(appyObj, 'getSupTitle'): return appyObj.getSupTitle(navInfo) + obj = self.appy() + if hasattr(obj, 'getSupTitle'): return obj.getSupTitle(navInfo) 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() + obj = self.appy() + if hasattr(obj, 'getSubTitle'): return obj.getSubTitle() + return '' + + def getSupBreadCrumb(self): + '''Gets the html code that can be shown besides the title of an object + in the breadcrumb.''' + obj = self.appy() + if hasattr(obj, 'getSupBreadCrumb'): return obj.getSupBreadCrumb() + return '' + + def getSubBreadCrumb(self): + '''Gets the content that must appear below the title of an object in the + breadcrumb.''' + obj = self.appy() + if hasattr(obj, 'getSubBreadCrumb'): return obj.getSubBreadCrumb() return '' # Workflow methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/gen/model.py b/gen/model.py index 54cec55..d1881a5 100644 --- a/gen/model.py +++ b/gen/model.py @@ -257,8 +257,8 @@ class Tool(ModelClass): users = gen.Ref(User, multiplicity=(0,None), add=True, link=False, back=gen.Ref(attribute='toTool', show=False), page=userPage, queryable=True, queryFields=('title', 'login'), - show=isManager, - showHeaders=True, shownInfo=('title', 'login', 'roles')) + show=isManager, showHeaders=True, + shownInfo=('title', 'login*120px', 'roles*120px')) def computeConnectedUsers(self): pass connectedUsers = gen.Computed(method=computeConnectedUsers, page=userPage, plainText=False, show=isManager) @@ -266,7 +266,8 @@ class Tool(ModelClass): back=gen.Ref(attribute='toTool2', show=False), page=gen.Page('groups', show=isManager), show=isManager, queryable=True, queryFields=('title', 'login'), - showHeaders=True, shownInfo=('title', 'login', 'roles')) + showHeaders=True, + shownInfo=('title', 'login*120px', 'roles*120px')) pt = gen.Page('translations', show=isManager) translations = gen.Ref(Translation, multiplicity=(0,None), add=False, link=False, show='view', page=pt, diff --git a/gen/ui/appy.css b/gen/ui/appy.css index 198cf72..d26244b 100644 --- a/gen/ui/appy.css +++ b/gen/ui/appy.css @@ -52,6 +52,7 @@ img { border: 0; vertical-align: middle } .xhtml img { margin-right: 5px } .xhtml p { margin: 3px 0 7px 0 } .clickable { cursor: pointer } +.refLink { font-style: italic; padding-left: 5px; font-size: 90%; color: grey } .main { width: 900px; height: 95%; box-shadow: 3px 3px 3px #A9A9A9; border-style: solid; border-width: 1px; border-color: grey} .top { height: 89px; margin-left: 3em; vertical-align: top; @@ -62,9 +63,7 @@ img { border: 0; vertical-align: middle } .userStripText { padding: 0 0.3em 0 0.3em; color: white } .userStrip a { color: #e7e7e7 } .userStrip a:visited { color: #e7e7e7 } -.navigate { border-bottom: 1px solid #5F7983; height: 100%; - background-color: #dbdde1; font-weight: bold } -.navigate td { padding: 4px 9px } +.breadcrumb { font-size: 11pt } .login { margin: 3px; color: black } input.button { color: #666666; height: 20px; width: 130px; cursor:pointer; font-size: 90%; padding: 1px 0 0 10px; @@ -84,26 +83,25 @@ input.buttonSmall { width: 100px !important; font-size: 85%; height: 18px; .focus td { padding: 4px 0px 4px 4px } .discreet { font-size: 90%; color: grey } .title { color: #BA9440 } -.breadcrumb { color: #BA9440; font-size: 13px } .lostPassword { font-size: 90%; color: white; padding-left: 1em } +.current { font-weight: bold } .portlet { width: 150px; border-right: 1px solid #5F7983; background-color: #ededed } .portletContent { margin: 4px 9px } .portletTitle { font-size: 110%; margin-bottom: 4px } -.portletCurrent { font-weight: bold; color: grey } .portletSep { border-top: 1px solid #5F7983; margin-top: 2px } -.portletPage { font-style: italic } .portletGroup { font-variant: small-caps; font-weight: bold; font-size: 110%; margin: 0.1em 0 0.3em ; border-bottom: 1px dashed grey } .portletSearch { font-size: 90%; font-style: italic } .inputSearch { height: 15px; width: 132px; margin: 3px 3px 2px 3px !important } td.search { padding-top: 8px } -.content { padding: 14px 14px 9px 15px; background-color: #f1f1f1 } +.content { padding: 9px; background-color: #f1f1f1 } .popup { display: none; position: absolute; top: 30%; left: 35%; width: 350px; z-index : 100; background: white; padding: 8px; border: 1px solid grey; box-shadow: 2px 2px 2px #888888} .dropdown { display:none; position: absolute; border: 1px solid #cccccc; - background-color: white; padding: 3px 4px 0 } + background-color: white; padding: 3px 4px 0; font-size: 8pt; + font-weight: normal } .dropdownMenu { cursor: pointer; padding-right: 4px; font-size: 93% } .dropdown a:hover { text-decoration: underline } .list { margin-bottom: 3px } @@ -130,18 +128,20 @@ td.search { padding-top: 8px } color: white } .even { background-color: #f9f9f9 } .odd { background-color: #f4f4f4 } -.summary { margin-bottom: 5px; background-color: #f9f9f9; - border-bottom: 1px dashed #cccccc; border-top: 1px dashed #cccccc; } -.objectTitle { font-size: 11pt; border-bottom: 3px solid grey; - font-weight: bold } +.summary { margin-bottom: 5px; background-color: #f9f9f9 } .by { padding: 5px; color: grey; font-size: 97% } .underline { border-bottom: 1px dotted grey } .state { font-weight: bold; border-bottom: 1px dashed grey } .historyLabel { font-variant: small-caps; font-weight: bold } -.history td { border-top: 1px solid grey; padding: 0 5px 0 5px } +.history td { border-top: 1px solid #e6e6e6; padding: 0 5px 0 5px } .history th { font-style: italic; text-align: left; padding: 0 5px 0 5px } .topSpace { margin-top: 15px } .bottomSpace { margin-bottom: 15px } +.phase { background-color: white; border: 1px solid #d0d0d0; + box-shadow: 2px 2px 2px #888888; margin-bottom: 7px } +.phase td { padding: 3px 7px 3px 7px; border-right: 1px solid #d0d0d0; + font-size: 96% } +.currentPage { background-color: #e6e6e6 } .pageLink { margin-right: 8px } .footer { font-size: 95%; height: 100% } .footer td { background-color: #CBCBC9; border-top: 1px solid grey; @@ -159,3 +159,6 @@ td.search { padding-top: 8px } .podName { font-size: 90% } .podTable { margin-left: 15px } .cbCell { width: 10px; text-align: center} +.tabs { position:relative; bottom:-2px } +.tab { padding: 0 10px 0 10px; text-align: center; font-size: 90%; + font-weight: bold} diff --git a/gen/ui/tabBg.png b/gen/ui/tabBg.png index fd50a4715a955e4f1365aac32c9134f80ab3b87c..d5e9fa34eeb4a2645a66f5cf130edd279e5e4a09 100644 GIT binary patch delta 102 zcmZ3-xPftkIpkRY^oaR4C8wjk^(m zAP_{)8+tIb73suMunWtB42pnf#P}J{%*+?=+u0oev2gdGmBgcLC867L1b_fibA&Kc tbEIPm06ov@I9>i#UijsA(#h(v8api#KN%T-A~yg4002ovPDHLkV1hHWI&uI2 delta 143 zcmV;A0C4}+0oehNHwpFt_5k+Vphn4&KpuPC2@?+~IDw3eyZ`_ISxH1eR4C8wjk^ti zFcbqHQ5K+N8`y+VU<<}eIx>PKlB47!LPv+oJIihWtHs|zNs&icQp7Fe0RRImuK}i> xyaps8sV*ep&a+$FUH+ZD%%YKdtI|Kj# diff --git a/gen/ui/tabLeftu.png b/gen/ui/tabLeftu.png index a9425c9848372018a04a19313e3cb123dcc6909a..b5f1a89bbb29196d3c1f5e2bdf7a00d6febac80f 100644 GIT binary patch delta 89 zcmV-f0H*)A0k8p(UQ*r!9S{{096tKT0000mNkla3|NlP&F2I5=@cQ*@xN0U` v5-5`B5^zau5*WsgN)8f9#{UftIMWFLK5i7`4cA@b00000NkvXXu0mjf@8Kaj delta 97 zcmV-n0G|J_0k{E>URvA<6AvXXuIfg20000uNkla3|NlP&F2I5=@b&B0|5zoz ze*OCY_qQ)_J`*kpxFj|S6rI?>sN?`iGX8IHz?n_}YfBytbn%Ku00000NkvXXu0mjf D3PC9p diff --git a/gen/ui/tabRight.png b/gen/ui/tabRight.png index a8f80435e79ff91aaa8deab7f6237e3efde9ce63..aed966b579fdb9f917262529785bedd1df9e6f58 100644 GIT binary patch delta 107 zcmV-x0F?jV0oDPKHwpOw`2hLC6N|KwKpqa>1RW3u5sJj?H~;_uR*`HaMgBv<-xm-5 z|8H=B(EtB4{Qv(SA&E@^6S5sl;_@gCVq(ApMkQ${$@m{VoisYanE(i9LW2;J&;I}b N002ovPDHLkV1k+mEFk~@ delta 116 zcmcb{c%N~CIp;S9AiTZ6?c_uUIleob!u*=n60LXH7#JAhC+4X7)&2YP^Z)bn^Z)a3|NlP&F2M5o^=r7SsHi9- zvLq8S2U#J8B)S47Y<9sEFfrf(qmlz8$@ss)0cSb^0H&-JBz2S%?EnA(07*qoM6N<$ Ef=m@8=l}o! delta 110 zcmV-!0FnQ>0mT83UT5416AvZ;E*2>50000*Nkla3|NlP&F2M5j>sPoeH#avU zisbKaU*Mdt3=IE~6)+*I{Qd0<1F}g>==LBhU}C@nMkNPGlJS3o1I}~;03tCQXS(xA Q`Tzg`07*qoM6N<$f~or~QUCw| diff --git a/gen/wrappers/ToolWrapper.py b/gen/wrappers/ToolWrapper.py index 21dabdb..dcc0bde 100644 --- a/gen/wrappers/ToolWrapper.py +++ b/gen/wrappers/ToolWrapper.py @@ -154,24 +154,14 @@ class ToolWrapper(AbstractWrapper): currentSearch=req.get('search', None); currentClass=req.get('className', None); currentPage=req['PATH_INFO'].rsplit('/',1)[-1]; - rootClasses=ztool.getRootClasses(); - phases=zobj and zobj.getAppyPhases() or None"> - - - :phase.pxView -
+ rootClasses=ztool.getRootClasses()"> -
+
::_(className + '_plural') + 'current' or ''">::_(className + '_plural')
@@ -220,7 +210,7 @@ class ToolWrapper(AbstractWrapper):
''') diff --git a/gen/wrappers/__init__.py b/gen/wrappers/__init__.py index 670f86a..780078c 100644 --- a/gen/wrappers/__init__.py +++ b/gen/wrappers/__init__.py @@ -48,10 +48,13 @@ class AbstractWrapper(object): ''') pxNavigationStrip = Px(''' - + - -
:obj.pxNavigateSiblings
''') +
+ + :phases[0].pxAllPhases''') # The template PX for all pages. pxTemplate = Px(''' @@ -267,19 +274,22 @@ class AbstractWrapper(object): - - - - :obj.pxNavigationStrip - - - +
:tool.pxPortlet:content + + + + + + +
:obj.pxNavigationStrip
:content
+