From f91a4983426a4f4acdc69fd87756b8791f4caa37 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Fri, 12 Jul 2013 10:34:41 +0200 Subject: [PATCH] take fields for state change form from transition; store in context (if appropriate) and in change record --- organize/stateful/base.py | 13 +++++++--- organize/stateful/browser.py | 47 +++++++++++++++++++++--------------- organize/stateful/task.py | 17 +++++++++---- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/organize/stateful/base.py b/organize/stateful/base.py index fc2d942..be2a257 100644 --- a/organize/stateful/base.py +++ b/organize/stateful/base.py @@ -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) diff --git a/organize/stateful/browser.py b/organize/stateful/browser.py index 34742b1..6d97497 100644 --- a/organize/stateful/browser.py +++ b/organize/stateful/browser.py @@ -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 diff --git a/organize/stateful/task.py b/organize/stateful/task.py index 5e60ee5..dea88d4 100644 --- a/organize/stateful/task.py +++ b/organize/stateful/task.py @@ -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')