--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/zmi/types.py Fri Nov 10 12:07:43 2017 +0100
@@ -0,0 +1,577 @@
+#
+# 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 standard library
+import json
+
+# import interfaces
+from pyams_content.interfaces import MANAGE_TOOL_PERMISSION
+from pyams_content.shared.common.interfaces.types import ITypedSharedTool, ITypedDataManager, \
+ IBaseDataType, IDataType, ISubType
+from pyams_i18n.interfaces import II18n
+from pyams_skin.interfaces.container import ITableElementName
+from pyams_skin.interfaces.viewlet import IWidgetTitleViewletManager
+from pyams_skin.layer import IPyAMSLayer
+from pyams_viewlet.interfaces import IViewletManager
+from pyams_zmi.interfaces.menu import IPropertiesMenu
+from pyams_zmi.layer import IAdminLayer
+from z3c.form.interfaces import DISPLAY_MODE, IDataExtractedEvent
+from z3c.table.interfaces import IValues, IColumn
+
+# import packages
+from pyams_content.shared.common.types import DataType, SubType
+from pyams_form.form import AJAXAddForm, AJAXEditForm
+from pyams_form.security import ProtectedFormObjectMixin
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.table import BaseTable, SorterColumn, TrashColumn, NameColumn, ActionColumn
+from pyams_skin.viewlet.menu import MenuItem
+from pyams_skin.viewlet.toolbar import ToolbarAction
+from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter, ContextRequestAdapter
+from pyams_utils.traversing import get_parent
+from pyams_utils.unicode import translate_string
+from pyams_utils.url import absolute_url
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
+from pyams_zmi.view import ContainerAdminView
+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 zope.interface import Invalid
+
+from pyams_content import _
+
+
+@viewlet_config(name='data-types.menu', context=ITypedSharedTool, layer=IAdminLayer,
+ manager=IPropertiesMenu, permission=MANAGE_TOOL_PERMISSION, weight=20)
+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"""
+
+ id = 'types_list'
+ 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':
+ '/--static--/pyams_content/js/pyams_content{MyAMS.devext}.js',
+ '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"""
+
+
+@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="PyAMS_content.types.switchSubtypes">' \
+ ' <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='trash', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
+ provides=IColumn)
+class TypedSharedToolTypesTrashColumn(TrashColumn):
+ """Typed shared tool types trash column"""
+
+ permission = MANAGE_TOOL_PERMISSION
+
+
+@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
+
+
+#
+# Typed shared data types manager views
+#
+
+@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"""
+ translate = request.localizer.translate
+ name = request.params.get('object_name')
+ if not name:
+ return {'status': 'message',
+ 'messagebox': {'status': 'error',
+ 'content': translate(_("No provided object_name argument!"))}}
+ if name not in request.context:
+ return {'status': 'message',
+ 'messagebox': {'status': 'error',
+ 'content': translate(_("Given data type doesn't exist!"))}}
+ del request.context[name]
+ return {'status': 'success'}
+
+
+@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'}
+
+
+#
+# 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)
+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'
+
+ fields = field.Fields(IDataType).omit('__parent__', '__name__')
+
+ ajax_handler = 'add-data-type.json'
+ 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 absolute_url(self.context, self.request, 'admin#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!")),)
+
+
+@view_config(name='add-data-type.json', context=ITypedSharedTool, request_type=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
+class DataTypeAJAXAddForm(AJAXAddForm, DataTypeAddForm):
+ """Data type add form, JSON renderer"""
+
+ def nextURL(self):
+ return '#data-types.html'
+
+
+@pagelet_config(name='properties.html', context=IDataType, layer=IPyAMSLayer, permission=MANAGE_TOOL_PERMISSION)
+class DataTypeEditForm(AdminDialogEditForm):
+ """Data type edit form"""
+
+ 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'
+
+ fields = field.Fields(IDataType).omit('__parent__', '__name__')
+
+ ajax_handler = 'properties.json'
+ 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
+
+
+@view_config(name='properties.json', context=IDataType, request_type=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
+class DataTypeAJAXEditForm(AJAXEditForm, DataTypeEditForm):
+ """Data type edit form, JSON renderer"""
+
+
+#
+# Subtypes views
+#
+
+class DatatypeSubtypesTable(BaseTable):
+ """Data type subtypes table"""
+
+ @property
+ def id(self):
+ return 'subtypes_{0}_list'.format(self.context.__name__)
+
+ 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-plugins': 'pyams_content',
+ 'data-ams-plugin-pyams_content-src':
+ '/--static--/pyams_content/js/pyams_content{MyAMS.devext}.js',
+ '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', {}).setdefault('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"""
+
+
+@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='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()
+
+
+@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'}
+
+
+@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"""
+ translate = request.localizer.translate
+ name = request.params.get('object_name')
+ if not name:
+ return {'status': 'message',
+ 'messagebox': {'status': 'error',
+ 'content': translate(_("No provided object_name argument!"))}}
+ if name not in request.context:
+ return {'status': 'message',
+ 'messagebox': {'status': 'error',
+ 'content': translate(_("Given data subtype doesn't exist!"))}}
+ del request.context[name]
+ return {'status': 'success'}
+
+
+#
+# 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)
+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__')
+
+ ajax_handler = 'add-data-subtype.json'
+ 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')
+
+
+@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!")),)
+
+
+@view_config(name='add-data-subtype.json', context=IDataType, request_type=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
+class DataSubtypeAJAXAddForm(AJAXAddForm, DataSubtypeAddForm):
+ """Data subtype add form, JSON renderer"""
+
+ def get_ajax_output(self, changes):
+ subtypes_table = DatatypeSubtypesTable(self.context, self.request)
+ subtypes_table.update()
+ return {'status': 'success',
+ 'message': self.request.localizer.translate(_("Subtype was correctly added.")),
+ 'events': [{
+ 'event': 'PyAMS_content.changed_item',
+ 'options': {
+ 'handler': 'PyAMS_content.types.refreshSubtypes',
+ 'object_name': subtypes_table.id,
+ 'table': subtypes_table.render()
+ }
+ }]}
+
+
+@pagelet_config(name='properties.html', context=ISubType, layer=IPyAMSLayer, permission=MANAGE_TOOL_PERMISSION)
+class DataSubtypeEditForm(AdminDialogEditForm):
+ """Data subtype edit form"""
+
+ 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__')
+
+ ajax_handler = 'properties.json'
+ 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
+
+
+@view_config(name='properties.json', context=ISubType, request_type=IPyAMSLayer,
+ permission=MANAGE_TOOL_PERMISSION, renderer='json', xhr=True)
+class DataSubtypeAJAXEditForm(AJAXEditForm, DataSubtypeEditForm):
+ """Data subtype edit form, JSON renderer"""
+
+ def get_ajax_output(self, changes):
+ if 'label' in changes.get(IBaseDataType, ()):
+ target = get_parent(self.context, IDataType)
+ subtypes_table = DatatypeSubtypesTable(target, self.request)
+ subtypes_table.update()
+ return {'status': 'success',
+ 'message': self.request.localizer.translate(self.successMessage),
+ 'events': [{
+ 'event': 'PyAMS_content.changed_item',
+ 'options': {
+ 'handler': 'PyAMS_content.types.refreshSubtypes',
+ 'object_name': subtypes_table.id,
+ 'table': subtypes_table.render()
+ }
+ }]}
+ else:
+ return super(DataSubtypeAJAXEditForm, self).get_ajax_output(changes)
--- a/src/pyams_content/skin/resources/js/pyams_content.min.js Fri Nov 10 12:07:09 2017 +0100
+++ b/src/pyams_content/skin/resources/js/pyams_content.min.js Fri Nov 10 12:07:43 2017 +0100
@@ -1,1 +1,1 @@
-(function(c,b){var e=b.MyAMS;var d={refreshForm:function(g){var f=c("#"+g.object_name);f.replaceWith(c(g.form));f=c("#"+g.object_name);e.initContent(f);return f},refreshTable:function(f){var g=c("#"+f.object_name).parent(".ams-widget");g.replaceWith(c(f.table));g=c("#"+f.object_name).parent(".ams-widget");e.initContent(g);return g},TinyMCE:{initEditor:function(f){f.image_list=d.TinyMCE.getImagesList;f.link_list=d.TinyMCE.getLinksList;return f},getImagesList:function(i){var f=c(document.activeElement).parents("form");if(f.exists()){var g=f.attr("data-ams-form-handler")||f.attr("action");var h=g.substr(0,g.lastIndexOf("/")+1);return e.ajax.post(h+"get-images-list.json",{},i)}},getLinksList:function(i){var f=c(document.activeElement).parents("form");if(f.exists()){var g=f.attr("data-ams-form-handler")||f.attr("action");var h=g.substr(0,g.lastIndexOf("/")+1);return e.ajax.post(h+"get-links-list.json",{},i)}}},profile:{switchFavorite:function(){var g=c(this);var f=g.data("sequence-oid");e.ajax.post("switch-user-favorite.json",{oid:f},function(h,i){if(h.favorite){g.removeClass("fa-star-o").addClass("fa-star")}else{g.removeClass("fa-star").addClass("fa-star-o")}})}},galleries:{updateImageTitle:function(f){c('img[id="'+f.image_id+'"]').attr("original-title",f.title)},switchImageVisibility:function(f){return function(){var h=c(this);var i=h.parents(".image");var g=i.parents(".gallery");e.ajax.post(g.data("ams-location")+"/set-image-visibility.json",{object_name:i.data("ams-element-name")},function(j,k){if(j.visible){c("i",h).attr("class","fa fa-fw fa-eye");h.parents(".btn-group").siblings("a.fancyimg").removeClass("not-visible")}else{c("i",h).attr("class","fa fa-fw fa-eye-slash text-danger");h.parents(".btn-group").siblings("a.fancyimg").addClass("not-visible")}})}},setOrder:function(h,i){if(i&&i.item.hasClass("already-dropped")){return}var f=i.item.parents(".gallery");var g=c(".image",f).listattr("data-ams-element-name");e.ajax.post(f.data("ams-location")+"/set-images-order.json",{images:JSON.stringify(g)})},removeFile:function(f){return function(){var g=c(this);e.skin.bigBox({title:e.i18n.WARNING,content:'<i class="text-danger fa fa-2x fa-bell shake animated"></i> '+e.i18n.DELETE_WARNING,buttons:e.i18n.BTN_OK_CANCEL},function(k){if(k===e.i18n.BTN_OK){var j=g.parents(".gallery");var i=j.data("ams-location");var l=g.parents(".image");var h=l.data("ams-element-name");e.ajax.post(i+"/delete-element.json",{object_name:h},function(m,n){l.remove()})}})}},afterFancyboxLoad:function(h,g){var f=h.element;if(f.hasClass("not-visible")){h.inner.prepend('<div class="hidden-mask"></div>')}}},imgmap:{init:function(){var f=c(this);e.ajax.check(c.fn.canvasAreaDraw,"/--static--/pyams_content/js/jquery-canvasAreaDraw"+e.devext+".js",function(){f.canvasAreaDraw({imageUrl:f.data("ams-image-url")})})},initSummary:function(){var f=c(this);e.ajax.check(c.fn.mapster,"/--static--/pyams_content/js/jquery-imagemapster-1.2.10"+e.devext+".js",function(){f.mapster({fillColor:"ff0000",fillOpacity:0.35,selected:true,highlight:true,staticState:true})})}},associations:{refreshAssociations:function(f){var h=d.refreshTable(f);var g=h.siblings("legend");if(g.parents("fieldset:first").hasClass("switched")){g.click()}},switchVisibility:function(f){return function(){var i=c(this);var h=i.parents("tr");var g=h.parents("table");e.ajax.post(g.data("ams-location")+"/set-association-visibility.json",{object_name:h.data("ams-element-name")},function(j,k){if(j.visible){c("i",i).attr("class","fa fa-fw fa-eye")}else{c("i",i).attr("class","fa fa-fw fa-eye-slash text-danger")}})}}},paragraphs:{preReload:function(){d.paragraphs.switched=c("i.switch.fa-minus-square-o","#paragraphs_list").parents("tr").listattr("id")},postReload:function(){c(d.paragraphs.switched).each(function(){c("i.switch.fa-plus-square-o",'[id="'+this+'"]').parents("div:first").click()});delete d.paragraphs.switched},switchVisibility:function(f){return function(){var i=c(this);var g=i.parents("tr");var h=g.parents("table");e.ajax.post(h.data("ams-location")+"/set-paragraph-visibility.json",{object_name:g.data("ams-element-name")},function(j,k){if(j.visible){c("i",i).attr("class","fa fa-fw fa-eye")}else{c("i",i).attr("class","fa fa-fw fa-eye-slash text-danger")}})}},refreshParagraph:function(h){var g=c('table[id="paragraphs_list"]');var f=c('tr[data-ams-element-name="'+h.object_name+'"]',g);c("span.title",f).html(h.title||" - - - - - - - -")},switchEditor:function(h){var k=c(this);var j=c("i.switch",k);var l=k.parents("td");var i=c(".editor",l);var f=k.parents("tr");if(j.hasClass("fa-plus-square-o")){var g=f.parents("table");i.html('<h1 class="loading"><i class="fa fa-2x fa-gear fa-spin"></i></h1>');e.ajax.post(g.data("ams-location")+"/get-paragraph-editor.json",{object_name:f.data("ams-element-name")},function(m){i.html(m);if(m){e.initContent(i);j.removeClass("fa-plus-square-o").addClass("fa-minus-square-o");f.data("ams-disabled-handlers",true)}})}else{e.skin.cleanContainer(i);i.empty();j.removeClass("fa-minus-square-o").addClass("fa-plus-square-o");f.removeData("ams-disabled-handlers")}},switchAllEditors:function(g){var i=c(this);var h=c("i",i);var f=i.parents("table");if(h.hasClass("fa-plus-square-o")){h.removeClass("fa-plus-square-o").addClass("fa-cog fa-spin");e.ajax.post(f.data("ams-location")+"/get-paragraphs-editors.json",{},function(k){for(var l in k){if(!k.hasOwnProperty(l)){continue}var j=c('tr[data-ams-element-name="'+l+'"]',f);var m=c(".editor",j);if(m.is(":empty")){m.html(k[l]);e.initContent(m)}c(".fa-plus-square-o",j).removeClass("fa-plus-square-o").addClass("fa-minus-square-o");j.data("ams-disabled-handlers",true)}if(!c("i.fa-plus-square-o",c("tbody",f)).exists()){h.removeClass("fa-cog fa-spin").addClass("fa-minus-square-o")}})}else{c(".editor",f).each(function(){e.skin.cleanContainer(c(this));c(this).empty()});c(".fa-minus-square-o",f).removeClass("fa-minus-square-o").addClass("fa-plus-square-o");c("tr",f).removeData("ams-disabled-handlers")}},updateToolbar:function(h){var g=c('table[id="paragraphs_list"]');var f=c('tr[data-ams-element-name="'+h.object_name+'"]',g);var i=c(".title-toolbar",f);i.replaceWith(h.toolbar_tag);i=c(".title-toolbar",f);e.initContent(i)},updateMarkers:function(i){var h=c('table[id="paragraphs_list"]');var f=c('tr[data-ams-element-name="'+i.object_name+'"]',h);var j=c(".title-toolbar",f);var g=c("DIV.action."+i.marker_type,j);if(g.exists()){g.replaceWith(i.marker_tag)}else{c(i.marker_tag).appendTo(j)}if(i.marker_tag){g=c("DIV.action."+i.marker_type,j);e.initContent(g)}e.helpers.sort(j,"weight")}},illustration:{addIllustration:function(){var g=c(this);var h=g.parents(".btn-group");var f=h.siblings("legend.switcher");c("i.fa-plus",f).click();g.hide()}},fields:{refreshField:function(h){var g=c('table[id="form_fields_list"]');var f=c('tr[data-ams-element-name="'+h.object_name+'"]',g);c("td:nth-child(4)",f).html(h.title)},switchVisibility:function(f){return function(){var i=c(this);var h=i.parents("tr");var g=h.parents("table");e.ajax.post(g.data("ams-location")+"/set-form-field-visibility.json",{object_name:h.data("ams-element-name")},function(j,k){if(j.visible){c("i",i).attr("class","fa fa-fw fa-eye")}else{c("i",i).attr("class","fa fa-fw fa-eye-slash text-danger")}})}}},themes:{initExtracts:function(h){var g=c('select[name="form.widgets.thesaurus_name:list"]',h);var f=g.val();var j=c('select[name="form.widgets.extract_name:list"]',h);var i=j.val();if(f){e.jsonrpc.post("getExtracts",{thesaurus_name:f},{url:"/api/thesaurus/json"},function(k){j.empty();c(k.result).each(function(){c("<option></option>").attr("value",this.id).attr("selected",this.id===i).text(this.text).appendTo(j)})})}j.attr("data-ams-events-handlers",'{"select2-open": "PyAMS_content.themes.getExtracts"}')},getExtracts:function(i){var f=c(i.currentTarget);var h=f.parents("form");var g=c('select[name="form.widgets.thesaurus_name:list"]',h).val();if(g){e.jsonrpc.post("getExtracts",{thesaurus_name:g},{url:"/api/thesaurus/json"},function(l){var k=c('select[name="form.widgets.extract_name:list"]',h);var j=k.data("select2");j.results.empty();j.opts.populateResults.call(j,j.results,l.result,{term:""})})}}},review:{timer:null,timer_duration:{general:30000,chat:5000},initComments:function(g){var f=c(".chat-body",g);f.animate({scrollTop:f[0].scrollHeight},1000);clearInterval(d.review.timer);d.review.timer=setInterval(d.review.updateComments,d.review.timer_duration.chat);e.skin.registerCleanCallback(d.review.cleanCommentsCallback)},cleanCommentsCallback:function(){clearInterval(d.review.timer);d.review.timer=setInterval(d.review.updateComments,d.review.timer_duration.general)},updateComments:function(){var f=c(".badge",'nav a[href="#review-comments.html"]'),h;var g=c(".chat-body",".widget-body");if(g.exists()){h=c(".message",g).length}else{h=parseInt(f.text())}e.ajax.post("get-last-review-comments.json",{count:h},function(i){if(g.exists()){f.removeClass("bg-color-danger").addClass("bg-color-info")}if(h!==i.count){f.text(i.count).removeClass("hidden");if(g.exists()){c(".messages",g).append(i.content);g.animate({scrollTop:g[0].scrollHeight},1000)}if(!g.exists()){f.removeClass("bg-color-info").addClass("bg-color-danger").animate({padding:"3px 12px 2px","margin-right":"9px"},"slow",function(){c(this).animate({padding:"3px 6px 2px","margin-right":"15px"},"slow")})}}})},initCommentData:function(f){var g=c(".chat-body",".widget-body");return{count:c(".message",g).length}},addCommentAction:function(){return function(){c('textarea[name="comment"]').focus()}},addCommentCallback:function(g){var h=c(this);var i=h.parents(".widget-body");c(".messages",i).append(g.content);c('textarea[name="comment"]',h).val("");var f=c(".chat-body",i);f.animate({scrollTop:f[0].scrollHeight},1000);c(".badge",'nav a[href="#review-comments.html"]').text(g.count).removeClass("hidden")}}};b.PyAMS_content=d;c(b.document).on("PyAMS_content.changed_item",function(g,f){e.executeFunctionByName(f.handler,document,f)});var a=c(".badge",'nav a[href="#review-comments.html"]');if(a.exists()){d.review.timer=setInterval(d.review.updateComments,d.review.timer_duration.general)}})(jQuery,this);
\ No newline at end of file
+!function(a,e){"use strict";var t=e.MyAMS,s={refreshForm:function(e){var s=a("#"+e.object_name);return s.replaceWith(a(e.form)),s=a("#"+e.object_name),t.initContent(s),s},refreshTable:function(e){var s=a("#"+e.object_name).parent(".ams-widget");return s.replaceWith(a(e.table)),s=a("#"+e.object_name).parent(".ams-widget"),t.initContent(s),s},TinyMCE:{initEditor:function(a){return a.image_list=s.TinyMCE.getImagesList,a.link_list=s.TinyMCE.getLinksList,a},getImagesList:function(e){var s=a(document.activeElement).parents("form");if(s.exists()){var n=s.attr("data-ams-form-handler")||s.attr("action"),i=n.substr(0,n.lastIndexOf("/")+1);return t.ajax.post(i+"get-images-list.json",{},e)}},getLinksList:function(e){var s=a(document.activeElement).parents("form");if(s.exists()){var n=s.attr("data-ams-form-handler")||s.attr("action"),i=n.substr(0,n.lastIndexOf("/")+1);return t.ajax.post(i+"get-links-list.json",{},e)}}},profile:{switchFavorite:function(){var e=a(this),s=e.data("sequence-oid");t.ajax.post("switch-user-favorite.json",{oid:s},function(a,t){a.favorite?e.removeClass("fa-star-o").addClass("fa-star"):e.removeClass("fa-star").addClass("fa-star-o")})}},galleries:{updateImageTitle:function(e){a('img[id="'+e.image_id+'"]').attr("original-title",e.title)},switchImageVisibility:function(e){return function(){var e=a(this),s=e.parents(".image"),n=s.parents(".gallery");t.ajax.post(n.data("ams-location")+"/set-image-visibility.json",{object_name:s.data("ams-element-name")},function(t,s){t.visible?(a("i",e).attr("class","fa fa-fw fa-eye"),e.parents(".btn-group").siblings("a.fancyimg").removeClass("not-visible")):(a("i",e).attr("class","fa fa-fw fa-eye-slash text-danger"),e.parents(".btn-group").siblings("a.fancyimg").addClass("not-visible"))})}},setOrder:function(e,s){if(!s||!s.item.hasClass("already-dropped")){var n=s.item.parents(".gallery"),i=a(".image",n).listattr("data-ams-element-name");t.ajax.post(n.data("ams-location")+"/set-images-order.json",{images:JSON.stringify(i)})}},removeFile:function(e){return function(){var e=a(this);t.skin.bigBox({title:t.i18n.WARNING,content:'<i class="text-danger fa fa-2x fa-bell shake animated"></i> '+t.i18n.DELETE_WARNING,buttons:t.i18n.BTN_OK_CANCEL},function(a){if(a===t.i18n.BTN_OK){var s=e.parents(".gallery").data("ams-location"),n=e.parents(".image"),i=n.data("ams-element-name");t.ajax.post(s+"/delete-element.json",{object_name:i},function(a,e){n.remove()})}})}},afterFancyboxLoad:function(a,e){a.element.hasClass("not-visible")&&a.inner.prepend('<div class="hidden-mask"></div>')}},imgmap:{init:function(){var e=a(this);t.ajax.check(a.fn.canvasAreaDraw,"/--static--/pyams_content/js/jquery-canvasAreaDraw"+t.devext+".js",function(){e.canvasAreaDraw({imageUrl:e.data("ams-image-url")})})},initSummary:function(){var e=a(this);t.ajax.check(a.fn.mapster,"/--static--/pyams_content/js/jquery-imagemapster-1.2.10"+t.devext+".js",function(){e.mapster({fillColor:"ff0000",fillOpacity:.35,selected:!0,highlight:!0,staticState:!0})})}},associations:{refreshAssociations:function(a){var e=s.refreshTable(a).siblings("legend");e.parents("fieldset:first").hasClass("switched")&&e.click()},switchVisibility:function(e){return function(){var e=a(this),s=e.parents("tr"),n=s.parents("table");t.ajax.post(n.data("ams-location")+"/set-association-visibility.json",{object_name:s.data("ams-element-name")},function(t,s){t.visible?a("i",e).attr("class","fa fa-fw fa-eye"):a("i",e).attr("class","fa fa-fw fa-eye-slash text-danger")})}}},types:{switchSubtypes:function(e){var s=a(this),n=a("i.switch",s),i=s.parents("td"),r=a(".subtypes",i),o=s.parents("tr");if(n.hasClass("fa-plus-square-o")){var l=o.parents("table");r.html('<h1 class="loading"><i class="fa fa-2x fa-gear fa-spin"></i></h1>'),t.ajax.post(l.data("ams-location")+"/get-subtypes-table.json",{object_name:o.data("ams-element-name")},function(a){r.html(a),a&&(t.initContent(r),n.removeClass("fa-plus-square-o").addClass("fa-minus-square-o"))})}else t.skin.cleanContainer(r),r.empty(),n.removeClass("fa-minus-square-o").addClass("fa-plus-square-o")},refreshSubtypes:function(a){s.refreshTable(a)}},paragraphs:{preReload:function(){s.paragraphs.switched=a("i.switch.fa-minus-square-o","#paragraphs_list").parents("tr").listattr("id")},postReload:function(){a(s.paragraphs.switched).each(function(){a("i.switch.fa-plus-square-o",'[id="'+this+'"]').parents("div:first").click()}),delete s.paragraphs.switched},switchVisibility:function(e){return function(){var e=a(this),s=e.parents("tr"),n=s.parents("table");t.ajax.post(n.data("ams-location")+"/set-paragraph-visibility.json",{object_name:s.data("ams-element-name")},function(t,s){t.visible?a("i",e).attr("class","fa fa-fw fa-eye"):a("i",e).attr("class","fa fa-fw fa-eye-slash text-danger")})}},refreshParagraphs:function(a){var e=s.refreshTable(a).siblings("legend");e.parents("fieldset:first").hasClass("switched")&&e.click()},refreshParagraph:function(e){var t=a('table[id="paragraphs_list"]'),s=a('tr[data-ams-element-name="'+e.object_name+'"]',t);a("span.title",s).html(e.title||" - - - - - - - -")},switchEditor:function(e){var s=a(this),n=a("i.switch",s),i=s.parents("td"),r=a(".editor",i),o=s.parents("tr");if(n.hasClass("fa-plus-square-o")){var l=o.parents("table");r.html('<h1 class="loading"><i class="fa fa-2x fa-gear fa-spin"></i></h1>'),t.ajax.post(l.data("ams-location")+"/get-paragraph-editor.json",{object_name:o.data("ams-element-name")},function(a){r.html(a),a&&(t.initContent(r),n.removeClass("fa-plus-square-o").addClass("fa-minus-square-o"),o.data("ams-disabled-handlers",!0))})}else t.skin.cleanContainer(r),r.empty(),n.removeClass("fa-minus-square-o").addClass("fa-plus-square-o"),o.removeData("ams-disabled-handlers")},switchAllEditors:function(e){var s=a(this),n=a("i",s),i=s.parents("table");n.hasClass("fa-plus-square-o")?(n.removeClass("fa-plus-square-o").addClass("fa-cog fa-spin"),t.ajax.post(i.data("ams-location")+"/get-paragraphs-editors.json",{},function(e){for(var s in e)if(e.hasOwnProperty(s)){var r=a('tr[data-ams-element-name="'+s+'"]',i),o=a(".editor",r);o.is(":empty")&&(o.html(e[s]),t.initContent(o)),a(".fa-plus-square-o",r).removeClass("fa-plus-square-o").addClass("fa-minus-square-o"),r.data("ams-disabled-handlers",!0)}a("i.fa-plus-square-o",a("tbody",i)).exists()||n.removeClass("fa-cog fa-spin").addClass("fa-minus-square-o")})):(a(".editor",i).each(function(){t.skin.cleanContainer(a(this)),a(this).empty()}),a(".fa-minus-square-o",i).removeClass("fa-minus-square-o").addClass("fa-plus-square-o"),a("tr",i).removeData("ams-disabled-handlers"))},updateToolbar:function(e){var s=a('table[id="paragraphs_list"]'),n=a('tr[data-ams-element-name="'+e.object_name+'"]',s),i=a(".title-toolbar",n);i.replaceWith(e.toolbar_tag),i=a(".title-toolbar",n),t.initContent(i)},updateMarkers:function(e){var s=a('table[id="paragraphs_list"]'),n=a('tr[data-ams-element-name="'+e.object_name+'"]',s),i=a(".title-toolbar",n),r=a("DIV.action."+e.marker_type,i);r.exists()?r.replaceWith(e.marker_tag):a(e.marker_tag).appendTo(i),e.marker_tag&&(r=a("DIV.action."+e.marker_type,i),t.initContent(r)),t.helpers.sort(i,"weight")}},illustration:{addIllustration:function(){var e=a(this),t=e.parents(".btn-group").siblings("legend.switcher");a("i.fa-plus",t).click(),e.hide()}},fields:{refreshField:function(e){var t=a('table[id="form_fields_list"]'),s=a('tr[data-ams-element-name="'+e.object_name+'"]',t);a("td:nth-child(4)",s).html(e.title)},switchVisibility:function(e){return function(){var e=a(this),s=e.parents("tr"),n=s.parents("table");t.ajax.post(n.data("ams-location")+"/set-form-field-visibility.json",{object_name:s.data("ams-element-name")},function(t,s){t.visible?a("i",e).attr("class","fa fa-fw fa-eye"):a("i",e).attr("class","fa fa-fw fa-eye-slash text-danger")})}}},themes:{initExtracts:function(e){var s=a('select[name="form.widgets.thesaurus_name:list"]',e).val(),n=a('select[name="form.widgets.extract_name:list"]',e),i=n.val();s&&t.jsonrpc.post("getExtracts",{thesaurus_name:s},{url:"/api/thesaurus/json"},function(e){n.empty(),a(e.result).each(function(){a("<option></option>").attr("value",this.id).attr("selected",this.id===i).text(this.text).appendTo(n)})}),n.attr("data-ams-events-handlers",'{"select2-open": "PyAMS_content.themes.getExtracts"}')},getExtracts:function(e){var s=a(e.currentTarget).parents("form"),n=a('select[name="form.widgets.thesaurus_name:list"]',s).val();n&&t.jsonrpc.post("getExtracts",{thesaurus_name:n},{url:"/api/thesaurus/json"},function(e){var t=a('select[name="form.widgets.extract_name:list"]',s).data("select2");t.results.empty(),t.opts.populateResults.call(t,t.results,e.result,{term:""})})}},review:{timer:null,timer_duration:{general:3e4,chat:5e3},initComments:function(e){var n=a(".chat-body",e);n.animate({scrollTop:n[0].scrollHeight},1e3),clearInterval(s.review.timer),s.review.timer=setInterval(s.review.updateComments,s.review.timer_duration.chat),t.skin.registerCleanCallback(s.review.cleanCommentsCallback)},cleanCommentsCallback:function(){clearInterval(s.review.timer),s.review.timer=setInterval(s.review.updateComments,s.review.timer_duration.general)},updateComments:function(){var e,s=a(".badge",'nav a[href="#review-comments.html"]'),n=a(".chat-body",".widget-body");e=n.exists()?a(".message",n).length:parseInt(s.text()),t.ajax.post("get-last-review-comments.json",{count:e},function(t){n.exists()&&s.removeClass("bg-color-danger").addClass("bg-color-info"),e!==t.count&&(s.text(t.count).removeClass("hidden"),n.exists()&&(a(".messages",n).append(t.content),n.animate({scrollTop:n[0].scrollHeight},1e3)),n.exists()||s.removeClass("bg-color-info").addClass("bg-color-danger").animate({padding:"3px 12px 2px","margin-right":"9px"},"slow",function(){a(this).animate({padding:"3px 6px 2px","margin-right":"15px"},"slow")}))})},initCommentData:function(e){var t=a(".chat-body",".widget-body");return{count:a(".message",t).length}},addCommentAction:function(){return function(){a('textarea[name="comment"]').focus()}},addCommentCallback:function(e){var t=a(this),s=t.parents(".widget-body");a(".messages",s).append(e.content),a('textarea[name="comment"]',t).val("");var n=a(".chat-body",s);n.animate({scrollTop:n[0].scrollHeight},1e3),a(".badge",'nav a[href="#review-comments.html"]').text(e.count).removeClass("hidden")}}};e.PyAMS_content=s,a(e.document).on("PyAMS_content.changed_item",function(a,e){t.executeFunctionByName(e.handler,document,e)}),a(".badge",'nav a[href="#review-comments.html"]').exists()&&(s.review.timer=setInterval(s.review.updateComments,s.review.timer_duration.general))}(jQuery,this);