merge branch master

This commit is contained in:
Helmut Merz 2013-04-27 15:15:35 +02:00
commit 3c43a14af9
17 changed files with 154 additions and 17 deletions

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 2012 Helmut Merz helmutm@cy55.de # Copyright (c) 2013 Helmut Merz helmutm@cy55.de
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -50,6 +50,7 @@ from cybertools.meta.interfaces import IOptions
from cybertools.typology.interfaces import IType, ITypeManager from cybertools.typology.interfaces import IType, ITypeManager
from cybertools.util.jeep import Jeep from cybertools.util.jeep import Jeep
from loops.browser.common import EditForm, BaseView, LoopsTerms, concept_macros from loops.browser.common import EditForm, BaseView, LoopsTerms, concept_macros
from loops.browser.common import ViewMode
from loops.common import adapted from loops.common import adapted
from loops.concept import Concept, ConceptTypeSourceList, PredicateSourceList from loops.concept import Concept, ConceptTypeSourceList, PredicateSourceList
from loops.i18n.browser import I18NView from loops.i18n.browser import I18NView
@ -746,3 +747,30 @@ class ListTypeInstances(ListChildren):
noDuplicates, useFilter, [self.typePredicate]): noDuplicates, useFilter, [self.typePredicate]):
yield c yield c
class TabbedPage(ConceptView):
@Lazy
def subpagePredicates(self):
pred = self.conceptManager.get('issubpage')
if pred is None:
pred = self.isPartOfPredicate
return [pred]
def viewModes(self):
modes = Jeep()
for s in self.getSiblings(self.subpagePredicates):
url = self.nodeView.getUrlForTarget(s)
modes.append(ViewMode(getName(s), s.title, url))
if not modes:
return modes
modes[getName(self.context)].active = True
return modes
def getSiblings(self, preds):
for p in self.context.getParents(preds):
parent = p
break
else:
return []
return p.getChildren(preds)

View file

@ -553,6 +553,14 @@
factory="loops.browser.concept.ListTypeInstances" factory="loops.browser.concept.ListTypeInstances"
permission="zope.View" /> permission="zope.View" />
<zope:adapter
name="tabbed_page.html"
for="loops.interfaces.IConcept
zope.publisher.interfaces.browser.IBrowserRequest"
provides="zope.interface.Interface"
factory="loops.browser.concept.TabbedPage"
permission="zope.View" />
<!-- dialogs/forms (end-user views) --> <!-- dialogs/forms (end-user views) -->
<page <page

View file

@ -117,6 +117,7 @@
<tal:img condition="cell/img"> <tal:img condition="cell/img">
<a dojoType="dojox.image.Lightbox" group="mediasset" <a dojoType="dojox.image.Lightbox" group="mediasset"
i18n:attributes="title" i18n:attributes="title"
tal:omit-tag="python:part.imageSize in ('large',)"
tal:attributes="href cell/img/fullImageUrl; tal:attributes="href cell/img/fullImageUrl;
title python: cell.img['description'] or cell.img['title']"> title python: cell.img['description'] or cell.img['title']">
<img tal:condition="showImageLink|python:False" <img tal:condition="showImageLink|python:False"

View file

