take fields for state change form from transition; store in context (if appropriate) and in change record

This commit is contained in:
Helmut Merz 2013-07-12 10:34:41 +02:00
parent 4814947c5f
commit f91a498342
3 changed files with 49 additions and 28 deletions

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
# it under the terms of the GNU General Public License as published by
@ -18,8 +18,6 @@
"""
Basic implementations for stateful objects and adapters.
$Id$
"""
from zope.app.catalog.interfaces import ICatalog
@ -27,6 +25,7 @@ from zope.cachedescriptors.property import Lazy
from zope import component
from zope.component import adapts, adapter
from cybertools.composer.schema.field import Field
from cybertools.meta.interfaces import IOptions
from cybertools.stateful.base import Stateful as BaseStateful
from cybertools.stateful.base import StatefulAdapter, IndexInfo
@ -34,6 +33,7 @@ from cybertools.stateful.interfaces import IStatesDefinition, ITransitionEvent
from loops.common import adapted
from loops.interfaces import ILoopsObject, IConcept, IResource
from loops import util
from loops.util import _
class Stateful(BaseStateful):
@ -93,3 +93,10 @@ def handleTransition(obj, event):
if next != previous:
cat = component.getUtility(ICatalog)
cat.index_doc(int(util.getUidForObject(obj)), obj)
# predefined fields for transition forms
commentsField = Field('comments', _(u'label_transition_comments'), 'textarea',
description=_(u'desc_transition_comments'),
nostore=True)

View file

@ -28,8 +28,6 @@ from zope.i18n import translate
from zope.lifecycleevent import ObjectModifiedEvent, Attributes
from cybertools.browser.action import Action, actions
from cybertools.composer.schema.field import Field
from cybertools.composer.schema.interfaces import ISchemaFactory
from cybertools.composer.schema.schema import Schema
from cybertools.stateful.interfaces import IStateful, IStatesDefinition
from loops.browser.common import BaseView
@ -118,8 +116,18 @@ class ChangeStateBase(object):
def stateObject(self):
return self.stateful.getStateObject()
@Lazy
def schema(self):
schema = self.transition.schema
if schema is None:
return Schema()
else:
schema.manager = self
schema.request = self.request
return schema
class ChangeStateForm(ObjectForm, ChangeStateBase):
class ChangeStateForm(ChangeStateBase, ObjectForm):
form_action = 'change_state_action'
data = {}
@ -132,27 +140,26 @@ class ChangeStateForm(ObjectForm, ChangeStateBase):
def title(self):
return self.virtualTargetObject.title
@Lazy
def schema(self):
# TODO: use field information specified in transition.schema
# schema = self.transition.schema
commentsField = Field('comments', _(u'label_transition_comments'),
'textarea', description=_(u'desc_transition_comments'),
storeData=False)
fields = [commentsField]
return Schema(name='change_state', request=self.request,
manager=self, *fields)
class ChangeState(EditObject, ChangeStateBase):
class ChangeState(ChangeStateBase, EditObject):
def update(self):
# TODO: get field information from self.schema,
# store data in context if field.storeData is set, always track
comments = self.request.form.get('comments') or u''
formData = self.request.form
# store data in context (unless field.nostore)
self.object = self.context
formState = self.instance.applyTemplate(data=formData)
# TODO: check formState
# track all fields
trackData = dict(transition=self.action)
for f in self.fields:
if f.readonly:
continue
name = f.name
fi = formState.fieldInstances[name]
rawValue = fi.getRawValue(formData, name, u'')
trackData[name] = fi.unmarshall(rawValue)
self.stateful.doTransition(self.action)
notify(ObjectModifiedEvent(self.view.virtualTargetObject,
dict(transition=self.action, comments=comments)))
notify(ObjectModifiedEvent(self.view.virtualTargetObject, trackData))
return True

View file

@ -26,12 +26,15 @@ from zope.component import adapter
from zope.interface import implementer
from zope.traversing.api import getName
from cybertools.composer.schema.schema import Schema
from cybertools.stateful.definition import StatesDefinition
from cybertools.stateful.definition import State, Transition
from cybertools.stateful.interfaces import IStatesDefinition, IStateful
from loops.common import adapted
from loops.organize.stateful.base import commentsField
from loops.organize.stateful.base import StatefulLoopsObject
from loops.security.interfaces import ISecuritySetter
from loops.util import _
def setPermissionsForRoles(settings):
@ -42,6 +45,10 @@ def setPermissionsForRoles(settings):
return setSecurity
defaultSchema = Schema(commentsField,
name='change_state')
@implementer(IStatesDefinition)
def taskStates():
return StatesDefinition('task_states',
@ -55,11 +62,11 @@ def taskStates():
color='x'),
State('archived', 'archived', ('reopen',),
color='grey'),
Transition('release', 'release', 'active'),
Transition('finish', 'finish', 'finished'),
Transition('cancel', 'cancel', 'cancelled'),
Transition('reopen', 're-open', 'draft'),
Transition('archive', 'archive', 'archived'),
Transition('release', 'release', 'active', schema=defaultSchema),
Transition('finish', 'finish', 'finished', schema=defaultSchema),
Transition('cancel', 'cancel', 'cancelled', schema=defaultSchema),
Transition('reopen', 're-open', 'draft', schema=defaultSchema),
Transition('archive', 'archive', 'archived', schema=defaultSchema),
initialState='draft')