Merged branch dev-v7 into dev-v7

This commit is contained in:
Sebastiaan Janssen
2016-01-27 15:30:54 +01:00
16 changed files with 362 additions and 230 deletions

View File

@@ -910,7 +910,7 @@ namespace Umbraco.Core.Services
new MoveEventArgs<IContent>(evtMsgs, new MoveEventInfo<IContent>(content, originalPath, Constants.System.RecycleBinContent)),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var moveInfo = new List<MoveEventInfo<IContent>>
@@ -957,7 +957,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Move, "Move Content to Recycle Bin performed by user", userId, content.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
}
@@ -1080,7 +1080,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<IContent>(asArray, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
}
using (new WriteLock(Locker))
@@ -1124,7 +1124,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Save, "Bulk Save content performed by user", userId == -1 ? 0 : userId, Constants.System.Root);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
}
@@ -1147,7 +1147,7 @@ namespace Umbraco.Core.Services
new DeleteEventArgs<IContent>(content, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
//Make sure that published content is unpublished before being deleted
@@ -1178,7 +1178,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Delete, "Delete Content performed by user", userId, content.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
}
@@ -2043,7 +2043,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<IContent>(content, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
}
@@ -2075,7 +2075,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Save, "Save Content performed by user", userId, content.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
}

View File

