[gen] UI improvements.

This commit is contained in:
Gaetan Delannay 2013-04-11 16:01:52 +02:00
parent 1d2a19a1c6
commit d480e58d01
12 changed files with 87 additions and 77 deletions

View file

@ -1215,7 +1215,7 @@ class String(Type):
if width == None: if width == None:
if format == String.TEXT: self.width = 60 if format == String.TEXT: self.width = 60
# This width corresponds to the standard width of an Appy page. # This width corresponds to the standard width of an Appy page.
if format == String.XHTML: self.width = 870 if format == String.XHTML: self.width = None
else: self.width = 30 else: self.width = 30
if height == None: if height == None:
if format == String.TEXT: self.height = 5 if format == String.TEXT: self.height = 5

View file

@ -928,10 +928,11 @@ class BaseMixin:
return None return None
return res return res
def getIcons(self, navInfo=''): def getSupTitle(self, navInfo=''):
'''Gets the icons that can be shown besides the title of an object.''' '''Gets the html code (icons,...) that can be shown besides the title
of an object.'''
appyObj = self.appy() appyObj = self.appy()
if hasattr(appyObj, 'getIcons'): return appyObj.getIcons(navInfo) if hasattr(appyObj, 'getSupTitle'): return appyObj.getSupTitle(navInfo)
return '' return ''
def getSubTitle(self): def getSubTitle(self):
@ -1836,8 +1837,8 @@ class BaseMixin:
# this field. # this field.
field = self.getAppyType(name) field = self.getAppyType(name)
ckAttrs = {'toolbar': 'Appy', ckAttrs = {'toolbar': 'Appy',
'format_tags': '%s' % ';'.join(field.styles), 'format_tags': '%s' % ';'.join(field.styles)}
'width': field.width} if field.width: ckAttrs['width'] = field.width
if field.allowImageUpload: if field.allowImageUpload:
ckAttrs['filebrowserUploadUrl'] = '%s/upload' % self.absolute_url() ckAttrs['filebrowserUploadUrl'] = '%s/upload' % self.absolute_url()
ck = [] ck = []

View file