@ -1,4 +1,4 @@
/* $Id$ */ /* loops.js */
function openEditWindow(url) { function openEditWindow(url) {
zmi = window.open(url, 'zmi'); zmi = window.open(url, 'zmi');
@ -19,6 +19,12 @@ function toggleCheckBoxes(toggle, fieldName) {
for (i in w) w[i].checked=toggle.checked; for (i in w) w[i].checked=toggle.checked;
} }
function setRadioButtons(value) {
dojo.forEach(dojo.query('input[type="radio"][value="' + value + '"]'),
function(n) {
n.checked = true;})
}
function validate(nodeName, required) { function validate(nodeName, required) {
// (work in progress) - may be used for onBlur event handler // (work in progress) - may be used for onBlur event handler
var w = dojo.byId(nodeName); var w = dojo.byId(nodeName);

View file

@ -195,9 +195,12 @@ class NodeView(BaseView):
cm.register('portlet_left', 'calendar', title=_(u'Calendar'), cm.register('portlet_left', 'calendar', title=_(u'Calendar'),
subMacro=calendar_macros.macros['main'], subMacro=calendar_macros.macros['main'],
priority=90) priority=90)
if self.setupTarget: # force early portlet registrations by target by setting up target view
# force early portlet registrations by target if self.virtualTarget is not None:
self.virtualTarget std = self.virtualTarget.typeOptions('portlet_states')
if std:
from loops.organize.stateful.browser import registerStatesPortlet
registerStatesPortlet(self.controller, self.virtualTarget, std)
@Lazy @Lazy
def usersPresent(self): def usersPresent(self):

View file

@ -42,14 +42,19 @@ template = ViewPageTemplateFile('view_macros.pt')
class SurveyView(ConceptView): class SurveyView(ConceptView):
tabview = 'index.html'
data = None data = None
errors = None errors = None
@Lazy @Lazy
def macro(self): def macro(self):
self.registerDojo()
return template.macros['survey'] return template.macros['survey']
@Lazy
def tabview(self):
if self.editable:
return 'index.html'
def results(self): def results(self):
result = [] result = []
response = None response = None

View file

@ -39,10 +39,9 @@ class Responses(BaseRecordManager):
self.context = context self.context = context
def save(self, data): def save(self, data):
if not self.personId: if self.personId:
return self.storage.saveUserTrack(self.uid, 0, self.personId, data,
self.storage.saveUserTrack(self.uid, 0, self.personId, data, update=True, overwrite=True)
update=True, overwrite=True)
def load(self): def load(self):
if self.personId: if self.personId:

View file

@ -85,6 +85,9 @@
</table> </table>
<input type="submit" name="submit" value="Evaluate Questionnaire" <input type="submit" name="submit" value="Evaluate Questionnaire"
i18n:attributes="value" /> i18n:attributes="value" />
<input type="button" name="reset_responses" value="Reset Responses Entered"
i18n:attributes="value"
onclick="setRadioButtons('none'); return false" />
</form> </form>
</div> </div>
</metal:block> </metal:block>

View file

@ -158,4 +158,5 @@ class TargetLayoutInstance(NodeLayoutInstance):
target = self.viewAnnotations.get('target') target = self.viewAnnotations.get('target')
if target is None: if target is None:
target = adapted(self.context.target) target = adapted(self.context.target)
#self.viewAnnotations['target'] = target # TODO: has to be tested!
return target return target

Binary file not shown.

View file

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: 0.13.0\n" "Project-Id-Version: 0.13.0\n"
"POT-Creation-Date: 2007-05-22 12:00 CET\n" "POT-Creation-Date: 2007-05-22 12:00 CET\n"
"PO-Revision-Date: 2013-04-01 12:00 CET\n" "PO-Revision-Date: 2013-04-06 12:00 CET\n"
"Last-Translator: Helmut Merz <helmutm@cy55.de>\n" "Last-Translator: Helmut Merz <helmutm@cy55.de>\n"
"Language-Team: loops developers <helmutm@cy55.de>\n" "Language-Team: loops developers <helmutm@cy55.de>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -241,6 +241,9 @@ msgstr "Trifft für unser Unternehmen voll und ganz zu"
msgid "Evaluate Questionnaire" msgid "Evaluate Questionnaire"
msgstr "Fragebogen auswerten" msgstr "Fragebogen auswerten"
msgid "Reset Responses Entered"
msgstr "Eingaben zurücksetzen"
msgid "Back to Questionnaire" msgid "Back to Questionnaire"
msgstr "Zurück zum Fragebogen" msgstr "Zurück zum Fragebogen"

View file

@ -27,6 +27,18 @@
class="loops.organize.browser.member.MemberRegistration" class="loops.organize.browser.member.MemberRegistration"
permission="zope.View" /> permission="zope.View" />
<browser:page
for="loops.interfaces.INode"
name="selfservice_registration.html"
class="loops.organize.browser.member.SecureMemberRegistration"
permission="zope.View" />
<browser:page
for="loops.interfaces.INode"
name="selfservice_confirmation.html"
class="loops.organize.browser.member.ConfirmMemberRegistration"
permission="zope.View" />
<browser:page <browser:page
for="loops.interfaces.INode" for="loops.interfaces.INode"
name="change_password.html" name="change_password.html"

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de # Copyright (c) 2013 Helmut Merz helmutm@cy55.de
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -19,8 +19,6 @@
""" """
Definition of view classes and other browser related stuff for Definition of view classes and other browser related stuff for
members (persons). members (persons).
$Id$
""" """
from zope import interface, component from zope import interface, component
@ -78,7 +76,7 @@ class PersonalInfo(ConceptView):
class MemberRegistration(NodeView, CreateForm): class MemberRegistration(NodeView, CreateForm):
interface = IMemberRegistration interface = IMemberRegistration # TODO: add company, create institution
message = _(u'The user account has been created.') message = _(u'The user account has been created.')
formErrors = dict( formErrors = dict(
@ -99,7 +97,7 @@ class MemberRegistration(NodeView, CreateForm):
def checkPermissions(self): def checkPermissions(self):
personType = adapted(self.conceptManager['person']) personType = adapted(self.conceptManager['person'])
perms = IOptions(personType)('registration.permission') perms = IOptions(personType)(self.permissions_key)
if perms: if perms:
return checkPermission(perms[0], self.context) return checkPermission(perms[0], self.context)
return checkPermission('loops.ManageSite', self.context) return checkPermission('loops.ManageSite', self.context)
@ -114,7 +112,7 @@ class MemberRegistration(NodeView, CreateForm):
schema.fields.remove('birthDate') schema.fields.remove('birthDate')
schema.fields.reorder(-2, 'loginName') schema.fields.reorder(-2, 'loginName')
return schema return schema
# TODO: add company, create institution
@Lazy @Lazy
def object(self): def object(self):
return Person(Concept()) return Person(Concept())
@ -157,6 +155,31 @@ class MemberRegistration(NodeView, CreateForm):
return False return False
class SecureMemberRegistration(MemberRegistration):
permissions_key = u'secure_registration.permissions'
roles_key = u'secure_registration.roles'
@Lazy
def schema(self):
schema = super(MemberRegistration, self).schema
schema.fields.remove('birthDate')
schema.fields.remove('password')
schema.fields.remove('passwordConfirm')
schema.fields.remove('phoneNumbers')
schema.fields.reorder(-2, 'loginName')
return schema
class ConfirmMemberRegistration(NodeView):
# TODO: control form via interface?
@Lazy
def macro(self):
return organize_macros.macros['confirm']
class PasswordChange(NodeView, Form): class PasswordChange(NodeView, Form):
interface = IPasswordChange interface = IPasswordChange

View file

@ -1,5 +1,9 @@
<html i18n:domain="loops"> <html i18n:domain="loops">
<metal:registration define-macro="confirm">
</metal:registration>
<metal:task define-macro="task"> <metal:task define-macro="task">
<metal:data use-macro="view/concept_macros/conceptdata"> <metal:data use-macro="view/concept_macros/conceptdata">
</metal:data> </metal:data>

View file

@ -43,6 +43,16 @@ statefulActions = ('classification_quality',
'publishable_task',) 'publishable_task',)
def registerStatesPortlet(controller, view, statesDefs,
region='portlet_right', priority=98):
cm = controller.macros
stfs = [component.getAdapter(view.context, IStateful, name=std)
for std in statesDefs]
cm.register(region, 'states', title=_(u'States'),
subMacro=template.macros['portlet_states'],
priority=priority, info=view, stfs=stfs)
class StateAction(Action): class StateAction(Action):
url = None url = None

View file

@ -68,4 +68,32 @@
</metal:query> </metal:query>
<!-- portlets -->
<metal:actions define-macro="portlet_states">
<div tal:repeat="stf macro/stfs">
<div tal:condition="python:len(macro.stfs) > 1">
<span i18n:translate="">Workflow</span>
<span i18n:translate=""
tal:content="stf/statesDefinition" />
</div>
<div>
<b i18n:translate="">State</b>:
<span i18n:translate=""
tal:content="stf/state" />
</div>
<div>
<div><b i18n:translate="">Available Transitions</b>:</div>
<ul>
<li tal:repeat="action stf/getAvailableTransitionsForUser">
<a i18n:translate=""
tal:attributes="href string:change_state.html"
tal:content="action/title" />
</li>
</ul>
</div>
</div>
</metal:actions>
</html> </html>

View file

@ -20,6 +20,7 @@
Base class(es) for track/record managers. Base class(es) for track/record managers.
""" """
from zope.app.security.interfaces import IUnauthenticatedPrincipal
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from cybertools.meta.interfaces import IOptions from cybertools.meta.interfaces import IOptions
@ -65,6 +66,8 @@ class BaseRecordManager(object):
else: else:
principal = getPrincipalForUserId(userId, context=self.context) principal = getPrincipalForUserId(userId, context=self.context)
if principal is not None: if principal is not None:
if IUnauthenticatedPrincipal.providedBy(principal):
return None
person = getPersonForUser(self.context, principal=principal) person = getPersonForUser(self.context, principal=principal)
if person is None: if person is None:
return principal.id return principal.id