@@ -68,13 +68,16 @@ namespace Umbraco.Core.Services
repo.AddOrUpdate(container);
uow.Commit();
SavedContentTypeContainer.RaiseEvent(new SaveEventArgs<EntityContainer>(container, evtMsgs), this);
//TODO: Audit trail ?
return Attempt.Succeed(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.Success, evtMsgs));
}
catch (Exception ex)
{
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(null, OperationStatusType.FailedExceptionThrown, evtMsgs), ex);
}
//TODO: Audit trail ?
}
}
@@ -93,7 +96,7 @@ namespace Umbraco.Core.Services
CreatorId = userId
};
if (SavingContentTypeContainer.IsRaisedEventCancelled(
if (SavingMediaTypeContainer.IsRaisedEventCancelled(
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
{
@@ -102,13 +105,16 @@ namespace Umbraco.Core.Services
repo.AddOrUpdate(container);
uow.Commit();
SavedMediaTypeContainer.RaiseEvent(new SaveEventArgs<EntityContainer>(container, evtMsgs), this);
//TODO: Audit trail ?
return Attempt.Succeed(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.Success, evtMsgs));
}
catch (Exception ex)
{
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(null, OperationStatusType.FailedExceptionThrown, evtMsgs), ex);
}
//TODO: Audit trail ?
}
}
@@ -138,20 +144,20 @@ namespace Umbraco.Core.Services
if (container.ContainedObjectType != containerObjectType)
{
var ex = new InvalidOperationException("Not a " + objectTypeName + " container.");
return Attempt.Fail(OperationStatus.Exception(evtMsgs, ex), ex);
return OperationStatus.Exception(evtMsgs, ex);
}
if (container.HasIdentity && container.IsPropertyDirty("ParentId"))
{
var ex = new InvalidOperationException("Cannot save a container with a modified parent, move the container instead.");
return Attempt.Fail(OperationStatus.Exception(evtMsgs, ex), ex);
return OperationStatus.Exception(evtMsgs, ex);
}
if (savingEvent.IsRaisedEventCancelled(
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var uow = UowProvider.GetUnitOfWork();
@@ -165,7 +171,7 @@ namespace Umbraco.Core.Services
//TODO: Audit trail ?
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
public EntityContainer GetContentTypeContainer(int containerId)
@@ -274,28 +280,54 @@ namespace Umbraco.Core.Services
}
}
public void DeleteContentTypeContainer(int containerId, int userId = 0)
public Attempt<OperationStatus> DeleteContentTypeContainer(int containerId, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid))
{
var container = repo.Get(containerId);
if (container == null) return;
if (container == null) return OperationStatus.NoOperation(evtMsgs);
if (DeletingContentTypeContainer.IsRaisedEventCancelled(
new DeleteEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
repo.Delete(container);
uow.Commit();
DeletedContentTypeContainer.RaiseEvent(new DeleteEventArgs<EntityContainer>(container, evtMsgs), this);
return OperationStatus.Success(evtMsgs);
//TODO: Audit trail ?
}
}
public void DeleteMediaTypeContainer(int containerId, int userId = 0)
public Attempt<OperationStatus> DeleteMediaTypeContainer(int containerId, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid))
{
var container = repo.Get(containerId);
if (container == null) return;
if (container == null) return OperationStatus.NoOperation(evtMsgs);
if (DeletingMediaTypeContainer.IsRaisedEventCancelled(
new DeleteEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
repo.Delete(container);
uow.Commit();
DeletedMediaTypeContainer.RaiseEvent(new DeleteEventArgs<EntityContainer>(container, evtMsgs), this);
return OperationStatus.Success(evtMsgs);
//TODO: Audit trail ?
}
}

View File

@@ -29,8 +29,9 @@ namespace Umbraco.Core.Services
#region Containers
public Attempt<int> CreateContainer(int parentId, string name, int userId = 0)
public Attempt<OperationStatus<EntityContainer, OperationStatusType>> CreateContainer(int parentId, string name, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
{
@@ -42,15 +43,26 @@ namespace Umbraco.Core.Services
ParentId = parentId,
CreatorId = userId
};
if (SavingContainer.IsRaisedEventCancelled(
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
repo.AddOrUpdate(container);
uow.Commit();
return Attempt.Succeed(container.Id);
SavedContainer.RaiseEvent(new SaveEventArgs<EntityContainer>(container, evtMsgs), this);
//TODO: Audit trail ?
return Attempt.Succeed(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.Success, evtMsgs));
}
catch (Exception ex)
{
return Attempt<int>.Fail(ex);
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(null, OperationStatusType.FailedExceptionThrown, evtMsgs), ex);
}
//TODO: Audit trail ?
}
}
@@ -107,31 +119,65 @@ namespace Umbraco.Core.Services
}
}
public void SaveContainer(EntityContainer container, int userId = 0)
public Attempt<OperationStatus> SaveContainer(EntityContainer container, int userId = 0)
{
if (container.ContainedObjectType != Constants.ObjectTypes.DataTypeGuid)
throw new InvalidOperationException("Not a data type container.");
var evtMsgs = EventMessagesFactory.Get();
if (container.ContainedObjectType != Constants.ObjectTypes.DataTypeGuid)
{
var ex = new InvalidOperationException("Not a " + Constants.ObjectTypes.DataTypeGuid + " container.");
return OperationStatus.Exception(evtMsgs, ex);
}
if (container.HasIdentity && container.IsPropertyDirty("ParentId"))
throw new InvalidOperationException("Cannot save a container with a modified parent, move the container instead.");
{
var ex = new InvalidOperationException("Cannot save a container with a modified parent, move the container instead.");
return OperationStatus.Exception(evtMsgs, ex);
}
if (SavingContainer.IsRaisedEventCancelled(
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return OperationStatus.Cancelled(evtMsgs);
}
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
{
repo.AddOrUpdate(container);
uow.Commit();
//TODO: Audit trail ?
}
SavedContainer.RaiseEvent(new SaveEventArgs<EntityContainer>(container, evtMsgs), this);
//TODO: Audit trail ?
return OperationStatus.Success(evtMsgs);
}
public void DeleteContainer(int containerId, int userId = 0)
public Attempt<OperationStatus> DeleteContainer(int containerId, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
{
var container = repo.Get(containerId);
if (container == null) return;
if (container == null) return OperationStatus.NoOperation(evtMsgs);
if (DeletingContainer.IsRaisedEventCancelled(
new DeleteEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
repo.Delete(container);
uow.Commit();
DeletedContainer.RaiseEvent(new DeleteEventArgs<EntityContainer>(container, evtMsgs), this);
return OperationStatus.Success(evtMsgs);
//TODO: Audit trail ?
}
}
@@ -537,6 +583,12 @@ namespace Umbraco.Core.Services
}
#region Event Handlers
public static event TypedEventHandler<IDataTypeService, SaveEventArgs<EntityContainer>> SavingContainer;
public static event TypedEventHandler<IDataTypeService, SaveEventArgs<EntityContainer>> SavedContainer;
public static event TypedEventHandler<IDataTypeService, DeleteEventArgs<EntityContainer>> DeletingContainer;
public static event TypedEventHandler<IDataTypeService, DeleteEventArgs<EntityContainer>> DeletedContainer;
/// <summary>
/// Occurs before Delete
/// </summary>

View File

@@ -33,7 +33,7 @@ namespace Umbraco.Core.Services
new DeleteEventArgs<IDomain>(domain, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var uow = UowProvider.GetUnitOfWork();
@@ -45,7 +45,7 @@ namespace Umbraco.Core.Services
var args = new DeleteEventArgs<IDomain>(domain, false, evtMsgs);
Deleted.RaiseEvent(args, this);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
public IDomain GetByName(string name)
@@ -91,7 +91,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<IDomain>(domainEntity, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var uow = UowProvider.GetUnitOfWork();
@@ -102,7 +102,7 @@ namespace Umbraco.Core.Services
}
Saved.RaiseEvent(new SaveEventArgs<IDomain>(domainEntity, false, evtMsgs), this);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
#region Event Handlers

View File

@@ -36,8 +36,8 @@ namespace Umbraco.Core.Services
IEnumerable<EntityContainer> GetMediaTypeContainers(int[] containerIds);
IEnumerable<EntityContainer> GetMediaTypeContainers(string folderName, int level);
IEnumerable<EntityContainer> GetMediaTypeContainers(IMediaType mediaType);
void DeleteMediaTypeContainer(int folderId, int userId = 0);
void DeleteContentTypeContainer(int containerId, int userId = 0);
Attempt<OperationStatus> DeleteMediaTypeContainer(int folderId, int userId = 0);
Attempt<OperationStatus> DeleteContentTypeContainer(int containerId, int userId = 0);
/// <summary>
/// Gets all property type aliases.

View File

@@ -10,14 +10,14 @@ namespace Umbraco.Core.Services
/// </summary>
public interface IDataTypeService : IService
{
Attempt<int> CreateContainer(int parentId, string name, int userId = 0);
void SaveContainer(EntityContainer container, int userId = 0);
Attempt<OperationStatus<EntityContainer, OperationStatusType>> CreateContainer(int parentId, string name, int userId = 0);
Attempt<OperationStatus> SaveContainer(EntityContainer container, int userId = 0);
EntityContainer GetContainer(int containerId);
EntityContainer GetContainer(Guid containerId);
IEnumerable<EntityContainer> GetContainers(string folderName, int level);
IEnumerable<EntityContainer> GetContainers(IDataTypeDefinition dataTypeDefinition);
IEnumerable<EntityContainer> GetContainers(int[] containerIds);
void DeleteContainer(int containerId, int userId = 0);
Attempt<OperationStatus> DeleteContainer(int containerId, int userId = 0);
/// <summary>
/// Gets a <see cref="IDataTypeDefinition"/> by its Name

View File

@@ -747,7 +747,7 @@ namespace Umbraco.Core.Services
if (Deleting.IsRaisedEventCancelled(
new DeleteEventArgs<IMedia>(media, evtMsgs), this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
//Delete children before deleting the 'possible parent'
@@ -772,7 +772,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Delete, "Delete Media performed by user", userId, media.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
/// <summary>
@@ -791,7 +791,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<IMedia>(media, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
}
@@ -816,7 +816,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Save, "Save Media performed by user", userId, media.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
/// <summary>
@@ -836,7 +836,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<IMedia>(asArray, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
}
@@ -864,7 +864,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Save, "Save Media items performed by user", userId, -1);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
/// <summary>
@@ -966,7 +966,7 @@ namespace Umbraco.Core.Services
if (Trashing.IsRaisedEventCancelled(
new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)), this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var moveInfo = new List<MoveEventInfo<IMedia>>
@@ -1008,7 +1008,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
/// <summary>

View File

@@ -45,20 +45,25 @@ namespace Umbraco.Core.Services
#region Static Helper methods
internal static OperationStatus Exception(EventMessages eventMessages, Exception ex)
internal static Attempt<OperationStatus> Exception(EventMessages eventMessages, Exception ex)
{
eventMessages.Add(new EventMessage("", ex.Message, EventMessageType.Error));
return new OperationStatus(OperationStatusType.FailedExceptionThrown, eventMessages);
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedExceptionThrown, eventMessages), ex);
}
internal static OperationStatus Cancelled(EventMessages eventMessages)
internal static Attempt<OperationStatus> Cancelled(EventMessages eventMessages)
{
return new OperationStatus(OperationStatusType.FailedCancelledByEvent, eventMessages);
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, eventMessages));
}
internal static OperationStatus Success(EventMessages eventMessages)
internal static Attempt<OperationStatus> Success(EventMessages eventMessages)
{
return new OperationStatus(OperationStatusType.Success, eventMessages);
return Attempt.Succeed(new OperationStatus(OperationStatusType.Success, eventMessages));
}
internal static Attempt<OperationStatus> NoOperation(EventMessages eventMessages)
{
return Attempt.Succeed(new OperationStatus(OperationStatusType.NoOperation, eventMessages));
}
#endregion

View File

@@ -12,7 +12,7 @@ namespace Umbraco.Core.Services
/// The saving was successful.
/// </summary>
Success = 0,
/// <summary>
/// The saving has been cancelled by a 3rd party add-in
/// </summary>
@@ -22,6 +22,11 @@ namespace Umbraco.Core.Services
/// Failed, an exception was thrown/handled
/// </summary>
FailedExceptionThrown = 15,
/// <summary>
/// When no operation is executed because it was not needed (i.e. deleting an item that doesn't exist)
/// </summary>
NoOperation = 100,
//TODO: In the future, we might need to add more operations statuses, potentially like 'FailedByPermissions', etc...
}

