> Test_Deleted;
+
public class TestEventArgs : CancellableObjectEventArgs
{
public TestEventArgs(object eventObject) : base(eventObject)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js
index d98246ac42..556019857b 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js
@@ -77,7 +77,7 @@
@param {string} icon (binding): The node icon.
@param {string} name (binding): The node name.
-@param {boolean} published (binding): The node pusblished state.
+@param {boolean} published (binding): The node published state.
@param {string} description (binding): A short description.
@param {boolean} sortable (binding): Will add a move cursor on the node preview. Can used in combination with ui-sortable.
@param {boolean} allowRemove (binding): Show/Hide the remove button.
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbpasswordtoggle.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbpasswordtoggle.directive.js
index d75b9e2de0..aac1b8dac1 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbpasswordtoggle.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbpasswordtoggle.directive.js
@@ -1,4 +1,15 @@
-(function () {
+/**
+@ngdoc directive
+@name umbraco.directives.directive:umbPasswordToggle
+@restrict E
+@scope
+
+@description
+Added in Umbraco v. 7.7.4: Use this directive to render a password toggle.
+
+**/
+
+(function () {
'use strict';
// comes from https://codepen.io/jakob-e/pen/eNBQaP
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtable.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtable.directive.js
index 17d4dd93ff..c45a9f78e5 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtable.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtable.directive.js
@@ -1,3 +1,114 @@
+/**
+@ngdoc directive
+@name umbraco.directives.directive:umbTable
+@restrict E
+@scope
+
+@description
+Added in Umbraco v. 7.4: Use this directive to render a data table.
+
+Markup example
+
+
+
+
+
+
+
+
+
+Controller example
+
+ (function () {
+ "use strict";
+
+ function Controller() {
+
+ var vm = this;
+
+ vm.items = [
+ {
+ "icon": "icon-document",
+ "name": "My node 1",
+ "published": true,
+ "description": "A short description of my node",
+ "author": "Author 1"
+ },
+ {
+ "icon": "icon-document",
+ "name": "My node 2",
+ "published": true,
+ "description": "A short description of my node",
+ "author": "Author 2"
+ }
+ ];
+
+ vm.options = {
+ includeProperties: [
+ { alias: "description", header: "Description" },
+ { alias: "author", header: "Author" }
+ ]
+ };
+
+ vm.selectItem = selectItem;
+ vm.clickItem = clickItem;
+ vm.selectAll = selectAll;
+ vm.isSelectedAll = isSelectedAll;
+ vm.isSortDirection = isSortDirection;
+ vm.sort = sort;
+
+ function selectAll($event) {
+ alert("select all");
+ }
+
+ function isSelectedAll() {
+
+ }
+
+ function clickItem(item) {
+ alert("click node");
+ }
+
+ function selectItem(selectedItem, $index, $event) {
+ alert("select node");
+ }
+
+ function isSortDirection(col, direction) {
+
+ }
+
+ function sort(field, allow, isSystem) {
+
+ }
+
+ }
+
+ angular.module("umbraco").controller("My.TableController", Controller);
+
+ })();
+
+
+@param {string} icon (binding): The node icon.
+@param {string} name (binding): The node name.
+@param {string} published (binding): The node published state.
+@param {function} onSelect (expression): Callback function when the row is selected.
+@param {function} onClick (expression): Callback function when the "Name" column link is clicked.
+@param {function} onSelectAll (expression): Callback function when selecting all items.
+@param {function} onSelectedAll (expression): Callback function when all items are selected.
+@param {function} onSortingDirection (expression): Callback function when sorting direction is changed.
+@param {function} onSort (expression): Callback function when sorting items.
+**/
+
(function () {
'use strict';
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less
index 2e5d1ef77d..b26ca2aede 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less
@@ -535,7 +535,7 @@
color: @gray-3;
}
-.umb-grid .umb-cell-rte textarea {
+.umb-grid .umb-cell-rte textarea.mceNoEditor {
display: none !important;
}
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less
index b2927c7ddc..9e038bd571 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less
@@ -36,6 +36,7 @@
.umb-node-preview__content {
flex: 1 1 auto;
margin-right: 25px;
+ overflow: hidden;
}
.umb-node-preview__name {
@@ -49,6 +50,13 @@
color: @gray-3;
}
+.umb-node-preview__name,
+.umb-node-preview__description {
+ /*text-overflow: ellipsis;
+ overflow: hidden;*/
+ word-wrap: break-word;
+}
+
.umb-node-preview__actions {
flex: 0 0 auto;
display: flex;
diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less
index ffaa1a6a92..7082c15a14 100644
--- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less
+++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less
@@ -281,6 +281,12 @@ ul.color-picker li a {
display: block;
}
+.umb-sortable-thumbnails .umb-sortable-thumbnails__wrapper {
+ width: 120px;
+ height: 114px;
+ overflow: hidden;
+}
+
.umb-sortable-thumbnails .umb-sortable-thumbnails__actions {
position: absolute;
bottom: 10px;
@@ -308,6 +314,7 @@ ul.color-picker li a {
justify-content: center;
align-items: center;
margin-left: 5px;
+ text-decoration: none;
}
.umb-sortable-thumbnails .umb-sortable-thumbnails__action.-red {
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/imagepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/imagepicker.controller.js
index 48bb1e81ec..6e7071a7e4 100644
--- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/imagepicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/imagepicker.controller.js
@@ -1,20 +1,25 @@
function imageFilePickerController($scope) {
- $scope.pick = function() {
- $scope.mediaPickerDialog = {};
- $scope.mediaPickerDialog.view = "mediapicker";
- $scope.mediaPickerDialog.show = true;
-
- $scope.mediaPickerDialog.submit = function(model) {
- $scope.model.value = model.selectedImages[0].image;
- $scope.mediaPickerDialog.show = false;
- $scope.mediaPickerDialog = null;
+ $scope.add = function() {
+ $scope.mediaPickerOverlay = {
+ view: "mediapicker",
+ disableFolderSelect: true,
+ onlyImages: true,
+ show: true,
+ submit: function (model) {
+ $scope.model.value = model.selectedImages[0].image;
+ $scope.mediaPickerOverlay.show = false;
+ $scope.mediaPickerOverlay = null;
+ },
+ close: function () {
+ $scope.mediaPickerOverlay.show = false;
+ $scope.mediaPickerOverlay = null;
+ }
};
+ };
- $scope.mediaPickerDialog.close = function(oldModel) {
- $scope.mediaPickerDialog.show = false;
- $scope.mediaPickerDialog = null;
- };
+ $scope.remove = function () {
+ $scope.model.value = null;
};
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/imagepicker.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/imagepicker.html
index d9d988d7e5..1a37a624d5 100644
--- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/imagepicker.html
+++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/imagepicker.html
@@ -1,19 +1,28 @@
Email
Fout
Vind
- Hogte
+ Hoogte
Help
Icoon
Import
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml
index ec24bd69cb..115a227948 100644
--- a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml
+++ b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml
@@ -153,6 +153,7 @@
Нумерованный список
Вставить макрос
Вставить изображение
+ Повторить
Править связи
Вернуться к списку
Сохранить
@@ -168,6 +169,7 @@
Выбрать стиль
Показать стили
Вставить таблицу
+ Отменить
Чтобы сменить тип документа для выбранного узла, сначала выберите тип из списка разрешенных для данного расположения.
@@ -375,6 +377,7 @@
Свойства макроса
Этот макрос не имеет редактируемых свойств
Заголовок ссылки
+ Ни одной пиктограммы не найдено
Вставить
Изменить разрешения для
Установить разрешения для
@@ -596,6 +599,7 @@
Новый
След
Нет
+ Здесь пока нет элементов
из
Выкл
Ok
@@ -696,6 +700,8 @@
Выбрать дополнительно
Выбрать по-умолчанию
добавлены
+ Оставьте пустым или задайте 0 для снятия лимита
+ Максимальное количество
Страница
@@ -1049,7 +1055,7 @@
- и указав на нужный файл. Пакеты Umbraco обычно являются архивами с расширением ".umb" или ".zip".
+ и указав на нужный файл. Пакеты Umbraco обычно являются архивами с расширением '.zip'.
]]>
Перетащите сюда
или нажмите здесь для выбора файла пакета
@@ -1215,12 +1221,12 @@
Заголовок
- Укажите заголовок
+ Укажите заголовок ссылки
выбрать страницу сайта
указать внешнюю ссылку
Укажите ссылку
Ссылка
- В новом окне
+ Открыть в новом окне
Переименована
@@ -1393,8 +1399,6 @@
'%0%' сейчас заблокирован
При блокировке пользователя произошла ошибка
Группы пользователей установлены
- Удалено %0% групп пользователей
- '%0%' была удалена
Разблокировано %0% пользователей
При разблокировке пользователей произошла ошибка
'%0%' сейчас разблокирован
@@ -1517,8 +1521,8 @@
Поле замены
Добавить значение по-умолчанию
Значение по-умолчанию
- Альтернативное поле
- Текст по-умолчанию
+ Поле замены
+ Значение по-умолчанию
Регистр
Выбрать поле
Преобразовать переводы строк
@@ -1715,11 +1719,22 @@
Профиль
Сбросить пароль
Поиск всех дочерних документов
+ Выбрать группы пользователей
Отправить приглашение
Сессия истекает через
Разделы, доступные пользователю
Начальный узел не задан
Начальные узлы не заданы
+ Имя (А-Я)
+ Имя (Я-А)
+ Сначала новые
+ Сначала старые
+ Недавно зашедшие
+ Активные
+ Все
+ Отключенные
+ Заблокированные
+ Приглашенные
Начальный узел содержимого
Можно ограничить доступ к дереву содержимого (какой-либо его части), задав начальный узел
Начальные узлы содержимого
@@ -1736,6 +1751,7 @@
Новому пользователю было отправлено приглашение, в котором содержатся инструкции для входа в панель Umbraco.
Здравствуйте и добро пожаловать в Umbraco! Все будет готово в течении пары минут, нам лишь нужно задать Ваш пароль для входа и добавить аватар.
Загрузите изображение, это поможет другим пользователям идентифицировать Вас.
+ Управление пользователями
Разрешения для пользователя
Автор
Ваша недавняя история
diff --git a/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs b/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs
index 27fbc6d5c5..b1b013c974 100644
--- a/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs
+++ b/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs
@@ -805,13 +805,13 @@ namespace Umbraco.Web.Cache
///
/// Used to cache all found event handlers
///
- private static readonly ConcurrentDictionary FoundHandlers = new ConcurrentDictionary();
+ private static readonly ConcurrentDictionary FoundHandlers = new ConcurrentDictionary();
internal static MethodInfo FindHandler(IEventDefinition eventDefinition)
{
var name = eventDefinition.Sender.GetType().Name + "_" + eventDefinition.EventName;
- return FoundHandlers.GetOrAdd(eventDefinition, _ => CandidateHandlers.Value.FirstOrDefault(x => x.Name == name));
+ return FoundHandlers.GetOrAdd(name, n => CandidateHandlers.Value.FirstOrDefault(x => x.Name == n));
}
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
index c6121b2e10..2fa919716c 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
@@ -58,7 +58,7 @@ namespace Umbraco.Web.Models.Mapping
.ToDictionary(t => t.Alias, t => t.Name)))
.ForMember(display => display.Tabs, expression => expression.ResolveUsing(new TabsAndPropertiesResolver(applicationContext.Services.TextService)))
.ForMember(display => display.AllowedActions, expression => expression.ResolveUsing(
- new ActionButtonsResolver(new Lazy(() => applicationContext.Services.UserService))))
+ new ActionButtonsResolver(new Lazy(() => applicationContext.Services.UserService), new Lazy(() => applicationContext.Services.ContentService))))
.AfterMap((content, display) => AfterMap(content, display, applicationContext.Services.DataTypeService, applicationContext.Services.TextService,
applicationContext.Services.ContentTypeService));
@@ -154,10 +154,14 @@ namespace Umbraco.Web.Models.Mapping
private class ActionButtonsResolver : ValueResolver>
{
private readonly Lazy _userService;
+ private readonly Lazy _contentService;
- public ActionButtonsResolver(Lazy userService)
+ public ActionButtonsResolver(Lazy userService, Lazy contentService)
{
+ if (userService == null) throw new ArgumentNullException("userService");
+ if (contentService == null) throw new ArgumentNullException("contentService");
_userService = userService;
+ _contentService = contentService;
}
protected override IEnumerable ResolveCore(IContent source)
@@ -169,14 +173,21 @@ namespace Umbraco.Web.Models.Mapping
}
var svc = _userService.Value;
- var permissions = svc.GetPermissions(
+ string path;
+ if (source.HasIdentity)
+ path = source.Path;
+ else
+ {
+ var parent = _contentService.Value.GetById(source.ParentId);
+ path = parent == null ? "-1" : parent.Path;
+ }
+
+ var permissions = svc.GetPermissionsForPath(
//TODO: This is certainly not ideal usage here - perhaps the best way to deal with this in the future is
// with the IUmbracoContextAccessor. In the meantime, if used outside of a web app this will throw a null
// refrence exception :(
UmbracoContext.Current.Security.CurrentUser,
- // Here we need to do a special check since this could be new content, in which case we need to get the permissions
- // from the parent, not the existing one otherwise permissions would be coming from the root since Id is 0.
- source.HasIdentity ? source.Id : source.ParentId)
+ path)
.GetAllPermissions();
return permissions;
diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs
index a4793f9a67..fb40905a03 100644
--- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs
+++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs
@@ -74,11 +74,47 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
public virtual IEnumerable GetAtRoot(UmbracoContext umbracoContext, bool preview)
{
- //TODO: We should be able to look these ids first in Examine!
+ var searchProvider = GetSearchProviderSafe();
+
+ if (searchProvider != null)
+ {
+ try
+ {
+ // first check in Examine for the cache values
+ // +(+parentID:-1) +__IndexType:media
+
+ var criteria = searchProvider.CreateSearchCriteria("media");
+ var filter = criteria.ParentId(-1).Not().Field(UmbracoContentIndexer.IndexPathFieldName, "-1,-21,".MultipleCharacterWildcard());
+
+ var result = searchProvider.Search(filter.Compile());
+ if (result != null)
+ return result.Select(x => CreateFromCacheValues(ConvertFromSearchResult(x)));
+ }
+ catch (Exception ex)
+ {
+ if (ex is FileNotFoundException)
+ {
+ //Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
+ //See this thread: http://examine.cdodeplex.com/discussions/264341
+ //Catch the exception here for the time being, and just fallback to GetMedia
+ //TODO: Need to fix examine in LB scenarios!
+ LogHelper.Error("Could not load data from Examine index for media", ex);
+ }
+ else if (ex is AlreadyClosedException)
+ {
+ //If the app domain is shutting down and the site is under heavy load the index reader will be closed and it really cannot
+ //be re-opened since the app domain is shutting down. In this case we have no option but to try to load the data from the db.
+ LogHelper.Error("Could not load data from Examine index for media, the app domain is most likely in a shutdown state", ex);
+ }
+ else throw;
+ }
+ }
+
+ //something went wrong, fetch from the db
var rootMedia = _applicationContext.Services.MediaService.GetRootMedia();
- return rootMedia.Select(m => GetUmbracoMedia(m.Id));
- }
+ return rootMedia.Select(m => CreateFromCacheValues(ConvertFromIMedia(m)));
+ }
public virtual IPublishedContent GetSingleByXPath(UmbracoContext umbracoContext, bool preview, string xpath, XPathVariable[] vars)
{