@ -1,6 +1,7 @@
body { font: 75% Helvetica,Arial,sans-serif; background-color: #EAEAEA; body { font: 75% "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif;
margin-top: 18px } background-color: #EAEAEA; margin-top: 18px }
pre { font: 100% Helvetica,Arial,sans-serif; margin: 0 } pre { font: 100% "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif;
margin: 0 }
h1 { font-size: 14pt; margin:6px 0 6px 0 } h1 { font-size: 14pt; margin:6px 0 6px 0 }
h2 { font-size: 13pt; margin:6px 0 6px 0; font-style: italic; h2 { font-size: 13pt; margin:6px 0 6px 0; font-style: italic;
font-weight: normal } font-weight: normal }
@ -13,9 +14,9 @@ a { text-decoration: none; color: #436976 }
a:visited { color: #436976 } a:visited { color: #436976 }
table { font-size: 100%; border-spacing: 0px; border-collapse:collapse;} table { font-size: 100%; border-spacing: 0px; border-collapse:collapse;}
form { margin: 0; padding: 0 } form { margin: 0; padding: 0 }
p { margin: 0 } p { margin: 0 0 5px 0 }
acronym { cursor: help } acronym { cursor: help }
input { font: 92% Helvetica,Arial,sans-serif } input { font: 92% "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif }
input[type=image] { border: 0; background: none; cursor: pointer } input[type=image] { border: 0; background: none; cursor: pointer }
input[type=checkbox] { border: 0; background: none; cursor: pointer } input[type=checkbox] { border: 0; background: none; cursor: pointer }
input[type=radio] { border: 0; background: none; cursor: pointer } input[type=radio] { border: 0; background: none; cursor: pointer }
@ -26,13 +27,13 @@ input[type=button] { border: 1px solid #d0d0d0; margin: 0 3px;
input[type=submit] { border: 1px solid #d0d0d0; background-color: #f8f8f8; input[type=submit] { border: 1px solid #d0d0d0; background-color: #f8f8f8;
cursor: pointer } cursor: pointer }
input[type=password] { border: 1px solid #d0d0d0; background-color: #f8f8f8; input[type=password] { border: 1px solid #d0d0d0; background-color: #f8f8f8;
font-family: Helvetica,Arial,sans-serif } font-family: "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif }
input[type=text] { border: 1px solid #d0d0d0; background-color: #f8f8f8; input[type=text] { border: 1px solid #d0d0d0; background-color: #f8f8f8;
font-family: Helvetica,Arial,sans-serif; font-family: "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif;
margin-bottom: 1px } margin-bottom: 1px }
select { border: 1px solid #d0d0d0; background-color: #f8f8f8 } select { border: 1px solid #d0d0d0; background-color: #f8f8f8 }
textarea { width: 99%; font: 100% Helvetica,Arial,sans-serif; textarea { width: 99%; font: 100% "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif;
border: 1px solid #d0d0d0; background-color: #f8f8f8 } border: 1px solid #d0d0d0; background-color: #f8f8f8 }
label { font-weight: 600; font-style: italic; line-height: 1.4em } label { font-weight: 600; font-style: italic; line-height: 1.4em }
legend { padding-bottom: 2px; padding-right: 3px; color: black } legend { padding-bottom: 2px; padding-right: 3px; color: black }
@ -64,7 +65,8 @@ img { border: 0; vertical-align: middle }
.login { margin-top: 2px; margin-bottom: 2px; color: black } .login { margin-top: 2px; margin-bottom: 2px; color: black }
.buttons { margin-left: 4px } .buttons { margin-left: 4px }
.fakeButton { border: 1px solid #D7DEE4; background-color: #fde8e0; .fakeButton { border: 1px solid #D7DEE4; background-color: #fde8e0;
padding: 0px 8px 2px; font: italic 92% Helvetica,Arial,sans-serif} padding: 0px 8px 2px;
font: italic 92% "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif }
.message { position: absolute; top: -40px; left: 150px; font-size: 90%; .message { position: absolute; top: -40px; left: 150px; font-size: 90%;
width: 600px; border: 1px #F0C36D solid; padding: 6px; width: 600px; border: 1px #F0C36D solid; padding: 6px;
background-color: #F9EDBE; text-align: center; background-color: #F9EDBE; text-align: center;
@ -74,6 +76,7 @@ img { border: 0; vertical-align: middle }
box-shadow: 0 2px 4px #A9A9A9 } box-shadow: 0 2px 4px #A9A9A9 }
.focus td { padding: 4px 0px 4px 4px } .focus td { padding: 4px 0px 4px 4px }
.discreet { font-size: 90%; color: grey } .discreet { font-size: 90%; color: grey }
.objectLink {}
.lostPassword a { font-size: 90%; color: white; padding-left: 1em } .lostPassword a { font-size: 90%; color: white; padding-left: 1em }
.portlet { width: 150px; border-right: 1px solid #5F7983; .portlet { width: 150px; border-right: 1px solid #5F7983;
background-color: #ededed } background-color: #ededed }
@ -86,13 +89,13 @@ img { border: 0; vertical-align: middle }
margin: 0.1em 0 0.3em ; border-bottom: 1px dashed grey } margin: 0.1em 0 0.3em ; border-bottom: 1px dashed grey }
.portletSearch { font-size: 90%; font-style: italic } .portletSearch { font-size: 90%; font-style: italic }
.content { padding: 14px 14px 9px 15px; background-color: #f1f1f1 } .content { padding: 14px 14px 9px 15px; background-color: #f1f1f1 }
.grey { display: none; position: absolute; left: 0px; top: 0px; .grey { display: none; position: absolute; left: 0px; top: 0px; z-index:2;
background:grey; opacity:0.5; -moz-opacity:0.5; -khtml-opacity:0.5; background:grey; opacity:0.5; -moz-opacity:0.5; -khtml-opacity:0.5;
filter:alpha(Opacity=50) } filter:alpha(Opacity=50) }
.popup { display: none; position: absolute; top: 30%; left: 35%; .popup { display: none; position: absolute; top: 30%; left: 35%;
width: 350px; z-index : 100; background: white; padding: 8px; width: 350px; z-index : 100; background: white; padding: 8px;
border: 1px solid grey } border: 1px solid grey }
.list { border: 1px solid grey; margin-bottom: 3px } .list { 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 }
@ -109,12 +112,12 @@ img { border: 0; vertical-align: middle }
padding: 0.3em 0em 0.2em 0.1em; background-color: #eef3f5; padding: 0.3em 0em 0.2em 0.1em; background-color: #eef3f5;
border-top: 1px solid #8CACBB;border-bottom: 1px solid #8CACBB } border-top: 1px solid #8CACBB;border-bottom: 1px solid #8CACBB }
.section2 { font-size: 110%; font-style: italic; margin: 0.45em 0em 0.2em 0; .section2 { font-size: 110%; font-style: italic; margin: 0.45em 0em 0.2em 0;
border-bottom: 2px solid grey } border-bottom: 1px solid #DADADA }
.section3 { font-size: 100%; font-style: italic; font-weight: bold; .section3 { font-size: 100%; font-style: italic; font-weight: bold;
margin: 0.45em 0em 0.1em 0; background-color: #95a1b3; margin: 0.45em 0em 0.1em 0; background-color: #a1aeb5;
text-align: center; color: white } text-align: center; color: white }
.odd { background-color: #f9f9f9 } .even { background-color: #f9f9f9 }
.even { background-color: #f4f4f4 } .odd { background-color: #f4f4f4 }
.summary { margin-bottom: 5px; background-color: #e9e9e9; .summary { margin-bottom: 5px; background-color: #e9e9e9;
border: 1px dashed grey } border: 1px dashed grey }
.objectTitle { font-size: 11pt; border-bottom: 3px solid grey; .objectTitle { font-size: 11pt; border-bottom: 3px solid grey;

View file

@ -235,7 +235,7 @@ function setSubTitles(value) {
var subTitles = getElementsHavingName('div', 'subTitle'); var subTitles = getElementsHavingName('div', 'subTitle');
if (subTitles.length == 0) return; if (subTitles.length == 0) return;
for (var i=0; i < subTitles.length; i++) { for (var i=0; i < subTitles.length; i++) {
if (value == 'true') subTitles[i].style.display = 'block'; if (value == 'true') subTitles[i].style.display = 'inline';
else subTitles[i].style.display = 'none'; else subTitles[i].style.display = 'none';
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 899 B

After

Width:  |  Height:  |  Size: 904 B

View file

@ -6,7 +6,7 @@ CKEDITOR.editorConfig = function(config) {
config.toolbar = 'Appy'; config.toolbar = 'Appy';
config.toolbar_Appy = [ config.toolbar_Appy = [
{ name: 'basicstyles', { name: 'basicstyles',
items: ["Bold", "Italic", "Underline"]}, items: ["Format", "Bold", "Italic", "Underline"]},
{ name: 'paragraph', { name: 'paragraph',
items: ["NumberedList","BulletedList","Outdent","Indent"]}, items: ["NumberedList","BulletedList","Outdent","Indent"]},
{ name: 'clipboard', { name: 'clipboard',

Binary file not shown.

Before

Width:  |  Height:  |  Size: 589 B

After

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 636 B

After

Width:  |  Height:  |  Size: 615 B

View file

@ -189,7 +189,6 @@
<table width="100%" class="summary"> <table width="100%" class="summary">
<tr> <tr>
<td colspan="2" class="by"> <td colspan="2" class="by">
<tal:icons replace="structure contextObj/getIcons"/>
<tal:comment replace="nothing">Creator and last modification date</tal:comment> <tal:comment replace="nothing">Creator and last modification date</tal:comment>
<tal:comment replace="nothing">Plus/minus icon for accessing history</tal:comment> <tal:comment replace="nothing">Plus/minus icon for accessing history</tal:comment>
<tal:accessHistory condition="hasHistory"> <tal:accessHistory condition="hasHistory">

View file

@ -3,10 +3,12 @@
<tal:comment replace="nothing">Title</tal:comment> <tal:comment replace="nothing">Title</tal:comment>
<tal:title condition="python: widget['name'] == 'title'"> <tal:title condition="python: widget['name'] == 'title'">
<tal:nav define="navInfo python:'search.%s.%s.%d.%d' % (className, searchName, startNumber+currentNumber, totalNumber)"> <tal:nav define="navInfo python:'search.%s.%s.%d.%d' % (className, searchName, startNumber+currentNumber, totalNumber)">
<tal:icons replace="structure python: obj.getIcons(navInfo)"/> <tal:sup replace="structure python: obj.getSupTitle(navInfo)"/>
<a tal:content="obj/Title" tal:attributes="href python: obj.getUrl(nav=navInfo, page=obj.getDefaultViewPage())"></a> <a class="objectLink" tal:content="obj/Title" tal:condition="enableLinks"
<div name="subTitle" tal:content="structure obj/getSubTitle" tal:attributes="href python: obj.getUrl(nav=navInfo, page=obj.getDefaultViewPage())"></a><span
tal:attributes="style python: showSubTitles and 'display:block' or 'display:none'"></div> tal:condition="not: enableLinks" class="objectLink" tal:content="obj/Title"></span><span
name="subTitle" tal:content="structure obj/getSubTitle"
tal:attributes="style python: showSubTitles and 'display:inline' or 'display:none'"></span>
<tal:comment replace="nothing">Actions: edit, delete</tal:comment> <tal:comment replace="nothing">Actions: edit, delete</tal:comment>
<div tal:attributes="align dright" tal:condition="obj/mayAct"> <div tal:attributes="align dright" tal:condition="obj/mayAct">
<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);"
@ -33,9 +35,10 @@
</metal:field> </metal:field>
<tal:comment replace="nothing">Show query results as a list.</tal:comment> <tal:comment replace="nothing">Show query results as a list.</tal:comment>
<table metal:define-macro="list" class="list" width="100%"> <table metal:define-macro="list" class="list" width="100%"
tal:define="showHeaders showHeaders|python:True">
<tal:comment replace="nothing">Headers, with filters and sort arrows</tal:comment> <tal:comment replace="nothing">Headers, with filters and sort arrows</tal:comment>
<tr> <tr tal:condition="showHeaders">
<tal:header repeat="column columns"> <tal:header repeat="column columns">
<th tal:define="widget column/field; <th tal:define="widget column/field;
sortable python: tool.isSortable(widget['name'], className, 'search'); sortable python: tool.isSortable(widget['name'], className, 'search');
@ -110,7 +113,8 @@
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'; showSubTitles python: request.get('showSubTitles', 'true') == 'true';
resultMode python: tool.getResultMode(className); resultMode python: tool.getResultMode(className);
showNewSearch showNewSearch|python:True"> showNewSearch showNewSearch|python:True;
enableLinks enableLinks|python: 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>

View file

@ -32,6 +32,45 @@
</head> </head>
<body tal:on-error="structure python: tool.manageError(error)"> <body tal:on-error="structure python: tool.manageError(error)">
<tal:comment replace="nothing">Grey background shown when popups are shown</tal:comment>
<div id="grey" class="grey"></div>
<tal:comment replace="nothing">Popup for confirming an action</tal:comment>
<div id="confirmActionPopup" class="popup">
<form id="confirmActionForm" method="post">
<div align="center">
<p id="appyConfirmText"></p>
<input type="hidden" name="actionType"/>
<input type="hidden" name="action"/>
<div id="commentArea" tal:attributes="align dleft"><br/>
<span tal:content="python: _('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')"
tal:attributes="value python:_('no')"/>
</div>
</form>
</div>
<tal:comment replace="nothing">Popup for reinitializing the password</tal:comment>
<div id="askPasswordReinitPopup" class="popup" tal:condition="python: isAnon and tool.showForgotPassword()">
<form id="askPasswordReinitForm" method="post"
tal:attributes="action python: tool.absolute_url() + '/askPasswordReinit'">
<div align="center">
<p tal:content="python: _('app_login')"></p>
<input type="text" size="35" name="login" id="login" value=""/>
<br/><br/>
<input type="button" onClick="doAskPasswordReinit()"
tal:attributes="value python:_('ask_password_reinit')"/>
<input type="button" value="No" onClick="closePopup('askPasswordReinitPopup')"
tal:attributes="value python:_('object_cancel')"/>
</div>
</form>
</div>
<table class="main" align="center" cellpadding="0"> <table class="main" align="center" cellpadding="0">
<tal:comment replace="nothing">Top banner</tal:comment> <tal:comment replace="nothing">Top banner</tal:comment>
<tr class="top" metal:define-slot="top"> <tr class="top" metal:define-slot="top">
@ -77,44 +116,6 @@
<div style="position: relative"> <div style="position: relative">
<metal:msg use-macro="app/ui/page/macros/message"/> <metal:msg use-macro="app/ui/page/macros/message"/>
</div> </div>
<tal:comment replace="nothing">Grey background shown when popups are shown</tal:comment>
<div id="grey" class="grey"></div>
<tal:comment replace="nothing">Popup for confirming an action</tal:comment>
<div id="confirmActionPopup" class="popup">
<form id="confirmActionForm" method="post">
<div align="center">
<p id="appyConfirmText"></p>
<input type="hidden" name="actionType"/>
<input type="hidden" name="action"/>
<div id="commentArea" tal:attributes="align dleft"><br/>
<span tal:content="python: _('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')"
tal:attributes="value python:_('no')"/>
</div>
</form>
</div>
<tal:comment replace="nothing">Popup for reinitializing the password</tal:comment>
<div id="askPasswordReinitPopup" class="popup" tal:condition="python: isAnon and tool.showForgotPassword()">
<form id="askPasswordReinitForm" method="post"
tal:attributes="action python: tool.absolute_url() + '/askPasswordReinit'">
<div align="center">
<p tal:content="python: _('app_login')"></p>
<input type="text" size="35" name="login" id="login" value=""/>
<br/><br/>
<input type="button" onClick="doAskPasswordReinit()"
tal:attributes="value python:_('ask_password_reinit')"/>
<input type="button" value="No" onClick="closePopup('askPasswordReinitPopup')"
tal:attributes="value python:_('object_cancel')"/>
</div>
</form>
</div>
</td> </td>
</tr> </tr>
<tal:comment replace="nothing">The user strip</tal:comment> <tal:comment replace="nothing">The user strip</tal:comment>

View file

@ -2,19 +2,23 @@
We begin with some sub-macros used within macro "show" defined below. We begin with some sub-macros used within macro "show" defined below.
</tal:comment> </tal:comment>
<metal:objectTitle define-macro="objectTitle"> <metal:objectTitle define-macro="objectTitle"
tal:define="navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['pageName'], repeat['obj'].number()+startNumber, totalNumber);
navInfo python: test(appyType['isBack'], '', navInfo)">
<tal:comment replace="nothing">Displays the title of a referenced object, with a link on <tal:comment replace="nothing">Displays the title of a referenced object, with a link on
it to reach the consult view for this object. If we are on a back reference, the link it to reach the consult view for this object. If we are on a back reference, the link
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"/> <tal:sup replace="structure python: obj.getSupTitle(navInfo)"/>
<a tal:define="includeShownInfo includeShownInfo | python:False; <a class="objectLink"
navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['pageName'], repeat['obj'].number()+startNumber, totalNumber); tal:define="includeShownInfo includeShownInfo | python:False;
navInfo python: test(appyType['isBack'], '', navInfo);
pageName python: appyType['isBack'] and appyType['backd']['pageName'] or 'main'; pageName python: appyType['isBack'] and appyType['backd']['pageName'] or 'main';
fullUrl python: obj.getUrl(page=pageName, nav=navInfo)" fullUrl python: obj.getUrl(page=pageName, nav=navInfo)"
tal:attributes="href fullUrl" tal:content="python: (not includeShownInfo) and obj.Title() or contextObj.getReferenceLabel(fieldName, obj.appy())"></a> tal:attributes="href fullUrl"
tal:content="python: (not includeShownInfo) and obj.Title() or contextObj.getReferenceLabel(fieldName, obj.appy())"></a><span
name="subTitle" tal:content="structure obj/getSubTitle"
tal:attributes="style python: showSubTitles and 'display:inline' or 'display:none'"></span>
</metal:objectTitle> </metal:objectTitle>
<metal:objectActions define-macro="objectActions"> <metal:objectActions define-macro="objectActions">
@ -202,8 +206,6 @@
<tal:def define="widget column/field"> <tal:def define="widget column/field">
<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"> <div tal:attributes="align dright" tal:condition="obj/mayAct">
<metal:showObjectActions use-macro="app/ui/widgets/ref/macros/objectActions" /> <metal:showObjectActions use-macro="app/ui/widgets/ref/macros/objectActions" />
</div> </div>