View File

@@ -982,7 +982,7 @@ namespace Umbraco.Core.Services
_logger.Error<PackagingService>("Could not create folder: " + rootFolder, tryCreateFolder.Exception);
throw tryCreateFolder.Exception;
}
current = _dataTypeService.GetContainer(tryCreateFolder.Result);
current = _dataTypeService.GetContainer(tryCreateFolder.Result.Entity.Id);
}
importedFolders.Add(name, current.Id);
@@ -1015,7 +1015,7 @@ namespace Umbraco.Core.Services
_logger.Error<PackagingService>("Could not create folder: " + folderName, tryCreateFolder.Exception);
throw tryCreateFolder.Exception;
}
return _dataTypeService.GetContainer(tryCreateFolder.Result);
return _dataTypeService.GetContainer(tryCreateFolder.Result.Entity.Id);
}
private void SavePrevaluesFromXml(List<IDataTypeDefinition> dataTypes, IEnumerable<XElement> dataTypeElements)

View File

@@ -183,7 +183,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<PublicAccessEntry>(entry, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
repo.AddOrUpdate(entry);
@@ -191,7 +191,7 @@ namespace Umbraco.Core.Services
uow.Commit();
Saved.RaiseEvent(new SaveEventArgs<PublicAccessEntry>(entry, false, evtMsgs), this);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
}
@@ -207,7 +207,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<PublicAccessEntry>(entry, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var uow = UowProvider.GetUnitOfWork();
@@ -218,7 +218,7 @@ namespace Umbraco.Core.Services
}
Saved.RaiseEvent(new SaveEventArgs<PublicAccessEntry>(entry, false, evtMsgs), this);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
/// <summary>
@@ -232,7 +232,7 @@ namespace Umbraco.Core.Services
new DeleteEventArgs<PublicAccessEntry>(entry, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var uow = UowProvider.GetUnitOfWork();
@@ -243,7 +243,7 @@ namespace Umbraco.Core.Services
}
Deleted.RaiseEvent(new DeleteEventArgs<PublicAccessEntry>(entry, false, evtMsgs), this);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
/// <summary>

