|
1 # |
|
2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net> |
|
3 # All Rights Reserved. |
|
4 # |
|
5 # This software is subject to the provisions of the Zope Public License, |
|
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
|
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
10 # FOR A PARTICULAR PURPOSE. |
|
11 # |
|
12 from pyams_utils.text import text_to_html |
|
13 |
|
14 __docformat__ = 'restructuredtext' |
|
15 |
|
16 |
|
17 # import standard library |
|
18 from datetime import datetime |
|
19 |
|
20 # import interfaces |
|
21 from pyams_content.shared.common.interfaces import IWfSharedContent, ISharedTool, ISharedContent |
|
22 from pyams_form.interfaces.form import IInnerTabForm, IFormPrefixViewletsManager, IWidgetsPrefixViewletsManager, \ |
|
23 IFormSuffixViewletsManager |
|
24 from pyams_security.interfaces import ISecurityManager |
|
25 from pyams_skin.interfaces import IInnerPage |
|
26 from pyams_skin.layer import IPyAMSLayer |
|
27 from pyams_workflow.interfaces import IWorkflowInfo, IWorkflowTransitionInfo, IWorkflowPublicationInfo, \ |
|
28 IWorkflowCommentInfo, IWorkflowVersions, IWorkflowState, IWorkflowManagedContent, IWorkflow, IWorkflowStateLabel, \ |
|
29 IWorkflowRequestUrgencyInfo, SYSTEM, MANUAL |
|
30 from z3c.form.interfaces import IDataExtractedEvent |
|
31 |
|
32 # import packages |
|
33 from pyams_content.shared.common.zmi.summary import SharedContentSummaryForm |
|
34 from pyams_content.workflow import DRAFT, DELETED |
|
35 from pyams_form.form import AJAXAddForm, InnerDisplayForm |
|
36 from pyams_form.schema import CloseButton |
|
37 from pyams_pagelet.pagelet import pagelet_config |
|
38 from pyams_template.template import template_config |
|
39 from pyams_utils.adapter import adapter_config |
|
40 from pyams_utils.date import format_datetime |
|
41 from pyams_utils.registry import get_utility |
|
42 from pyams_utils.timezone import tztime |
|
43 from pyams_utils.traversing import get_parent |
|
44 from pyams_utils.url import absolute_url |
|
45 from pyams_viewlet.viewlet import viewlet_config, Viewlet |
|
46 from pyams_workflow.zmi.transition import WorkflowContentTransitionForm, WorkflowContentTransitionAJAXForm |
|
47 from pyramid.events import subscriber |
|
48 from pyramid.view import view_config |
|
49 from z3c.form import field, button |
|
50 from zope.interface import implementer, Interface, Invalid |
|
51 |
|
52 from pyams_content import _ |
|
53 |
|
54 |
|
55 # |
|
56 # Workflow summary view |
|
57 # |
|
58 |
|
59 @adapter_config(name='workflow-summary', |
|
60 context=(IWfSharedContent, IPyAMSLayer, SharedContentSummaryForm), |
|
61 provides=IInnerTabForm) |
|
62 class WfSharedContentWorkflowSummary(InnerDisplayForm): |
|
63 """Shared content workflow summary""" |
|
64 |
|
65 weight = 10 |
|
66 tab_label = _("Workflow") |
|
67 tab_target = 'workflow-summary.html' |
|
68 |
|
69 fields = field.Fields(Interface) |
|
70 |
|
71 |
|
72 @pagelet_config(name='workflow-summary.html', context=IWfSharedContent, layer=IPyAMSLayer) |
|
73 @implementer(IInnerPage, IInnerTabForm) |
|
74 class WorkflowSummaryDisplayForm(InnerDisplayForm): |
|
75 """Workflow summary display form""" |
|
76 |
|
77 @property |
|
78 def fields(self): |
|
79 fields = field.Fields(IWorkflowState).omit('history') + \ |
|
80 field.Fields(IWorkflowPublicationInfo) |
|
81 workflow = IWorkflow(self.context) |
|
82 if IWorkflowState(self.context).state not in workflow.waiting_states: |
|
83 fields = fields.omit('state_urgency') |
|
84 return fields |
|
85 |
|
86 def updateWidgets(self, prefix=None): |
|
87 super(WorkflowSummaryDisplayForm, self).updateWidgets(prefix) |
|
88 state = IWorkflowState(self.context) |
|
89 content = get_parent(self.context, IWorkflowManagedContent) |
|
90 workflow = get_utility(IWorkflow, name=content.workflow_name) |
|
91 self.widgets['state'].value = self.request.localizer.translate(workflow.get_state_label(state.state)) |
|
92 self.widgets['state_date'].value = format_datetime(tztime(state.state_date)) |
|
93 info = IWorkflowPublicationInfo(self.context) |
|
94 if info.publication_date: |
|
95 self.widgets['publication_date'].value = format_datetime(tztime(info.publication_date)) |
|
96 if info.first_publication_date: |
|
97 self.widgets['first_publication_date'].value = format_datetime(tztime(info.first_publication_date)) |
|
98 if info.publication_effective_date: |
|
99 self.widgets['publication_effective_date'].value = format_datetime(tztime(info.publication_effective_date)) |
|
100 if info.publication_expiration_date: |
|
101 self.widgets['publication_expiration_date'].value = format_datetime((tztime(info.publication_expiration_date))) |
|
102 |
|
103 |
|
104 # |
|
105 # Generic transition info |
|
106 # |
|
107 |
|
108 @viewlet_config(name='wf-transition-info', context=IWfSharedContent, layer=IPyAMSLayer, |
|
109 view=WorkflowContentTransitionForm, manager=IFormSuffixViewletsManager, weight=10) |
|
110 @template_config(template='templates/wf-transition-info.pt') |
|
111 class WorkflowContentTransitionFormInfo(Viewlet): |
|
112 """Publication request form info message""" |
|
113 |
|
114 @property |
|
115 def previous_step(self): |
|
116 translate = self.request.localizer.translate |
|
117 workflow = IWorkflow(self.context) |
|
118 state = IWorkflowState(self.context) |
|
119 adapter = self.request.registry.queryAdapter(workflow, IWorkflowStateLabel, |
|
120 name=state.state) |
|
121 if adapter is None: |
|
122 adapter = self.request.registry.queryAdapter(workflow, IWorkflowStateLabel) |
|
123 if adapter is not None: |
|
124 state_label = adapter.get_label(self.context, request=self.request) |
|
125 else: |
|
126 security = get_utility(ISecurityManager) |
|
127 state_label = translate(_("{state} by {principal}")).format( |
|
128 state=translate(workflow.get_state_label(state.state)), |
|
129 principal=security.get_principal(state.state_principal).title) |
|
130 return translate(_("{state} {date}")).format(state=state_label, |
|
131 date=format_datetime(state.state_date, request=self.request)) |
|
132 |
|
133 @property |
|
134 def previous_message(self): |
|
135 workflow = IWorkflow(self.context) |
|
136 state = IWorkflowState(self.context) |
|
137 position = 0 |
|
138 history_item = None |
|
139 trigger = SYSTEM |
|
140 while trigger != MANUAL: |
|
141 position -= 1 |
|
142 history_item = state.history[position] |
|
143 if history_item.transition_id: |
|
144 trigger = workflow.get_transition_by_id(history_item.transition_id).trigger |
|
145 else: |
|
146 break |
|
147 if history_item: |
|
148 return text_to_html((history_item.comment or '').strip()) |
|
149 |
|
150 @property |
|
151 def next_step(self): |
|
152 transition = self.__parent__.transition |
|
153 return self.request.localizer.translate(transition.user_data.get('next_step')) \ |
|
154 if 'next_step' in transition.user_data else None |
|
155 |
|
156 |
|
157 # |
|
158 # Request publication form |
|
159 # |
|
160 |
|
161 class IPublicationRequestButtons(Interface): |
|
162 """Shared content publication request buttons""" |
|
163 |
|
164 close = CloseButton(name='close', title=_("Cancel")) |
|
165 action = button.Button(name='action', title=_("Request publication")) |
|
166 |
|
167 |
|
168 @pagelet_config(name='wf-propose.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.ManageContent') |
|
169 class PublicationRequestForm(WorkflowContentTransitionForm): |
|
170 """Shared content publication request form""" |
|
171 |
|
172 fields = field.Fields(IWorkflowTransitionInfo) + \ |
|
173 field.Fields(IWorkflowPublicationInfo).select('publication_effective_date', |
|
174 'publication_expiration_date') + \ |
|
175 field.Fields(IWorkflowRequestUrgencyInfo) + \ |
|
176 field.Fields(IWorkflowCommentInfo) |
|
177 buttons = button.Buttons(IPublicationRequestButtons) |
|
178 ajax_handler = 'wf-propose.json' |
|
179 |
|
180 def updateWidgets(self, prefix=None): |
|
181 super(PublicationRequestForm, self).updateWidgets(prefix) |
|
182 self.widgets['publication_effective_date'].required = True |
|
183 self.widgets['publication_effective_date'].value = datetime.now().strftime('%d/%m/%y %H:%M') |
|
184 self.widgets['comment'].required = True |
|
185 |
|
186 def createAndAdd(self, data): |
|
187 pub_info = IWorkflowPublicationInfo(self.context) |
|
188 pub_info.publication_effective_date = data.get('publication_effective_date') |
|
189 pub_info.publication_expiration_date = data.get('publication_expiration_date') |
|
190 return super(PublicationRequestForm, self).createAndAdd(data) |
|
191 |
|
192 |
|
193 @view_config(name='wf-propose.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
194 permission='pyams.ManageContent', renderer='json', xhr=True) |
|
195 class PublicationRequestAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRequestForm): |
|
196 """Shared content publication request form, JSON renderer""" |
|
197 |
|
198 |
|
199 @subscriber(IDataExtractedEvent, form_selector=PublicationRequestForm) |
|
200 def handle_publication_request_form_data_extraction(event): |
|
201 """Handle publication request form data extraction""" |
|
202 if not event.data.get('publication_effective_date'): |
|
203 event.form.widgets.errors += (Invalid(_("Publication start date is required")), ) |
|
204 comment = (event.data.get('comment') or '').strip() |
|
205 if not comment: |
|
206 event.form.widgets.errors += (Invalid(_("A comment is required")), ) |
|
207 |
|
208 |
|
209 @viewlet_config(name='wf-propose-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
210 view=PublicationRequestForm, manager=IFormPrefixViewletsManager, weight=10) |
|
211 @template_config(template='templates/wf-owner-warning.pt') |
|
212 class PublicationRequestFormWarning(Viewlet): |
|
213 """Publication request form warning message""" |
|
214 |
|
215 def __new__(cls, context, request, view, manager): |
|
216 if request.principal.id in context.owner: |
|
217 return None |
|
218 return Viewlet.__new__(cls) |
|
219 |
|
220 |
|
221 @viewlet_config(name='wf-propose-message', context=IWfSharedContent, layer=IPyAMSLayer, view=PublicationRequestForm, |
|
222 manager=IWidgetsPrefixViewletsManager, weight=20) |
|
223 @template_config(template='templates/wf-propose-message.pt') |
|
224 class PublicationRequestFormMessage(Viewlet): |
|
225 """Publication request form info message""" |
|
226 |
|
227 |
|
228 # |
|
229 # Cancel publication request form |
|
230 # |
|
231 |
|
232 class IPublicationRequestCancelButtons(Interface): |
|
233 """Shared content publication request cancel buttons""" |
|
234 |
|
235 close = CloseButton(name='close', title=_("Cancel")) |
|
236 action = button.Button(name='action', title=_("Cancel publication request")) |
|
237 |
|
238 |
|
239 @pagelet_config(name='wf-cancel-propose.html', context=IWfSharedContent, layer=IPyAMSLayer, |
|
240 permission='pyams.ManageContent') |
|
241 class PublicationRequestCancelForm(WorkflowContentTransitionForm): |
|
242 """Shared content publication request cancel form""" |
|
243 |
|
244 buttons = button.Buttons(IPublicationRequestCancelButtons) |
|
245 ajax_handler = 'wf-cancel-propose.json' |
|
246 |
|
247 |
|
248 @view_config(name='wf-cancel-propose.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
249 permission='pyams.ManageContent', renderer='json', xhr=True) |
|
250 class PublicationRequestCancelAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRequestCancelForm): |
|
251 """Shared content publication request cancel form, JSON renderer""" |
|
252 |
|
253 |
|
254 @viewlet_config(name='wf-cancel-propose-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
255 view=PublicationRequestCancelForm, manager=IFormPrefixViewletsManager, weight=10) |
|
256 @template_config(template='templates/wf-owner-warning.pt') |
|
257 class PublicationRequestCancelFormWarning(Viewlet): |
|
258 """Publication request cancel form warning message""" |
|
259 |
|
260 def __new__(cls, context, request, view, manager): |
|
261 if request.principal.id in context.owner: |
|
262 return None |
|
263 return Viewlet.__new__(cls) |
|
264 |
|
265 |
|
266 @viewlet_config(name='wf-cancel-propose-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
267 view=PublicationRequestCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
268 @template_config(template='templates/wf-cancel-propose-message.pt') |
|
269 class PublicationRequestCancelFormMessage(Viewlet): |
|
270 """Publication request cancel form info message""" |
|
271 |
|
272 |
|
273 # |
|
274 # Refuse publication form |
|
275 # |
|
276 |
|
277 class IPublicationRequestRefuseButtons(Interface): |
|
278 """Shared content publication request refuse buttons""" |
|
279 |
|
280 close = CloseButton(name='close', title=_("Cancel")) |
|
281 action = button.Button(name='action', title=_("Refuse publication request")) |
|
282 |
|
283 |
|
284 @pagelet_config(name='wf-refuse.html', context=IWfSharedContent, layer=IPyAMSLayer, |
|
285 permission='pyams.PublishContent') |
|
286 class PublicationRequestRefuseForm(WorkflowContentTransitionForm): |
|
287 """Shared content publication request refuse form""" |
|
288 |
|
289 buttons = button.Buttons(IPublicationRequestRefuseButtons) |
|
290 ajax_handler = 'wf-refuse.json' |
|
291 |
|
292 def updateWidgets(self, prefix=None): |
|
293 super(PublicationRequestRefuseForm, self).updateWidgets(prefix) |
|
294 self.widgets['comment'].required = True |
|
295 |
|
296 |
|
297 @view_config(name='wf-refuse.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
298 permission='pyams.PublishContent', renderer='json', xhr=True) |
|
299 class PublicationRequestRefuseAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRequestRefuseForm): |
|
300 """Shared content publication request refuse form, JSON renderer""" |
|
301 |
|
302 |
|
303 @subscriber(IDataExtractedEvent, form_selector=PublicationRequestRefuseForm) |
|
304 def handle_publication_request_refuse_form_data_extraction(event): |
|
305 """Handle publication request refuse form data extraction""" |
|
306 comment = (event.data.get('comment') or '').strip() |
|
307 if not comment: |
|
308 event.form.widgets.errors += (Invalid(_("A comment is required")), ) |
|
309 |
|
310 |
|
311 @viewlet_config(name='wf-refuse-operator-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
312 view=PublicationRequestRefuseForm, manager=IFormPrefixViewletsManager, weight=10) |
|
313 @template_config(template='templates/wf-operator-warning.pt') |
|
314 class PublicationRequestRefuseFormWarning(Viewlet): |
|
315 """Publication request refuse form warning message""" |
|
316 |
|
317 def __new__(cls, context, request, view, manager): |
|
318 state = IWorkflowState(context) |
|
319 if state.state_principal in context.owner: |
|
320 return None |
|
321 return Viewlet.__new__(cls) |
|
322 |
|
323 |
|
324 @viewlet_config(name='wf-refuse-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
325 view=PublicationRequestRefuseForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
326 @template_config(template='templates/wf-refuse-propose-message.pt') |
|
327 class PublicationRequestRefuseFormMessage(Viewlet): |
|
328 """Publication request refuse form info message""" |
|
329 |
|
330 |
|
331 # |
|
332 # Publish form |
|
333 # |
|
334 |
|
335 class IPublicationButtons(Interface): |
|
336 """Shared content publication buttons""" |
|
337 |
|
338 close = CloseButton(name='close', title=_("Cancel")) |
|
339 action = button.Button(name='action', title=_("Publish")) |
|
340 |
|
341 |
|
342 @pagelet_config(name='wf-publish.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.PublishContent') |
|
343 class PublicationForm(WorkflowContentTransitionForm): |
|
344 """Shared content publication form""" |
|
345 |
|
346 fields = field.Fields(IWorkflowTransitionInfo) + \ |
|
347 field.Fields(IWorkflowPublicationInfo).select('publication_effective_date', |
|
348 'publication_expiration_date') + \ |
|
349 field.Fields(IWorkflowCommentInfo) |
|
350 buttons = button.Buttons(IPublicationButtons) |
|
351 ajax_handler = 'wf-publish.json' |
|
352 |
|
353 def updateWidgets(self, prefix=None): |
|
354 super(PublicationForm, self).updateWidgets(prefix) |
|
355 pub_info = IWorkflowPublicationInfo(self.context) |
|
356 self.widgets['publication_effective_date'].required = True |
|
357 if ('publication_effective_date' in self.widgets) and pub_info.publication_effective_date: |
|
358 self.widgets['publication_effective_date'].value = \ |
|
359 tztime(pub_info.publication_effective_date).strftime('%d/%m/%y %H:%M') |
|
360 if ('publication_expiration_date' in self.widgets) and pub_info.publication_expiration_date: |
|
361 self.widgets['publication_expiration_date'].value = \ |
|
362 tztime(pub_info.publication_expiration_date).strftime('%d/%m/%y %H:%M') |
|
363 |
|
364 def createAndAdd(self, data): |
|
365 pub_info = IWorkflowPublicationInfo(self.context) |
|
366 pub_info.publication_effective_date = data.get('publication_effective_date') |
|
367 pub_info.publication_expiration_date = data.get('publication_expiration_date') |
|
368 return super(PublicationForm, self).createAndAdd(data) |
|
369 |
|
370 |
|
371 @view_config(name='wf-publish.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
372 permission='pyams.PublishContent', renderer='json', xhr=True) |
|
373 class PublicationAJAXForm(WorkflowContentTransitionAJAXForm, PublicationForm): |
|
374 """Shared content publication form, JSON renderer""" |
|
375 |
|
376 |
|
377 @subscriber(IDataExtractedEvent, form_selector=PublicationForm) |
|
378 def handle_publication_form_data_extraction(event): |
|
379 """Handle publication form data extraction""" |
|
380 if not event.data.get('publication_effective_date'): |
|
381 event.form.widgets.errors += (Invalid(_("Publication start date is required")), ) |
|
382 |
|
383 |
|
384 @viewlet_config(name='wf-publish-operator-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
385 view=PublicationForm, manager=IFormPrefixViewletsManager, weight=10) |
|
386 @template_config(template='templates/wf-operator-warning.pt') |
|
387 class PublicationFormWarning(Viewlet): |
|
388 """Shared content publication form warning message""" |
|
389 |
|
390 def __new__(cls, context, request, view, manager): |
|
391 state = IWorkflowState(context) |
|
392 if state.state_principal in context.owner: |
|
393 return None |
|
394 return Viewlet.__new__(cls) |
|
395 |
|
396 |
|
397 @viewlet_config(name='wf-publish-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
398 view=PublicationForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
399 @template_config(template='templates/wf-publish-message.pt') |
|
400 class PublicationFormMessage(Viewlet): |
|
401 """Shared content publication form info message""" |
|
402 |
|
403 |
|
404 # |
|
405 # Publication retire request form |
|
406 # |
|
407 |
|
408 class IPublicationRetireRequestButtons(Interface): |
|
409 """Shared content publication retire request buttons""" |
|
410 |
|
411 close = CloseButton(name='close', title=_("Cancel")) |
|
412 action = button.Button(name='action', title=_("Request retire")) |
|
413 |
|
414 |
|
415 @pagelet_config(name='wf-retiring.html', context=IWfSharedContent, layer=IPyAMSLayer, |
|
416 permission='pyams.ManageContent') |
|
417 class PublicationRetireRequestForm(WorkflowContentTransitionForm): |
|
418 """Shared content publication request refuse form""" |
|
419 |
|
420 fields = field.Fields(IWorkflowTransitionInfo) + \ |
|
421 field.Fields(IWorkflowRequestUrgencyInfo) + \ |
|
422 field.Fields(IWorkflowCommentInfo) |
|
423 buttons = button.Buttons(IPublicationRetireRequestButtons) |
|
424 ajax_handler = 'wf-retiring.json' |
|
425 |
|
426 def updateWidgets(self, prefix=None): |
|
427 super(PublicationRetireRequestForm, self).updateWidgets(prefix) |
|
428 self.widgets['comment'].required = True |
|
429 |
|
430 |
|
431 @view_config(name='wf-retiring.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
432 permission='pyams.ManageContent', renderer='json', xhr=True) |
|
433 class PublicationRetireRequestAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRetireRequestForm): |
|
434 """Shared content publication retire request form, JSON renderer""" |
|
435 |
|
436 |
|
437 @subscriber(IDataExtractedEvent, form_selector=PublicationRetireRequestForm) |
|
438 def handle_publication_retire_request_form_data_extraction(event): |
|
439 """Handle publication retire request form data extraction""" |
|
440 comment = (event.data.get('comment') or '').strip() |
|
441 if not comment: |
|
442 event.form.widgets.errors += (Invalid(_("A comment is required")), ) |
|
443 |
|
444 |
|
445 @viewlet_config(name='wf-retiring-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
446 view=PublicationRetireRequestForm, manager=IFormPrefixViewletsManager, weight=10) |
|
447 @template_config(template='templates/wf-owner-warning.pt') |
|
448 class PublicationRetireRequestFormWarning(Viewlet): |
|
449 """Publication retire request form warning message""" |
|
450 |
|
451 def __new__(cls, context, request, view, manager): |
|
452 if request.principal.id in context.owner: |
|
453 return None |
|
454 return Viewlet.__new__(cls) |
|
455 |
|
456 |
|
457 @viewlet_config(name='wf-retiring-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
458 view=PublicationRetireRequestForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
459 @template_config(template='templates/wf-retiring-message.pt') |
|
460 class PublicationRetireRequestFormMessage(Viewlet): |
|
461 """Publication retire request form info message""" |
|
462 |
|
463 |
|
464 # |
|
465 # Publication retire cancel form |
|
466 # |
|
467 |
|
468 class IPublicationRetireCancelButtons(Interface): |
|
469 """Shared content publication retire request cancel buttons""" |
|
470 |
|
471 close = CloseButton(name='close', title=_("Cancel")) |
|
472 action = button.Button(name='action', title=_("Cancel retire request")) |
|
473 |
|
474 |
|
475 @pagelet_config(name='wf-cancel-retiring.html', context=IWfSharedContent, layer=IPyAMSLayer, |
|
476 permission='pyams.ManageContent') |
|
477 class PublicationRetireCancelForm(WorkflowContentTransitionForm): |
|
478 """Shared content publication retire request cancel form""" |
|
479 |
|
480 buttons = button.Buttons(IPublicationRetireCancelButtons) |
|
481 ajax_handler = 'wf-cancel-retiring.json' |
|
482 |
|
483 |
|
484 @view_config(name='wf-cancel-retiring.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
485 permission='pyams.ManageContent', renderer='json', xhr=True) |
|
486 class PublicationRetireCancelAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRetireCancelForm): |
|
487 """Shared content publication retire request cancel form, JSON renderer""" |
|
488 |
|
489 |
|
490 @viewlet_config(name='wf-cancel-retiring-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
491 view=PublicationRetireCancelForm, manager=IFormPrefixViewletsManager, weight=10) |
|
492 @template_config(template='templates/wf-owner-warning.pt') |
|
493 class PublicationRetireCancelFormWarning(Viewlet): |
|
494 """Publication retire request cancel form warning message""" |
|
495 |
|
496 def __new__(cls, context, request, view, manager): |
|
497 if request.principal.id in context.owner: |
|
498 return None |
|
499 return Viewlet.__new__(cls) |
|
500 |
|
501 |
|
502 @viewlet_config(name='wf-cancel-retiring-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
503 view=PublicationRetireCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
504 @template_config(template='templates/wf-cancel-retiring-message.pt') |
|
505 class PublicationRetireCancelFormMessage(Viewlet): |
|
506 """Publication retire request form info message""" |
|
507 |
|
508 |
|
509 # |
|
510 # Publication retire form |
|
511 # |
|
512 |
|
513 class IPublicationRetireButtons(Interface): |
|
514 """Shared content publication retire buttons""" |
|
515 |
|
516 close = CloseButton(name='close', title=_("Cancel")) |
|
517 action = button.Button(name='action', title=_("Retire")) |
|
518 |
|
519 |
|
520 @pagelet_config(name='wf-retire.html', context=IWfSharedContent, layer=IPyAMSLayer, |
|
521 permission='pyams.PublishContent') |
|
522 class PublicationRetireForm(WorkflowContentTransitionForm): |
|
523 """Shared content publication retire form""" |
|
524 |
|
525 buttons = button.Buttons(IPublicationRetireButtons) |
|
526 ajax_handler = 'wf-retire.json' |
|
527 |
|
528 |
|
529 @view_config(name='wf-retire.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
530 permission='pyams.PublishContent', renderer='json', xhr=True) |
|
531 class PublicationRetireAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRetireForm): |
|
532 """Shared content publication retire form, JSON renderer""" |
|
533 |
|
534 |
|
535 @viewlet_config(name='wf-retire-operator-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
536 view=PublicationRetireForm, manager=IFormPrefixViewletsManager, weight=10) |
|
537 @template_config(template='templates/wf-operator-warning.pt') |
|
538 class PublicationRetireFormWarning(Viewlet): |
|
539 """Publication retire form warning message""" |
|
540 |
|
541 def __new__(cls, context, request, view, manager): |
|
542 state = IWorkflowState(context) |
|
543 if state.state_principal in context.owner: |
|
544 return None |
|
545 return Viewlet.__new__(cls) |
|
546 |
|
547 |
|
548 @viewlet_config(name='wf-retire-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
549 view=PublicationRetireForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
550 @template_config(template='templates/wf-retire-message.pt') |
|
551 class PublicationRetireFormMessage(Viewlet): |
|
552 """Publication retire form info message""" |
|
553 |
|
554 |
|
555 # |
|
556 # Publication archive request form |
|
557 # |
|
558 |
|
559 class IPublicationArchiveRequestButtons(Interface): |
|
560 """Shared content publication archive request buttons""" |
|
561 |
|
562 close = CloseButton(name='close', title=_("Cancel")) |
|
563 action = button.Button(name='action', title=_("Request archive")) |
|
564 |
|
565 |
|
566 @pagelet_config(name='wf-archiving.html', context=IWfSharedContent, layer=IPyAMSLayer, |
|
567 permission='pyams.ManageContent') |
|
568 class PublicationArchiveRequestForm(WorkflowContentTransitionForm): |
|
569 """Shared content publication request archive form""" |
|
570 |
|
571 fields = field.Fields(IWorkflowTransitionInfo) + \ |
|
572 field.Fields(IWorkflowRequestUrgencyInfo) + \ |
|
573 field.Fields(IWorkflowCommentInfo) |
|
574 buttons = button.Buttons(IPublicationArchiveRequestButtons) |
|
575 ajax_handler = 'wf-archiving.json' |
|
576 |
|
577 def updateWidgets(self, prefix=None): |
|
578 super(PublicationArchiveRequestForm, self).updateWidgets(prefix) |
|
579 self.widgets['comment'].required = True |
|
580 |
|
581 |
|
582 @view_config(name='wf-archiving.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
583 permission='pyams.ManageContent', renderer='json', xhr=True) |
|
584 class PublicationArchiveRequestAJAXForm(WorkflowContentTransitionAJAXForm, PublicationArchiveRequestForm): |
|
585 """Shared content publication archive request form, JSON renderer""" |
|
586 |
|
587 |
|
588 @subscriber(IDataExtractedEvent, form_selector=PublicationArchiveRequestForm) |
|
589 def handle_archive_request_form_data_extraction(event): |
|
590 """Handle archive request form data extraction""" |
|
591 comment = (event.data.get('comment') or '').strip() |
|
592 if not comment: |
|
593 event.form.widgets.errors += (Invalid(_("A comment is required")), ) |
|
594 |
|
595 |
|
596 @viewlet_config(name='wf-archiving-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
597 view=PublicationArchiveRequestForm, manager=IFormPrefixViewletsManager, weight=10) |
|
598 @template_config(template='templates/wf-owner-warning.pt') |
|
599 class PublicationArchiveRequestFormWarning(Viewlet): |
|
600 """Publication archive request form warning message""" |
|
601 |
|
602 def __new__(cls, context, request, view, manager): |
|
603 if request.principal.id in context.owner: |
|
604 return None |
|
605 return Viewlet.__new__(cls) |
|
606 |
|
607 |
|
608 @viewlet_config(name='wf-archiving-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
609 view=PublicationArchiveRequestForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
610 @template_config(template='templates/wf-archiving-message.pt') |
|
611 class PublicationArchiveRequestFormMessage(Viewlet): |
|
612 """Publication archive request form info message""" |
|
613 |
|
614 |
|
615 # |
|
616 # Publication archive cancel form |
|
617 # |
|
618 |
|
619 class IPublicationArchiveCancelButtons(Interface): |
|
620 """Shared content publication archive request cancel buttons""" |
|
621 |
|
622 close = CloseButton(name='close', title=_("Cancel")) |
|
623 action = button.Button(name='action', title=_("Cancel archive request")) |
|
624 |
|
625 |
|
626 @pagelet_config(name='wf-cancel-archiving.html', context=IWfSharedContent, layer=IPyAMSLayer, |
|
627 permission='pyams.ManageContent') |
|
628 class PublicationArchiveCancelForm(WorkflowContentTransitionForm): |
|
629 """Shared content publication archive request cancel form""" |
|
630 |
|
631 buttons = button.Buttons(IPublicationArchiveCancelButtons) |
|
632 ajax_handler = 'wf-cancel-archiving.json' |
|
633 |
|
634 |
|
635 @view_config(name='wf-cancel-archiving.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
636 permission='pyams.ManageContent', renderer='json', xhr=True) |
|
637 class PublicationArchiveCancelAJAXForm(WorkflowContentTransitionAJAXForm, PublicationArchiveCancelForm): |
|
638 """Shared content publication archive request cancel form, JSON renderer""" |
|
639 |
|
640 |
|
641 @viewlet_config(name='wf-cancel-archiving-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
642 view=PublicationArchiveCancelForm, manager=IFormPrefixViewletsManager, weight=10) |
|
643 @template_config(template='templates/wf-owner-warning.pt') |
|
644 class PublicationArchiveCancelFormWarning(Viewlet): |
|
645 """Publication archive cancel form warning message""" |
|
646 |
|
647 def __new__(cls, context, request, view, manager): |
|
648 if request.principal.id in context.owner: |
|
649 return None |
|
650 return Viewlet.__new__(cls) |
|
651 |
|
652 |
|
653 @viewlet_config(name='wf-cancel-archiving-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
654 view=PublicationArchiveCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
655 @template_config(template='templates/wf-cancel-archiving-message.pt') |
|
656 class PublicationArchiveCancelFormMessage(Viewlet): |
|
657 """Publication archive cancel form info message""" |
|
658 |
|
659 |
|
660 # |
|
661 # Publication archive form |
|
662 # |
|
663 |
|
664 class IPublicationArchiveButtons(Interface): |
|
665 """Shared content publication archive buttons""" |
|
666 |
|
667 close = CloseButton(name='close', title=_("Cancel")) |
|
668 action = button.Button(name='action', title=_("Archive")) |
|
669 |
|
670 |
|
671 @pagelet_config(name='wf-archive.html', context=IWfSharedContent, layer=IPyAMSLayer, |
|
672 permission='pyams.PublishContent') |
|
673 class PublicationArchiveForm(WorkflowContentTransitionForm): |
|
674 """Shared content publication archive form""" |
|
675 |
|
676 buttons = button.Buttons(IPublicationArchiveButtons) |
|
677 ajax_handler = 'wf-archive.json' |
|
678 |
|
679 |
|
680 @view_config(name='wf-archive.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
681 permission='pyams.PublishContent', renderer='json', xhr=True) |
|
682 class PublicationArchiveAJAXForm(WorkflowContentTransitionAJAXForm, PublicationArchiveForm): |
|
683 """Shared content publication archive form, JSON renderer""" |
|
684 |
|
685 |
|
686 @viewlet_config(name='wf-archive-operator-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
687 view=PublicationArchiveForm, manager=IFormPrefixViewletsManager, weight=10) |
|
688 @template_config(template='templates/wf-operator-warning.pt') |
|
689 class PublicationArchiveFormWarning(Viewlet): |
|
690 """Publication archive form warning message""" |
|
691 |
|
692 def __new__(cls, context, request, view, manager): |
|
693 state = IWorkflowState(context) |
|
694 if state.state_principal in context.owner: |
|
695 return None |
|
696 return Viewlet.__new__(cls) |
|
697 |
|
698 |
|
699 @viewlet_config(name='wf-archive-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
700 view=PublicationArchiveForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
701 @template_config(template='templates/wf-archive-message.pt') |
|
702 class PublicationArchiveFormMessage(Viewlet): |
|
703 """Publication archive form info message""" |
|
704 |
|
705 |
|
706 # |
|
707 # Clone form |
|
708 # |
|
709 |
|
710 class ISharedContentCloneButtons(Interface): |
|
711 """Shared content clone buttons""" |
|
712 |
|
713 close = CloseButton(name='close', title=_("Cancel")) |
|
714 action = button.Button(name='action', title=_("Create new version")) |
|
715 |
|
716 |
|
717 @pagelet_config(name='wf-clone.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.CreateContent') |
|
718 class SharedContentCloneForm(WorkflowContentTransitionForm): |
|
719 """Shared content clone form""" |
|
720 |
|
721 buttons = button.Buttons(ISharedContentCloneButtons) |
|
722 ajax_handler = 'wf-clone.json' |
|
723 |
|
724 def createAndAdd(self, data): |
|
725 info = IWorkflowInfo(self.context) |
|
726 return info.fire_transition_toward(DRAFT, comment=data.get('comment')) |
|
727 |
|
728 |
|
729 @view_config(name='wf-clone.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
730 permission='pyams.CreateContent', renderer='json', xhr=True) |
|
731 class SharedContentCloneAJAXForm(AJAXAddForm, SharedContentCloneForm): |
|
732 """Shared content clone form, JSON rendener""" |
|
733 |
|
734 def get_ajax_output(self, changes): |
|
735 return {'status': 'redirect', |
|
736 'location': absolute_url(changes, self.request, 'admin.html#properties.html')} |
|
737 |
|
738 |
|
739 @viewlet_config(name='wf-clone-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
740 view=SharedContentCloneForm, manager=IFormPrefixViewletsManager, weight=10) |
|
741 @template_config(template='templates/wf-owner-warning.pt') |
|
742 class SharedContentCloneFormWarning(Viewlet): |
|
743 """Shared content clone form warning message""" |
|
744 |
|
745 def __new__(cls, context, request, view, manager): |
|
746 if request.principal.id in context.owner: |
|
747 return None |
|
748 return Viewlet.__new__(cls) |
|
749 |
|
750 |
|
751 @viewlet_config(name='wf-clone-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
752 view=SharedContentCloneForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
753 @template_config(template='templates/wf-clone-message.pt') |
|
754 class SharedContentCloneFormMessage(Viewlet): |
|
755 """Shared content clone form info message""" |
|
756 |
|
757 |
|
758 # |
|
759 # Delete form |
|
760 # |
|
761 |
|
762 class ISharedContentDeleteButtons(Interface): |
|
763 """Shared content delete form buttons""" |
|
764 |
|
765 close = CloseButton(name='close', title=_("Cancel")) |
|
766 action = button.Button(name='action', title=_("Delete version")) |
|
767 |
|
768 |
|
769 @pagelet_config(name='wf-delete.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.ManageContent') |
|
770 class SharedContentDeleteForm(WorkflowContentTransitionForm): |
|
771 """Shared content delete form""" |
|
772 |
|
773 buttons = button.Buttons(ISharedContentDeleteButtons) |
|
774 ajax_handler = 'wf-delete.json' |
|
775 |
|
776 def createAndAdd(self, data): |
|
777 state = IWorkflowState(self.context) |
|
778 if state.version_id == 1: # remove the first and only version => remove all |
|
779 content = get_parent(self.context, ISharedContent) |
|
780 self.__target = get_parent(content, ISharedTool) |
|
781 del content.__parent__[content.__name__] |
|
782 else: |
|
783 self.__target = get_parent(self.context, ISharedTool) |
|
784 IWorkflowVersions(self.context).remove_version(state.version_id, state=DELETED, comment=data.get('comment')) |
|
785 |
|
786 |
|
787 @view_config(name='wf-delete.json', context=IWfSharedContent, request_type=IPyAMSLayer, |
|
788 permission='pyams.ManageContent', renderer='json', xhr=True) |
|
789 class SharedContentDeleteAJAXForm(AJAXAddForm, SharedContentDeleteForm): |
|
790 """Shared content delete form, JSON rendener""" |
|
791 |
|
792 def get_ajax_output(self, changes): |
|
793 return {'status': 'redirect', |
|
794 'location': absolute_url(self._SharedContentDeleteForm__target, self.request, 'admin.html')} |
|
795 |
|
796 |
|
797 @viewlet_config(name='wf-delete-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, |
|
798 view=SharedContentDeleteForm, manager=IFormPrefixViewletsManager, weight=10) |
|
799 @template_config(template='templates/wf-owner-warning.pt') |
|
800 class SharedContentDeleteFormWarning(Viewlet): |
|
801 """Shared content delete form warning message""" |
|
802 |
|
803 def __new__(cls, context, request, view, manager): |
|
804 if request.principal.id in context.owner: |
|
805 return None |
|
806 return Viewlet.__new__(cls) |
|
807 |
|
808 |
|
809 @viewlet_config(name='wf-delete-message', context=IWfSharedContent, layer=IPyAMSLayer, |
|
810 view=SharedContentDeleteForm, manager=IWidgetsPrefixViewletsManager, weight=20) |
|
811 @template_config(template='templates/wf-delete-message.pt') |
|
812 class SharedContentDeleteFormMessage(Viewlet): |
|
813 """Shared content delete form info message""" |