--- a/src/pyams_content/shared/common/zmi/types.py Thu May 23 17:16:27 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,620 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-
-__docformat__ = 'restructuredtext'
-
-import json
-
-from pyramid.decorator import reify
-from pyramid.events import subscriber
-from pyramid.exceptions import NotFound
-from pyramid.view import view_config
-from z3c.form import field
-from z3c.form.interfaces import DISPLAY_MODE, IDataExtractedEvent
-from z3c.table.interfaces import IColumn, IValues
-from zope.interface import Invalid, implementer
-
-from pyams_content import _
-from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION, MANAGE_TOOL_PERMISSION
-from pyams_content.reference.pictograms.zmi.widget import PictogramSelectFieldWidget
-from pyams_content.shared.common.interfaces.types import IBaseDataType, IDataType, ISubType, ITypedDataManager, \
- ITypedSharedTool, IWfTypedSharedContent
-from pyams_content.shared.common.types import DataType, SubType
-from pyams_content.shared.common.zmi import SharedContentAddForm
-from pyams_content.shared.common.zmi.properties import SharedContentPropertiesEditForm
-from pyams_content.zmi import pyams_content
-from pyams_form.form import AJAXAddForm, ajax_config
-from pyams_form.interfaces.form import IWidgetForm
-from pyams_form.security import ProtectedFormObjectMixin
-from pyams_i18n.interfaces import II18n
-from pyams_i18n.widget import I18nSEOTextLineFieldWidget
-from pyams_pagelet.pagelet import pagelet_config
-from pyams_skin.container import delete_container_element
-from pyams_skin.event import get_json_table_refresh_event
-from pyams_skin.interfaces import IInnerPage
-from pyams_skin.interfaces.container import ITableElementName
-from pyams_skin.interfaces.viewlet import IWidgetTitleViewletManager
-from pyams_skin.layer import IPyAMSLayer
-from pyams_skin.table import ActionColumn, BaseTable, NameColumn, SorterColumn, TrashColumn
-from pyams_skin.viewlet.menu import MenuItem
-from pyams_skin.viewlet.toolbar import ToolbarAction
-from pyams_utils.adapter import ContextRequestAdapter, ContextRequestViewAdapter, adapter_config
-from pyams_utils.fanstatic import get_resource_path
-from pyams_utils.traversing import get_parent
-from pyams_utils.unicode import translate_string
-from pyams_utils.url import absolute_url
-from pyams_viewlet.interfaces import IViewletManager
-from pyams_viewlet.viewlet import viewlet_config
-from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm, AdminEditForm
-from pyams_zmi.interfaces.menu import IPropertiesMenu
-from pyams_zmi.layer import IAdminLayer
-from pyams_zmi.view import ContainerAdminView
-
-
-@viewlet_config(name='data-types.menu', context=ITypedSharedTool, layer=IAdminLayer,
- manager=IPropertiesMenu, permission=MANAGE_TOOL_PERMISSION, weight=5)
-class TypedSharedToolTypesMenu(MenuItem):
- """Typed shared tool types menu"""
-
- label = _("Data types")
- icon_class = 'fa-folder-o'
- url = '#data-types.html'
-
-
-#
-# Typed shared data types manager target views
-#
-
-class TypedSharedToolTypesTable(ProtectedFormObjectMixin, BaseTable):
- """Typed shared tool types table"""
-
- prefix = 'types'
-
- hide_header = True
- sortOn = None
-
- @property
- def cssClasses(self):
- classes = ['table', 'table-bordered', 'table-striped', 'table-hover', 'table-tight']
- permission = self.permission
- if (not permission) or self.request.has_permission(permission, self.context):
- classes.append('table-dnd')
- return {'table': ' '.join(classes)}
-
- @property
- def data_attributes(self):
- attributes = super(TypedSharedToolTypesTable, self).data_attributes
- attributes['table'] = {
- 'id': self.id,
- 'data-ams-plugins': 'pyams_content',
- 'data-ams-plugin-pyams_content-src': get_resource_path(pyams_content),
- 'data-ams-location': absolute_url(ITypedDataManager(self.context), self.request),
- 'data-ams-tablednd-drag-handle': 'td.sorter',
- 'data-ams-tablednd-drop-target': 'set-types-order.json'
- }
- return attributes
-
- @reify
- def values(self):
- return list(super(TypedSharedToolTypesTable, self).values)
-
- def render(self):
- if not self.values:
- translate = self.request.localizer.translate
- return translate(_("No currently defined data type."))
- return super(TypedSharedToolTypesTable, self).render()
-
-
-@adapter_config(context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable), provides=IValues)
-class TypedSharedToolTypesValues(ContextRequestViewAdapter):
- """Typed shared tool types table values adapter"""
-
- @property
- def values(self):
- return ITypedDataManager(self.context).values()
-
-
-@adapter_config(name='sorter', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
- provides=IColumn)
-class TypedSharedToolTypesSorterColumn(ProtectedFormObjectMixin, SorterColumn):
- """Typed shared tool types sorter column"""
-
-
-@view_config(name='set-types-order.json', context=ITypedDataManager, request_type=IPyAMSLayer,
- permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
-def set_data_types_order(request):
- """Update data types order"""
- order = list(map(str, json.loads(request.params.get('names'))))
- request.context.updateOrder(order)
- return {'status': 'success'}
-
-
-@adapter_config(name='name', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
- provides=IColumn)
-class TypedSharedToolTypesNameColumn(NameColumn):
- """Typed shared tool types name column"""
-
- _header = _("Data type label")
-
- def renderCell(self, item):
- return '<span data-ams-stop-propagation="true" ' \
- ' data-ams-click-handler="MyAMS.skin.switchCellContent" ' \
- ' data-ams-switch-handler="get-subtypes-table.json" ' \
- ' data-ams-switch-target=".subtypes">' \
- ' <span class="small hint" title="{hint}" data-ams-hint-gravity="e">' \
- ' <i class="fa fa-plus-square-o switch"></i>' \
- ' </span>' \
- '</span> <span class="title">{title}</span>' \
- '<div class="inner-table-form subtypes margin-x-10 margin-bottom-0 padding-left-5"></div>'.format(
- hint=self.request.localizer.translate(_("Click to see subtypes")),
- title=super(TypedSharedToolTypesNameColumn, self).renderCell(item))
-
-
-@adapter_config(name='paragraphs', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
- provides=IColumn)
-class TypedSharedToolTypesParagraphsColumn(ActionColumn):
- """Typed shared tool types paragraphs column"""
-
- weight = 100
-
- icon_class = 'fa fa-fw fa-paragraph'
- icon_hint = _("Default paragraphs")
-
- url = 'paragraphs-dialog.html'
- modal_target = True
-
- permission = MANAGE_TOOL_PERMISSION
-
-
-@adapter_config(name='associations', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
- provides=IColumn)
-class TypedSharedToolTypesAssociationsColumn(ActionColumn):
- """Typed shared tool types associations column"""
-
- weight = 110
-
- icon_class = 'fa fa-fw fa-link'
- icon_hint = _("Default associations")
-
- url = 'associations-dialog.html'
- modal_target = True
-
- permission = MANAGE_TOOL_PERMISSION
-
-
-@adapter_config(name='themes', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
- provides=IColumn)
-class TypedSharedToolTypesThemesColumn(ActionColumn):
- """Typed shared tool types themes column"""
-
- weight = 120
-
- icon_class = 'fa fa-fw fa-tags'
- icon_hint = _("Default themes")
-
- url = 'themes-dialog.html'
- modal_target = True
-
- permission = MANAGE_TOOL_PERMISSION
-
-
-@adapter_config(name='trash', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
- provides=IColumn)
-class TypedSharedToolTypesTrashColumn(TrashColumn):
- """Typed shared tool types trash column"""
-
- permission = MANAGE_TOOL_PERMISSION
-
-
-@view_config(name='delete-element.json', context=ITypedDataManager, request_type=IPyAMSLayer,
- permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
-def delete_data_type(request):
- """Data type delete view"""
- return delete_container_element(request, ignore_permission=True)
-
-
-@pagelet_config(name='data-types.html', context=ITypedSharedTool, layer=IPyAMSLayer,
- permission=MANAGE_TOOL_PERMISSION)
-class TypedSharedToolTypesView(ContainerAdminView):
- """Typed shared tool types view"""
-
- title = _("Content data types")
- table_class = TypedSharedToolTypesTable
-
-
-#
-# Data type views
-#
-
-@adapter_config(context=(IBaseDataType, IPyAMSLayer), provides=ITableElementName)
-class DataTypeElementNameAdapter(ContextRequestAdapter):
- """Types shared tool types name adapter"""
-
- @property
- def name(self):
- return II18n(self.context).query_attribute('label', request=self.request)
-
-
-@viewlet_config(name='add-data-type.action', context=ITypedSharedTool, layer=IAdminLayer,
- view=TypedSharedToolTypesView, manager=IWidgetTitleViewletManager,
- permission=MANAGE_TOOL_PERMISSION, weight=1)
-class DataTypeAddAction(ToolbarAction):
- """Data type adding action"""
-
- label = _("Add data type")
- label_css_class = 'fa fa-fw fa-plus'
- url = 'add-data-type.html'
- modal_target = True
-
-
-@pagelet_config(name='add-data-type.html', context=ITypedSharedTool, layer=IPyAMSLayer,
- permission=MANAGE_TOOL_PERMISSION)
-@ajax_config(name='add-data-type.json', context=ITypedSharedTool, layer=IPyAMSLayer, base=AJAXAddForm)
-class DataTypeAddForm(AdminDialogAddForm):
- """Data type add form"""
-
- legend = _("Add new data type")
- icon_css_class = 'fa fa-fw fa-folder-o'
- label_css_class = 'control-label col-md-4'
- input_css_class = 'col-md-8'
-
- @property
- def fields(self):
- fields = field.Fields(IDataType).omit('__parent__', '__name__')
- fields['pictogram'].widgetFactory = PictogramSelectFieldWidget
- if not self.context.shared_content_types_fields:
- fields = fields.omit('field_names')
- return fields
-
- edit_permission = MANAGE_TOOL_PERMISSION
-
- def create(self, data):
- return DataType()
-
- def add(self, object):
- name = translate_string(object.name, spaces='-')
- ITypedDataManager(self.context)[name] = object
-
- def nextURL(self):
- return '#data-types.html'
-
-
-@subscriber(IDataExtractedEvent, form_selector=DataTypeAddForm)
-def handle_datatype_add_form_data_extraction(event):
- """Check new data type for existing name"""
- context = event.form.context
- manager = ITypedDataManager(context)
- name = event.data.get('name')
- if translate_string(name, spaces='-') in manager:
- event.form.widgets.errors += (Invalid(_("Specified type name is already used!")),)
-
-
-@pagelet_config(name='properties.html', context=IDataType, layer=IPyAMSLayer, permission=MANAGE_TOOL_PERMISSION)
-@ajax_config(name='properties.json', context=IDataType, layer=IPyAMSLayer)
-class DataTypeEditForm(AdminDialogEditForm):
- """Data type edit form"""
-
- prefix = 'datatype_properties.'
-
- legend = _("Data type properties")
- icon_css_class = 'fa fa-fw fa-folder-o'
- label_css_class = 'control-label col-md-4'
- input_css_class = 'col-md-8'
-
- @property
- def fields(self):
- fields = field.Fields(IDataType).omit('__parent__', '__name__')
- fields['pictogram'].widgetFactory = PictogramSelectFieldWidget
- tool = get_parent(self.context, ITypedSharedTool)
- if not tool.shared_content_types_fields:
- fields = fields.omit('field_names')
- return fields
-
- edit_permission = MANAGE_TOOL_PERMISSION
-
- def updateWidgets(self, prefix=None):
- super(DataTypeEditForm, self).updateWidgets(prefix)
- if 'name' in self.widgets:
- self.widgets['name'].mode = DISPLAY_MODE
-
-
-#
-# Subtypes views
-#
-
-class DatatypeSubtypesTable(BaseTable):
- """Data type subtypes table"""
-
- prefix = 'subtypes'
-
- hide_header = True
- sortOn = None
-
- widget_class = 'ams-widget margin-top-5'
- cssClasses = {'table': 'table table-bordered table-striped table-hover table-tight table-dnd'}
-
- @property
- def data_attributes(self):
- attributes = super(DatatypeSubtypesTable, self).data_attributes
- attributes['table'] = {
- 'id': self.id,
- 'data-ams-location': absolute_url(self.context, self.request),
- 'data-ams-tablednd-drag-handle': 'td.sorter',
- 'data-ams-tablednd-drop-target': 'set-subtypes-order.json'
- }
- attributes.setdefault('tr', {}).update({'data-ams-stop-propagation': 'true'})
- return attributes
-
- @reify
- def values(self):
- return list(super(DatatypeSubtypesTable, self).values)
-
-
-@adapter_config(context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable), provides=IValues)
-class DatatypeSubtypesTableValues(ContextRequestViewAdapter):
- """Data type subtypes table values adapter"""
-
- @property
- def values(self):
- return self.context.values()
-
-
-@adapter_config(name='sorter', context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable), provides=IColumn)
-class DatatypeSubtypesTableSorterColumn(SorterColumn):
- """Data type subtypes table sorter column"""
-
-
-@view_config(name='set-subtypes-order.json', context=IDataType, request_type=IPyAMSLayer,
- permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
-def set_subtypes_order(request):
- """Update subtypes order"""
- order = list(map(str, json.loads(request.params.get('names'))))
- request.context.updateOrder(order)
- return {'status': 'success'}
-
-
-@adapter_config(name='name', context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable), provides=IColumn)
-class DatatypeSubtypesTableNameColumn(NameColumn):
- """Data type subtypes table name column"""
-
- _header = _("Subtype label")
-
- def renderHeadCell(self):
- result = super(DatatypeSubtypesTableNameColumn, self).renderHeadCell()
- registry = self.request.registry
- viewlet = registry.queryMultiAdapter((self.context, self.request, self.table), IViewletManager,
- name='pyams.widget_title')
- if viewlet is not None:
- viewlet.update()
- result += viewlet.render()
- return result
-
-
-@adapter_config(name='paragraphs', context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable),
- provides=IColumn)
-class DatatypeSubtypesTableParagraphsColumn(ActionColumn):
- """Data type subtypes paragraphs column"""
-
- weight = 100
-
- icon_class = 'fa fa-fw fa-paragraph'
- icon_hint = _("Default paragraphs")
-
- url = 'paragraphs-dialog.html'
- modal_target = True
-
- permission = MANAGE_TOOL_PERMISSION
-
-
-@adapter_config(name='associations', context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable),
- provides=IColumn)
-class DatatypeSubtypesTableAssociationsColumn(ActionColumn):
- """Data type subtypes associations column"""
-
- weight = 110
-
- icon_class = 'fa fa-fw fa-link'
- icon_hint = _("Default associations")
-
- url = 'associations-dialog.html'
- modal_target = True
-
- permission = MANAGE_TOOL_PERMISSION
-
-
-@adapter_config(name='trash', context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable), provides=IColumn)
-class DatatypeSubtypesTableTrashColumn(TrashColumn):
- """Data type subtypes table trash column"""
-
- permission = MANAGE_TOOL_PERMISSION
-
-
-@view_config(name='delete-element.json', context=IDataType, request_type=IPyAMSLayer,
- permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
-def delete_subtype(request):
- """Data subtype delete view"""
- return delete_container_element(request, ignore_permission=True)
-
-
-@view_config(name='get-subtypes-table.json', context=ITypedDataManager, request_type=IPyAMSLayer,
- permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
-def get_subtypes_table(request):
- """Get subtypes table"""
- datatype = request.context.get(str(request.params.get('object_name')))
- if datatype is None:
- raise NotFound()
- table = DatatypeSubtypesTable(datatype, request)
- table.update()
- return table.render()
-
-
-#
-# Data sub-types views
-#
-
-@viewlet_config(name='add-data-subtype.action', context=IDataType, layer=IPyAMSLayer,
- view=DatatypeSubtypesTable, manager=IWidgetTitleViewletManager,
- permission=MANAGE_TOOL_PERMISSION, weight=1)
-class DataSubtypeAddAction(ToolbarAction):
- """Data subtype adding action"""
-
- label = _("Add subtype")
- label_css_class = 'fa fa-fw fa-plus'
- url = 'add-data-subtype.html'
- modal_target = True
-
-
-@pagelet_config(name='add-data-subtype.html', context=IDataType, layer=IPyAMSLayer,
- permission=MANAGE_TOOL_PERMISSION)
-@ajax_config(name='add-data-subtype.json', context=IDataType, layer=IPyAMSLayer, base=AJAXAddForm)
-class DataSubtypeAddForm(AdminDialogAddForm):
- """Data subtype add form"""
-
- legend = _("Add new subtype")
- icon_css_class = 'fa fa-fw fa-folder-o'
- label_css_class = 'control-label col-md-4'
- input_css_class = 'col-md-8'
-
- fields = field.Fields(ISubType).omit('__parent__', '__name__')
- fields['pictogram'].widgetFactory = PictogramSelectFieldWidget
-
- edit_permission = MANAGE_TOOL_PERMISSION
-
- def create(self, data):
- return SubType()
-
- def add(self, object):
- name = translate_string(object.name, spaces='-')
- IDataType(self.context)[name] = object
-
- def nextURL(self):
- return absolute_url(self.context, self.request, 'admin#data-types.html')
-
- def get_ajax_output(self, changes):
- return {
- 'status': 'success',
- 'message': self.request.localizer.translate(_("Subtype was correctly added.")),
- 'events': [
- get_json_table_refresh_event(self.context, self.request, DatatypeSubtypesTable)
- ]
- }
-
-
-@subscriber(IDataExtractedEvent, form_selector=DataSubtypeAddForm)
-def handle_subtype_add_form_data_extraction(event):
- """Check new data subtype for existing name"""
- context = event.form.context
- manager = IDataType(context)
- name = event.data.get('name')
- if translate_string(name, spaces='-') in manager:
- event.form.widgets.errors += (Invalid(_("Specified subtype name is already used!")),)
-
-
-@pagelet_config(name='properties.html', context=ISubType, layer=IPyAMSLayer, permission=MANAGE_TOOL_PERMISSION)
-@ajax_config(name='properties.json', context=ISubType, layer=IPyAMSLayer)
-class DataSubtypeEditForm(AdminDialogEditForm):
- """Data subtype edit form"""
-
- prefix = 'subtype_properties.'
-
- legend = _("Data subtype properties")
- icon_css_class = 'fa fa-fw fa-folder-o'
- label_css_class = 'control-label col-md-4'
- input_css_class = 'col-md-8'
-
- fields = field.Fields(ISubType).omit('__parent__', '__name__')
- fields['pictogram'].widgetFactory = PictogramSelectFieldWidget
-
- edit_permission = MANAGE_TOOL_PERMISSION
-
- def updateWidgets(self, prefix=None):
- super(DataSubtypeEditForm, self).updateWidgets(prefix)
- if 'name' in self.widgets:
- self.widgets['name'].mode = DISPLAY_MODE
-
- def get_ajax_output(self, changes):
- if 'label' in changes.get(IBaseDataType, ()):
- target = get_parent(self.context, IDataType)
- return {
- 'status': 'success',
- 'message': self.request.localizer.translate(self.successMessage),
- 'events': [
- get_json_table_refresh_event(target, self.request, DatatypeSubtypesTable)
- ]
- }
- else:
- return super(self.__class__, self).get_ajax_output(changes)
-
-
-#
-# Typed shared content views
-#
-
-class TypedSharedContentAddForm(SharedContentAddForm):
- """Typed shared content add form"""
-
- fields = field.Fields(IWfTypedSharedContent).select('title', 'data_type', 'notepad')
-
- def updateWidgets(self, prefix=None):
- super(TypedSharedContentAddForm, self).updateWidgets(prefix)
- if 'data_type' in self.widgets:
- self.widgets['data_type'].prompt = True
- self.widgets['data_type'].promptMessage = _("Select content type...")
-
-
-@pagelet_config(name='properties.html', context=IWfTypedSharedContent, layer=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION)
-@ajax_config(name='properties.json', context=IWfTypedSharedContent, layer=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION)
-class TypedSharedContentPropertiesEditForm(SharedContentPropertiesEditForm):
- """Typed shared content properties edit form"""
-
- interface = IWfTypedSharedContent
-
- @property
- def fields(self):
- fields = field.Fields(self.interface).select('title', 'short_name', 'content_url',
- 'data_type', 'header', 'description', 'notepad')
- fields['title'].widgetFactory = I18nSEOTextLineFieldWidget
- if not self.context.handle_content_url:
- fields = fields.omit('content_url')
- if not self.context.handle_header:
- fields = fields.omit('header')
- if not self.context.handle_description:
- fields = fields.omit('description')
- return fields
-
-
-#
-# Typed shared content custom fields edit form
-#
-
-@implementer(IWidgetForm, IInnerPage)
-class TypedSharedContentTypeFieldsEditForm(AdminEditForm):
- """Typed shared content type fields properties edit form"""
-
- prefix = 'type_properties.'
-
- @property
- def legend(self):
- translate = self.request.localizer.translate
- data_type = self.context.get_data_type()
- return translate(_("Custom properties for type « {0} »")).format(
- II18n(data_type).query_attribute('label', request=self.request))
-
- @property
- def fields(self):
- data_type = self.context.get_data_type()
- if data_type is not None:
- manager = get_parent(self.context, ITypedSharedTool)
- return field.Fields(manager.shared_content_types_fields).select(*data_type.field_names)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/zmi/types/__init__.py Thu May 23 18:01:42 2019 +0200
@@ -0,0 +1,444 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+import json
+
+from pyramid.decorator import reify
+from pyramid.events import subscriber
+from pyramid.exceptions import NotFound
+from pyramid.view import view_config
+from z3c.form import field
+from z3c.form.interfaces import DISPLAY_MODE, IDataExtractedEvent
+from z3c.table.interfaces import IColumn, IValues
+from zope.interface import Invalid, implementer
+
+from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION, MANAGE_TOOL_PERMISSION
+from pyams_content.reference.pictograms.zmi.widget import PictogramSelectFieldWidget
+from pyams_content.shared.common.interfaces.types import IBaseDataType, IDataType, ISubType, \
+ ITypedDataManager, ITypedSharedTool, IWfTypedSharedContent
+from pyams_content.shared.common.types import DataType, SubType
+from pyams_content.shared.common.zmi import SharedContentAddForm
+from pyams_content.shared.common.zmi.properties import SharedContentPropertiesEditForm
+from pyams_content.shared.common.zmi.types.manager import TypedSharedToolTypesView
+from pyams_form.form import AJAXAddForm, ajax_config
+from pyams_form.interfaces.form import IWidgetForm
+from pyams_i18n.interfaces import II18n
+from pyams_i18n.widget import I18nSEOTextLineFieldWidget
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.container import delete_container_element
+from pyams_skin.event import get_json_table_refresh_event
+from pyams_skin.interfaces import IInnerPage
+from pyams_skin.interfaces.container import ITableElementName
+from pyams_skin.interfaces.viewlet import IWidgetTitleViewletManager
+from pyams_skin.layer import IPyAMSLayer
+from pyams_skin.table import ActionColumn, BaseTable, NameColumn, SorterColumn, TrashColumn
+from pyams_skin.viewlet.toolbar import ToolbarAction
+from pyams_utils.adapter import ContextRequestAdapter, ContextRequestViewAdapter, adapter_config
+from pyams_utils.traversing import get_parent
+from pyams_utils.unicode import translate_string
+from pyams_utils.url import absolute_url
+from pyams_viewlet.interfaces import IViewletManager
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm, AdminEditForm
+from pyams_zmi.layer import IAdminLayer
+
+from pyams_content import _
+
+
+#
+# Data type views
+#
+
+@adapter_config(context=(IBaseDataType, IPyAMSLayer), provides=ITableElementName)
+class DataTypeElementNameAdapter(ContextRequestAdapter):
+ """Types shared tool types name adapter"""
+
+ @property
+ def name(self):
+ return II18n(self.context).query_attribute('label', request=self.request)
+
+
+@viewlet_config(name='add-data-type.action', context=ITypedSharedTool, layer=IAdminLayer,
+ view=TypedSharedToolTypesView, manager=IWidgetTitleViewletManager,
+ permission=MANAGE_TOOL_PERMISSION, weight=1)
+class DataTypeAddAction(ToolbarAction):
+ """Data type adding action"""
+
+ label = _("Add data type")
+ label_css_class = 'fa fa-fw fa-plus'
+ url = 'add-data-type.html'
+ modal_target = True
+
+
+@pagelet_config(name='add-data-type.html', context=ITypedSharedTool, layer=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION)
+@ajax_config(name='add-data-type.json', context=ITypedSharedTool, layer=IPyAMSLayer, base=AJAXAddForm)
+class DataTypeAddForm(AdminDialogAddForm):
+ """Data type add form"""
+
+ legend = _("Add new data type")
+ icon_css_class = 'fa fa-fw fa-folder-o'
+ label_css_class = 'control-label col-md-4'
+ input_css_class = 'col-md-8'
+
+ @property
+ def fields(self):
+ fields = field.Fields(IDataType).omit('__parent__', '__name__')
+ fields['pictogram'].widgetFactory = PictogramSelectFieldWidget
+ if not self.context.shared_content_types_fields:
+ fields = fields.omit('field_names')
+ return fields
+
+ edit_permission = MANAGE_TOOL_PERMISSION
+
+ def create(self, data):
+ return DataType()
+
+ def add(self, object):
+ name = translate_string(object.name, spaces='-')
+ ITypedDataManager(self.context)[name] = object
+
+ def nextURL(self):
+ return '#data-types.html'
+
+
+@subscriber(IDataExtractedEvent, form_selector=DataTypeAddForm)
+def handle_datatype_add_form_data_extraction(event):
+ """Check new data type for existing name"""
+ context = event.form.context
+ manager = ITypedDataManager(context)
+ name = event.data.get('name')
+ if translate_string(name, spaces='-') in manager:
+ event.form.widgets.errors += (Invalid(_("Specified type name is already used!")),)
+
+
+@pagelet_config(name='properties.html', context=IDataType, layer=IPyAMSLayer, permission=MANAGE_TOOL_PERMISSION)
+@ajax_config(name='properties.json', context=IDataType, layer=IPyAMSLayer)
+class DataTypeEditForm(AdminDialogEditForm):
+ """Data type edit form"""
+
+ prefix = 'datatype_properties.'
+
+ legend = _("Data type properties")
+ icon_css_class = 'fa fa-fw fa-folder-o'
+ label_css_class = 'control-label col-md-4'
+ input_css_class = 'col-md-8'
+
+ @property
+ def fields(self):
+ fields = field.Fields(IDataType).omit('__parent__', '__name__')
+ fields['pictogram'].widgetFactory = PictogramSelectFieldWidget
+ tool = get_parent(self.context, ITypedSharedTool)
+ if not tool.shared_content_types_fields:
+ fields = fields.omit('field_names')
+ return fields
+
+ edit_permission = MANAGE_TOOL_PERMISSION
+
+ def updateWidgets(self, prefix=None):
+ super(DataTypeEditForm, self).updateWidgets(prefix)
+ if 'name' in self.widgets:
+ self.widgets['name'].mode = DISPLAY_MODE
+
+
+#
+# Subtypes views
+#
+
+class DatatypeSubtypesTable(BaseTable):
+ """Data type subtypes table"""
+
+ prefix = 'subtypes'
+
+ hide_header = True
+ sortOn = None
+
+ widget_class = 'ams-widget margin-top-5'
+ cssClasses = {'table': 'table table-bordered table-striped table-hover table-tight table-dnd'}
+
+ @property
+ def data_attributes(self):
+ attributes = super(DatatypeSubtypesTable, self).data_attributes
+ attributes['table'] = {
+ 'id': self.id,
+ 'data-ams-location': absolute_url(self.context, self.request),
+ 'data-ams-tablednd-drag-handle': 'td.sorter',
+ 'data-ams-tablednd-drop-target': 'set-subtypes-order.json'
+ }
+ attributes.setdefault('tr', {}).update({'data-ams-stop-propagation': 'true'})
+ return attributes
+
+ @reify
+ def values(self):
+ return list(super(DatatypeSubtypesTable, self).values)
+
+
+@adapter_config(context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable), provides=IValues)
+class DatatypeSubtypesTableValues(ContextRequestViewAdapter):
+ """Data type subtypes table values adapter"""
+
+ @property
+ def values(self):
+ return self.context.values()
+
+
+@adapter_config(name='sorter', context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable), provides=IColumn)
+class DatatypeSubtypesTableSorterColumn(SorterColumn):
+ """Data type subtypes table sorter column"""
+
+
+@view_config(name='set-subtypes-order.json', context=IDataType, request_type=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
+def set_subtypes_order(request):
+ """Update subtypes order"""
+ order = list(map(str, json.loads(request.params.get('names'))))
+ request.context.updateOrder(order)
+ return {'status': 'success'}
+
+
+@adapter_config(name='name', context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable), provides=IColumn)
+class DatatypeSubtypesTableNameColumn(NameColumn):
+ """Data type subtypes table name column"""
+
+ _header = _("Subtype label")
+
+ def renderHeadCell(self):
+ result = super(DatatypeSubtypesTableNameColumn, self).renderHeadCell()
+ registry = self.request.registry
+ viewlet = registry.queryMultiAdapter((self.context, self.request, self.table), IViewletManager,
+ name='pyams.widget_title')
+ if viewlet is not None:
+ viewlet.update()
+ result += viewlet.render()
+ return result
+
+
+@adapter_config(name='paragraphs', context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable),
+ provides=IColumn)
+class DatatypeSubtypesTableParagraphsColumn(ActionColumn):
+ """Data type subtypes paragraphs column"""
+
+ weight = 100
+
+ icon_class = 'fa fa-fw fa-paragraph'
+ icon_hint = _("Default paragraphs")
+
+ url = 'paragraphs-dialog.html'
+ modal_target = True
+
+ permission = MANAGE_TOOL_PERMISSION
+
+
+@adapter_config(name='associations', context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable),
+ provides=IColumn)
+class DatatypeSubtypesTableAssociationsColumn(ActionColumn):
+ """Data type subtypes associations column"""
+
+ weight = 110
+
+ icon_class = 'fa fa-fw fa-link'
+ icon_hint = _("Default associations")
+
+ url = 'associations-dialog.html'
+ modal_target = True
+
+ permission = MANAGE_TOOL_PERMISSION
+
+
+@adapter_config(name='trash', context=(IDataType, IPyAMSLayer, DatatypeSubtypesTable), provides=IColumn)
+class DatatypeSubtypesTableTrashColumn(TrashColumn):
+ """Data type subtypes table trash column"""
+
+ permission = MANAGE_TOOL_PERMISSION
+
+
+@view_config(name='delete-element.json', context=IDataType, request_type=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
+def delete_subtype(request):
+ """Data subtype delete view"""
+ return delete_container_element(request, ignore_permission=True)
+
+
+@view_config(name='get-subtypes-table.json', context=ITypedDataManager, request_type=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
+def get_subtypes_table(request):
+ """Get subtypes table"""
+ datatype = request.context.get(str(request.params.get('object_name')))
+ if datatype is None:
+ raise NotFound()
+ table = DatatypeSubtypesTable(datatype, request)
+ table.update()
+ return table.render()
+
+
+#
+# Data sub-types views
+#
+
+@viewlet_config(name='add-data-subtype.action', context=IDataType, layer=IPyAMSLayer,
+ view=DatatypeSubtypesTable, manager=IWidgetTitleViewletManager,
+ permission=MANAGE_TOOL_PERMISSION, weight=1)
+class DataSubtypeAddAction(ToolbarAction):
+ """Data subtype adding action"""
+
+ label = _("Add subtype")
+ label_css_class = 'fa fa-fw fa-plus'
+ url = 'add-data-subtype.html'
+ modal_target = True
+
+
+@pagelet_config(name='add-data-subtype.html', context=IDataType, layer=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION)
+@ajax_config(name='add-data-subtype.json', context=IDataType, layer=IPyAMSLayer, base=AJAXAddForm)
+class DataSubtypeAddForm(AdminDialogAddForm):
+ """Data subtype add form"""
+
+ legend = _("Add new subtype")
+ icon_css_class = 'fa fa-fw fa-folder-o'
+ label_css_class = 'control-label col-md-4'
+ input_css_class = 'col-md-8'
+
+ fields = field.Fields(ISubType).omit('__parent__', '__name__')
+ fields['pictogram'].widgetFactory = PictogramSelectFieldWidget
+
+ edit_permission = MANAGE_TOOL_PERMISSION
+
+ def create(self, data):
+ return SubType()
+
+ def add(self, object):
+ name = translate_string(object.name, spaces='-')
+ IDataType(self.context)[name] = object
+
+ def nextURL(self):
+ return absolute_url(self.context, self.request, 'admin#data-types.html')
+
+ def get_ajax_output(self, changes):
+ return {
+ 'status': 'success',
+ 'message': self.request.localizer.translate(_("Subtype was correctly added.")),
+ 'events': [
+ get_json_table_refresh_event(self.context, self.request, DatatypeSubtypesTable)
+ ]
+ }
+
+
+@subscriber(IDataExtractedEvent, form_selector=DataSubtypeAddForm)
+def handle_subtype_add_form_data_extraction(event):
+ """Check new data subtype for existing name"""
+ context = event.form.context
+ manager = IDataType(context)
+ name = event.data.get('name')
+ if translate_string(name, spaces='-') in manager:
+ event.form.widgets.errors += (Invalid(_("Specified subtype name is already used!")),)
+
+
+@pagelet_config(name='properties.html', context=ISubType, layer=IPyAMSLayer, permission=MANAGE_TOOL_PERMISSION)
+@ajax_config(name='properties.json', context=ISubType, layer=IPyAMSLayer)
+class DataSubtypeEditForm(AdminDialogEditForm):
+ """Data subtype edit form"""
+
+ prefix = 'subtype_properties.'
+
+ legend = _("Data subtype properties")
+ icon_css_class = 'fa fa-fw fa-folder-o'
+ label_css_class = 'control-label col-md-4'
+ input_css_class = 'col-md-8'
+
+ fields = field.Fields(ISubType).omit('__parent__', '__name__')
+ fields['pictogram'].widgetFactory = PictogramSelectFieldWidget
+
+ edit_permission = MANAGE_TOOL_PERMISSION
+
+ def updateWidgets(self, prefix=None):
+ super(DataSubtypeEditForm, self).updateWidgets(prefix)
+ if 'name' in self.widgets:
+ self.widgets['name'].mode = DISPLAY_MODE
+
+ def get_ajax_output(self, changes):
+ if 'label' in changes.get(IBaseDataType, ()):
+ target = get_parent(self.context, IDataType)
+ return {
+ 'status': 'success',
+ 'message': self.request.localizer.translate(self.successMessage),
+ 'events': [
+ get_json_table_refresh_event(target, self.request, DatatypeSubtypesTable)
+ ]
+ }
+ else:
+ return super(self.__class__, self).get_ajax_output(changes)
+
+
+#
+# Typed shared content views
+#
+
+class TypedSharedContentAddForm(SharedContentAddForm):
+ """Typed shared content add form"""
+
+ fields = field.Fields(IWfTypedSharedContent).select('title', 'data_type', 'notepad')
+
+ def updateWidgets(self, prefix=None):
+ super(TypedSharedContentAddForm, self).updateWidgets(prefix)
+ if 'data_type' in self.widgets:
+ self.widgets['data_type'].prompt = True
+ self.widgets['data_type'].promptMessage = _("Select content type...")
+
+
+@pagelet_config(name='properties.html', context=IWfTypedSharedContent, layer=IPyAMSLayer,
+ permission=MANAGE_CONTENT_PERMISSION)
+@ajax_config(name='properties.json', context=IWfTypedSharedContent, layer=IPyAMSLayer,
+ permission=MANAGE_CONTENT_PERMISSION)
+class TypedSharedContentPropertiesEditForm(SharedContentPropertiesEditForm):
+ """Typed shared content properties edit form"""
+
+ interface = IWfTypedSharedContent
+
+ @property
+ def fields(self):
+ fields = field.Fields(self.interface).select('title', 'short_name', 'content_url',
+ 'data_type', 'header', 'description', 'notepad')
+ fields['title'].widgetFactory = I18nSEOTextLineFieldWidget
+ if not self.context.handle_content_url:
+ fields = fields.omit('content_url')
+ if not self.context.handle_header:
+ fields = fields.omit('header')
+ if not self.context.handle_description:
+ fields = fields.omit('description')
+ return fields
+
+
+#
+# Typed shared content custom fields edit form
+#
+
+@implementer(IWidgetForm, IInnerPage)
+class TypedSharedContentTypeFieldsEditForm(AdminEditForm):
+ """Typed shared content type fields properties edit form"""
+
+ prefix = 'type_properties.'
+
+ @property
+ def legend(self):
+ translate = self.request.localizer.translate
+ data_type = self.context.get_data_type()
+ return translate(_("Custom properties for type « {0} »")).format(
+ II18n(data_type).query_attribute('label', request=self.request))
+
+ @property
+ def fields(self):
+ data_type = self.context.get_data_type()
+ if data_type is not None:
+ manager = get_parent(self.context, ITypedSharedTool)
+ return field.Fields(manager.shared_content_types_fields).select(*data_type.field_names)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/zmi/types/manager.py Thu May 23 18:01:42 2019 +0200
@@ -0,0 +1,209 @@
+#
+# Copyright (c) 2008-2019 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+import json
+
+from pyramid.decorator import reify
+from pyramid.view import view_config
+from z3c.table.interfaces import IColumn, IValues
+
+from pyams_content.interfaces import MANAGE_TOOL_PERMISSION
+from pyams_content.shared.common.interfaces.types import ITypedDataManager, ITypedSharedTool
+from pyams_content.zmi import pyams_content
+from pyams_form.security import ProtectedFormObjectMixin
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.container import delete_container_element
+from pyams_skin.layer import IPyAMSLayer
+from pyams_skin.table import ActionColumn, BaseTable, NameColumn, SorterColumn, TrashColumn
+from pyams_skin.viewlet.menu import MenuItem
+from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
+from pyams_utils.fanstatic import get_resource_path
+from pyams_utils.url import absolute_url
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.interfaces.menu import IPropertiesMenu
+from pyams_zmi.layer import IAdminLayer
+from pyams_zmi.view import ContainerAdminView
+
+from pyams_content import _
+
+
+@viewlet_config(name='data-types.menu', context=ITypedSharedTool, layer=IAdminLayer,
+ manager=IPropertiesMenu, permission=MANAGE_TOOL_PERMISSION, weight=5)
+class TypedSharedToolTypesMenu(MenuItem):
+ """Typed shared tool types menu"""
+
+ label = _("Data types")
+ icon_class = 'fa-folder-o'
+ url = '#data-types.html'
+
+
+#
+# Typed shared data types manager target views
+#
+
+class TypedSharedToolTypesTable(ProtectedFormObjectMixin, BaseTable):
+ """Typed shared tool types table"""
+
+ prefix = 'types'
+
+ hide_header = True
+ sortOn = None
+
+ @property
+ def cssClasses(self):
+ classes = ['table', 'table-bordered', 'table-striped', 'table-hover', 'table-tight']
+ permission = self.permission
+ if (not permission) or self.request.has_permission(permission, self.context):
+ classes.append('table-dnd')
+ return {'table': ' '.join(classes)}
+
+ @property
+ def data_attributes(self):
+ attributes = super(TypedSharedToolTypesTable, self).data_attributes
+ attributes['table'] = {
+ 'id': self.id,
+ 'data-ams-plugins': 'pyams_content',
+ 'data-ams-plugin-pyams_content-src': get_resource_path(pyams_content),
+ 'data-ams-location': absolute_url(ITypedDataManager(self.context), self.request),
+ 'data-ams-tablednd-drag-handle': 'td.sorter',
+ 'data-ams-tablednd-drop-target': 'set-types-order.json'
+ }
+ return attributes
+
+ @reify
+ def values(self):
+ return list(super(TypedSharedToolTypesTable, self).values)
+
+ def render(self):
+ if not self.values:
+ translate = self.request.localizer.translate
+ return translate(_("No currently defined data type."))
+ return super(TypedSharedToolTypesTable, self).render()
+
+
+@adapter_config(context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable), provides=IValues)
+class TypedSharedToolTypesValues(ContextRequestViewAdapter):
+ """Typed shared tool types table values adapter"""
+
+ @property
+ def values(self):
+ return ITypedDataManager(self.context).values()
+
+
+@adapter_config(name='sorter', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
+ provides=IColumn)
+class TypedSharedToolTypesSorterColumn(ProtectedFormObjectMixin, SorterColumn):
+ """Typed shared tool types sorter column"""
+
+
+@view_config(name='set-types-order.json', context=ITypedDataManager, request_type=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
+def set_data_types_order(request):
+ """Update data types order"""
+ order = list(map(str, json.loads(request.params.get('names'))))
+ request.context.updateOrder(order)
+ return {'status': 'success'}
+
+
+@adapter_config(name='name', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
+ provides=IColumn)
+class TypedSharedToolTypesNameColumn(NameColumn):
+ """Typed shared tool types name column"""
+
+ _header = _("Data type label")
+
+ def renderCell(self, item):
+ return '<span data-ams-stop-propagation="true" ' \
+ ' data-ams-click-handler="MyAMS.skin.switchCellContent" ' \
+ ' data-ams-switch-handler="get-subtypes-table.json" ' \
+ ' data-ams-switch-target=".subtypes">' \
+ ' <span class="small hint" title="{hint}" data-ams-hint-gravity="e">' \
+ ' <i class="fa fa-plus-square-o switch"></i>' \
+ ' </span>' \
+ '</span> <span class="title">{title}</span>' \
+ '<div class="inner-table-form subtypes margin-x-10 margin-bottom-0 padding-left-5"></div>'.format(
+ hint=self.request.localizer.translate(_("Click to see subtypes")),
+ title=super(TypedSharedToolTypesNameColumn, self).renderCell(item))
+
+
+@adapter_config(name='paragraphs', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
+ provides=IColumn)
+class TypedSharedToolTypesParagraphsColumn(ActionColumn):
+ """Typed shared tool types paragraphs column"""
+
+ weight = 100
+
+ icon_class = 'fa fa-fw fa-paragraph'
+ icon_hint = _("Default paragraphs")
+
+ url = 'paragraphs-dialog.html'
+ modal_target = True
+
+ permission = MANAGE_TOOL_PERMISSION
+
+
+@adapter_config(name='associations', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
+ provides=IColumn)
+class TypedSharedToolTypesAssociationsColumn(ActionColumn):
+ """Typed shared tool types associations column"""
+
+ weight = 110
+
+ icon_class = 'fa fa-fw fa-link'
+ icon_hint = _("Default associations")
+
+ url = 'associations-dialog.html'
+ modal_target = True
+
+ permission = MANAGE_TOOL_PERMISSION
+
+
+@adapter_config(name='themes', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
+ provides=IColumn)
+class TypedSharedToolTypesThemesColumn(ActionColumn):
+ """Typed shared tool types themes column"""
+
+ weight = 120
+
+ icon_class = 'fa fa-fw fa-tags'
+ icon_hint = _("Default themes")
+
+ url = 'themes-dialog.html'
+ modal_target = True
+
+ permission = MANAGE_TOOL_PERMISSION
+
+
+@adapter_config(name='trash', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
+ provides=IColumn)
+class TypedSharedToolTypesTrashColumn(TrashColumn):
+ """Typed shared tool types trash column"""
+
+ permission = MANAGE_TOOL_PERMISSION
+
+
+@view_config(name='delete-element.json', context=ITypedDataManager, request_type=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
+def delete_data_type(request):
+ """Data type delete view"""
+ return delete_container_element(request, ignore_permission=True)
+
+
+@pagelet_config(name='data-types.html', context=ITypedSharedTool, layer=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION)
+class TypedSharedToolTypesView(ContainerAdminView):
+ """Typed shared tool types view"""
+
+ title = _("Content data types")
+ table_class = TypedSharedToolTypesTable