diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 6e421da5d7..96014f65b7 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,4 +1,4 @@ -_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/temp8/docs/CONTRIBUTING.md) to go to the v8 branch_ +_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/temp8/.github/V8_GETTING_STARTED.md) to go to the v8 branch_ # Contributing to Umbraco CMS 👍🎉 First off, thanks for taking the time to contribute! 🎉👍 @@ -16,9 +16,9 @@ This document gives you a quick overview on how to get started, we will link to ## Guidelines for contributions we welcome -Not all changes are wanted so on occassion we might close a PR without merging it. We will give you feedback why we can't accept your changes and we'll be nice about it, thanking you for spending your valueable time. +Not all changes are wanted, so on occassion we might close a PR without merging it. We will give you feedback why we can't accept your changes and we'll be nice about it, thanking you for spending your valueable time. -We have [documented what we consider small and large changes](CONTRIBUTION_GUIDELINES.md), make sure to talk to us before making large changes. +We have [documented what we consider small and large changes](CONTRIBUTION_GUIDELINES.md). Make sure to talk to us before making large changes. Remember, if an issue is in the `Up for grabs` list or you've asked for some feedback before you sent us a PR, your PR will not be closed as unwanted. @@ -36,7 +36,7 @@ Great question! The short version goes like this: * **Build** - build your fork of Umbraco locally as described in [building Umbraco from source code](BUILD.md) * **Change** - make your changes, experiment, have fun, explore and learn, and don't be afraid. We welcome all contributions and will [happily give feedback](#questions) - * **Commit** - done? Yay! 🎉 It is recommended to create a new branch now and name it after the issue you're fixing, we usually follow the format: `temp-U4-12345`. This means it's a temporary branch for the particular issue you're working on, in this case `U4-12345` + * **Commit** - done? Yay! 🎉 It is recommended to create a new branch now and name it after the issue you're fixing, we usually follow the format: `temp-12345`. This means it's a temporary branch for the particular issue you're working on, in this case `12345` * **Push** - great, now you can push the changes up to your fork on GitHub * **Create pull request** - exciting! You're ready to show us your changes (or not quite ready, you just need some feedback to progress). GitHub has picked up on the new branch you've pushed and will offer to create a Pull Request. Click that green button and away you go. @@ -72,7 +72,6 @@ The pull request team consists of a member of Umbraco HQ, [Sebastiaan](https://g - [Anders Bjerner](https://github.com/abjerner) - [Dave Woestenborghs](https://github.com/dawoe) - [Emma Burstow](https://github.com/emmaburstow) -- [Kyle Weems](https://github.com/cssquirrel) - [Poornima Nayar](https://github.com/poornimanayar) These wonderful volunteers will provide you with a first reply to your PR, review and test out your changes and might ask more questions. After that they'll let Umbraco HQ know if everything seems okay. diff --git a/.github/CONTRIBUTING_DETAILED.md b/.github/CONTRIBUTING_DETAILED.md index a07539da6a..b3e34ef55d 100644 --- a/.github/CONTRIBUTING_DETAILED.md +++ b/.github/CONTRIBUTING_DETAILED.md @@ -25,7 +25,7 @@ When contributing code to Umbraco there's plenty of things you'll want to know, ### Reporting Bugs This section guides you through submitting a bug report for Umbraco CMS. Following these guidelines helps maintainers and the community understand your report 📝, reproduce the behavior 💻 💻, and find related reports 🔎. -Before creating bug reports, please check [this list](#before-submitting-a-bug-report) as you might find out that you don't need to create one. When you are creating a bug report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](http://issues.umbraco.org/issues#newissue=61-30118), the information it asks for helps us resolve issues faster. +Before creating bug reports, please check [this list](#before-submitting-a-bug-report) as you might find out that you don't need to create one. When you are creating a bug report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](https://github.com/umbraco/Umbraco-CMS/issues/new/choose), the information it asks for helps us resolve issues faster. > **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6275d161dc..8cb9017518 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,11 +1,12 @@ ### Prerequisites -- [ ] I have [created an issue](https://github.com/umbraco/Umbraco-CMS/issues) for the proposed changes in this PR, the link is: - [ ] I have added steps to test this contribution in the description below +If there's an existing issue for this PR then this fixes: + ### Description - - + + diff --git a/.github/README.md b/.github/README.md index cf29f4e527..5a1340006e 100644 --- a/.github/README.md +++ b/.github/README.md @@ -15,7 +15,7 @@ Once a track is done, we start releasing previews where we ask people to test th Umbraco CMS =========== -The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 443,000 websites worldwide: [https://umbraco.com](https://umbraco.com) +The friendliest, most flexible and fastest growing ASP.NET CMS, and used by more than 443,000 websites worldwide: [https://umbraco.com](https://umbraco.com) [![ScreenShot](img/vimeo.png)](https://vimeo.com/172382998/) @@ -28,34 +28,34 @@ Umbraco is a free open source Content Management System built on the ASP.NET pla ## Umbraco - The Friendly CMS -For the first time on the Microsoft platform, there is a free user and developer friendly CMS that makes it quick and easy to create websites - or a breeze to build complex web applications. Umbraco has award-winning integration capabilities and supports ASP.NET MVC or Web Forms, including User and Custom Controls, out of the box. +For the first time on the Microsoft platform, there is a free user- and developer-friendly CMS that makes it quick and easy to create websites - and a breeze to build complex web applications. Umbraco has award-winning integration capabilities and supports ASP.NET MVC or Web Forms, including User and Custom Controls, right out of the box. -Umbraco is not only loved by developers, but is a content editors dream. Enjoy intuitive editing tools, media management, responsive views and approval workflows to send your content live. +Umbraco is not only loved by developers, but is a content editor's dream. Enjoy intuitive editing tools, media management, responsive views, and approval workflows to send your content live. -Used by more than 443,000 active websites including Carlsberg, Segway, Amazon and Heinz and **The Official ASP.NET and IIS.NET website from Microsoft** ([https://asp.net](https://asp.net) / [https://iis.net](https://iis.net)), you can be sure that the technology is proven, stable and scales. Backed by the team at Umbraco HQ, and supported by a dedicated community of over 220,000 craftspeople globally, you can trust that Umbraco is a safe choice and is here to stay. +Used by more than 443,000 active websites including Carlsberg, Segway, Amazon and Heinz and **The Official ASP.NET and IIS.NET website from Microsoft** ([https://asp.net](https://asp.net) / [https://iis.net](https://iis.net)), you can be sure that the technology is proven, stable and scalable. Backed by the team at Umbraco HQ, and supported by a dedicated community of over 220,000 craftspeople globally, you can trust that Umbraco is a safe choice and is here to stay. To view more examples, please visit [https://umbraco.com/case-studies-testimonials/](https://umbraco.com/case-studies-testimonials/) ## Why Open Source? -As an Open Source platform, Umbraco is more than just a CMS. We are transparent with our roadmap for future versions, our incremental sprint planning notes are publicly accessible and community contributions and packages are available for all to use. +As an Open Source platform, Umbraco is more than just a CMS. We are transparent with our roadmap for future versions, our incremental sprint planning notes are publicly accessible, and community contributions and packages are available for all to use. ## Trying out Umbraco CMS -[Umbraco Cloud](https://umbraco.com/cloud) is the easiest and fastest way to use Umbraco yet with full support for all your custom .NET code and intergrations. You're up and running in less than a minute and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14 day trial, no credit card needed. +[Umbraco Cloud](https://umbraco.com/cloud) is the easiest and fastest way to use Umbraco yet, with full support for all your custom .NET code and integrations. You're up and running in less than a minute, and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14-day trial, no credit card needed. -If you want to DIY you can [download Umbraco](https://our.umbraco.com/download) either as a ZIP file or via NuGet. It's the same version of Umbraco CMS that powers Umbraco Cloud, but you'll need to find a place to host yourself and handling deployments and upgrades is all down to you. +If you want to DIY, you can [download Umbraco](https://our.umbraco.com/download) either as a ZIP file or via NuGet. It's the same version of Umbraco CMS that powers Umbraco Cloud, but you'll need to find a place to host it yourself, and handling deployments and upgrades will be all up to you. ## Community -Our friendly community is available 24/7 at the community hub we call ["Our Umbraco"](https://our.umbraco.com). Our Umbraco feature forums for questions and answers, documentation, downloadable plugins for Umbraco and a rich collection of community resources. +Our friendly community is available 24/7 at the community hub we call ["Our Umbraco"](https://our.umbraco.com). Our Umbraco features forums for questions and answers, documentation, downloadable plugins for Umbraco, and a rich collection of community resources. ## Contribute to Umbraco -Umbraco is contribution focused and community driven. If you want to contribute back to Umbraco please check out our [guide to contributing](CONTRIBUTING.md). +Umbraco is contribution-focused and community-driven. If you want to contribute back to Umbraco, please check out our [guide to contributing](CONTRIBUTING.md). ## Found a bug? Another way you can contribute to Umbraco is by providing issue reports. For information on how to submit an issue report refer to our [online guide for reporting issues](CONTRIBUTING_DETAILED.md#reporting-bugs). You can comment and report issues on the [github issue tracker](https://github.com/umbraco/Umbraco-CMS/issues). -Since [September 2018](https://umbraco.com/blog/a-second-take-on-umbraco-issue-tracker-hello-github-issues/) the old issue tracker is in read only mode, but can still be found at [http://issues.umbraco.org](http://issues.umbraco.org). +Since [September 2018](https://umbraco.com/blog/a-second-take-on-umbraco-issue-tracker-hello-github-issues/), the old issue tracker is in read-only mode, but can still be found at [http://issues.umbraco.org](http://issues.umbraco.org). diff --git a/src/ApiDocs/umbracotemplate/partials/footer.tmpl.partial b/src/ApiDocs/umbracotemplate/partials/footer.tmpl.partial index 69f51a101f..7aac413bfd 100644 --- a/src/ApiDocs/umbracotemplate/partials/footer.tmpl.partial +++ b/src/ApiDocs/umbracotemplate/partials/footer.tmpl.partial @@ -7,7 +7,7 @@ Back to top - Copyright © 2016 Umbraco
Generated by DocFX
+ Copyright © 2016-present Umbraco
Generated by DocFX
diff --git a/src/Umbraco.Core/Migrations/Expressions/Alter/Table/AlterTableBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Alter/Table/AlterTableBuilder.cs index 8d95d9c14c..f5bef4144c 100644 --- a/src/Umbraco.Core/Migrations/Expressions/Alter/Table/AlterTableBuilder.cs +++ b/src/Umbraco.Core/Migrations/Expressions/Alter/Table/AlterTableBuilder.cs @@ -154,8 +154,8 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table var index = new CreateIndexExpression(_context, new IndexDefinition { Name = indexName, - TableName = Expression.TableName, - IsUnique = true + TableName = Expression.TableName, + IndexType = IndexTypes.UniqueNonClustered }); index.Index.Columns.Add(new IndexColumnDefinition diff --git a/src/Umbraco.Core/Migrations/Expressions/Create/Column/CreateColumnBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Create/Column/CreateColumnBuilder.cs index 28de5aef14..3c59c5ffd7 100644 --- a/src/Umbraco.Core/Migrations/Expressions/Create/Column/CreateColumnBuilder.cs +++ b/src/Umbraco.Core/Migrations/Expressions/Create/Column/CreateColumnBuilder.cs @@ -112,8 +112,8 @@ namespace Umbraco.Core.Migrations.Expressions.Create.Column var index = new CreateIndexExpression(_context, new IndexDefinition { Name = indexName, - TableName = Expression.TableName, - IsUnique = true + TableName = Expression.TableName, + IndexType = IndexTypes.UniqueNonClustered }); index.Index.Columns.Add(new IndexColumnDefinition diff --git a/src/Umbraco.Core/Migrations/Expressions/Create/Index/CreateIndexBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Create/Index/CreateIndexBuilder.cs index ad8ac7f22d..1f2cb93f95 100644 --- a/src/Umbraco.Core/Migrations/Expressions/Create/Index/CreateIndexBuilder.cs +++ b/src/Umbraco.Core/Migrations/Expressions/Create/Index/CreateIndexBuilder.cs @@ -56,41 +56,29 @@ namespace Umbraco.Core.Migrations.Expressions.Create.Index /// ICreateIndexOnColumnBuilder ICreateIndexColumnOptionsBuilder.Unique() - { - Expression.Index.IsUnique = true; - //if it is Unique then it must be unique nonclustered and set the other flags - Expression.Index.IndexType = IndexTypes.UniqueNonClustered; - Expression.Index.IsClustered = false; + { + Expression.Index.IndexType = IndexTypes.UniqueNonClustered; return this; } /// public ICreateIndexOnColumnBuilder NonClustered() { - Expression.Index.IndexType = IndexTypes.NonClustered; - Expression.Index.IsClustered = false; - Expression.Index.IndexType = IndexTypes.NonClustered; - Expression.Index.IsUnique = false; + Expression.Index.IndexType = IndexTypes.NonClustered; return this; } /// public ICreateIndexOnColumnBuilder Clustered() - { - Expression.Index.IndexType = IndexTypes.Clustered; - Expression.Index.IsClustered = true; - //if it is clustered then we have to change the index type set the other flags - Expression.Index.IndexType = IndexTypes.Clustered; - Expression.Index.IsClustered = true; - Expression.Index.IsUnique = false; - return this; + { + Expression.Index.IndexType = IndexTypes.Clustered; + return this; } /// ICreateIndexOnColumnBuilder ICreateIndexOptionsBuilder.Unique() { - Expression.Index.IndexType = IndexTypes.UniqueNonClustered; - Expression.Index.IsUnique = true; + Expression.Index.IndexType = IndexTypes.UniqueNonClustered; return this; } } diff --git a/src/Umbraco.Core/Migrations/Expressions/Create/Table/CreateTableBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Create/Table/CreateTableBuilder.cs index 10836fd228..8f7eda89c2 100644 --- a/src/Umbraco.Core/Migrations/Expressions/Create/Table/CreateTableBuilder.cs +++ b/src/Umbraco.Core/Migrations/Expressions/Create/Table/CreateTableBuilder.cs @@ -176,8 +176,8 @@ namespace Umbraco.Core.Migrations.Expressions.Create.Table { Name = indexName, SchemaName = Expression.SchemaName, - TableName = Expression.TableName, - IsUnique = true + TableName = Expression.TableName, + IndexType = IndexTypes.UniqueNonClustered }); index.Index.Columns.Add(new IndexColumnDefinition diff --git a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs index 97f995e99d..5a0e44a281 100644 --- a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs +++ b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs @@ -159,9 +159,7 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions Name = indexName, IndexType = attribute.IndexType, ColumnName = columnName, - TableName = tableName, - IsClustered = attribute.IndexType == IndexTypes.Clustered, - IsUnique = attribute.IndexType == IndexTypes.UniqueNonClustered + TableName = tableName, }; if (string.IsNullOrEmpty(attribute.ForColumns) == false) diff --git a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/IndexDefinition.cs b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/IndexDefinition.cs index d4f2a27ae6..05ae879c20 100644 --- a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/IndexDefinition.cs +++ b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/IndexDefinition.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Persistence.DatabaseModelDefinitions @@ -14,7 +15,11 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } public virtual string ColumnName { get; set; } + + [Obsolete("Use the IndexType property instead and set it to IndexTypes.UniqueNonClustered")] public virtual bool IsUnique { get; set; } + + [Obsolete("Use the IndexType property instead and set it to IndexTypes.Clustered")] public bool IsClustered { get; set; } public virtual ICollection Columns { get; set; } public IndexTypes IndexType { get; set; } diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index 4ff0545281..d69786fbfc 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -334,14 +334,9 @@ ORDER BY TABLE_NAME, INDEX_NAME", switch (systemMethod) { case SystemMethods.NewGuid: - return null; // NOT SUPPORTED! - //return "NEWID()"; + return null; // NOT SUPPORTED! case SystemMethods.CurrentDateTime: return "CURRENT_TIMESTAMP"; - //case SystemMethods.NewSequentialId: - // return "NEWSEQUENTIALID()"; - //case SystemMethods.CurrentUTCDateTime: - // return "GETUTCDATE()"; } return null; diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index 9cc559ccd5..9ff149b355 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -11,6 +11,15 @@ using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Services { /// + /// Moves an object to a new location + /// + /// The to move + /// Id of the Media's new Parent + /// Id of the User moving the Media + /// True if moving succeeded, otherwise False + Attempt Move(IMedia media, int parentId, int userId = 0); + + /// /// Defines the Media Service, which is an easy access to operations involving /// public interface IMediaService : IContentServiceBase @@ -152,6 +161,7 @@ namespace Umbraco.Core.Services /// Id of the Media's new Parent /// Id of the User moving the Media void Move(IMedia media, int parentId, int userId = 0); + /// /// Deletes an object by moving it to the Recycle Bin diff --git a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs index 8e7681d17a..df842dc43c 100644 --- a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs +++ b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs @@ -89,7 +89,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine, var sqlSyntax = new SqlServerSyntaxProvider(new Lazy(() => null)); var indexDefinition = CreateIndexDefinition(); - indexDefinition.IsClustered = false; + indexDefinition.IndexType = IndexTypes.Clustered; var actual = sqlSyntax.Format(indexDefinition); Assert.AreEqual("CREATE CLUSTERED INDEX [IX_A] ON [TheTable] ([A])", actual); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js index 9bdf94d245..6f41943c5c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js @@ -1,5 +1,5 @@ angular.module("umbraco.directives") - .directive('gridRte', function (tinyMceService, stylesheetResource, angularHelper, assetsService, $q, $timeout) { + .directive('gridRte', function (tinyMceService, stylesheetResource, angularHelper, assetsService, $q, $timeout, eventsService) { return { scope: { uniqueId: '=', @@ -362,8 +362,16 @@ angular.module("umbraco.directives") // tinyMceEditor.fire('LoadContent', null); //}; + + var tabShownListener = eventsService.on("valTab.tabShown", function (e, args) { + //the tab has been shown, trigger the mceAutoResize (as it could have timed out before the tab was shown) + if (tinyMceEditor !== undefined && tinyMceEditor != null) { + tinyMceEditor.execCommand('mceAutoResize', false, null, null); + } + }); + //listen for formSubmitting event (the result is callback used to remove the event subscription) - var unsubscribe = scope.$on("formSubmitting", function () { + var formSubmittingListener = scope.$on("formSubmitting", function () { //TODO: Here we should parse out the macro rendered content so we can save on a lot of bytes in data xfer // we do parse it out on the server side but would be nice to do that on the client side before as well. scope.value = tinyMceEditor ? tinyMceEditor.getContent() : null; @@ -373,7 +381,8 @@ angular.module("umbraco.directives") // NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom // element might still be there even after the modal has been hidden. scope.$on('$destroy', function () { - unsubscribe(); + formSubmittingListener(); + eventsService.unsubscribe(tabShownListener); if (tinyMceEditor !== undefined && tinyMceEditor != null) { tinyMceEditor.destroy() } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js index 512b040ce3..1012e4d91d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js @@ -6,7 +6,7 @@ * @description Used to show validation warnings for a tab to indicate that the tab content has validations errors in its data. * In order for this directive to work, the valFormManager directive must be placed on the containing form. **/ -function valTab() { +function valTab(eventsService) { return { require: ['^^form', '^^valFormManager'], restrict: "A", @@ -14,7 +14,7 @@ function valTab() { var valFormManager = ctrs[1]; var tabAlias = scope.tab.alias; - scope.tabHasError = false; + scope.tabHasError = false; //listen for form validation changes valFormManager.onValidationStatusChanged(function (evt, args) { diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js index 9cf96f8e7a..1d6d5171a1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js @@ -116,9 +116,20 @@ function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) { { error: function(data){ var errorMsg = 'Failed to move media'; - - if(data.parentId === data.id){ - errorMsg = 'Media can\'t be moved into itself'; + if (data.id !== undefined && data.parentId !== undefined) { + if (data.id === data.parentId) { + errorMsg = 'Media can\'t be moved into itself'; + } + } + else if (data.notifications !== undefined) { + if (data.notifications.length > 0) { + if (data.notifications[0].header.length > 0) { + errorMsg = data.notifications[0].header; + } + if (data.notifications[0].message.length > 0) { + errorMsg = errorMsg + ": " + data.notifications[0].message; + } + } } return { diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js index 8dc64e4cac..d194ae2c73 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js @@ -3,7 +3,7 @@ * @name umbraco.resources.mediaTypeResource * @description Loads in data for media types **/ -function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { +function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter, localizationService) { return { @@ -208,13 +208,15 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { throw "args.id cannot be null"; } + var promise = localizationService.localize("media_moveFailed"); + return umbRequestHelper.resourcePromise( $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostMove"), { parentId: args.parentId, id: args.id }, { responseType: 'text' }), - 'Failed to move content'); + promise); }, copy: function (args) { @@ -228,33 +230,39 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { throw "args.id cannot be null"; } + var promise = localizationService.localize("media_copyFailed"); + return umbRequestHelper.resourcePromise( $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostCopy"), { parentId: args.parentId, id: args.id }, { responseType: 'text' }), - 'Failed to copy content'); + promise); }, createContainer: function(parentId, name) { + var promise = localizationService.localize("media_createFolderFailed", [parentId]); + return umbRequestHelper.resourcePromise( $http.post( umbRequestHelper.getApiUrl( "mediaTypeApiBaseUrl", "PostCreateContainer", { parentId: parentId, name: encodeURIComponent(name) })), - 'Failed to create a folder under parent id ' + parentId); + promise); }, renameContainer: function (id, name) { + var promise = localizationService.localize("media_renameFolderFailed", [id]); + return umbRequestHelper.resourcePromise( $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostRenameContainer", { id: id, name: name })), - "Failed to rename the folder with id " + id + promise ); } diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index 2441bd2d8f..838d9670e2 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -469,7 +469,7 @@ function navigationService($rootScope, $routeParams, $location, $q, $timeout, $i //if it is not two parts long then this most likely means that it's a legacy action var js = action.metaData["jsAction"].replace("javascript:", ""); - //there's not really a different way to acheive this except for eval + //there's not really a different way to achieve this except for eval eval(js); } else { diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js index 2263d095a6..aaa9a0ba72 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js @@ -242,7 +242,7 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar $scope.authenticated = false; })); - //when the application is ready and the user is authorized setup the data + //when the application is ready and the user is authorized, setup the data evts.push(eventsService.on("app.ready", function (evt, data) { init(); })); diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index c1d42c249e..a3d5374491 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -115,6 +115,7 @@ @import "components/umb-confirm-action.less"; @import "components/umb-keyboard-shortcuts-overview.less"; @import "components/umb-checkbox-list.less"; +@import "components/umb-radiobuttons-list.less"; @import "components/umb-locked-field.less"; @import "components/umb-tabs.less"; @import "components/umb-load-indicator.less"; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/prevalues/multivalues.less b/src/Umbraco.Web.UI.Client/src/less/components/prevalues/multivalues.less index 43f6697eb1..0dbc4c381c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/prevalues/multivalues.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/prevalues/multivalues.less @@ -5,6 +5,10 @@ .umb-overlay & { width: 500px; } + + p{ + margin: 7px 0; + } } .umb-prevalues-multivalues__left { diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less index c6fdf8a7bf..6dc2dd6ff3 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less @@ -3,7 +3,7 @@ flex-flow: row wrap; .umb-color-box { - border: 1px solid @gray-8; + border: 1px solid rgba(0,0,0,0.15); color: @white; cursor: pointer; padding: 1px; @@ -36,10 +36,11 @@ &.with-labels { .umb-color-box { - width: 120px; - height: 100%; + width: 130px; + height: auto; display: flex; flex-flow: row wrap; + border: 1px solid @gray-8; .umb-color-box-inner { display: flex; @@ -47,15 +48,21 @@ flex: 0 0 100%; max-width: 100%; min-height: 80px; - padding-top: 10px; + padding: 0; + + .check_circle { + margin: 15px auto; + } .umb-color-box__label { background: @white; font-size: 14px; display: flex; flex-flow: column wrap; - flex: 0 0 100%; + flex: 1 0 100%; + justify-content: flex-end; padding: 1px 5px; + min-height: 45px; max-width: 100%; margin-top: auto; margin-bottom: -3px; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-nested-content.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-nested-content.less index 5a11403bb3..df8977a2bf 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-nested-content.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-nested-content.less @@ -209,26 +209,6 @@ width: 99%; } -.usky-grid.umb-nested-content__node-type-picker { - .cell-tools-menu { - position: relative; - transform: translate(-50%, -25%); - } - - .elements li { - &:hover { - i { - color: @white !important; - } - } - - i { - // make sure the item icons shown are in the correct color according to their doc type icon instead of the grid editor item color - color: unset; - } - } -} - // this resolves the layout issue introduced in nested content in 7.12 with the addition of the input for link anchors // the attribute selector ensures the change only applies to the linkpicker overlay .form-horizontal .umb-nested-content--narrow [ng-controller*="Umbraco.Overlays.LinkPickerController"] .controls-row { diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-radiobuttons-list.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-radiobuttons-list.less new file mode 100644 index 0000000000..2fe3487a8f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-radiobuttons-list.less @@ -0,0 +1,80 @@ +.umb-radiobuttons{ + &__label{ + position: relative; + padding: 0; + + &-text{ + margin: 0 0 0 32px; + position: relative; + top: 1px; + } + } + + &__input{ + position: absolute; + top: 0; + left: 0; + opacity: 0; + + &:focus ~ .umb-radiobuttons__state{ + box-shadow: 0 1px 3px fade(@black, 12%), 0 1px 2px fade(@black, 24%); + } + + &:focus:checked ~ .umb-radiobuttons__state{ + box-shadow: none; + } + + &:checked ~ .umb-radiobuttons__state{ + &:before{ + width: 100%; + height: 100%; + } + } + + &:checked ~ .umb-radiobuttons__state .umb-radiobuttons__icon{ + opacity: 1; + } + } + + &__state{ + display: flex; + flex-wrap: wrap; + border: 1px solid @gray-8; + border-radius: 100%; + width: 22px; + height: 22px; + position: relative; + + &:before{ + content: ""; + background: @green; + width: 0; + height: 0; + transition: .1s ease-out; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; + border-radius: 100%; + } + } + + &__icon{ + color: @white; + text-align: center; + font-size: 15px; + opacity: 0; + transition: .3s ease-out; + + &:before{ + position: absolute; + top: 2px; + right: 0; + left: 0; + bottom: 0; + margin: auto; + } + } +} diff --git a/src/Umbraco.Web.UI.Client/src/less/forms/umb-validation-label.less b/src/Umbraco.Web.UI.Client/src/less/forms/umb-validation-label.less index a57748c35e..417447c3dc 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms/umb-validation-label.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms/umb-validation-label.less @@ -1,5 +1,7 @@ .umb-validation-label { - position: relative; + position: absolute; + top: 27px; + width: 200px; padding: 1px 5px; background: @red; color: @white; diff --git a/src/Umbraco.Web.UI.Client/src/less/main.less b/src/Umbraco.Web.UI.Client/src/less/main.less index 0284a79865..12a13e11ed 100644 --- a/src/Umbraco.Web.UI.Client/src/less/main.less +++ b/src/Umbraco.Web.UI.Client/src/less/main.less @@ -23,7 +23,7 @@ margin-top: 0px; margin-bottom: 15px; font-size: 14px; - color: @gray-7; + color: @gray-7; } h5{ @@ -141,7 +141,7 @@ h5.-black { padding-bottom: 0; } -.block-form .umb-control-group label .help-block, +.block-form .umb-control-group label .help-block, .block-form .umb-control-group label small { font-size: 13px; padding-top: 2px; @@ -250,9 +250,9 @@ label:not([for]) { } .umb-version { - color: @gray-7; - position: absolute; - bottom: 5px; + color: @gray-7; + position: absolute; + bottom: 5px; right: 20px; } @@ -660,3 +660,15 @@ input[type=checkbox]:checked + .input-label--small { background-color: @green-l3; text-decoration: none; } + +.visuallyhidden{ + position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + padding:0 !important; + border:0 !important; + height: 1px !important; + width: 1px !important; + overflow: hidden; +} + diff --git a/src/Umbraco.Web.UI.Client/src/less/panel.less b/src/Umbraco.Web.UI.Client/src/less/panel.less index 912e7d90e2..3d9df196d7 100644 --- a/src/Umbraco.Web.UI.Client/src/less/panel.less +++ b/src/Umbraco.Web.UI.Client/src/less/panel.less @@ -16,7 +16,7 @@ .umb-panel-header { background: @gray-10; - border-bottom: 1px solid @gray-8; + border-bottom: 1px solid @purple-l3; position: absolute; height: 99px; top: 0px; @@ -43,23 +43,23 @@ } .umb-mediapicker-upload { - display: -ms-flexbox; - display: -webkit-box; - display: -webkit-flex; display: flex; .form-search { - -webkit-flex: 1; - -ms-flex: 1; flex: 1; &__toggle{ margin: 10px 0; + display: flex; + align-items: center; - label{ - margin-right: 10px; - position: relative; - top: -2px; + input { + margin: 0; + } + + label { + margin-left: 5px; + margin-bottom: 0; } } } 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 27a51bc80c..949668fc8f 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -107,11 +107,11 @@ div.umb-codeeditor { border: 1px solid @gray-8; } div.umb-codeeditor .umb-el-wrap { - padding: 0px; + padding: 0; } div.umb-codeeditor .umb-btn-toolbar { - padding: 0px; - margin: 0px; + padding: 0; + margin: 0; border-bottom: @gray-8 1px solid; background: @gray-10; } @@ -127,7 +127,7 @@ div.umb-codeeditor .umb-btn-toolbar { position: absolute; } } -.mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0px !important;} +.mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0 !important;} .mce-panel{background: @gray-10 !important; border-color: @gray-8 !important;} .mce-btn-group, .mce-btn{border: none !important; background: none !important;} .mce-ico{font-size: 12px !important; color: @gray-1 !important;} @@ -157,6 +157,7 @@ div.umb-codeeditor .umb-btn-toolbar { border-radius: 3px; margin-top: auto; margin-bottom: auto; + flex: 0 0 auto; } .handle { @@ -208,7 +209,7 @@ div.umb-codeeditor .umb-btn-toolbar { } label { - border: 1px solid #fff; + border: 1px solid @white; padding: 6px 10px; font-family: monospace; border: 1px solid #dfdfe1; @@ -218,6 +219,49 @@ div.umb-codeeditor .umb-btn-toolbar { } } +// +// Image Cropper +// -------------------------------------------------- + +.umb-prevalues-multivalues.umb-cropsizes{ + + max-width: 500px; + width: 100%; + min-width: 66.6%; + + @media (min-width: 1101px) and (max-width: 1300px), (max-width: 930px) { + max-width: none; + } + + .umb-overlay__form & { + width: 100%; + } +} + +.umb-cropsizes { + + &__add { + display: inline-flex; + align-items: center; + } + + &__controls { + margin: 24px 0 0; + display: flex; + } + + &__input { + width: 100%; + &-wrap{ + flex: 1 1 auto; + margin-right: 10px; + &--narrow { + flex: 0 1 100px; + } + } + } +} + // // Media picker @@ -240,6 +284,18 @@ div.umb-codeeditor .umb-btn-toolbar { } } +.umb-mediapicker .label{ + &__trashed{ + background-color: @red; + position: absolute; + top: 50%; + left: 50%; + z-index: 1; + transform: translate3d(-50%,-50%,0); + margin: 0; + } +} + .umb-mediapicker .picked-image { position: absolute; bottom: 10px; @@ -338,7 +394,7 @@ div.umb-codeeditor .umb-btn-toolbar { background-image: url(../img/checkered-background.png); } -.umb-sortable-thumbnails li img.trashed { +.umb-sortable-thumbnails li .trashed { opacity:0.3; } @@ -705,7 +761,7 @@ div.umb-codeeditor .umb-btn-toolbar { .umb-fileupload ul { list-style: none; vertical-align: middle; - margin-bottom: 0px; + margin-bottom: 0; } .umb-fileupload label { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js index 40f5035d11..fde8d23187 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js @@ -308,21 +308,9 @@ angular.module("umbraco") debounceSearchMedia(); }; - /** - * Toggle the $scope.model.allowAsRoot value to either true or false - */ - $scope.toggle = function(){ - + $scope.toggle = function() { // Make sure to activate the changeSearch function everytime the toggle is clicked $scope.changeSearch(); - - // Toggle the showChilds option - if($scope.showChilds){ - $scope.showChilds = false; - return; - } - - $scope.showChilds = true; } $scope.changePagination = function(pageNumber) { diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html index 949cd41b0e..4d56a08965 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html @@ -6,7 +6,7 @@
-
{{ color.label }}
+
{{ color.label || color.value }}
#{{ color.value }}
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html index 68ef225d18..9d2997625e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html @@ -37,12 +37,6 @@ -
- - You can drag files here to upload - -
-
    diff --git a/src/Umbraco.Web.UI.Client/src/views/content/copy.html b/src/Umbraco.Web.UI.Client/src/views/content/copy.html index 10184dcccc..03a024c439 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/copy.html @@ -84,10 +84,10 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/content/emptyrecyclebin.html b/src/Umbraco.Web.UI.Client/src/views/content/emptyrecyclebin.html index ec3ff44006..cdde683cf1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/emptyrecyclebin.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/emptyrecyclebin.html @@ -7,7 +7,7 @@

    When items are deleted from the recycle bin, they will be gone forever. - Are you sure? + Are you sure?

    diff --git a/src/Umbraco.Web.UI.Client/src/views/content/move.html b/src/Umbraco.Web.UI.Client/src/views/content/move.html index 56ca1fe528..708c3d3f82 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/move.html @@ -74,10 +74,10 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/content/notify.html b/src/Umbraco.Web.UI.Client/src/views/content/notify.html index ec9b3d2b0d..cb12d92f08 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/notify.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/notify.html @@ -1,44 +1,46 @@
    -
    -
    -
    -
    -
    {{vm.saveError.errorMsg}}
    -
    {{vm.saveError.data.message}}
    +
    +
    + +
    +
    +
    {{vm.saveError.errorMsg}}
    +
    {{vm.saveError.data.message}}
    +
    -
    -
    -
    - {{currentNode.name}} +
    +
    + {{currentNode.name}} +
    -
    -
    -
    -
    Set your notification for {{ currentNode.name }}
    - - - - +
    +
    +
    Set your notification for {{ currentNode.name }}
    + + + + +
    -
    - - + +
    +
    +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html index daf92e0223..70fb4ec804 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html @@ -4,9 +4,9 @@

    This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section:

    Find out more:
    diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html index 5094ac64a7..565410f363 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html @@ -45,10 +45,10 @@
    diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.html index 0329111488..4085e84ccd 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.html @@ -82,16 +82,16 @@ - - + + - - + + diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html index 65ba048515..af0ce58227 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html @@ -45,10 +45,10 @@
    diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.controller.js index 2aa856ba66..849b5ccd7b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.controller.js @@ -6,42 +6,86 @@ * @description * The controller for the content type editor templates sub view */ -(function() { +(function () { 'use strict'; - function TemplatesController($scope, entityResource, contentTypeHelper, $routeParams) { + function TemplatesController($scope, entityResource, contentTypeHelper, templateResource, $routeParams) { /* ----------- SCOPE VARIABLES ----------- */ var vm = this; vm.availableTemplates = []; + vm.canCreateTemplate = false; vm.updateTemplatePlaceholder = false; vm.loadingTemplates = false; + vm.createTemplate = createTemplate; /* ---------- INIT ---------- */ function onInit() { vm.loadingTemplates = true; - - entityResource.getAll("Template").then(function(templates){ + entityResource.getAll("Template").then(function (templates) { vm.availableTemplates = templates; // update placeholder template information on new doc types if (!$routeParams.notemplate && $scope.model.id === 0) { - vm.updateTemplatePlaceholder = true; - vm.availableTemplates = contentTypeHelper.insertTemplatePlaceholder(vm.availableTemplates); + vm.updateTemplatePlaceholder = true; + vm.availableTemplates = contentTypeHelper.insertTemplatePlaceholder(vm.availableTemplates); } vm.loadingTemplates = false; + checkIfTemplateExists(); }); } + function createTemplate() { + + vm.createTemplateButtonState = "busy"; + + templateResource.getScaffold(-1).then(function (template) { + + template.alias = $scope.model.alias; + template.name = $scope.model.name; + + templateResource.save(template).then(function (savedTemplate) { + + // add icon + savedTemplate.icon = "icon-layout"; + + vm.availableTemplates.push(savedTemplate); + vm.canCreateTemplate = false; + + $scope.model.allowedTemplates.push(savedTemplate); + + if ($scope.model.defaultTemplate === null) { + $scope.model.defaultTemplate = savedTemplate; + } + + vm.createTemplateButtonState = "success"; + + }, function() { + vm.createTemplateButtonState = "error"; + }); + + }, function() { + vm.createTemplateButtonState = "error"; + }); + }; + + function checkIfTemplateExists() { + var existingTemplate = vm.availableTemplates.find(function (availableTemplate) { + return (availableTemplate.name === $scope.model.name || availableTemplate.placeholder); + }); + + vm.canCreateTemplate = existingTemplate ? false : true; + } + onInit(); } diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html index e5317c134e..8084497441 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html @@ -9,15 +9,26 @@
    - + + + + +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/media/emptyrecyclebin.html b/src/Umbraco.Web.UI.Client/src/views/media/emptyrecyclebin.html index 4558a21e2a..cc7d261a95 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/emptyrecyclebin.html +++ b/src/Umbraco.Web.UI.Client/src/views/media/emptyrecyclebin.html @@ -8,7 +8,7 @@

    When items are deleted from the recycle bin, they will be gone forever. - Are you sure? + Are you sure?

    diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js index 88d657a2be..c5ff80b7fb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js @@ -54,8 +54,10 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", }; $scope.move = function () { + $scope.busy = true; mediaResource.move({ parentId: $scope.target.id, id: node.id }) .then(function (path) { + $scope.busy = false; $scope.error = false; $scope.success = true; diff --git a/src/Umbraco.Web.UI.Client/src/views/media/move.html b/src/Umbraco.Web.UI.Client/src/views/media/move.html index 3d457cf807..6d93eb4e22 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/media/move.html @@ -50,7 +50,7 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html index 5427c71cee..3d8c3b0845 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html @@ -45,10 +45,10 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.controller.js b/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.controller.js index be91b66ab5..8ff9106def 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.controller.js @@ -35,8 +35,7 @@ function MediaTypesCreateController($scope, $location, navigationService, mediaT var section = appState.getSectionState("currentSection"); }, function(err) { - - //TODO: Handle errors + $scope.error = err; }); }; } diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.html index 35556f035a..45fbebbe71 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.html @@ -29,6 +29,13 @@ ng-submit="createContainer()" val-form-manager> +
    +
    +
    {{error.errorMsg}}
    +
    {{error.data.message}}
    +
    +
    + diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html index 00a0ba3925..1ae686f5d5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html @@ -45,10 +45,10 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js new file mode 100644 index 0000000000..b4381b699b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js @@ -0,0 +1,62 @@ +angular.module("umbraco").controller("Umbraco.PrevalueEditors.ColorPickerController", + function ($scope) { + + //setup the default config + var config = { + useLabel: false + }; + + //map the user config + angular.extend(config, $scope.model.config); + + //map back to the model + $scope.model.config = config; + + $scope.isConfigured = $scope.model.prevalues && _.keys($scope.model.prevalues).length > 0; + + $scope.model.items = []; + + // Make an array from the dictionary + var items = []; + + if (angular.isArray($scope.model.prevalues)) { + + for (var i in $scope.model.prevalues) { + var oldValue = $scope.model.prevalues[i]; + + if (!isValidHex(oldValue.value || oldValue)) + continue; + + if (oldValue.hasOwnProperty("value")) { + var hexCode = toFullHex(oldValue.value); + items.push({ + value: hexCode.substr(1, hexCode.length), + label: oldValue.label, + id: i + }); + } else { + var hexCode = toFullHex(oldValue); + items.push({ + value: hexCode.substr(1, hexCode.length), + label: oldValue, + id: i + }); + } + } + + // Now make the editor model the array + $scope.model.items = items; + } + + function toFullHex(hex) { + if (hex.length === 4 && hex.charAt(0) === "#") { + hex = "#" + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2) + hex.charAt(3) + hex.charAt(3); + } + return hex.toLowerCase(); + } + + function isValidHex(str) { + return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(str); + } + + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html new file mode 100644 index 0000000000..7f3e6f0b05 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html @@ -0,0 +1,14 @@ +
    + +
    + You haven't defined any colors +
    + + + + + +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.controller.js index 3a99c90a50..5a0b43d105 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.controller.js @@ -1,10 +1,13 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.CropSizesController", - function ($scope, $timeout) { + function ($scope) { if (!$scope.model.value) { $scope.model.value = []; } + $scope.editMode = false; + $scope.setFocus = false; + $scope.remove = function (item, evt) { evt.preventDefault(); $scope.model.value = _.reject($scope.model.value, function (x) { @@ -13,32 +16,57 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.CropSizesControlle }; $scope.edit = function (item, evt) { - evt.preventDefault(); + evt.preventDefault(); + $scope.editMode = true; + $scope.setFocus = false; + $scope.newItem = item; }; $scope.cancel = function (evt) { - evt.preventDefault(); + evt.preventDefault(); + $scope.editMode = false; + $scope.setFocus = true; + $scope.newItem = null; }; - $scope.add = function (evt) { - evt.preventDefault(); + $scope.change = function () { + // Listen to the change event and set focus 2 false + if($scope.setFocus){ + $scope.setFocus = false; + return; + } + } - if ($scope.newItem && $scope.newItem.alias && + $scope.add = function (evt) { + evt.preventDefault(); + + $scope.editMode = false; + + $scope.setFocus = true; + + if ($scope.newItem && $scope.newItem.alias && angular.isNumber($scope.newItem.width) && angular.isNumber($scope.newItem.height) && $scope.newItem.width > 0 && $scope.newItem.height > 0) { - var exists = _.find($scope.model.value, function (item) { return $scope.newItem.alias === item.alias; }); + var exists = _.find($scope.model.value, function (item) { return $scope.newItem.alias === item.alias; }); + if (!exists) { $scope.model.value.push($scope.newItem); $scope.newItem = {}; - $scope.hasError = false; + $scope.hasError = false; + $scope.cropAdded = false; return; - } + } + else{ + $scope.newItem = null; + $scope.hasError = false; + return; + } } //there was an error, do the highlight (will be set back by the directive) $scope.hasError = true; - }; - }); \ No newline at end of file + }; + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.html index ac3ce946c0..86804fddb0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.html @@ -1,49 +1,74 @@ -
    +
    +
    -
    -
      -
    • - - +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + + Cancel +
      - {{node.alias}} -
      {{node.width}}px × {{node.height}}px -
    • -
    -
    -

    Define crop

    -

    - Give the crop an alias and it's default width and height. -

    - -
    - - +
    +
    + +
    +

    {{item.alias}} ({{item.width}}px × {{item.height}}px)

    +
    +
    + Edit + Remove +
    - -
    - - - × - -
    - -
    - - Cancel -
    -
    - -
    -
    diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index e90bf7ae7d..b6bb5a2444 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -59,6 +59,11 @@ function listViewController($scope, $routeParams, $injector, $timeout, currentUs items: [] }; + $scope.createAllowedButtonSingle = false; + $scope.createAllowedButtonSingleWithBlueprints = false; + $scope.createAllowedButtonMultiWithBlueprints = false; + + //when this is null, we don't check permissions $scope.currentNodePermissions = null; @@ -695,9 +700,28 @@ function listViewController($scope, $routeParams, $injector, $timeout, currentUs id = -1; } - getContentTypesCallback(id).then(function (items) { - $scope.listViewAllowedTypes = items; - }); + //$scope.listViewAllowedTypes = getContentTypesCallback(id); + getContentTypesCallback(id).then(function (listViewAllowedTypes) { + var blueprints = false; + $scope.listViewAllowedTypes = listViewAllowedTypes; + + angular.forEach(listViewAllowedTypes, function (allowedType) { + angular.forEach(allowedType.blueprints, function (value, key) { + blueprints = true; + }); + }); + + if (listViewAllowedTypes.length === 1 && blueprints === false) { + $scope.createAllowedButtonSingle = true; + } + if (listViewAllowedTypes.length === 1 && blueprints === true) { + $scope.createAllowedButtonSingleWithBlueprints = true; + } + if (listViewAllowedTypes.length > 1) { + $scope.createAllowedButtonMultiWithBlueprints = true; + } + }); + $scope.contentId = id; $scope.isTrashed = id === "-20" || id === "-21"; @@ -749,6 +773,22 @@ function listViewController($scope, $routeParams, $injector, $timeout, currentUs } } + + function createBlank(entityType,docTypeAlias) { + $location + .path("/" + entityType + "/" + entityType + "/edit/" + $scope.contentId) + .search("doctype=" + docTypeAlias + "&create=true"); + } + + function createFromBlueprint(entityType,docTypeAlias, blueprintId) { + $location + .path("/" + entityType + "/" + entityType + "/edit/" + $scope.contentId) + .search("doctype=" + docTypeAlias + "&create=true&blueprintId=" + blueprintId); + } + + $scope.createBlank = createBlank; + $scope.createFromBlueprint = createFromBlueprint; + //GO! initView(); } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js index 3ce28f0dab..361354c524 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js @@ -11,7 +11,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl $scope.allowAddMedia = false; function setupViewModel() { - $scope.images = []; + $scope.mediaItems = []; $scope.ids = []; $scope.isMultiPicker = multiPicker; @@ -67,7 +67,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl media.thumbnail = mediaHelper.resolveFileFromEntity(media, true); } - $scope.images.push(media); + $scope.mediaItems.push(media); if ($scope.model.config.idType === "udi") { $scope.ids.push(media.udi); @@ -129,7 +129,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl } $scope.remove = function (index) { - $scope.images.splice(index, 1); + $scope.mediaItems.splice(index, 1); $scope.ids.splice(index, 1); sync(); }; @@ -182,7 +182,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl media.thumbnail = mediaHelper.resolveFileFromEntity(media, true); } - $scope.images.push(media); + $scope.mediaItems.push(media); if ($scope.model.config.idType === "udi") { $scope.ids.push(media.udi); @@ -217,7 +217,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl // content picker. Then we don't have to worry about setting ids, render models, models, we just set one and let the // watch do all the rest. $timeout(function () { - angular.forEach($scope.images, function (value, key) { + angular.forEach($scope.mediaItems, function(value, key) { r.push($scope.model.config.idType === "udi" ? value.udi : value.id); }); $scope.ids = r; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html index 002ade8902..69f8230b70 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html @@ -1,35 +1,39 @@
    -

    -

    - -
    -
      -
    • +

      +

      + +
      +
        +
      • + +

        + + +

        -
        - + - - + + - +
        - - .{{image.extension}} + + .{{media.metaData.umbracoExtension.Value}} - {{image.name}} - + {{media.name}} +
      • - +
      • diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.controller.js index adf2216d58..6e67d2d251 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.controller.js @@ -116,12 +116,6 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop $scope.showIcons = $scope.model.config.showIcons || true; $scope.wideMode = $scope.model.config.hideLabel == "1"; - $scope.overlayMenu = { - show: false, - style: {}, - showFilter: false - }; - // helper to force the current form into the dirty state $scope.setDirty = function () { if ($scope.propertyForm) { @@ -136,30 +130,48 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop $scope.currentNode = newNode; $scope.setDirty(); - - $scope.closeNodeTypePicker(); }; - $scope.openNodeTypePicker = function (event) { + $scope.openNodeTypePicker = function ($event) { if ($scope.nodes.length >= $scope.maxItems) { return; } + $scope.overlayMenu = { + title: localizationService.localize('grid_insertControl'), + show: false, + style: {}, + filter: $scope.scaffolds.length > 15 ? true : false, + view: "itempicker", + event: $event, + submit: function(model) { + if(model && model.selectedItem) { + $scope.addNode(model.selectedItem.alias); + } + $scope.overlayMenu.show = false; + $scope.overlayMenu = null; + }, + close: function() { + $scope.overlayMenu.show = false; + $scope.overlayMenu = null; + } + }; + // this could be used for future limiting on node types - $scope.overlayMenu.scaffolds = []; + $scope.overlayMenu.availableItems = []; _.each($scope.scaffolds, function (scaffold) { - $scope.overlayMenu.scaffolds.push({ + $scope.overlayMenu.availableItems.push({ alias: scaffold.contentTypeAlias, name: scaffold.contentTypeName, icon: iconHelper.convertFromLegacyIcon(scaffold.icon) }); }); - if ($scope.overlayMenu.scaffolds.length == 0) { + if ($scope.overlayMenu.availableItems.length === 0) { return; } - if ($scope.overlayMenu.scaffolds.length == 1) { + if ($scope.overlayMenu.availableItems.length === 1) { // only one scaffold type - no need to display the picker $scope.addNode($scope.scaffolds[0].contentTypeAlias); return; @@ -168,10 +180,6 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop $scope.overlayMenu.show = true; }; - $scope.closeNodeTypePicker = function () { - $scope.overlayMenu.show = false; - }; - $scope.editNode = function (idx) { if ($scope.currentNode && $scope.currentNode.key == $scope.nodes[idx].key) { $scope.currentNode = undefined; @@ -359,8 +367,6 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop $scope.currentNode = $scope.nodes[0]; } - $scope.overlayMenu.showFilter = $scope.scaffolds.length > 15; - inited = true; } } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.html index 9a5d75ae92..0117bac92d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.html @@ -42,33 +42,13 @@
      -
      -
      -
      - -
      - - - - -
      -
      - + + + +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/radiobuttons/radiobuttons.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/radiobuttons/radiobuttons.html index 3231e3c7e9..a5fc2bfb39 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/radiobuttons/radiobuttons.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/radiobuttons/radiobuttons.html @@ -1,11 +1,16 @@ 
    • -
    diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html index 79a9703c73..fdae716b39 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html @@ -19,7 +19,7 @@ name="email" id="email" val-email - required + ng-required="true" val-server-field="Email" /> Required diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index 7646851cd7..7864d3baae 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -209,7 +209,7 @@ Sidetitel Egenskaber Dette dokument er udgivet, men ikke synligt da den overliggende side '%0%' ikke er udgivet! - Upd: dette dokument er udgiver, men er ikke i cachen (intern fejl) + Ups: dette dokument er udgivet, men er ikke i cachen (intern fejl) Kunne ikke hente url'en Dette dokument er udgivet, men dets url ville kollidere med indholdet %0% Udgiv @@ -260,6 +260,10 @@ Kan ikke uploade denne fil, den har ikke en godkendt filtype Maks filstørrelse er Medie rod + Flytning af mediet fejlede + Kopiering af mediet fejlede + Oprettelse af mappen under parent med id %0% fejlede + Omdøbning af mappen med id %0% fejlede Opret et nyt medlem diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml index 598748a4eb..73f213b8bc 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml @@ -1135,7 +1135,6 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à Réinitialiser Définir le recadrage - Donnez un alias au recadrage ainsi que sa largeur et sa hauteur par défaut Sauvegarder le recadrage Ajouter un nouveau recadrage diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml index 98a63a946c..d42511abdb 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml @@ -8,7 +8,7 @@ Beheer domeinnamen Documentgeschiedenis Node bekijken - Wijzig document type + Wijzig documenttype Kopiëren Nieuw Nieuwe package @@ -38,7 +38,7 @@ Bijwerken Rechten instellen Deblokkeer - Content sjabloon aanmaken + Content template aanmaken Uitnodiging opnieuw versturen @@ -60,7 +60,7 @@ zouden moeten worden vermeden. Gebruik bij voorkeur de cultuurinstelling hierboven.]]> Overerven Cultuur - of erf de cultuur over van de ouder nodes. Zal ook van toepassing
    + of erf de cultuur over van de oudernodes. Zal ook van toepassing
    zijn op de huidige node, tenzij een domein hieronder ook van toepassing is.]]>
    Domeinen @@ -110,7 +110,7 @@ Documenttype gewijzigd Eigenschappen toewijzen Toewijzen aan eigenschap - Nieuw sjabloon + Nieuwe template Nieuw type geen Inhoud @@ -149,7 +149,7 @@ Pagina Titel Eigenschappen Dit document is gepubliceerd maar niet zichtbaar omdat de bovenliggende node '%0%' niet gepubliceerd is - Dit document is gepubliceerd, maar het is niet in de cache (interne serverfout) + Dit document is gepubliceerd, maar het staat niet in de cache (interne serverfout) Kan de Url niet ophalen Dit document is gepubliceerd, maar de Url conflicteert met %0% Publiceren @@ -179,14 +179,14 @@ Voeg nog een tekstvak toe Verwijder dit tekstvak Content root - Deze waarde is verborgen. Indien u toegang nodig heeft om deze waarde te bekijken, contacteer dan uw website administrator. + Deze waarde is verborgen. Indien u toegang nodig heeft om deze waarde te bekijken, neem dan contact op met uw websitebeheerder. Deze waarde is verborgen Klik om te uploaden Of klik hier om bestanden te kiezen Dit bestand heeft niet het juiste file-type. Dit bestand kan niet geupload worden. - Max file size is + Maximale bestandsgrootte is Maak nieuwe member aan @@ -196,16 +196,16 @@ Waar wil je de nieuwe %0% aanmaken? Aanmaken onder Kies een type en een titel - "Documenttypes".]]> - "Mediatypes".]]> + "Documenttypes".]]> + "Mediatypes".]]> Document Type zonder template - Nieuwe folder + Nieuwe map Nieuw data type Open je website - Verbergen - Als Umbraco niet geopend wordt dan moet je misschien popups toelaten voor deze site. + Als Umbraco niet geopend wordt dan moet je mogelijk popups toestaan voor deze site. is geopend in een nieuw venster Herstarten Bezoek @@ -216,7 +216,7 @@ Negeer wijzigingen Wijzigingen niet opgeslagen Weet je zeker dat deze pagina wilt verlaten? - er zijn onopgeslagen wijzigingen - Depubliceren zal deze pagina en alle onderliggend paginas verwijderen van de site. + Depubliceren zal deze pagina en alle onderliggende paginas verwijderen van de site. Done @@ -274,8 +274,8 @@ De items worden nu uit de prullenbak verwijderd. Sluit dit venster niet terwijl de actie nog niet voltooid is. De prullenbak is nu leeg. Als items worden verwijderd uit de prullenbak, zijn ze voorgoed verwijderd. - regexlib.com ondervindt momenteel prolemen waarover we geen controle hebben. Onze excuses voor het ongemak.]]> - Zoek naar een regular expressie om validatie aan een formulierveld toe te voegen. Voorbeeld: 'email, 'post-code' 'url' + regexlib.com ondervindt momenteel problemen waarover we geen controle hebben. Onze excuses voor het ongemak.]]> + Zoek naar een reguliere expressie om validatie aan een formulierveld toe te voegen. Voorbeeld: 'email, 'post-code' 'url' Verwijder Macro Verplicht veld Site is opnieuw geïndexeerd @@ -284,14 +284,14 @@ Aantal kolommen Aantal regels Plaats een placeholder id door een ID op uw placeholder te zetten kunt u inhoud plaatsen in deze template vanuit onderliggende templates, - door te referreren naar deze ID door gebruik te maken van een <asp:content /> element.]]> + door te verwijzen naar deze ID door gebruik te maken van een <asp:content /> element.]]>
    Selecteer een placeholder id uit onderstaande lijst. U kunt alleen Id's kiezen van de master van de huidige template..]]> Klik op de afbeelding voor volledige grootte Kies een item Toon cache item Relateer aan origineel - Descendants meenemen + Onderliggende nodes meenemen De vriendelijkste community Link naar pagina Opent het gelinkte document in een nieuw venster of tab @@ -362,8 +362,8 @@ Breedte en hoogte - Je data is opgeslagen, maar voordat je deze pagina kunt publiceren moet je eerst aan paar problemen herstellen: - Het wachtwoord veranderen wordt door de huidige Membership Provider niet ondersteund (EnablePasswordRetrieval moet op true staan) + Je data is opgeslagen, maar voordat je deze pagina kunt publiceren moet je eerst aan paar problemen oplossen: + Veranderen van het wachtwoord wordt door de huidige Membership Provider niet ondersteund (EnablePasswordRetrieval moet op true staan) %0% bestaat al Er zijn fouten geconstateerd: Er zijn fouten geconstateerd: @@ -378,8 +378,8 @@ Een error ontvangen van de server Het opgegeven bestandstype is niet toegestaan ​​door de beheerder OPMERKING! Ondanks dat CodeMiror is ingeschakeld, is het uitgeschakeld in Internet Explorer omdat het niet stabiel genoeg is. - Zowel de alias als de naam van het nieuwe eigenschappen type moeten worden ingevuld! - Er is een probleem met de lees/schrijf rechten op een bestand of map + Zowel de alias als de naam van het nieuwe eigenschappentype moeten worden ingevuld! + Er is een probleem met de lees/schrijfrechten op een bestand of map Error bij het laden van Partial View script (file: %0%) Error bij het laden van userControl '%0%' Vul een titel in @@ -624,7 +624,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Er zal een email worden gestuurd naar het emailadres van jouw account. Hierin staat een link om je wachtwoord te resetten Een email met daarin de wachtwoord reset uitleg zal worden gestuurd als het emailadres in onze database voorkomt. Terug naar loginformulier - Geeft alsjeblieft een nieuw wachtwoord op + Geef alsjeblieft een nieuw wachtwoord op Je wachtwoord is aangepast De link die je hebt aangeklikt is niet (meer) geldig. Umbraco: Wachtwoord Reset @@ -646,7 +646,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je De huidige node is niet toegestaan onder de geselecteerde node vanwege het node type De huidige node kan niet naar een van zijn subpagina’s worden verplaatst. De huidige node kan niet worden gebruikt op root-niveau - Deze actie is niet toegestaan omdat je onvoldoende rechten hebt op 1 of meer subitems. + Deze actie is niet toegestaan omdat je onvoldoende rechten hebt op één of meer subitems. Relateer gekopieerde items aan het origineel @@ -705,7 +705,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Package naam Package bevat geen inhoud
    - Je kunt dit package veilig verwijderen door 'verwijder package' te klikken. + Je kunt deze package veilig verwijderen door op 'verwijder package' te klikken. ]]>
    Geen upgrades beschikbaar Package opties @@ -717,7 +717,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Verwijder package Waarschuwing: alle documenten, media etc, die afhankelijk zijn van de items die je verwijderd, zullen niet meer werken en kan leiden tot een instabiele installatie, - wees dus voorzichtig met verwijderen. Als je niet zeker bent, neem dan contact op met de auteur van de package. + wees dus voorzichtig met verwijderen. Als je het niet zeker weet, neem dan contact op met de auteur van de package. ]]> Download update uit de repository Upgrade package @@ -734,11 +734,11 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Aan het installeren... Aan het herstarten, een ongenblik geduld aub... Geinstalleerd! Je browser zal nu automatisch ververst worden... - Kruk op "finish" om de installate te voltooien en de pagina te verversen. + Klik op "finish" om de installatie te voltooien en de pagina te verversen. Plakken met alle opmaak (Niet aanbevolen) - De tekst die je probeert te plakken bevat speciale karakters en/of opmaak. Dit kan veroorzaakt worden doordat de tekst vanuit Microsoft Word is gekopieerd. Umbraco kan deze speciale karakters en formattering automatisch verwijderen zodat de geplakte tekst geschikt is voor het web. + De tekst die je probeert te plakken bevat speciale tekens en/of opmaak. Dit kan veroorzaakt worden doordat de tekst vanuit Microsoft Word is gekopieerd. Umbraco kan deze speciale tekens en formattering automatisch verwijderen zodat de geplakte tekst geschikt is voor het web. Plakken als ruwe tekst en alle opmaak verwijderen Plakken, en verwijder de opmaak (aanbevolen) @@ -755,7 +755,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Kies de pagina met het login-formulier Verwijder beveiliging Kies de pagina's die het login-formulier en de error-berichten bevatten - Kies de roles wie toegang hebben tot deze pagina + Kies de roles die toegang hebben tot deze pagina Geef de gebruikersnaam en wachtwoord voor deze pagina Eenvoudig: Beveilig door middel van gebruikersnaam en wachtwoord Als je eenvoudige beveiliging wilt gebruiken met behulp van een enkele gebruikersnaam en wachtwoord @@ -795,7 +795,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Bijschrift Link In een nieuw venster openen - Voer het bijschrijft in + Voer het bijschrift in Voer de link in @@ -803,9 +803,9 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Huidige versie - Rode tekst wordt niet getoond in de geselecteerde versie , groen betekent toegevoegd]]> + Rode tekst wordt niet getoond in de geselecteerde versie, groen betekent toegevoegd]]> Document is teruggezet - Hiermee wordt de geselecteerde versie als html getoond, als u de verschillen tussen de 2 versies tegelijk wilt zien, gebruik dan de diff view + Hiermee wordt de geselecteerde versie als html getoond, als u de verschillen tussen de twee versies tegelijk wilt zien, gebruik dan de diff view Terugzetten naar Selecteer versie Bekijk @@ -865,11 +865,11 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Wegens onvoldoende rechten kon deze handeling kon niet worden uitegevoerd Geannuleerd Uitvoering is g eannuleerd door de plugin van een 3e partij - Publicatie werd geannuleerd doordeeen plugin van een 3e partij - Eigenschappen type bestaat al - Eigenschappen type aangemaakt + Publicatie werd geannuleerd door een plugin van een 3e partij + Eigenschappentype bestaat al + Eigenschappentype aangemaakt Data type: %1%]]> - Eigenschappen type verwijderd + Eigenschappentype verwijderd Inhoudstype opgeslagen Tab aangemaakt Tab verwijderd @@ -941,9 +941,9 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Invoegen dictionary item Invoegen Macro Invoegen Umbraco page field - Basis sjabloon + Basistemplate Quick Guide voor Umbraco template tags - Sjabloon + Template Image @@ -996,11 +996,11 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Sta toe op root-niveau Sta editors toe om content van dit type aan te maken op root-niveau Toegestane child node types - Sta contetn van een bepaalde type toe om onder dit type aangemaakt te kunnen worden + Sta content van een bepaald type toe om onder dit type aangemaakt te kunnen worden Kies child node - Overerfde tabs en properties van een bestaand document-type. Nieuwe tabs worden toegevoegd aan het huidige document-type of samengevoegd als een tab met de identieke naam al bestaat. - Dit content-type wordt gebruikt in een compositie en kan daarom niet zelf een compositie worden. - Er zijn geen content-typen beschikbaar om als compositie te gebruiken. + Overgeërfde tabs en properties van een bestaand documenttype. Nieuwe tabs worden toegevoegd aan het huidige documenttype of samengevoegd als een tab met dezelfde naam al bestaat. + Dit contenttype wordt gebruikt in een compositie en kan daarom niet zelf een compositie worden. + Er zijn geen contenttypen beschikbaar om als compositie te gebruiken. Beschikbare editors Herbruik Editor instellingen @@ -1011,10 +1011,10 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Selecteer de map om te verplaatsen Selecteer de map om te kopieren naar de boomstructuur onder - Alle Document types + Alle Documenttypes Alle documenten Alle media items - die gebruik maken van dit document type zullen permanent verwijderd worden. Bevestig aub dat je deze ook wilt verwijderen. + die gebruik maken van dit documenttype zullen permanent verwijderd worden. Bevestig aub dat je deze ook wilt verwijderen. die gebruik maken van dit media type zullen permanent verwijderd worden. Bevestig aub dat je deze ook wilt verwijderen. die gebruik maken van dit member type zullen permanent verwijderd worden. Bevestig aub dat je deze ook wilt verwijderen. en alle documenten van dit type @@ -1059,7 +1059,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Hoofdletters URL-encoderen Speciale karakters in URL's worden geëncodeerd - Zal alleen worden gebruikt waneer de bovenstaande veld waardes leeg zijn + Zal alleen worden gebruikt waneer de bovenstaande veldwaardes leeg zijn Dit veld zal alleen worden gebruikt als het primaire veld leeg is Ja, met tijd. Scheidingsteken: @@ -1083,7 +1083,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je De Umbraco Robot ]]> - Geen vertaal-gebruikers gevonden. Maak eerst een vertaal-gebruiker aan voordat je pagina's voor vertaling verstuurd + Geen vertaal-gebruikers gevonden. Maak eerst een vertaal-gebruiker aan voordat je pagina's voor vertaling verstuurt De pagina '%0%' is verstuurd voor vertaling Stuur voor vertaling Totaal aantal woorden @@ -1132,7 +1132,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Toegang - Gebaseerd op de gebruikers groepen en start pagina's heeft de bruiker toegang tot de volgende pagina's + Gebaseerd op de gebruikersgroepen en startpagina's heeft de gebruiker toegang tot de volgende pagina's Toegang geven Beheerders Categorieveld @@ -1143,7 +1143,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je is niet gedeblokkeerd Het wachtwoord is niet gewijzigd Bevestig nieuw password - Je kunt je wachtwoord veranderen door onderstaan formulier in te vullen en op de knop 'Verander wachtwoord' te klikken + Je kunt je wachtwoord veranderen door onderstaand formulier in te vullen en op de knop 'Verander wachtwoord' te klikken Inhoudskanaal Nog een gebruiker aanmaken Maak nieuwe gebruikers aan om hun toegang te geven tot Umbraco. Wanneer een nieuwe gebruiker wordt aangemaakt wordt er een wachtwoord gegenereerd dat je met hun kan delen. @@ -1158,15 +1158,15 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Nog een gebruiker uitnodigen Nodig gebruikers uit om hen toegang te geven to Umbraco. Een uitnodiging wordt via e-mail verstuurd met instructies hoe de gebruiker kan inloggen. Taal - Stel de taal in die gebruiker zal zien in menu's en dialoog vensters - Laatst geblokkeerd datu, + Stel de taal in die gebruiker zal zien in menu's en dialoogvensters + Laatst geblokkeerd datum Laatste keer ingelogd - Laatste keer paswoord gewijzigd + Laatste keer wachtwoord gewijzigd Loginnaam Startnode in Mediabibliotheek Beperk de mediabibliotheek tot een specifieke startnode Startnodes in Mediabibliotheek - Beperk de mediabibliotheek tot een specifieke startnodes + Beperk de mediabibliotheek tot een specifieke startnode Secties Blokkeer Umbraco toegang heeft nog niet ingelogd @@ -1195,9 +1195,9 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Geen startnode geselecteerd Geen startnodes geselecteerd Startnode in Content - Beperk de content toegan een specifieke start node + Beperk de content toegang tot een specifieke startnode Startnodes in Content - Beperk de content toegan een specifieke start nodes + Beperk de content toegang tot specifieke startnodes Laatste keer bijgewerkt is aangemaakt De gebruiker is aangemaakt. Om in te loggen in Umbraco gebruik je onderstaand wachtwoord. @@ -1207,7 +1207,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Gebruikersgroep is uitgenodigd Een uitnodiging is gestuurd naar de nieuwe gebruiker met informatie over hoe in te loggen in Umbraco - Hallo en welk in Umbraco! Binnen ongeveer 1 minuut kan je aan de slag. Je moet enkel je wachtwoord instellen en een foto toevoegen. + Hallo en welkom in Umbraco! Binnen ongeveer één minuut kan je aan de slag. Je moet enkel je wachtwoord instellen en een foto toevoegen. Wijzig je foto zodat andere gebruikers je makkelijk kunnen herkennen. Auteur Wijzig @@ -1313,7 +1313,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Uitnodigen Uitnodiging opnieuw aan het versturen... Verwijder gebruiker - Ben je zeker dat je deze gebruiker wil verwijderen? + Weet je zeker dat je deze gebruiker wil verwijderen? Validatie @@ -1331,9 +1331,9 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je 3: Configuration file path --> Waarde is insteld naar the aanbevolen waarde: '%0%'. - Waarde was '%1%' voor XPath '%2%' in configuratie bestand '%3%'. - De verwachtte waarde voor '%2%' is '%1%' in configuratie bestand '%3%', maar is '%0%'. - Onverwachte waarde '%0%' gevonden voor '%2%' in configuratie bestand '%3%'. + Waarde was '%1%' voor XPath '%2%' in configuratiebestand '%3%'. + De verwachte waarde voor '%2%' is '%1%' in configuratiebestand '%3%', maar is '%0%'. + Onverwachte waarde '%0%' gevonden voor '%2%' in configuratiebestand '%3%'. @@ -1402,7 +1402,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je 0: Comma delimitted list of headers found --> %0%.]]> - Er zijn geen headeres gevonden welke informatie over de gebruikte website technologie prijsgeven! + Er zijn geen headers gevonden die informatie prijsgeven over de gebruikte website technologie! In de Web.config werd system.net/mailsettings niet gevonden In de Web.config sectie system.net/mailsettings is de host niet geconfigureerd. SMTP instellingen zijn correct ingesteld en werken zoals verwacht. diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml index 779a3c2a76..918e1e31c0 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml @@ -960,8 +960,6 @@ Naciśnij przycisk instaluj, aby zainstalować bazę danych Umb Resetuj - Zdefiniuj przycięcie - Ustaw alias dla przycięcia, a także jego domyślną szerokość i długość Zapisz przycięcie Dodaj nowe przycięcie diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml index 942f77e85b..3280d99997 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml @@ -788,8 +788,6 @@ Сбросить - Задать рамку - Задайте рамке имя (алиас), а также ширину и высоту по-умолчанию Сохранить рамку Добавить новую рамку diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml index 7a3380996c..262df44eaf 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml @@ -419,7 +419,7 @@ nuvarande Inbäddning Hämta - valgt + valda Bakgrundsfärg @@ -625,8 +625,6 @@ Återställ - Definiera beskräning - Ge beskärningen ett alias och dess standardbredd och -höjd spara beskärning Lägg till ny beskärning diff --git a/src/Umbraco.Web.UI/Umbraco/developer/Macros/editMacro.aspx b/src/Umbraco.Web.UI/Umbraco/developer/Macros/editMacro.aspx index 9bad79d6df..ccdb593287 100644 --- a/src/Umbraco.Web.UI/Umbraco/developer/Macros/editMacro.aspx +++ b/src/Umbraco.Web.UI/Umbraco/developer/Macros/editMacro.aspx @@ -92,7 +92,7 @@ -  Seconds +  Seconds @@ -137,7 +137,7 @@ Required
    - + @@ -149,10 +149,10 @@ Required
    Numbers only
    - + - + @@ -160,11 +160,11 @@ Required
    - + Required
    - + Required
    @@ -178,7 +178,7 @@ <%-- The macro parameter will automatically get sort order when created. --%> - + diff --git a/src/Umbraco.Web.UI/Umbraco/dialogs/ChangeDocType.aspx b/src/Umbraco.Web.UI/Umbraco/dialogs/ChangeDocType.aspx index 058954deee..00040e6584 100644 --- a/src/Umbraco.Web.UI/Umbraco/dialogs/ChangeDocType.aspx +++ b/src/Umbraco.Web.UI/Umbraco/dialogs/ChangeDocType.aspx @@ -19,7 +19,7 @@ .umb-dialog .umb-control-group .umb-el-wrap { overflow: hidden; } .umb-dialog .umb-control-group .umb-el-wrap label { float: left; width: 140px; font-weight: bold; } .umb-dialog .umb-control-group .umb-el-wrap label:after { content:":"; } - .umb-dialog .umb-control-group .umb-el-wrap .controls-row { float: left; width: 280px; padding-top: 8px; } + .umb-dialog .umb-control-group .umb-el-wrap .controls-row { float: left; width: 280px; padding-bottom: 8px; } .umb-dialog .umb-control-group .umb-el-wrap .controls-row select { width: auto; } diff --git a/src/Umbraco.Web/Controllers/UmbLoginController.cs b/src/Umbraco.Web/Controllers/UmbLoginController.cs index 7edcae782e..760de76328 100644 --- a/src/Umbraco.Web/Controllers/UmbLoginController.cs +++ b/src/Umbraco.Web/Controllers/UmbLoginController.cs @@ -37,7 +37,6 @@ namespace Umbraco.Web.Controllers //redirect to current page by default return RedirectToCurrentUmbracoPage(); - //return RedirectToCurrentUmbracoUrl(); } } } diff --git a/src/Umbraco.Web/Editors/ContentControllerBase.cs b/src/Umbraco.Web/Editors/ContentControllerBase.cs index 6a77e35409..2d5a61d1f7 100644 --- a/src/Umbraco.Web/Editors/ContentControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentControllerBase.cs @@ -106,7 +106,7 @@ namespace Umbraco.Web.Editors protected virtual void HandleInvalidModelState(IErrorModel display) { - //lasty, if it is not valid, add the modelstate to the outgoing object and throw a 403 + //lastly, if it is not valid, add the modelstate to the outgoing object and throw a 403 if (!ModelState.IsValid) { display.Errors = ModelState.ToErrorDictionary(); diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 9bb80cc2b3..63346f177a 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -196,20 +196,6 @@ namespace Umbraco.Web.Editors public CreatedContentTypeCollectionResult PostCreateCollection(int parentId, string collectionName, bool collectionCreateTemplate, string collectionItemName, bool collectionItemCreateTemplate, string collectionIcon, string collectionItemIcon) { - var storeInContainer = false; - var allowUnderDocType = -1; - // check if it's a folder - if (Services.ContentTypeService.Get(parentId) == null) - { - storeInContainer = true; - } else - { - // if it's not a container, we'll change the parentid to the root, - // and use the parent id as the doc type the collection should be allowed under - allowUnderDocType = parentId; - parentId = -1; - } - // create item doctype var itemDocType = new ContentType(parentId); itemDocType.Name = collectionItemName; @@ -247,20 +233,16 @@ namespace Umbraco.Web.Editors // save collection doctype Services.ContentTypeService.Save(collectionDocType); - // test if the parent id exist and then allow the collection underneath - if (storeInContainer == false && allowUnderDocType != -1) + // test if the parent exist and then allow the collection underneath + var parentCt = Services.ContentTypeService.GetContentType(parentId); + if (parentCt != null) { - var parentCt = Services.ContentTypeService.Get(allowUnderDocType); - if (parentCt != null) - { - var allowedCts = parentCt.AllowedContentTypes.ToList(); - allowedCts.Add(new ContentTypeSort(collectionDocType.Id, allowedCts.Count())); - parentCt.AllowedContentTypes = allowedCts; - Services.ContentTypeService.Save(parentCt); - } + var allowedCts = parentCt.AllowedContentTypes.ToList(); + allowedCts.Add(new ContentTypeSort(collectionDocType.Id, allowedCts.Count())); + parentCt.AllowedContentTypes = allowedCts; + Services.ContentTypeService.Save(parentCt); } - return new CreatedContentTypeCollectionResult { CollectionId = collectionDocType.Id, diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index f61cbc5952..fe15c4d33b 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -424,12 +424,25 @@ namespace Umbraco.Web.Editors public HttpResponseMessage PostMove(MoveOrCopy move) { var toMove = ValidateMoveOrCopy(move); + var destinationParentID = move.ParentId; + var sourceParentID = toMove.ParentId; + + var moveResult = Services.MediaService.WithResult().Move(toMove, move.ParentId); - Services.MediaService.Move(toMove, move.ParentId); - - var response = Request.CreateResponse(HttpStatusCode.OK); - response.Content = new StringContent(toMove.Path, Encoding.UTF8, "text/plain"); - return response; + if (sourceParentID == destinationParentID) + { + return Request.CreateValidationErrorResponse(new SimpleNotificationModel(new Notification("",Services.TextService.Localize("media/moveToSameFolderFailed"),SpeechBubbleIcon.Error))); + } + if (moveResult == false) + { + return Request.CreateValidationErrorResponse(new SimpleNotificationModel()); + } + else + { + var response = Request.CreateResponse(HttpStatusCode.OK); + response.Content = new StringContent(toMove.Path, Encoding.UTF8, "text/plain"); + return response; + } } /// diff --git a/src/Umbraco.Web/Editors/PasswordChanger.cs b/src/Umbraco.Web/Editors/PasswordChanger.cs index 69cc28ccb6..ad8a2a6f60 100644 --- a/src/Umbraco.Web/Editors/PasswordChanger.cs +++ b/src/Umbraco.Web/Editors/PasswordChanger.cs @@ -67,8 +67,9 @@ namespace Umbraco.Web.Editors throw new InvalidOperationException("The membership provider cannot have a password format of " + membershipPasswordHasher.MembershipProvider.PasswordFormat + " and be configured with secured hashed passwords"); } - //Are we resetting the password?? In ASP.NET Identity APIs, this flag indicates that an admin user is changing another user's password - //without knowing the original password. + //Are we resetting the password? + //This flag indicates that either an admin user is changing another user's password without knowing the original password + // or that the password needs to be reset to an auto-generated one. if (passwordModel.Reset.HasValue && passwordModel.Reset.Value) { //if it's the current user, the current user cannot reset their own password @@ -109,7 +110,6 @@ namespace Umbraco.Web.Editors } //we cannot arbitrarily change the password without knowing the old one and no old password was supplied - need to return an error - //TODO: What if the current user is admin? We should allow manually changing then? if (passwordModel.OldPassword.IsNullOrWhiteSpace()) { //if password retrieval is not enabled but there is no old password we cannot continue @@ -161,10 +161,43 @@ namespace Umbraco.Web.Editors } } - //Are we resetting the password?? - //TODO: I don't think this is required anymore since from 7.7 we no longer display the reset password checkbox since that didn't make sense. + //Are we resetting the password? + //This flag indicates that either an admin user is changing another user's password without knowing the original password + // or that the password needs to be reset to an auto-generated one. if (passwordModel.Reset.HasValue && passwordModel.Reset.Value) { + //if a new password is supplied then it's an admin user trying to change another user's password without knowing the original password + //this is only possible when using a membership provider if the membership provider supports AllowManuallyChangingPassword + if (passwordModel.NewPassword.IsNullOrWhiteSpace() == false) + { + if (membershipProvider is MembershipProviderBase umbracoBaseProvider && umbracoBaseProvider.AllowManuallyChangingPassword) + { + //this provider allows manually changing the password without the old password, so we can just do it + try + { + var result = umbracoBaseProvider.ChangePassword(username, string.Empty, passwordModel.NewPassword); + + if (result && backofficeUserManager != null && userId >= 0) + backofficeUserManager.RaisePasswordChangedEvent(userId); + + return result == false + ? Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, invalid username or password", new[] { "value" }) }) + : Attempt.Succeed(new PasswordChangedModel()); + } + catch (Exception ex) + { + _logger.WarnWithException("Could not change member password", ex); + return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, error: " + ex.Message + " (see log for full details)", new[] { "value" }) }); + } + } + else + { + return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Provider does not support manually changing passwords", new[] { "value" }) }); + } + } + + //we've made it here which means we need to generate a new password + var canReset = membershipProvider.CanResetPassword(_userService); if (canReset == false) { @@ -174,12 +207,13 @@ namespace Umbraco.Web.Editors { return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Password reset requires a password answer", new[] { "resetPassword" }) }); } + //ok, we should be able to reset it try { var newPass = membershipProvider.ResetPassword( - username, - membershipProvider.RequiresQuestionAndAnswer ? passwordModel.Answer : null); + username, + membershipProvider.RequiresQuestionAndAnswer ? passwordModel.Answer : null); if (membershipProvider.IsUmbracoUsersProvider() && backofficeUserManager != null && userId >= 0) backofficeUserManager.RaisePasswordResetEvent(userId); @@ -201,25 +235,8 @@ namespace Umbraco.Web.Editors return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Cannot set an empty password", new[] { "value" }) }); } - //This is an edge case and is only necessary for backwards compatibility: - if (membershipProvider is MembershipProviderBase umbracoBaseProvider && umbracoBaseProvider.AllowManuallyChangingPassword) - { - //this provider allows manually changing the password without the old password, so we can just do it - try - { - var result = umbracoBaseProvider.ChangePassword(username, "", passwordModel.NewPassword); - return result == false - ? Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, invalid username or password", new[] { "value" }) }) - : Attempt.Succeed(new PasswordChangedModel()); - } - catch (Exception ex) - { - _logger.Warn(ex, "Could not change member password"); - return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, error: " + ex.Message + " (see log for full details)", new[] { "value" }) }); - } - } - - //The provider does not support manually chaning the password but no old password supplied - need to return an error + //without being able to retrieve the original password, + //we cannot arbitrarily change the password without knowing the old one and no old password was supplied - need to return an error if (passwordModel.OldPassword.IsNullOrWhiteSpace() && membershipProvider.EnablePasswordRetrieval == false) { //if password retrieval is not enabled but there is no old password we cannot continue diff --git a/src/Umbraco.Web/HttpRequestExtensions.cs b/src/Umbraco.Web/HttpRequestExtensions.cs index 257bd823df..e5a1ef39ff 100644 --- a/src/Umbraco.Web/HttpRequestExtensions.cs +++ b/src/Umbraco.Web/HttpRequestExtensions.cs @@ -16,10 +16,11 @@ namespace Umbraco.Web /// /// /// + /// /// - public static string CleanForXss(this HttpRequest request, string key) + public static string CleanForXss(this HttpRequest request, string key, string valueIfNotFound = "") { - var item = request.GetItemAsString(key); + var item = request.GetItemAsString(key, valueIfNotFound); return item.CleanForXss(); } diff --git a/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs b/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs index 39caf15775..8ba943756f 100644 --- a/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs +++ b/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs @@ -51,7 +51,6 @@ break; } - // constraintValue = condition.Property.Type == "string" ? string.Format("\"{0}\"", condition.ConstraintValue) : condition.ConstraintValue; } switch (condition.Term.Operathor) diff --git a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs index 9739b7a30b..f7d886f637 100644 --- a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs @@ -312,7 +312,7 @@ namespace Umbraco.Web.PropertyEditors { if (propValues[propKey] == null) yield return new ValidationResult("Item " + (i + 1) + " '" + propType.Name + "' cannot be null", new[] { propKey }); - else if (propValues[propKey].ToString().IsNullOrWhiteSpace()) + else if (propValues[propKey].ToString().IsNullOrWhiteSpace() || (propValues[propKey].Type == JTokenType.Array && !propValues[propKey].HasValues)) yield return new ValidationResult("Item " + (i + 1) + " '" + propType.Name + "' cannot be empty", new[] { propKey }); } diff --git a/src/Umbraco.Web/Templates/TemplateRenderer.cs b/src/Umbraco.Web/Templates/TemplateRenderer.cs index e0b5c8c301..a6ef39a82b 100644 --- a/src/Umbraco.Web/Templates/TemplateRenderer.cs +++ b/src/Umbraco.Web/Templates/TemplateRenderer.cs @@ -178,7 +178,7 @@ namespace Umbraco.Web.Templates /// /// /// - /// To acheive this we temporarily change the output text writer of the current HttpResponse, then + /// To achieve this we temporarily change the output text writer of the current HttpResponse, then /// execute the controller via the handler which innevitably writes the result to the text writer /// that has been assigned to the response. Then we change the response textwriter back to the original /// before continuing . diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index 04c356a4fd..d9f872ab85 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -202,6 +202,9 @@ namespace Umbraco.Web.Trees return HasPathAccess(entity, queryStrings); } + internal override IEnumerable GetChildrenFromEntityService(int entityId) + => Services.EntityService.GetChildren(entityId, UmbracoObjectType).ToList(); + protected override IEnumerable GetChildEntities(string id, FormDataCollection queryStrings) { var result = base.GetChildEntities(id, queryStrings); diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs index 0354e62ca7..560c15b568 100644 --- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs @@ -14,6 +14,7 @@ using Umbraco.Web.Models.Trees; using Umbraco.Web.WebApi.Filters; using System.Globalization; using Umbraco.Core.Models.Entities; +using Umbraco.Core.Services; using Umbraco.Web.Actions; using Umbraco.Web.Composing; @@ -196,8 +197,9 @@ namespace Umbraco.Web.Trees entityId = entity.Id; } - IEntitySlim[] result; + return GetChildrenFromEntityService(entityId); + /* // if a request is made for the root node but user has no access to // root node, return start nodes instead if (entityId == Constants.System.Root && UserStartNodes.Contains(Constants.System.Root) == false) @@ -211,9 +213,16 @@ namespace Umbraco.Web.Trees result = Services.EntityService.GetChildren(entityId, UmbracoObjectType).ToArray(); } - return result; + return result;*/ } + /// + /// Abstract method to fetch the entities from the entity service + /// + /// + /// + internal abstract IEnumerable GetChildrenFromEntityService(int entityId); + /// /// Returns true or false if the current user has access to the node based on the user's allowed start node (path) access /// diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs index 0292a907fc..68bd538748 100644 --- a/src/Umbraco.Web/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTreeController.cs @@ -162,5 +162,12 @@ namespace Umbraco.Web.Trees { return _treeSearcher.ExamineSearch(Umbraco, query, UmbracoEntityTypes.Media, pageSize, pageIndex, out totalFound, searchFrom); } + + internal override IEnumerable GetChildrenFromEntityService(int entityId) + // Not pretty having to cast the service, but it is the only way to get to use an internal method that we + // do not want to make public on the interface. Unfortunately also prevents this from being unit tested. + // See this issue for details on why we need this: + // https://github.com/umbraco/Umbraco-CMS/issues/3457 + => ((EntityService)Services.EntityService).GetMediaChildrenWithoutPropertyData(entityId).ToList(); } } diff --git a/src/Umbraco.Web/_Legacy/Controls/TabView.cs b/src/Umbraco.Web/_Legacy/Controls/TabView.cs index 4c3779076e..9d2657dad5 100644 --- a/src/Umbraco.Web/_Legacy/Controls/TabView.cs +++ b/src/Umbraco.Web/_Legacy/Controls/TabView.cs @@ -34,7 +34,7 @@ namespace Umbraco.Web._Legacy.Controls base.CreateChildControls(); _tabList.TagName = "ul"; - _tabList.Attributes.Add("class", "nav nav-tabs umb-nav-tabs span12 -padding-left"); + _tabList.Attributes.Add("class", "nav nav-tabs umb-nav-tabs -padding-left"); base.row.Controls.Add(_tabList); _body.TagName = "div"; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/EditRelationType.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/EditRelationType.aspx.cs index 3b1217d808..5a2a136832 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/EditRelationType.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/EditRelationType.aspx.cs @@ -1,4 +1,5 @@ //TODO: Rebuild with new tree format and apis and then remove +using umbraco.uicontrols; //using System; //using System.Collections.Generic; @@ -185,14 +186,16 @@ // protected override void CreateChildControls() // { // base.CreateChildControls(); +/* + var save = tabControl.Menu.NewButton(); + save.Click +=saveMenuImageButton_Click; + save.CausesValidation = true; + save.Text = ui.Text("save"); + save.ButtonType = MenuButtonType.Primary; + save.ID = "save"; + save.ValidationGroup = "RelationType";*/ -// var relationTypeTabPage = this.tabControl.NewTabPage("Relation Type"); -// relationTypeTabPage.Controls.Add(this.idPane); -// relationTypeTabPage.Controls.Add(this.nameAliasPane); -// relationTypeTabPage.Controls.Add(this.directionPane); -// relationTypeTabPage.Controls.Add(this.objectTypePane); - -// var saveMenuImageButton = tabControl.Menu.NewButton(); +// var relationsTabPage = this.tabControl.NewTabPage("Relations"); // saveMenuImageButton.ToolTip = "save relation type"; // saveMenuImageButton.Click +=saveMenuImageButton_Click; // saveMenuImageButton.CausesValidation = true; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/protectPage.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/protectPage.aspx.cs index e3fc136bad..07d13230e5 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/protectPage.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/protectPage.aspx.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Web; using System.Web.Security; using System.Web.UI.WebControls; using Umbraco.Core; @@ -417,7 +418,7 @@ namespace umbraco.presentation.umbraco.dialogs var content = Services.ContentService.GetById(pageId); var text = content == null ? "" : content.Name; - feedback_text.Text = Services.TextService.Localize("publicAccess/paIsProtected", new[] { text }); + feedback_text.Text = HttpUtility.HtmlEncode(Services.TextService.Localize("publicAccess/paIsProtected", new[] { text })); p_setup.Visible = false; p_feedback.Visible = true; @@ -438,7 +439,7 @@ namespace umbraco.presentation.umbraco.dialogs var content = Services.ContentService.GetById(pageId); var text = content == null ? "" : content.Name; - feedback_text.Text = Services.TextService.Localize("publicAccess/paIsRemoved", new[] { text }); + feedback_text.Text = HttpUtility.HtmlEncode(Services.TextService.Localize("publicAccess/paIsRemoved", new[] { text })); p_feedback.Visible = true;