merge branch master
This commit is contained in:
commit
3c43a14af9
17 changed files with 154 additions and 17 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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.
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue