--- a/src/pyams_content/shared/common/zmi/__init__.py Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/__init__.py Mon Jan 18 17:42:32 2016 +0100
@@ -26,7 +26,7 @@
from pyams_sequence.interfaces import ISequentialIntIds, ISequentialIdInfo
from pyams_skin.interfaces import IContentTitle
from pyams_skin.interfaces.container import ITable, ITableElementEditor
-from pyams_skin.interfaces.viewlet import IContextActions, IMenuHeader
+from pyams_skin.interfaces.viewlet import IContextActions, IMenuHeader, IBreadcrumbItem
from pyams_skin.layer import IPyAMSLayer
from pyams_utils.interfaces import FORBIDDEN_PERMISSION
from pyams_workflow.interfaces import IWorkflowVersions, IWorkflowInfo, IWorkflowState, IWorkflowCommentInfo, IWorkflow
@@ -39,6 +39,7 @@
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.page import DefaultPageHeaderAdapter
from pyams_skin.table import DefaultElementEditorAdapter
+from pyams_skin.viewlet.breadcrumb import BreadcrumbItem
from pyams_skin.viewlet.toolbar import ToolbarMenuItem
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter, ContextAdapter, ContextRequestAdapter
@@ -74,6 +75,7 @@
def updateWidgets(self, prefix=None):
super(SharedContentAddForm, self).updateWidgets(prefix)
+ self.widgets['title'].description = _("This title can be modified afterwards")
self.widgets['description'].label_css_class = 'textarea'
def create(self, data):
@@ -119,6 +121,19 @@
#
+# Shared tools common adapters
+#
+
+@adapter_config(context=(IWfSharedContent, IPyAMSLayer), provides=IBreadcrumbItem)
+class WfSharedContentBreadcrumbAdapter(BreadcrumbItem):
+ """Shared content breadcrumb adapter"""
+
+ @property
+ def label(self):
+ return II18n(self.context).query_attribute('short_name', request=self.request)
+
+
+#
# Edit adapters and views
#
@@ -171,7 +186,7 @@
class WfSharedContentSiteManagementMenuHeader(ContextRequestAdapter):
"""Shared content site management menu header adapter"""
- header = _("Manage this content")
+ header = ' '
@adapter_config(context=(IWfSharedContent, IPyAMSLayer, Interface), provides=IContentTitle)
@@ -223,7 +238,7 @@
"""Shared content duplication form buttons"""
close = CloseButton(name='close', title=_("Cancel"))
- duplicate = button.Button(name='duplicate', title=_("Duplicate content"))
+ duplicate = button.Button(name='duplicate', title=_("Duplicate this content"))
@pagelet_config(name='duplicate.html', context=IWfSharedContent, layer=IPyAMSLayer,
@@ -232,6 +247,8 @@
"""Shared content duplicate form"""
legend = _("Duplicate content")
+ icon_css_class = 'fa fa-fw fa-files-o'
+
fields = field.Fields(IWorkflowCommentInfo)
buttons = button.Buttons(ISharedContentDuplicateButtons)
@@ -314,6 +331,7 @@
item_dc = IZopeDublinCore(item)
if item_dc.modified and (item_dc.modified > IZopeDublinCore(content).created):
translate = self.request.localizer.translate
- value += '<i class="fa fa-fw fa-circle txt-color-orange pull-right hint" title="{0}" ' \
- 'data-ams-hint-gravity="e"></i>'.format(translate(_("Created or modified in this version")))
+ value += '<i class="fa fa-fw fa-circle txt-color-orange hint align-middle padding-left-5" ' \
+ 'title="{0}" data-ams-hint-gravity="w"></i>'.format(
+ translate(_("Created or modified in this version")))
return value
--- a/src/pyams_content/shared/common/zmi/dashboard.py Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/dashboard.py Mon Jan 18 17:42:32 2016 +0100
@@ -42,7 +42,7 @@
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.container import ContainerView
from pyams_skin.page import DefaultPageHeaderAdapter
-from pyams_skin.table import BaseTable, I18nColumn, ActionColumn
+from pyams_skin.table import BaseTable, I18nColumn, NameColumn, JsActionColumn
from pyams_skin.viewlet.menu import MenuItem
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
@@ -69,14 +69,19 @@
class BaseDashboardTable(BaseTable):
"""Base dashboard table"""
- _title = '{0} contents'
+ _single_title = '{0} content'
+ _plural_title = '{0} contents'
sortOn = None
dt_sort_order = 'desc'
@property
def title(self):
- return self.request.localizer.translate(self._title).format(len(self.values))
+ translate = self.request.localizer.translate
+ if len(self.values) < 2:
+ return translate(self._single_title).format(len(self.values))
+ else:
+ return translate(self._plural_title).format(len(self.values))
@property
def data_attributes(self):
@@ -92,13 +97,20 @@
return tuple(super(BaseDashboardTable, self).values)
+@adapter_config(name='name', context=(Interface, IPyAMSLayer, ISharedToolDashboardTable), provides=IColumn)
+class SharedToolDashboardNameColumn(NameColumn):
+ """Shared tool dashboard name column"""
+
+ _header = _("Title")
+
+
@adapter_config(context=(IWfSharedContent, IPyAMSLayer, ISharedToolDashboardTable), provides=ITableElementName)
class SharedToolDashboardContentNameAdapter(ContextRequestViewAdapter):
"""Shared tool dashboard content name adapter"""
@property
def name(self):
- return II18n(self.context).query_attribute('short_name', request=self.request)
+ return II18n(self.context).query_attribute('title', request=self.request)
@adapter_config(name='sequence', context=(Interface, IPyAMSLayer, ISharedToolDashboardTable), provides=IColumn)
@@ -125,27 +137,6 @@
return str(IWorkflowState(obj).version_id)
-@adapter_config(name='urgency', context=(Interface, IPyAMSLayer, ISharedToolDashboardTable), provides=IColumn)
-class SharedToolDashboardUrgencyColumn(ActionColumn):
- """Shared tool dashboard urgency column"""
-
- icon_class = 'fa fa-fw fa-exclamation-triangle txt-color-red'
- icon_hint = _("Urgent request !")
-
- url = '#'
- weight = 19
-
- def renderCell(self, item):
- state = IWorkflowState(item)
- if not state.state_urgency:
- return ''
- else:
- return super(SharedToolDashboardUrgencyColumn, self).renderCell(item)
-
- def get_url(self, item):
- return self.url
-
-
@adapter_config(name='status', context=(Interface, IPyAMSLayer, ISharedToolDashboardTable), provides=IColumn)
class SharedToolDashboardStatusColumn(I18nColumn, GetAttrColumn):
"""Shared tool dashboard status column"""
@@ -156,7 +147,10 @@
def getValue(self, obj):
workflow = IWorkflow(obj)
state = IWorkflowState(obj)
- return self.request.localizer.translate(workflow.get_state_label(state.state))
+ result = self.request.localizer.translate(workflow.get_state_label(state.state))
+ if state.state_urgency:
+ result += ' <i class="fa fa-fw fa-exclamation-triangle txt-color-red"></i>'
+ return result
@adapter_config(name='status_date', context=(Interface, IPyAMSLayer, ISharedToolDashboardTable), provides=IColumn)
@@ -263,7 +257,8 @@
class SharedToolDashboardManagerWaitingTable(BaseDashboardTable):
"""Shared tool dashboard waiting table"""
- _title = _("MANAGER - {0} content(s) waiting for your action")
+ _single_title = _("MANAGER - {0} content waiting for your action")
+ _plural_title = _("MANAGER - {0} contents waiting for your action")
dt_sort_order = 'asc'
@@ -304,7 +299,8 @@
class SharedToolDashboardOwnerWaitingTable(BaseDashboardTable):
"""Shared tool dashboard waiting owned contents table"""
- _title = _("CONTRIBUTOR - Your {0} content(s) waiting for action")
+ _single_title = _("CONTRIBUTOR - {0} content waiting for action")
+ _plural_title = _("CONTRIBUTOR - {0} contents waiting for action")
dt_sort_order = 'asc'
@@ -334,7 +330,14 @@
class SharedToolDashboardOwnerModifiedTable(BaseDashboardTable):
"""Shared tool dashboard owned modified contents table"""
- _title = _("CONTRIBUTOR - Your last modified contents (limited to {0})")
+ _single_title = _("CONTRIBUTOR - {0} modified content")
+
+ @property
+ def _plural_title(self):
+ if len(self.values) <= 50:
+ return _("CONTRIBUTOR - {0} modified contents")
+ else:
+ return _("CONTRIBUTOR - Last {0} modified contents")
@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolDashboardOwnerModifiedTable), provides=IValues)
@@ -350,7 +353,7 @@
return unique(map(lambda x: sorted(IWorkflowVersions(x).get_versions(IWorkflowState(x).state),
key=lambda y: IZopeDublinCore(y).modified, reverse=True)[0],
CatalogResultSet(CatalogQuery(catalog).query(params,
- limit=IAdminProfile(self.request.principal).table_page_length,
+ limit=50,
sort_index='modified_date',
reverse=True))))
@@ -372,6 +375,102 @@
#
+# My favorites
+# Dashboard of favorites contents
+#
+
+@viewlet_config(name='my-favorites.menu', context=ISharedTool, layer=IAdminLayer,
+ manager=IMyDashboardMenu, permission=VIEW_SYSTEM_PERMISSION, weight=3)
+class SharedToolFavoritesMenu(MenuItem):
+ """Shared tool favorites dashboard menu"""
+
+ label = _("My favorites")
+ icon_class = None
+ url = '#my-favorites.html'
+
+
+@implementer(ISharedToolDashboardTable)
+class SharedToolFavoritesTable(BaseDashboardTable):
+ """Shared tool favorites table"""
+
+ _single_title = _("CONTRIBUTOR - {0} favorite")
+ _plural_title = _("CONTRIBUTOR - {0} favorites")
+
+
+@adapter_config(name='show-hide', context=(Interface, IPyAMSLayer, SharedToolFavoritesTable),
+ provides=IColumn)
+class FavoritesColumnAddRemoveColumn(JsActionColumn):
+ """Favorites column add/remove column"""
+
+ cssClasses = {'th': 'action',
+ 'td': 'action switcher'}
+
+ icon_class = 'fa fa-fw fa-star'
+ icon_hint = _("Add/remove from favorites")
+
+ url = 'PyAMS_content.profile.switchFavorite'
+
+ weight = 1
+
+ def __init__(self, context, request, table):
+ super(FavoritesColumnAddRemoveColumn, self).__init__(context, request, table)
+ self.profile = IAdminProfile(request)
+
+ def get_icon(self, item):
+ oid = ISequentialIdInfo(item).hex_oid
+ icon_class = 'fa fa-fw fa-star{0}'.format('' if oid in (self.profile.favorites or ()) else '-o')
+ return '<i data-ams-plugins="pyams_content" ' \
+ 'data-ams-plugin-pyams_content-src="/--static--/pyams_content/js/pyams_content{{MyAMS.devext}}.js" ' \
+ 'data-ams-click-handler="PyAMS_content.profile.switchFavorite" data-ams-stop-propagation="true" ' \
+ 'data-sequence-oid="{oid}" ' \
+ 'class="{icon_class}"></i>'.format(
+ oid=oid,
+ title=self.request.localizer.translate(self.icon_hint),
+ icon_class=icon_class)
+
+ def get_url(self, item):
+ return ''
+
+
+@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolFavoritesTable), provides=IValues)
+class SharedToolFavoritesValues(ContextRequestViewAdapter):
+ """Shared tool favorites values adapter"""
+
+ @property
+ def values(self):
+ catalog = get_utility(ICatalog)
+ profile = IAdminProfile(self.request.principal)
+ params = And(Eq(catalog['content_type'], self.context.shared_content_type),
+ Any(catalog['oid'], profile.favorites or ()))
+ return unique(map(lambda x: IWorkflowVersions(x).get_last_versions()[0],
+ CatalogResultSet(CatalogQuery(catalog).query(params,
+ sort_index='modified_date',
+ reverse=True))))
+
+
+@pagelet_config(name='my-favorites.html', context=ISharedTool, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
+@implementer(IInnerPage)
+class SharedToolFavoritesView(AdminView, ContainerView):
+ """Shared tool favorites view"""
+
+ table_class = SharedToolFavoritesTable
+
+
+@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolFavoritesView), provides=IPageHeader)
+class SharedToolFavoritesHeaderAdapter(DefaultPageHeaderAdapter):
+ """Shared tool favorites header adapter"""
+
+ back_url = '#dashboard.html'
+ icon_class = 'fa fa-fw fa-user'
+
+ @property
+ def title(self):
+ return II18n(self.context).query_attribute('title', request=self.request)
+
+ subtitle = _("Your favorites")
+
+
+#
# My preparations
# Dashboard of owned and modified contents which can be updated
#
@@ -379,7 +478,7 @@
@viewlet_config(name='my-preparations.menu', context=ISharedTool, layer=IAdminLayer,
manager=IMyDashboardMenu, permission=VIEW_SYSTEM_PERMISSION, weight=5)
class SharedToolPreparationsMenu(MenuItem):
- """Site root preparations dashboard menu"""
+ """Shared tool preparations dashboard menu"""
label = _("My preparations")
icon_class = None
@@ -388,14 +487,15 @@
@implementer(ISharedToolDashboardTable)
class SharedToolPreparationsTable(BaseDashboardTable):
- """Site root preparations table"""
+ """Shared tool preparations table"""
- _title = _("CONTRIBUTOR - Your {0} prepared contents")
+ _single_title = _("CONTRIBUTOR - {0} prepared content")
+ _plural_title = _("CONTRIBUTOR - {0} prepared contents")
@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolPreparationsTable), provides=IValues)
class SharedToolPreparationsValues(ContextRequestViewAdapter):
- """Site root preparations values adapter"""
+ """Shared tool preparations values adapter"""
@property
def values(self):
@@ -404,7 +504,7 @@
params = And(Eq(catalog['content_type'], self.context.shared_content_type),
Or(Eq(catalog['role:owner'], self.request.principal.id),
Eq(catalog['role:contributor'], self.request.principal.id)),
- Any(catalog['workflow_state'], workflow.update_states))
+ Eq(catalog['workflow_state'], workflow.initial_state))
return unique(CatalogResultSet(CatalogQuery(catalog).query(params,
sort_index='modified_date',
reverse=True)))
@@ -413,14 +513,14 @@
@pagelet_config(name='my-preparations.html', context=ISharedTool, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
@implementer(IInnerPage)
class SharedToolPreparationsView(AdminView, ContainerView):
- """Site root preparations view"""
+ """Shared tool preparations view"""
table_class = SharedToolPreparationsTable
@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolPreparationsView), provides=IPageHeader)
class SharedToolPreparationsHeaderAdapter(DefaultPageHeaderAdapter):
- """Site root preparations header adapter"""
+ """Shared tool preparations header adapter"""
back_url = '#dashboard.html'
icon_class = 'fa fa-fw fa-user'
@@ -433,6 +533,68 @@
#
+# My submissions
+# Dashboard of owned and modified contents which are waiting for manager action
+#
+
+@viewlet_config(name='my-submissions.menu', context=ISharedTool, layer=IAdminLayer,
+ manager=IMyDashboardMenu, permission=VIEW_SYSTEM_PERMISSION, weight=7)
+class SharedToolSubmissionsMenu(MenuItem):
+ """Shared tool submissions dashboard menu"""
+
+ label = _("My submissions")
+ icon_class = None
+ url = '#my-submissions.html'
+
+
+@implementer(ISharedToolDashboardTable)
+class SharedToolSubmissionsTable(BaseDashboardTable):
+ """Shared tool submissions table"""
+
+ _single_title = _("CONTRIBUTOR - {0} submitted content")
+ _plural_title = _("CONTRIBUTOR - {0} submitted contents")
+
+
+@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolSubmissionsTable), provides=IValues)
+class SharedToolSubmissionsValues(ContextRequestViewAdapter):
+ """Shared tool submissions values adapter"""
+
+ @property
+ def values(self):
+ catalog = get_utility(ICatalog)
+ workflow = get_utility(IWorkflow, name=self.context.shared_content_workflow)
+ params = And(Eq(catalog['content_type'], self.context.shared_content_type),
+ Or(Eq(catalog['role:owner'], self.request.principal.id),
+ Eq(catalog['role:contributor'], self.request.principal.id)),
+ Any(catalog['workflow_state'], workflow.waiting_states))
+ return unique(CatalogResultSet(CatalogQuery(catalog).query(params,
+ sort_index='modified_date',
+ reverse=True)))
+
+
+@pagelet_config(name='my-submissions.html', context=ISharedTool, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
+@implementer(IInnerPage)
+class SharedToolSubmissionsView(AdminView, ContainerView):
+ """Shared tool submissions view"""
+
+ table_class = SharedToolSubmissionsTable
+
+
+@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolSubmissionsView), provides=IPageHeader)
+class SharedToolSubmissionsHeaderAdapter(DefaultPageHeaderAdapter):
+ """Shared tool submissions header adapter"""
+
+ back_url = '#dashboard.html'
+ icon_class = 'fa fa-fw fa-user'
+
+ @property
+ def title(self):
+ return II18n(self.context).query_attribute('title', request=self.request)
+
+ subtitle = _("Your submitted contents")
+
+
+#
# My publications
# Dashboard of owned and modified contents which are published
#
@@ -451,7 +613,8 @@
class SharedToolPublicationsTable(BaseDashboardTable):
"""Shared tool publications table"""
- _title = _("CONTRIBUTOR - Your {0} published contents")
+ _single_title = _("CONTRIBUTOR - {0} published content")
+ _plural_title = _("CONTRIBUTOR - {0} published contents")
@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolPublicationsTable), provides=IValues)
@@ -512,7 +675,8 @@
class SharedToolRetiredContentsTable(BaseDashboardTable):
"""Shared tool retired contents table"""
- _title = _("CONTRIBUTOR - Your {0} retired contents")
+ _single_title = _("CONTRIBUTOR - {0} retired content")
+ _plural_title = _("CONTRIBUTOR - {0} retired contents")
@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolRetiredContentsTable), provides=IValues)
@@ -574,7 +738,8 @@
class SharedToolArchivedContentsTable(BaseDashboardTable):
"""Shared tool archived contents table"""
- _title = _("CONTRIBUTOR - Your {0} archived contents")
+ _single_title = _("CONTRIBUTOR - {0} archived content")
+ _plural_title = _("CONTRIBUTOR - {0} archived contents")
@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolArchivedContentsTable), provides=IValues)
@@ -658,7 +823,14 @@
class SharedToolAllPublicationsTable(BaseDashboardTable):
"""Shared tool published contents table"""
- _title = _("CONTRIBUTORS - Last published contents (in the limit of 50)")
+ _single_title = _("CONTRIBUTORS - {0} published content")
+
+ @property
+ def _plural_title(self):
+ if len(self.values) <= 50:
+ return _("CONTRIBUTORS - Last {0} published contents")
+ else:
+ return _("CONTRIBUTORS - Last published contents (in the limit of 50)")
@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolAllPublicationsTable), provides=IValues)
@@ -719,7 +891,14 @@
class SharedToolAllUpdatesTable(BaseDashboardTable):
"""Shared tool updated contents table"""
- _title = _("CONTRIBUTORS - Last updated contents (in the limit of 50)")
+ _single_title = _("CONTRIBUTORS - {0} updated content")
+
+ @property
+ def _plural_title(self):
+ if len(self.values) <= 50:
+ return _("CONTRIBUTORS - Last {0} updated contents")
+ else:
+ return _("CONTRIBUTORS - Last updated contents (in the limit of 50)")
@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolAllUpdatesTable), provides=IValues)
--- a/src/pyams_content/shared/common/zmi/header.py Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/header.py Mon Jan 18 17:42:32 2016 +0100
@@ -9,6 +9,7 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
+from pyams_content.profile.interfaces import IAdminProfile
__docformat__ = 'restructuredtext'
@@ -31,6 +32,7 @@
from pyams_utils.traversing import get_parent
from pyams_utils.url import absolute_url
from pyams_viewlet.viewlet import contentprovider_config
+from pyramid.decorator import reify
from zope.interface import Interface
from pyams_content import _
@@ -61,27 +63,37 @@
versions = IWorkflowVersions(context)
state = IWorkflowState(context)
self.version_id = state.version_id
+ # init state format
+ state_format = translate(_("{state} by {principal}"))
+ if state.state_urgency:
+ state_format = state_format.replace('{state}',
+ '{state} <i class="fa fa-fw fa-exclamation-triangle txt-color-red"></i>');
+ state_class = 'text-danger' # if state.state in workflow.update_states else 'txt-color-text'
+ state_format = state_format.replace('{state}',
+ '<span class="{0}">{{state}}</span>'.format(state_class))
+ # init principal format
+ # principal_class = 'text-danger' if state.state_principal != owner else 'txt-color-text'
+ principal_class = 'text-danger' \
+ if state.state in (workflow.update_states | workflow.waiting_states) \
+ else 'txt-color-text'
+ state_format = state_format.replace('{principal}',
+ '<span class="{0}">{{principal}}</span>'.format(principal_class))
+ # get state label
state_label = request.registry.queryAdapter(workflow, IWorkflowStateLabel, name=state.state)
if state_label is None:
state_label = request.registry.queryAdapter(workflow, IWorkflowStateLabel)
if state_label is None:
- self.state = translate(_("{state} by {{principal}}")).format(
- state=translate(workflow.get_state_label(state.state)))
+ self.state = state_format.format(state=translate(workflow.get_state_label(state.state)),
+ principal=security.get_principal(state.state_principal).title)
else:
- self.state = state_label.get_label(context, request, format=False)
- principal_class = 'text-danger' if state.state_principal != owner else 'txt-color-text'
- self.state = self.state.replace('{principal}',
- '<span class="{0}">{{principal}}</span>'.format(principal_class))
- state_class = 'text-danger' if state.state in workflow.update_states else None
- if state_class:
- self.state = '<span class="{state_class}">{state}</span>'.format(state_class=state_class,
- state=self.state)
- self.state = self.state.format(principal=security.get_principal(state.state_principal).title)
+ self.state = state_format.format(state=state_label.get_label(context, request, format=False),
+ principal=security.get_principal(state.state_principal).title)
self.state_date = translate(_("since {date}")).format(date=format_datetime(state.state_date, request=request))
- if state.state not in workflow.update_states and versions.has_version(workflow.update_states):
+ has_update_state = versions.has_version(workflow.update_states)
+ if (state.state not in workflow.update_states and has_update_state) or \
+ (state.state in workflow.retired_states and has_update_state):
target = sorted(versions.get_versions(workflow.update_states),
- key=lambda x: IWorkflowState(x).version_id,
- reverse=True)[-1]
+ key=lambda x: IWorkflowState(x).version_id)[-1]
self.version_link = {
'css_class': 'text-danger',
'href': absolute_url(target, request, 'admin.html'),
@@ -92,7 +104,7 @@
key=lambda x: IWorkflowState(x).version_id,
reverse=True)[-1]
self.version_link = {
- 'css_class': 'txt-color-text',
+ 'css_class': 'text-danger',
'href': absolute_url(target, request, 'admin.html'),
'title': translate(_("access published version"))
}
@@ -104,6 +116,15 @@
tool = get_parent(self.context, ISharedTool)
return II18n(tool).query_attribute('title', request=self.request)
+ @reify
+ def hex_oid(self):
+ return ISequentialIdInfo(self.context).hex_oid
+
+ @property
+ def favorite_content(self):
+ profile = IAdminProfile(self.request.principal)
+ return self.hex_oid in (profile.favorites or '')
+
@contentprovider_config(name='content_header', context=IWfSharedContent, view=IInnerTabForm, layer=IPyAMSLayer)
class SharedContentInnerPageHeaderContentProvider(object):
--- a/src/pyams_content/shared/common/zmi/manager.py Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/manager.py Mon Jan 18 17:42:32 2016 +0100
@@ -21,7 +21,7 @@
from pyams_form.interfaces.form import IWidgetForm, IFormHelp
from pyams_i18n.interfaces import II18n, II18nManager
from pyams_skin.interfaces import IInnerPage, IPageHeader, IContentTitle
-from pyams_skin.interfaces.viewlet import IMenuHeader
+from pyams_skin.interfaces.viewlet import IMenuHeader, IBreadcrumbItem
from pyams_skin.layer import IPyAMSLayer
from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
from pyams_zmi.interfaces.menu import IPropertiesMenu, ISiteManagementMenu
@@ -32,6 +32,7 @@
from pyams_form.help import FormHelp
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.page import DefaultPageHeaderAdapter
+from pyams_skin.viewlet.breadcrumb import BreadcrumbItem
from pyams_skin.viewlet.menu import MenuItem
from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter, ContextRequestAdapter
from pyams_viewlet.manager import viewletmanager_config
@@ -48,6 +49,17 @@
# Shared tools common adapters
#
+@adapter_config(context=(ISharedTool, IPyAMSLayer), provides=IBreadcrumbItem)
+class SharedToolBreadcrumbAdapter(BreadcrumbItem):
+ """Shared tool breadcrumb adapter"""
+
+ @property
+ def label(self):
+ return II18n(self.context).query_attribute('short_name', request=self.request)
+
+ css_class = 'strong'
+
+
@adapter_config(context=(ISharedTool, IPyAMSLayer, Interface), provides=IContentTitle)
class SharedToolTitleAdapter(ContextRequestViewAdapter):
"""Shared tool title adapter"""
--- a/src/pyams_content/shared/common/zmi/properties.py Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/properties.py Mon Jan 18 17:42:32 2016 +0100
@@ -18,7 +18,7 @@
# import interfaces
from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
from pyams_content.shared.common.interfaces import IWfSharedContent
-from pyams_form.interfaces.form import IWidgetForm
+from pyams_form.interfaces.form import IWidgetForm, IInnerTabForm, IInnerSubForm
from pyams_skin.interfaces import IInnerPage, IPageHeader
from pyams_skin.layer import IPyAMSLayer
from pyams_zmi.interfaces.menu import IContentManagementMenu, IPropertiesMenu
@@ -26,16 +26,17 @@
# import packages
from pyams_content.shared.common.zmi import WfSharedContentHeaderAdapter
+from pyams_content.shared.common.zmi.summary import SharedContentSummaryForm
from pyams_form.form import AJAXEditForm
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.viewlet.menu import MenuItem
from pyams_utils.adapter import adapter_config
from pyams_viewlet.manager import viewletmanager_config
from pyams_viewlet.viewlet import viewlet_config
-from pyams_zmi.form import AdminEditForm
+from pyams_zmi.form import AdminEditForm, InnerAdminDisplayForm
from pyramid.view import view_config
from z3c.form import field
-from zope.interface import implementer
+from zope.interface import implementer, Interface
from pyams_content import _
@@ -53,7 +54,7 @@
label = _("Composition")
icon_class = 'fa-dropbox'
- url = '#'
+ url = '#summary.html'
@viewlet_config(name='properties.submenu', context=IWfSharedContent, layer=IAdminLayer,
@@ -74,7 +75,7 @@
legend = _("Content properties")
- fields = field.Fields(IWfSharedContent).omit('__parent__', '__name__', 'creator', 'first_owner', 'modifiers')
+ fields = field.Fields(IWfSharedContent).select('title', 'short_name', 'description', 'keywords', 'notepad')
ajax_handler = 'properties.json'
def updateWidgets(self, prefix=None):
@@ -96,3 +97,42 @@
"""Shared content properties header adapter"""
icon_class = 'fa fa-fw fa-edit'
+
+
+#
+# Properties summary
+#
+
+@adapter_config(name='properties-summary',
+ context=(IWfSharedContent, IPyAMSLayer, SharedContentSummaryForm),
+ provides=IInnerTabForm)
+class SharedContentPropertiesSummary(InnerAdminDisplayForm):
+ """Shared content properties summary tab"""
+
+ tab_label = _("Properties")
+ tab_target = 'properties-summary.html'
+
+ fields = field.Fields(Interface)
+
+ weight = 10
+
+
+@pagelet_config(name='properties-summary.html', context=IWfSharedContent, layer=IPyAMSLayer)
+@implementer(IInnerPage, IInnerTabForm)
+class SharedContentPropertiesSummaryDisplayForm(InnerAdminDisplayForm):
+ """Shared content properties summary display form"""
+
+ fields = field.Fields(Interface)
+
+
+@adapter_config(name='properties-main-summary.html',
+ context=(IWfSharedContent, IPyAMSLayer, SharedContentPropertiesSummaryDisplayForm),
+ provides=IInnerSubForm)
+class SharedContentMainPropertiesSummaryDisplayForm(InnerAdminDisplayForm):
+ """Shared content main properties summary display form"""
+
+ legend = _("Content properties")
+
+ fields = field.Fields(IWfSharedContent).select('title', 'short_name', 'description', 'keywords', 'notepad')
+
+ weight = 1
--- a/src/pyams_content/shared/common/zmi/summary.py Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/summary.py Mon Jan 18 17:42:32 2016 +0100
@@ -9,7 +9,6 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
-from pyams_workflow.interfaces import IWorkflowState, IWorkflowVersions
__docformat__ = 'restructuredtext'
@@ -19,46 +18,30 @@
# import interfaces
from pyams_content.interfaces import IBaseContentInfo
from pyams_content.shared.common.interfaces import IWfSharedContent, IWfSharedContentRoles, ISharedTool
-from pyams_content.zmi.interfaces import ISummaryMenu
-from pyams_form.interfaces.form import IWidgetForm, IInnerTabForm
-from pyams_sequence.interfaces import ISequentialIdInfo
+from pyams_form.interfaces.form import IWidgetForm, IInnerTabForm, IInnerSubForm
+from pyams_sequence.interfaces import ISequentialIdInfo, ISequentialIntIds
from pyams_skin.interfaces import IInnerPage
from pyams_skin.layer import IPyAMSLayer
from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
-from pyams_zmi.interfaces.menu import IContentManagementMenu
-from pyams_zmi.layer import IAdminLayer
+from pyams_workflow.interfaces import IWorkflowState, IWorkflow, IWorkflowPublicationInfo
# import packages
from pyams_content.shared.common.zmi.header import SharedContentHeaderContentProvider
-from pyams_form.form import InnerDisplayForm
from pyams_pagelet.pagelet import pagelet_config
-from pyams_skin.viewlet.menu import MenuItem
from pyams_utils.adapter import adapter_config
from pyams_utils.date import format_datetime
+from pyams_utils.registry import get_utility
from pyams_utils.timezone import tztime
from pyams_utils.traversing import get_parent
from pyams_utils.url import absolute_url
-from pyams_viewlet.manager import viewletmanager_config
-from pyams_viewlet.viewlet import viewlet_config, contentprovider_config
-from pyams_zmi.form import AdminDisplayForm
+from pyams_viewlet.viewlet import contentprovider_config
+from pyams_zmi.form import AdminDisplayForm, InnerAdminDisplayForm
from z3c.form import field
from zope.interface import implementer, Interface
from pyams_content import _
-@viewlet_config(name='summary.menu', context=IWfSharedContent, layer=IAdminLayer,
- manager=IContentManagementMenu, permission=VIEW_SYSTEM_PERMISSION, weight=1)
-@viewletmanager_config(name='summary.menu', layer=IAdminLayer, provides=ISummaryMenu)
-@implementer(ISummaryMenu)
-class SharedContentSummaryMenu(MenuItem):
- """Shared content summary menu"""
-
- label = _("Summary")
- icon_class = 'fa-info-circle'
- url = '#summary.html'
-
-
@pagelet_config(name='summary.html', context=IWfSharedContent, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
@implementer(IWidgetForm, IInnerPage)
class SharedContentSummaryForm(AdminDisplayForm):
@@ -67,7 +50,7 @@
legend = _("Display content summary")
css_class = 'ams-form form-horizontal form-tight'
- fields = field.Fields(IWfSharedContent).select('title', 'short_name', 'description', 'keywords')
+ fields = field.Fields(Interface)
@contentprovider_config(name='content_header', context=IWfSharedContent, view=SharedContentSummaryForm,
@@ -84,27 +67,68 @@
@adapter_config(name='dublincore-summary',
context=(IWfSharedContent, IPyAMSLayer, SharedContentSummaryForm),
provides=IInnerTabForm)
-class SharedContentDublinCoreSummary(InnerDisplayForm):
+class SharedContentDublinCoreSummary(InnerAdminDisplayForm):
"""Shared content DublinCore summary"""
weight = 1
tab_label = _("Identity card")
css_class = 'form-tight'
+ fields = field.Fields(Interface)
+
+
+@adapter_config(name='dublincore-version-summary',
+ context=(IWfSharedContent, IPyAMSLayer, SharedContentDublinCoreSummary),
+ provides=IInnerSubForm)
+class SharedContentDublinCoreVersionSummary(InnerAdminDisplayForm):
+ """Shared content version DublinCore summary"""
+
+ legend = _("About this version")
+ weight = 1
+
@property
def fields(self):
fields = field.Fields(ISequentialIdInfo).select('hex_oid') + \
+ field.Fields(IWorkflowState).select('version_id') + \
field.Fields(IWfSharedContentRoles).select('owner') + \
- field.Fields(IWfSharedContent).select('creator', 'first_owner') + \
- field.Fields(IBaseContentInfo) + \
- field.Fields(IWfSharedContent).select('modifiers', 'notepad')
- state = IWorkflowState(self.context)
- if state.version_id == 1:
- fields = fields.omit('first_owner')
+ field.Fields(IWfSharedContent).select('creator') + \
+ field.Fields(IBaseContentInfo).select('created_date') + \
+ field.Fields(IWorkflowPublicationInfo).select('publication') + \
+ field.Fields(IBaseContentInfo).select('modified_date') + \
+ field.Fields(IWfSharedContent).select('last_modifier', 'modifiers')
+ workflow = IWorkflow(self.context)
+ if IWorkflowState(self.context).state not in workflow.published_states:
+ fields = fields.omit('publication')
return fields
def updateWidgets(self, prefix=None):
- super(SharedContentDublinCoreSummary, self).updateWidgets(prefix)
+ super(SharedContentDublinCoreVersionSummary, self).updateWidgets(prefix)
+ sequence = get_utility(ISequentialIntIds)
+ self.widgets['hex_oid'].value = sequence.get_short_oid(ISequentialIdInfo(self.context).oid)
+ workflow = IWorkflow(self.context)
+ self.widgets['version_id'].label = _("Version")
+ self.widgets['version_id'].value = '{version_id} - {status}'.format(
+ version_id=IWorkflowState(self.context).version_id,
+ status=self.request.localizer.translate(workflow.get_state_label(IWorkflowState(self.context).state)))
info = IBaseContentInfo(self.context)
self.widgets['created_date'].value = format_datetime(tztime(info.created_date))
self.widgets['modified_date'].value = format_datetime(tztime(info.modified_date))
+
+
+@adapter_config(name='dublincore-history-summary',
+ context=(IWfSharedContent, IPyAMSLayer, SharedContentDublinCoreSummary),
+ provides=IInnerSubForm)
+class SharedContentDublinCoreHistorySummary(InnerAdminDisplayForm):
+ """Shared content history DublinCore summary"""
+
+ legend = _("Content history")
+
+ fields = field.Fields(IWfSharedContent).select('first_owner') + \
+ field.Fields(IWorkflowPublicationInfo).select('first_publication_date')
+
+ weight = 2
+
+ def updateWidgets(self, prefix=None):
+ super(SharedContentDublinCoreHistorySummary, self).updateWidgets(prefix)
+ info = IWorkflowPublicationInfo(self.context)
+ self.widgets['first_publication_date'].value = format_datetime(tztime(info.first_publication_date))
--- a/src/pyams_content/shared/common/zmi/templates/header.pt Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/templates/header.pt Mon Jan 18 17:42:32 2016 +0100
@@ -1,21 +1,29 @@
-<tal:block i18n:domain="pyams_content">
- <h1 class="page-title margin-bottom-5" tal:define="back_url view.back_url">
- <a class="font-xs hint" data-ams-target="#content"
- title="Back to previous page" i18n:attributes="title"
- tal:attributes="href back_url;
- data-ams-target view.back_target;">
- <i class="fa fa-chevron-left padding-right-10"></i>
- </a>
- <tal:var define="config extension:back_configuration"
- condition="config.display_content_icon">
- <i tal:attributes="class view.icon_class"></i>
- </tal:var>
- <tal:var content="view.title" />
- </h1>
- <div class="margin-left-10 margin-bottom-5 padding-left-20">
+<tal:block i18n:domain="pyams_content"
+ define="config extension:back_configuration">
+ <tal:if condition="config.display_shared_tool_title">
+ <h1 class="page-title margin-bottom-5" tal:define="back_url view.back_url">
+ <a class="font-xs hint" data-ams-target="#content"
+ title="Back to previous page" i18n:attributes="title"
+ tal:attributes="href back_url;
+ data-ams-target view.back_target;">
+ <i class="fa fa-chevron-left padding-right-10"></i>
+ </a>
+ <tal:if condition="config.display_content_icon">
+ <i tal:attributes="class view.icon_class"></i>
+ </tal:if>
+ <tal:var content="view.title" />
+ </h1>
+ </tal:if>
+ <div tal:attributes="class 'margin-left-10 margin-bottom-5 padding-left-20' if config.display_shared_tool_title else 'margin-bottom-5 padding-left-10'">
<span class="bold content-oid" tal:content="view.oid">OID</span> :
<span class="bold content-title" tal:content="i18n:context.title">Title</span> |
- <span class="content-owner" i18n:translate="">by <i18n:var name="owner" tal:content="view.owner" /></span><br />
+ <span class="content-owner" i18n:translate="">by <i18n:var name="owner" tal:content="view.owner" /></span>
+ <i data-ams-plugins="pyams_content"
+ data-ams-plugin-pyams_content-src="/--static--/pyams_content/js/pyams_content{MyAMS.devext}.js"
+ data-ams-click-handler="PyAMS_content.profile.switchFavorite"
+ data-ams-hint-gravity="w" title="Add/remove from favorites" i18n:attributes="title"
+ tal:attributes="class 'fa fa-star{0} txt-color-blue hint opaque align-middle padding-left-10 padding-bottom-5'.format('' if view.favorite_content else '-o');
+ data-sequence-oid view.hex_oid;"></i><br />
<span class="content-version" tal:content="string:V${view.version_id}">Version</span> =
<span class="content-state" tal:content="structure view.state">state</span> |
<span class="content-state-date" tal:content="view.state_date">state date</span>
--- a/src/pyams_content/shared/common/zmi/templates/wf-operator-warning.pt Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/templates/wf-operator-warning.pt Mon Jan 18 17:42:32 2016 +0100
@@ -1,3 +1,3 @@
-<div class="alert alert-danger margin-bottom-5" i18n:domain="pyams_content" i18n:translate="">
+<div class="alert alert-danger padding-5 margin-bottom-5 persistent" i18n:domain="pyams_content" i18n:translate="">
WARNING: this request was made by a contributor which is not the owner of this content.
</div>
--- a/src/pyams_content/shared/common/zmi/templates/wf-owner-warning.pt Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/templates/wf-owner-warning.pt Mon Jan 18 17:42:32 2016 +0100
@@ -1,3 +1,3 @@
-<div class="alert alert-danger margin-bottom-5" i18n:domain="pyams_content" i18n:translate="">
+<div class="alert alert-danger margin-bottom-5 padding-5" i18n:domain="pyams_content" i18n:translate="">
RECALL: you are not the owner of the content on which you are intervening.
</div>
--- a/src/pyams_content/shared/common/zmi/templates/wf-transition-info.pt Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/templates/wf-transition-info.pt Mon Jan 18 17:42:32 2016 +0100
@@ -1,6 +1,10 @@
<div class="alert alert-warning padding-5" i18n:domain="pyams_content">
<strong i18n:translate="">FOR YOUR INFORMATION</strong><br />
- <u i18n:translate="">Previous step:</u> <tal:var content="view.previous_step" />
+ <tal:if define="next_step view.next_step"
+ condition="next_step">
+ <u i18n:translate="">Next step</u> : <tal:var content="next_step" /><br />
+ </tal:if>
+ <u i18n:translate="">Previous step</u> : <tal:var content="view.previous_step" />
<tal:var define="message view.previous_message">
<tal:if condition="message"><br />
<span class="small" i18n:translate="">With this comment:</span>
@@ -8,8 +12,4 @@
</tal:if>
<br tal:condition="not:message" />
</tal:var>
- <tal:if define="next_step view.next_step"
- condition="next_step">
- <u i18n:translate="">Next step:</u> <tal:var content="next_step" />
- </tal:if>
</div>
--- a/src/pyams_content/shared/common/zmi/workflow.py Mon Jan 18 17:29:59 2016 +0100
+++ b/src/pyams_content/shared/common/zmi/workflow.py Mon Jan 18 17:42:32 2016 +0100
@@ -9,7 +9,6 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
-from pyams_utils.text import text_to_html
__docformat__ = 'restructuredtext'
@@ -18,6 +17,7 @@
from datetime import datetime
# import interfaces
+from pyams_content.interfaces import PUBLISH_CONTENT_PERMISSION, CREATE_CONTENT_PERMISSION, MANAGE_CONTENT_PERMISSION
from pyams_content.shared.common.interfaces import IWfSharedContent, ISharedTool, ISharedContent
from pyams_form.interfaces.form import IInnerTabForm, IFormPrefixViewletsManager, IWidgetsPrefixViewletsManager, \
IFormSuffixViewletsManager
@@ -32,18 +32,20 @@
# import packages
from pyams_content.shared.common.zmi.summary import SharedContentSummaryForm
from pyams_content.workflow import DRAFT, DELETED
-from pyams_form.form import AJAXAddForm, InnerDisplayForm
+from pyams_form.form import AJAXAddForm
from pyams_form.schema import CloseButton
from pyams_pagelet.pagelet import pagelet_config
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
from pyams_utils.date import format_datetime
from pyams_utils.registry import get_utility
+from pyams_utils.text import text_to_html
from pyams_utils.timezone import tztime
from pyams_utils.traversing import get_parent
from pyams_utils.url import absolute_url
from pyams_viewlet.viewlet import viewlet_config, Viewlet
from pyams_workflow.zmi.transition import WorkflowContentTransitionForm, WorkflowContentTransitionAJAXForm
+from pyams_zmi.form import InnerAdminDisplayForm
from pyramid.events import subscriber
from pyramid.view import view_config
from z3c.form import field, button
@@ -59,10 +61,10 @@
@adapter_config(name='workflow-summary',
context=(IWfSharedContent, IPyAMSLayer, SharedContentSummaryForm),
provides=IInnerTabForm)
-class WfSharedContentWorkflowSummary(InnerDisplayForm):
+class WfSharedContentWorkflowSummary(InnerAdminDisplayForm):
"""Shared content workflow summary"""
- weight = 10
+ weight = 990
tab_label = _("Workflow")
tab_target = 'workflow-summary.html'
@@ -71,9 +73,11 @@
@pagelet_config(name='workflow-summary.html', context=IWfSharedContent, layer=IPyAMSLayer)
@implementer(IInnerPage, IInnerTabForm)
-class WorkflowSummaryDisplayForm(InnerDisplayForm):
+class WorkflowSummaryDisplayForm(InnerAdminDisplayForm):
"""Workflow summary display form"""
+ legend = _("Workflow details")
+
@property
def fields(self):
fields = field.Fields(IWorkflowState).omit('history') + \
@@ -116,19 +120,22 @@
translate = self.request.localizer.translate
workflow = IWorkflow(self.context)
state = IWorkflowState(self.context)
- adapter = self.request.registry.queryAdapter(workflow, IWorkflowStateLabel,
- name=state.state)
+ registry = self.request.registry
+ adapter = registry.queryMultiAdapter((workflow, self.request), IWorkflowStateLabel, name=state.state)
if adapter is None:
- adapter = self.request.registry.queryAdapter(workflow, IWorkflowStateLabel)
+ adapter = registry.queryAdapter(workflow, IWorkflowStateLabel, name=state.state)
+ if adapter is None:
+ adapter = registry.queryAdapter(workflow, IWorkflowStateLabel)
if adapter is not None:
state_label = adapter.get_label(self.context, request=self.request)
else:
- security = get_utility(ISecurityManager)
- state_label = translate(_("{state} by {principal}")).format(
+ state_label = translate(_("{state} {date}")).format(
state=translate(workflow.get_state_label(state.state)),
- principal=security.get_principal(state.state_principal).title)
- return translate(_("{state} {date}")).format(state=state_label,
- date=format_datetime(state.state_date, request=self.request))
+ date=format_datetime(state.state_date, request=self.request))
+ security = get_utility(ISecurityManager)
+ return translate(_("{state} | by {principal}")).format(
+ state=state_label,
+ principal=security.get_principal(state.state_principal).title)
@property
def previous_message(self):
@@ -165,7 +172,8 @@
action = button.Button(name='action', title=_("Request publication"))
-@pagelet_config(name='wf-propose.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.ManageContent')
+@pagelet_config(name='wf-propose.html', context=IWfSharedContent, layer=IPyAMSLayer,
+ permission=MANAGE_CONTENT_PERMISSION)
class PublicationRequestForm(WorkflowContentTransitionForm):
"""Shared content publication request form"""
@@ -191,7 +199,7 @@
@view_config(name='wf-propose.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.ManageContent', renderer='json', xhr=True)
+ permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
class PublicationRequestAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRequestForm):
"""Shared content publication request form, JSON renderer"""
@@ -206,8 +214,15 @@
event.form.widgets.errors += (Invalid(_("A comment is required")), )
+@viewlet_config(name='wf-propose-message', context=IWfSharedContent, layer=IPyAMSLayer, view=PublicationRequestForm,
+ manager=IWidgetsPrefixViewletsManager, weight=20)
+@template_config(template='templates/wf-propose-message.pt')
+class PublicationRequestFormMessage(Viewlet):
+ """Publication request form info message"""
+
+
@viewlet_config(name='wf-propose-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationRequestForm, manager=IFormPrefixViewletsManager, weight=10)
+ view=PublicationRequestForm, manager=IWidgetsPrefixViewletsManager, weight=30)
@template_config(template='templates/wf-owner-warning.pt')
class PublicationRequestFormWarning(Viewlet):
"""Publication request form warning message"""
@@ -218,13 +233,6 @@
return Viewlet.__new__(cls)
-@viewlet_config(name='wf-propose-message', context=IWfSharedContent, layer=IPyAMSLayer, view=PublicationRequestForm,
- manager=IWidgetsPrefixViewletsManager, weight=20)
-@template_config(template='templates/wf-propose-message.pt')
-class PublicationRequestFormMessage(Viewlet):
- """Publication request form info message"""
-
-
#
# Cancel publication request form
#
@@ -237,7 +245,7 @@
@pagelet_config(name='wf-cancel-propose.html', context=IWfSharedContent, layer=IPyAMSLayer,
- permission='pyams.ManageContent')
+ permission=MANAGE_CONTENT_PERMISSION)
class PublicationRequestCancelForm(WorkflowContentTransitionForm):
"""Shared content publication request cancel form"""
@@ -246,13 +254,20 @@
@view_config(name='wf-cancel-propose.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.ManageContent', renderer='json', xhr=True)
+ permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
class PublicationRequestCancelAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRequestCancelForm):
"""Shared content publication request cancel form, JSON renderer"""
+@viewlet_config(name='wf-cancel-propose-message', context=IWfSharedContent, layer=IPyAMSLayer,
+ view=PublicationRequestCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20)
+@template_config(template='templates/wf-cancel-propose-message.pt')
+class PublicationRequestCancelFormMessage(Viewlet):
+ """Publication request cancel form info message"""
+
+
@viewlet_config(name='wf-cancel-propose-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationRequestCancelForm, manager=IFormPrefixViewletsManager, weight=10)
+ view=PublicationRequestCancelForm, manager=IWidgetsPrefixViewletsManager, weight=30)
@template_config(template='templates/wf-owner-warning.pt')
class PublicationRequestCancelFormWarning(Viewlet):
"""Publication request cancel form warning message"""
@@ -263,13 +278,6 @@
return Viewlet.__new__(cls)
-@viewlet_config(name='wf-cancel-propose-message', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationRequestCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20)
-@template_config(template='templates/wf-cancel-propose-message.pt')
-class PublicationRequestCancelFormMessage(Viewlet):
- """Publication request cancel form info message"""
-
-
#
# Refuse publication form
#
@@ -282,7 +290,7 @@
@pagelet_config(name='wf-refuse.html', context=IWfSharedContent, layer=IPyAMSLayer,
- permission='pyams.PublishContent')
+ permission=PUBLISH_CONTENT_PERMISSION)
class PublicationRequestRefuseForm(WorkflowContentTransitionForm):
"""Shared content publication request refuse form"""
@@ -295,7 +303,7 @@
@view_config(name='wf-refuse.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.PublishContent', renderer='json', xhr=True)
+ permission=PUBLISH_CONTENT_PERMISSION, renderer='json', xhr=True)
class PublicationRequestRefuseAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRequestRefuseForm):
"""Shared content publication request refuse form, JSON renderer"""
@@ -339,7 +347,8 @@
action = button.Button(name='action', title=_("Publish"))
-@pagelet_config(name='wf-publish.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.PublishContent')
+@pagelet_config(name='wf-publish.html', context=IWfSharedContent, layer=IPyAMSLayer,
+ permission=PUBLISH_CONTENT_PERMISSION)
class PublicationForm(WorkflowContentTransitionForm):
"""Shared content publication form"""
@@ -369,7 +378,7 @@
@view_config(name='wf-publish.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.PublishContent', renderer='json', xhr=True)
+ permission=PUBLISH_CONTENT_PERMISSION, renderer='json', xhr=True)
class PublicationAJAXForm(WorkflowContentTransitionAJAXForm, PublicationForm):
"""Shared content publication form, JSON renderer"""
@@ -413,7 +422,7 @@
@pagelet_config(name='wf-retiring.html', context=IWfSharedContent, layer=IPyAMSLayer,
- permission='pyams.ManageContent')
+ permission=MANAGE_CONTENT_PERMISSION)
class PublicationRetireRequestForm(WorkflowContentTransitionForm):
"""Shared content publication request refuse form"""
@@ -429,7 +438,7 @@
@view_config(name='wf-retiring.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.ManageContent', renderer='json', xhr=True)
+ permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
class PublicationRetireRequestAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRetireRequestForm):
"""Shared content publication retire request form, JSON renderer"""
@@ -442,8 +451,15 @@
event.form.widgets.errors += (Invalid(_("A comment is required")), )
+@viewlet_config(name='wf-retiring-message', context=IWfSharedContent, layer=IPyAMSLayer,
+ view=PublicationRetireRequestForm, manager=IWidgetsPrefixViewletsManager, weight=20)
+@template_config(template='templates/wf-retiring-message.pt')
+class PublicationRetireRequestFormMessage(Viewlet):
+ """Publication retire request form info message"""
+
+
@viewlet_config(name='wf-retiring-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationRetireRequestForm, manager=IFormPrefixViewletsManager, weight=10)
+ view=PublicationRetireRequestForm, manager=IWidgetsPrefixViewletsManager, weight=30)
@template_config(template='templates/wf-owner-warning.pt')
class PublicationRetireRequestFormWarning(Viewlet):
"""Publication retire request form warning message"""
@@ -454,13 +470,6 @@
return Viewlet.__new__(cls)
-@viewlet_config(name='wf-retiring-message', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationRetireRequestForm, manager=IWidgetsPrefixViewletsManager, weight=20)
-@template_config(template='templates/wf-retiring-message.pt')
-class PublicationRetireRequestFormMessage(Viewlet):
- """Publication retire request form info message"""
-
-
#
# Publication retire cancel form
#
@@ -473,7 +482,7 @@
@pagelet_config(name='wf-cancel-retiring.html', context=IWfSharedContent, layer=IPyAMSLayer,
- permission='pyams.ManageContent')
+ permission=MANAGE_CONTENT_PERMISSION)
class PublicationRetireCancelForm(WorkflowContentTransitionForm):
"""Shared content publication retire request cancel form"""
@@ -482,13 +491,20 @@
@view_config(name='wf-cancel-retiring.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.ManageContent', renderer='json', xhr=True)
+ permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
class PublicationRetireCancelAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRetireCancelForm):
"""Shared content publication retire request cancel form, JSON renderer"""
+@viewlet_config(name='wf-cancel-retiring-message', context=IWfSharedContent, layer=IPyAMSLayer,
+ view=PublicationRetireCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20)
+@template_config(template='templates/wf-cancel-retiring-message.pt')
+class PublicationRetireCancelFormMessage(Viewlet):
+ """Publication retire request form info message"""
+
+
@viewlet_config(name='wf-cancel-retiring-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationRetireCancelForm, manager=IFormPrefixViewletsManager, weight=10)
+ view=PublicationRetireCancelForm, manager=IWidgetsPrefixViewletsManager, weight=30)
@template_config(template='templates/wf-owner-warning.pt')
class PublicationRetireCancelFormWarning(Viewlet):
"""Publication retire request cancel form warning message"""
@@ -499,13 +515,6 @@
return Viewlet.__new__(cls)
-@viewlet_config(name='wf-cancel-retiring-message', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationRetireCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20)
-@template_config(template='templates/wf-cancel-retiring-message.pt')
-class PublicationRetireCancelFormMessage(Viewlet):
- """Publication retire request form info message"""
-
-
#
# Publication retire form
#
@@ -518,7 +527,7 @@
@pagelet_config(name='wf-retire.html', context=IWfSharedContent, layer=IPyAMSLayer,
- permission='pyams.PublishContent')
+ permission=PUBLISH_CONTENT_PERMISSION)
class PublicationRetireForm(WorkflowContentTransitionForm):
"""Shared content publication retire form"""
@@ -527,7 +536,7 @@
@view_config(name='wf-retire.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.PublishContent', renderer='json', xhr=True)
+ permission=PUBLISH_CONTENT_PERMISSION, renderer='json', xhr=True)
class PublicationRetireAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRetireForm):
"""Shared content publication retire form, JSON renderer"""
@@ -564,7 +573,7 @@
@pagelet_config(name='wf-archiving.html', context=IWfSharedContent, layer=IPyAMSLayer,
- permission='pyams.ManageContent')
+ permission=MANAGE_CONTENT_PERMISSION)
class PublicationArchiveRequestForm(WorkflowContentTransitionForm):
"""Shared content publication request archive form"""
@@ -580,7 +589,7 @@
@view_config(name='wf-archiving.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.ManageContent', renderer='json', xhr=True)
+ permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
class PublicationArchiveRequestAJAXForm(WorkflowContentTransitionAJAXForm, PublicationArchiveRequestForm):
"""Shared content publication archive request form, JSON renderer"""
@@ -593,8 +602,15 @@
event.form.widgets.errors += (Invalid(_("A comment is required")), )
+@viewlet_config(name='wf-archiving-message', context=IWfSharedContent, layer=IPyAMSLayer,
+ view=PublicationArchiveRequestForm, manager=IWidgetsPrefixViewletsManager, weight=20)
+@template_config(template='templates/wf-archiving-message.pt')
+class PublicationArchiveRequestFormMessage(Viewlet):
+ """Publication archive request form info message"""
+
+
@viewlet_config(name='wf-archiving-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationArchiveRequestForm, manager=IFormPrefixViewletsManager, weight=10)
+ view=PublicationArchiveRequestForm, manager=IWidgetsPrefixViewletsManager, weight=30)
@template_config(template='templates/wf-owner-warning.pt')
class PublicationArchiveRequestFormWarning(Viewlet):
"""Publication archive request form warning message"""
@@ -605,13 +621,6 @@
return Viewlet.__new__(cls)
-@viewlet_config(name='wf-archiving-message', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationArchiveRequestForm, manager=IWidgetsPrefixViewletsManager, weight=20)
-@template_config(template='templates/wf-archiving-message.pt')
-class PublicationArchiveRequestFormMessage(Viewlet):
- """Publication archive request form info message"""
-
-
#
# Publication archive cancel form
#
@@ -624,7 +633,7 @@
@pagelet_config(name='wf-cancel-archiving.html', context=IWfSharedContent, layer=IPyAMSLayer,
- permission='pyams.ManageContent')
+ permission=MANAGE_CONTENT_PERMISSION)
class PublicationArchiveCancelForm(WorkflowContentTransitionForm):
"""Shared content publication archive request cancel form"""
@@ -633,13 +642,20 @@
@view_config(name='wf-cancel-archiving.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.ManageContent', renderer='json', xhr=True)
+ permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
class PublicationArchiveCancelAJAXForm(WorkflowContentTransitionAJAXForm, PublicationArchiveCancelForm):
"""Shared content publication archive request cancel form, JSON renderer"""
+@viewlet_config(name='wf-cancel-archiving-message', context=IWfSharedContent, layer=IPyAMSLayer,
+ view=PublicationArchiveCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20)
+@template_config(template='templates/wf-cancel-archiving-message.pt')
+class PublicationArchiveCancelFormMessage(Viewlet):
+ """Publication archive cancel form info message"""
+
+
@viewlet_config(name='wf-cancel-archiving-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationArchiveCancelForm, manager=IFormPrefixViewletsManager, weight=10)
+ view=PublicationArchiveCancelForm, manager=IWidgetsPrefixViewletsManager, weight=30)
@template_config(template='templates/wf-owner-warning.pt')
class PublicationArchiveCancelFormWarning(Viewlet):
"""Publication archive cancel form warning message"""
@@ -650,13 +666,6 @@
return Viewlet.__new__(cls)
-@viewlet_config(name='wf-cancel-archiving-message', context=IWfSharedContent, layer=IPyAMSLayer,
- view=PublicationArchiveCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20)
-@template_config(template='templates/wf-cancel-archiving-message.pt')
-class PublicationArchiveCancelFormMessage(Viewlet):
- """Publication archive cancel form info message"""
-
-
#
# Publication archive form
#
@@ -669,7 +678,7 @@
@pagelet_config(name='wf-archive.html', context=IWfSharedContent, layer=IPyAMSLayer,
- permission='pyams.PublishContent')
+ permission=PUBLISH_CONTENT_PERMISSION)
class PublicationArchiveForm(WorkflowContentTransitionForm):
"""Shared content publication archive form"""
@@ -678,7 +687,7 @@
@view_config(name='wf-archive.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.PublishContent', renderer='json', xhr=True)
+ permission=PUBLISH_CONTENT_PERMISSION, renderer='json', xhr=True)
class PublicationArchiveAJAXForm(WorkflowContentTransitionAJAXForm, PublicationArchiveForm):
"""Shared content publication archive form, JSON renderer"""
@@ -714,7 +723,8 @@
action = button.Button(name='action', title=_("Create new version"))
-@pagelet_config(name='wf-clone.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.CreateContent')
+@pagelet_config(name='wf-clone.html', context=IWfSharedContent, layer=IPyAMSLayer,
+ permission=CREATE_CONTENT_PERMISSION)
class SharedContentCloneForm(WorkflowContentTransitionForm):
"""Shared content clone form"""
@@ -727,7 +737,7 @@
@view_config(name='wf-clone.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.CreateContent', renderer='json', xhr=True)
+ permission=CREATE_CONTENT_PERMISSION, renderer='json', xhr=True)
class SharedContentCloneAJAXForm(AJAXAddForm, SharedContentCloneForm):
"""Shared content clone form, JSON rendener"""
@@ -736,8 +746,15 @@
'location': absolute_url(changes, self.request, 'admin.html#properties.html')}
+@viewlet_config(name='wf-clone-message', context=IWfSharedContent, layer=IPyAMSLayer,
+ view=SharedContentCloneForm, manager=IWidgetsPrefixViewletsManager, weight=20)
+@template_config(template='templates/wf-clone-message.pt')
+class SharedContentCloneFormMessage(Viewlet):
+ """Shared content clone form info message"""
+
+
@viewlet_config(name='wf-clone-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer,
- view=SharedContentCloneForm, manager=IFormPrefixViewletsManager, weight=10)
+ view=SharedContentCloneForm, manager=IWidgetsPrefixViewletsManager, weight=30)
@template_config(template='templates/wf-owner-warning.pt')
class SharedContentCloneFormWarning(Viewlet):
"""Shared content clone form warning message"""
@@ -748,13 +765,6 @@
return Viewlet.__new__(cls)
-@viewlet_config(name='wf-clone-message', context=IWfSharedContent, layer=IPyAMSLayer,
- view=SharedContentCloneForm, manager=IWidgetsPrefixViewletsManager, weight=20)
-@template_config(template='templates/wf-clone-message.pt')
-class SharedContentCloneFormMessage(Viewlet):
- """Shared content clone form info message"""
-
-
#
# Delete form
#
@@ -766,13 +776,21 @@
action = button.Button(name='action', title=_("Delete version"))
-@pagelet_config(name='wf-delete.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.ManageContent')
+@pagelet_config(name='wf-delete.html', context=IWfSharedContent, layer=IPyAMSLayer,
+ permission=MANAGE_CONTENT_PERMISSION)
class SharedContentDeleteForm(WorkflowContentTransitionForm):
"""Shared content delete form"""
buttons = button.Buttons(ISharedContentDeleteButtons)
ajax_handler = 'wf-delete.json'
+ def updateActions(self):
+ super(SharedContentDeleteForm, self).updateActions()
+ if 'action' in self.actions:
+ state = IWorkflowState(self.context)
+ if state.version_id == 1: # remove the first and only version => remove all
+ self.actions['action'].title = _("Delete definitively")
+
def createAndAdd(self, data):
state = IWorkflowState(self.context)
if state.version_id == 1: # remove the first and only version => remove all
@@ -780,12 +798,13 @@
self.__target = get_parent(content, ISharedTool)
del content.__parent__[content.__name__]
else:
- self.__target = get_parent(self.context, ISharedTool)
- IWorkflowVersions(self.context).remove_version(state.version_id, state=DELETED, comment=data.get('comment'))
+ versions = IWorkflowVersions(self.context)
+ versions.remove_version(state.version_id, state=DELETED, comment=data.get('comment'))
+ self.__target = versions.get_last_versions(count=1)[0]
@view_config(name='wf-delete.json', context=IWfSharedContent, request_type=IPyAMSLayer,
- permission='pyams.ManageContent', renderer='json', xhr=True)
+ permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
class SharedContentDeleteAJAXForm(AJAXAddForm, SharedContentDeleteForm):
"""Shared content delete form, JSON rendener"""
@@ -794,8 +813,15 @@
'location': absolute_url(self._SharedContentDeleteForm__target, self.request, 'admin.html')}
+@viewlet_config(name='wf-delete-message', context=IWfSharedContent, layer=IPyAMSLayer,
+ view=SharedContentDeleteForm, manager=IWidgetsPrefixViewletsManager, weight=20)
+@template_config(template='templates/wf-delete-message.pt')
+class SharedContentDeleteFormMessage(Viewlet):
+ """Shared content delete form info message"""
+
+
@viewlet_config(name='wf-delete-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer,
- view=SharedContentDeleteForm, manager=IFormPrefixViewletsManager, weight=10)
+ view=SharedContentDeleteForm, manager=IWidgetsPrefixViewletsManager, weight=30)
@template_config(template='templates/wf-owner-warning.pt')
class SharedContentDeleteFormWarning(Viewlet):
"""Shared content delete form warning message"""
@@ -804,10 +830,3 @@
if request.principal.id in context.owner:
return None
return Viewlet.__new__(cls)
-
-
-@viewlet_config(name='wf-delete-message', context=IWfSharedContent, layer=IPyAMSLayer,
- view=SharedContentDeleteForm, manager=IWidgetsPrefixViewletsManager, weight=20)
-@template_config(template='templates/wf-delete-message.pt')
-class SharedContentDeleteFormMessage(Viewlet):
- """Shared content delete form info message"""