# HG changeset patch # User Thierry Florac # Date 1453135352 -3600 # Node ID 234db8f0592889e84e70203f576725a4eef60585 # Parent 35afd52c902b40185dcd7387e6f2fb04d644313c Updated management interface diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/__init__.py --- 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 += ''.format(translate(_("Created or modified in this version"))) + value += ''.format( + translate(_("Created or modified in this version"))) return value diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/dashboard.py --- 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 += ' ' + 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 ''.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) diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/header.py --- 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} '); + state_class = 'text-danger' # if state.state in workflow.update_states else 'txt-color-text' + state_format = state_format.replace('{state}', + '{{state}}'.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}', + '{{principal}}'.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}', - '{{principal}}'.format(principal_class)) - state_class = 'text-danger' if state.state in workflow.update_states else None - if state_class: - self.state = '{state}'.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): diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/manager.py --- 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""" diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/properties.py --- 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 diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/summary.py --- 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)) diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/templates/header.pt --- 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 @@ - -

- - - - - - - -

-
+ + +

+ + + + + + + +

+
+
OID : Title | - by
+ by +
Version = state | state date diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/templates/wf-operator-warning.pt --- 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 @@ -
+
WARNING: this request was made by a contributor which is not the owner of this content.
diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/templates/wf-owner-warning.pt --- 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 @@ -
+
RECALL: you are not the owner of the content on which you are intervening.
diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/templates/wf-transition-info.pt --- 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 @@
FOR YOUR INFORMATION
- Previous step: + + Next step :
+
+ Previous step :
With this comment: @@ -8,8 +12,4 @@

- - Next step: -
diff -r 35afd52c902b -r 234db8f05928 src/pyams_content/shared/common/zmi/workflow.py --- 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"""