View File

@@ -0,0 +1,28 @@
(function() {
'use strict';
function SelectWhen($timeout) {
function link(scope, el, attr, ctrl) {
attr.$observe("umbSelectWhen", function(newValue) {
if (newValue === "true") {
$timeout(function() {
el.select();
});
}
});
}
var directive = {
restrict: 'A',
link: link
};
return directive;
}
angular.module('umbraco.directives').directive('umbSelectWhen', SelectWhen);
})();

View File

@@ -24,12 +24,10 @@
// scope object, but that would mean we'd have to watch that value too in order to set the outer
// ngModelCtrl.$modelValue. It's seems like less overhead to just do this and not have 2x watches.
scope.lockedFieldForm.lockedField.$modelValue = undefined;
scope.lockedFieldForm.lockedField.$setViewValue(newValue);
scope.lockedFieldForm.lockedField.$render();
scope.lockedFieldForm.lockedField.$render();
}
scope.lockedFieldForm.lockedField.$setViewValue(scope.lockedFieldForm.lockedField.$modelValue);
});
var input = el.find('.umb-locked-field__input');
function activate() {
@@ -57,36 +55,14 @@
scope.lock = function() {
scope.locked = true;
input.unbind("blur");
};
scope.unlock = function() {
scope.locked = false;
autoFocusField();
};
function autoFocusField() {
var onBlurHandler = function() {
scope.$apply(function(){
scope.lock();
});
};
$timeout(function() {
input.focus();
input.select();
input.on("blur", onBlurHandler);
});
}
activate();
scope.$on('$destroy', function() {
input.unbind('blur');
});
}
var directive = {

View File

@@ -1,167 +1,194 @@
(function() {
'use strict';
'use strict';
function MediaGridDirective($filter, mediaHelper) {
function MediaGridDirective($filter, mediaHelper) {
function link(scope, el, attr, ctrl) {
function link(scope, el, attr, ctrl) {
var itemDefaultHeight = 200;
var itemDefaultWidth = 200;
var itemMaxWidth = 200;
var itemMaxHeight = 200;
var itemDefaultHeight = 200;
var itemDefaultWidth = 200;
var itemMaxWidth = 200;
var itemMaxHeight = 200;
var itemMinWidth = 125;
var itemMinHeight = 125;
function activate() {
function activate() {
for (var i = 0; scope.items.length > i; i++) {
var item = scope.items[i];
setItemData(item);
setOriginalSize(item, itemMaxHeight);
}
if (scope.itemMaxWidth) {
itemMaxWidth = scope.itemMaxWidth;
}
if(scope.items.length > 0) {
setFlexValues(scope.items);
}
if (scope.itemMaxHeight) {
itemMaxHeight = scope.itemMaxHeight;
}
}
if (scope.itemMinWidth) {
itemMinWidth = scope.itemMinWidth;
}
function setItemData(item) {
item.isFolder = !mediaHelper.hasFilePropertyType(item);
if(!item.isFolder){
item.thumbnail = mediaHelper.resolveFile(item, true);
item.image = mediaHelper.resolveFile(item, false);
}
}
if (scope.itemMinWidth) {
itemMinHeight = scope.itemMinHeight;
}
function setOriginalSize(item, maxHeight) {
for (var i = 0; scope.items.length > i; i++) {
var item = scope.items[i];
setItemData(item);
setOriginalSize(item, itemMaxHeight);
}
//set to a square by default
item.width = itemDefaultWidth;
item.height = itemDefaultHeight;
item.aspectRatio = 1;
var widthProp = _.find(item.properties, function(v) { return (v.alias === "umbracoWidth"); });
if (widthProp && widthProp.value) {
item.width = parseInt(widthProp.value, 10);
if (isNaN(item.width)) {
item.width = itemDefaultWidth;
}
}
var heightProp = _.find(item.properties, function(v) { return (v.alias === "umbracoHeight"); });
if (heightProp && heightProp.value) {
item.height = parseInt(heightProp.value, 10);
if (isNaN(item.height)) {
item.height = itemDefaultWidth;
}
}
item.aspectRatio = item.width / item.height;
// set max width and height
// landscape
if(item.aspectRatio >= 1) {
if(item.width > itemMaxWidth) {
item.width = itemMaxWidth;
item.height = itemMaxWidth / item.aspectRatio;
}
// portrait
} else {
if(item.height > itemMaxHeight) {
item.height = itemMaxHeight;
item.width = itemMaxHeight * item.aspectRatio;
}
}
}
function setFlexValues(mediaItems) {
var flexSortArray = mediaItems;
var smallestImageWidth = null;
var widestImageAspectRatio = null;
// sort array after image width with the widest image first
flexSortArray = $filter('orderBy')(flexSortArray, 'width', true);
// find widest image aspect ratio
widestImageAspectRatio = flexSortArray[0].aspectRatio;
// find smallest image width
smallestImageWidth = flexSortArray[flexSortArray.length - 1].width;
for (var i = 0; flexSortArray.length > i; i++) {
var mediaItem = flexSortArray[i];
var flex = 1 / (widestImageAspectRatio / mediaItem.aspectRatio);
if (flex === 0) {
flex = 1;
}
var imageMinWidth = smallestImageWidth * flex;
var flexStyle = {
"flex": flex + " 1 " + imageMinWidth + "px",
"max-width": mediaItem.width + "px",
"min-width": "125px"
};
mediaItem.flexStyle = flexStyle;
if (scope.items.length > 0) {
setFlexValues(scope.items);
}
}
}
scope.clickItem = function(item, $event, $index) {
if(scope.onClick) {
scope.onClick(item, $event, $index);
function setItemData(item) {
item.isFolder = !mediaHelper.hasFilePropertyType(item);
if (!item.isFolder) {
item.thumbnail = mediaHelper.resolveFile(item, true);
item.image = mediaHelper.resolveFile(item, false);
}
}
};
scope.clickItemName = function(item, $event, $index) {
if(scope.onClickName) {
scope.onClickName(item, $event, $index);
$event.stopPropagation();
function setOriginalSize(item, maxHeight) {
//set to a square by default
item.width = itemDefaultWidth;
item.height = itemDefaultHeight;
item.aspectRatio = 1;
var widthProp = _.find(item.properties, function(v) {
return (v.alias === "umbracoWidth");
});
if (widthProp && widthProp.value) {
item.width = parseInt(widthProp.value, 10);
if (isNaN(item.width)) {
item.width = itemDefaultWidth;
}
}
var heightProp = _.find(item.properties, function(v) {
return (v.alias === "umbracoHeight");
});
if (heightProp && heightProp.value) {
item.height = parseInt(heightProp.value, 10);
if (isNaN(item.height)) {
item.height = itemDefaultWidth;
}
}
item.aspectRatio = item.width / item.height;
// set max width and height
// landscape
if (item.aspectRatio >= 1) {
if (item.width > itemMaxWidth) {
item.width = itemMaxWidth;
item.height = itemMaxWidth / item.aspectRatio;
}
// portrait
} else {
if (item.height > itemMaxHeight) {
item.height = itemMaxHeight;
item.width = itemMaxHeight * item.aspectRatio;
}
}
}
};
scope.hoverItemDetails = function(item, $event, hover) {
if(scope.onDetailsHover) {
scope.onDetailsHover(item, $event, hover);
function setFlexValues(mediaItems) {
var flexSortArray = mediaItems;
var smallestImageWidth = null;
var widestImageAspectRatio = null;
// sort array after image width with the widest image first
flexSortArray = $filter('orderBy')(flexSortArray, 'width', true);
// find widest image aspect ratio
widestImageAspectRatio = flexSortArray[0].aspectRatio;
// find smallest image width
smallestImageWidth = flexSortArray[flexSortArray.length - 1].width;
for (var i = 0; flexSortArray.length > i; i++) {
var mediaItem = flexSortArray[i];
var flex = 1 / (widestImageAspectRatio / mediaItem.aspectRatio);
if (flex === 0) {
flex = 1;
}
var imageMinFlexWidth = smallestImageWidth * flex;
var flexStyle = {
"flex": flex + " 1 " + imageMinFlexWidth + "px",
"max-width": mediaItem.width + "px",
"min-width": itemMinWidth + "px",
"min-height": itemMinHeight + "px"
};
mediaItem.flexStyle = flexStyle;
}
}
};
var unbindItemsWatcher = scope.$watch('items', function(newValue, oldValue){
if(angular.isArray(newValue)) {
activate();
}
});
scope.clickItem = function(item, $event, $index) {
if (scope.onClick) {
scope.onClick(item, $event, $index);
}
};
scope.$on('$destroy', function(){
unbindItemsWatcher();
});
scope.clickItemName = function(item, $event, $index) {
if (scope.onClickName) {
scope.onClickName(item, $event, $index);
$event.stopPropagation();
}
};
}
scope.hoverItemDetails = function(item, $event, hover) {
if (scope.onDetailsHover) {
scope.onDetailsHover(item, $event, hover);
}
};
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/umb-media-grid.html',
scope: {
items: '=',
onDetailsHover: "=",
onClick: '=',
onClickName: "=",
filterBy: "="
},
link: link
};
var unbindItemsWatcher = scope.$watch('items', function(newValue, oldValue) {
if (angular.isArray(newValue)) {
activate();
}
});
return directive;
}
scope.$on('$destroy', function() {
unbindItemsWatcher();
});
angular.module('umbraco.directives').directive('umbMediaGrid', MediaGridDirective);
}
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/umb-media-grid.html',
scope: {
items: '=',
onDetailsHover: "=",
onClick: '=',
onClickName: "=",
filterBy: "=",
itemMaxWidth: "@",
itemMaxHeight: "@",
itemMinWidth: "@",
itemMinHeight: "@"
},
link: link
};
return directive;
}
angular.module('umbraco.directives').directive('umbMediaGrid', MediaGridDirective);
})();

View File

@@ -76,7 +76,11 @@
items="images"
filter-by="searchTerm"
on-click="clickHandler"
on-click-name="clickItemName">
on-click-name="clickItemName"
item-max-width="150"
item-max-height="150"
item-min-width="100"
item-min-height="100">
</umb-media-grid>
</div>

View File

@@ -21,7 +21,10 @@
umb-auto-resize
required
val-server-field="{{serverValidationField}}"
title="{{ngModel}}" />
title="{{ngModel}}"
focus-when="{{!locked}}"
umb-select-when="{{!locked}}"
on-blur="lock()" />
</div>