diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index d21ee5ea02..0e79851c0b 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -17,7 +17,7 @@ Assume positive intent and try to understand before being understood. Treat others as you would like to be treated. -This also goes for treating the HQ with respect. For example: don’t promote products on [our.umbraco.org](https://our.umbraco.org) that directly compete with our commercial offerings which enables us to work for a sustainable Umbraco. +This also goes for treating the HQ with respect. For example: don’t promote products on [our.umbraco.com](https://our.umbraco.com) that directly compete with our commercial offerings which enables us to work for a sustainable Umbraco. ## Open diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index c257600769..6e421da5d7 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -82,7 +82,7 @@ These wonderful volunteers will provide you with a first reply to your PR, revie You can get in touch with [the PR team](#the-pr-team) in multiple ways, we love open conversations and we are a friendly bunch. No question you have is stupid. Any questions you have usually helps out multiple people with the same question. Ask away: - If there's an existing issue on the issue tracker then that's a good place to leave questions and discuss how to start or move forward -- Unsure where to start? Did something not work as expected? Try leaving a note in the ["Contributing to Umbraco"](https://our.umbraco.org/forum/contributing-to-umbraco-cms/) forum, the team monitors that one closely +- Unsure where to start? Did something not work as expected? Try leaving a note in the ["Contributing to Umbraco"](https://our.umbraco.com/forum/contributing-to-umbraco-cms/) forum, the team monitors that one closely - We're also [active in the Gitter chatroom](https://gitter.im/umbraco/Umbraco-CMS) ## Code of Conduct diff --git a/.github/CONTRIBUTING_DETAILED.md b/.github/CONTRIBUTING_DETAILED.md index 020346dc5e..a07539da6a 100644 --- a/.github/CONTRIBUTING_DETAILED.md +++ b/.github/CONTRIBUTING_DETAILED.md @@ -31,7 +31,7 @@ Before creating bug reports, please check [this list](#before-submitting-a-bug-r ##### Before Submitting A Bug Report - * Most importantly, check **if you can reproduce the problem** in the [latest version of Umbraco](https://our.umbraco.org/download/). We might have already fixed your particular problem. + * Most importantly, check **if you can reproduce the problem** in the [latest version of Umbraco](https://our.umbraco.com/download/). We might have already fixed your particular problem. * It also helps tremendously to check if the issue you're experiencing is present in **a clean install** of the Umbraco version you're currently using. Custom code can have side-effects that don't occur in a clean install. * **Use the Google**. Whatever you're experiencing, Google it plus "Umbraco" - usually you can get some pretty good hints from the search results, including open issues and further troubleshooting hints. * If you do find and existing issue has **and the issue is still open**, add a comment to the existing issue if you have additional information. If you have the same problem and no new info to add, just "star" the issue. @@ -65,13 +65,11 @@ Most of the suggestions in the [reporting bugs](#reporting-bugs) section also co Some additional hints that may be helpful: * **Include screenshots and animated GIFs** which help you demonstrate the steps or point out the part of Umbraco which the suggestion is related to. - * **Explain why this enhancement would be useful to most Umbraco users** and isn't something that can or should be implemented as a [community package](https://our.umbraco.org/projects/). + * **Explain why this enhancement would be useful to most Umbraco users** and isn't something that can or should be implemented as a [community package](https://our.umbraco.com/projects/). ### Your First Code Contribution -Unsure where to begin contributing to Umbraco? You can start by looking through [these `Up for grabs` and issues](http://issues.umbraco.org/issues/U4?q=%28project%3A+%7BU4%7D+Difficulty%3A+%7BVery+Easy%7D+%23Easy+%23Unresolved+Priority%3A+Normal+%23Major+%23Show-stopper+State%3A+-%7BIn+Progress%7D+sort+by%3A+votes+Affected+versions%3A+-6.*+Affected+versions%3A+-4.*%29+OR+%28tag%3A+%7BUp+For+Grabs%7D+%23Unresolved+%29). - -The issue list is sorted by total number of upvotes. While not perfect, number of upvotes is a reasonable proxy for impact a given change will have. +Unsure where to begin contributing to Umbraco? You can start by looking through [these `Up for grabs` and issues](https://issues.umbraco.org/issues?q=&project=U4&tagValue=upforgrabs&release=&issueType=&search=search) or on the [new issue tracker](https://github.com/umbraco/Umbraco-CMS/issues?q=is%3Aopen+is%3Aissue+label%3Acommunity%2Fup-for-grabs). ### Pull Requests @@ -80,7 +78,7 @@ The most successful pull requests usually look a like this: * Fill in the required template * Include screenshots and animated GIFs in your pull request whenever possible. * Unit tests, while optional are awesome, thank you! - * New code is commented with documentation from which [the reference documentation](https://our.umbraco.org/documentation/Reference/) is generated + * New code is commented with documentation from which [the reference documentation](https://our.umbraco.com/documentation/Reference/) is generated Again, these are guidelines, not strict requirements. @@ -116,8 +114,8 @@ There's two big areas that you should know about: To find the general areas of something you're looking to fix or improve, have a look at the following two parts of the API documentation. - * [The AngularJS based backoffice files](https://our.umbraco.org/apidocs/ui/#/api) (to be found in `src\Umbraco.Web.UI.Client\src`) - * [The rest](https://our.umbraco.org/apidocs/csharp/) + * [The AngularJS based backoffice files](https://our.umbraco.com/apidocs/ui/#/api) (to be found in `src\Umbraco.Web.UI.Client\src`) + * [The rest](https://our.umbraco.com/apidocs/csharp/) ### What branch should I target for my contributions? diff --git a/LICENSE.md b/LICENSE.md index c5560c3ce1..fa83dba963 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # The MIT License (MIT) # -Copyright (c) 2013 Umbraco +Copyright (c) 2013-present Umbraco Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/src/ApiDocs/umbracotemplate/partials/head.tmpl.partial b/src/ApiDocs/umbracotemplate/partials/head.tmpl.partial index 591e1c1885..ccc4d50229 100644 --- a/src/ApiDocs/umbracotemplate/partials/head.tmpl.partial +++ b/src/ApiDocs/umbracotemplate/partials/head.tmpl.partial @@ -8,7 +8,7 @@ {{#_description}}{{/_description}} - + diff --git a/src/ApiDocs/umbracotemplate/styles/main.css b/src/ApiDocs/umbracotemplate/styles/main.css index 7756b2f7d4..d74d51b150 100644 --- a/src/ApiDocs/umbracotemplate/styles/main.css +++ b/src/ApiDocs/umbracotemplate/styles/main.css @@ -63,7 +63,7 @@ a:focus { } .navbar-header .navbar-brand { - background: url(https://our.umbraco.org/assets/images/logo.svg) left center no-repeat; + background: url(https://our.umbraco.com/assets/images/logo.svg) left center no-repeat; background-size: 40px auto; width:50px; } diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index d7f81c1bb1..b5af335791 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -2,7 +2,7 @@ using System.Resources; [assembly: AssemblyCompany("Umbraco")] -[assembly: AssemblyCopyright("Copyright © Umbraco 2017")] +[assembly: AssemblyCopyright("Copyright © Umbraco 2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index 7c274089f7..c00ab795d2 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -61,7 +61,8 @@ namespace Umbraco.Core.Configuration var config = WebConfigurationManager.OpenWebConfiguration(appPath); var settings = (MailSettingsSectionGroup)config.GetSectionGroup("system.net/mailSettings"); - if (settings == null || settings.Smtp == null) return false; + // note: "noreply@example.com" is/was the sample SMTP from email - we'll regard that as "not configured" + if (settings == null || settings.Smtp == null || "noreply@example.com".Equals(settings.Smtp.From, StringComparison.OrdinalIgnoreCase)) return false; if (settings.Smtp.SpecifiedPickupDirectory != null && string.IsNullOrEmpty(settings.Smtp.SpecifiedPickupDirectory.PickupDirectoryLocation) == false) return true; if (settings.Smtp.Network != null && string.IsNullOrEmpty(settings.Smtp.Network.Host) == false) diff --git a/src/Umbraco.Core/Configuration/UmbracoConfig.cs b/src/Umbraco.Core/Configuration/UmbracoConfig.cs index 6dd5617992..6a1203313e 100644 --- a/src/Umbraco.Core/Configuration/UmbracoConfig.cs +++ b/src/Umbraco.Core/Configuration/UmbracoConfig.cs @@ -193,4 +193,4 @@ namespace Umbraco.Core.Configuration //TODO: Add other configurations here ! } -} +} \ No newline at end of file diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs index 39861ac4e9..d2236bab70 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs @@ -81,12 +81,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings [ConfigurationProperty("loginBackgroundImage")] internal InnerTextConfigurationElement LoginBackgroundImage => GetOptionalTextElement("loginBackgroundImage", string.Empty); - [ConfigurationProperty("StripUdiAttributes")] - internal InnerTextConfigurationElement StripUdiAttributes - { - get { return GetOptionalTextElement("StripUdiAttributes", true); } - } - string IContentSection.NotificationEmailAddress => Notifications.NotificationEmailAddress; @@ -142,7 +136,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings bool IContentSection.EnableInheritedMediaTypes => EnableInheritedMediaTypes; - bool IContentSection.StripUdiAttributes => StripUdiAttributes; string IContentSection.LoginBackgroundImage => LoginBackgroundImage; } diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs index ef9ffeb014..fe2eea5d91 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs @@ -66,7 +66,5 @@ namespace Umbraco.Core.Configuration.UmbracoSettings bool EnableInheritedMediaTypes { get; } string LoginBackgroundImage { get; } - bool StripUdiAttributes { get; } - } -} +} \ No newline at end of file diff --git a/src/Umbraco.Core/Models/IContentTypeBase.cs b/src/Umbraco.Core/Models/IContentTypeBase.cs index ef5988344e..a1d4aee02f 100644 --- a/src/Umbraco.Core/Models/IContentTypeBase.cs +++ b/src/Umbraco.Core/Models/IContentTypeBase.cs @@ -21,7 +21,12 @@ namespace Umbraco.Core.Models string Description { get; set; } /// - /// Gets or Sets the Icon for the ContentType + /// Gets or sets the icon for the content type. The value is a CSS class name representing + /// the icon (eg. icon-home) along with an optional CSS class name representing the + /// color (eg. icon-blue). Put together, the value for this scenario would be + /// icon-home color-blue. + /// + /// If a class name for the color isn't specified, the icon color will default to black. /// string Icon { get; set; } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberGroupRepository.cs index e6783eaf6d..e0e5245734 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberGroupRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberGroupRepository.cs @@ -262,7 +262,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement var nonAssignedRoles = roleNames.Except(assignedRoles, StringComparer.CurrentCultureIgnoreCase); foreach (var toAssign in nonAssignedRoles) { - var groupId = rolesForNames.First(x => x.Text == toAssign).NodeId; + var groupId = rolesForNames.First(x => x.Text.InvariantEquals(toAssign)).NodeId; Database.Insert(new Member2MemberGroupDto { Member = mId, MemberGroup = groupId }); } } diff --git a/src/Umbraco.Tests/Services/MemberServiceTests.cs b/src/Umbraco.Tests/Services/MemberServiceTests.cs index 968b27a4f9..078336262f 100644 --- a/src/Umbraco.Tests/Services/MemberServiceTests.cs +++ b/src/Umbraco.Tests/Services/MemberServiceTests.cs @@ -292,6 +292,29 @@ namespace Umbraco.Tests.Services Assert.AreEqual(2, membersInRole.Count()); } + [Test] + public void Associate_Members_To_Roles_With_Member_Id_Casing() + { + ServiceContext.MemberService.AddRole("MyTestRole1"); + + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var member1 = MockedMember.CreateSimpleMember(memberType, "test1", "test1@test.com", "pass", "test1"); + ServiceContext.MemberService.Save(member1); + var member2 = MockedMember.CreateSimpleMember(memberType, "test2", "test2@test.com", "pass", "test2"); + ServiceContext.MemberService.Save(member2); + + // temp make sure they exist + Assert.IsNotNull(ServiceContext.MemberService.GetById(member1.Id)); + Assert.IsNotNull(ServiceContext.MemberService.GetById(member2.Id)); + + ServiceContext.MemberService.AssignRoles(new[] { member1.Id, member2.Id }, new[] { "mytestrole1" }); + + var membersInRole = ServiceContext.MemberService.GetMembersInRole("MyTestRole1"); + + Assert.AreEqual(2, membersInRole.Count()); + } + [Test] public void Associate_Members_To_Roles_With_Member_Username() { diff --git a/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs b/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs index df21739c0b..ff1b8902fa 100644 --- a/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs +++ b/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs @@ -1,8 +1,8 @@ using System; using System.Globalization; +using System.Linq; using System.Web; using LightInject; -using HtmlAgilityPack; using Moq; using NUnit.Framework; using Umbraco.Core; @@ -12,6 +12,7 @@ using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Tests.Testing.Objects.Accessors; @@ -63,14 +64,6 @@ namespace Umbraco.Tests.Web [TestCase("hello href=\"{localLink:umb://document-type/9931BDE0AAC34BABB838909A7B47570E}\" world ", "hello href=\"/my-test-url\" world ")] //this one has an invalid char so won't match [TestCase("hello href=\"{localLink:umb^://document-type/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"{localLink:umb^://document-type/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ")] - // with a-tag with data-udi attribute, that needs to be stripped - [TestCase("hello world ", "hello world ")] - // with a-tag with data-udi attribute spelled wrong, so don't need stripping - [TestCase("hello world ", "hello world ")] - // with a img-tag with data-udi id, that needs to be strippde - [TestCase("hello world ", "hello world ")] - // with a img-tag with data-udi id spelled wrong, so don't need stripping - [TestCase("hello world ", "hello world ")] public void ParseLocalLinks(string input, string result) { var serviceCtxMock = new TestObjects(null).GetServiceContextMock(); @@ -111,7 +104,7 @@ namespace Umbraco.Tests.Web //setup a quick mock of the WebRouting section Mock.Of(section => section.WebRouting == Mock.Of(routingSection => routingSection.UrlProviderMode == "AutoLegacy")), //pass in the custom url provider - new[] { testUrlProvider.Object }, + new[]{ testUrlProvider.Object }, globalSettings, new TestVariationContextAccessor(), true)) @@ -121,27 +114,5 @@ namespace Umbraco.Tests.Web Assert.AreEqual(result, output); } } - - [Test] - public void StripDataUdiAttributesUsingSrtringOnLinks() - { - var input = "hello world "; - var expected = "hello world "; - - var result = TemplateUtilities.StripUdiDataAttributes(input); - - Assert.AreEqual(expected, result); - } - - [Test] - public void StripDataUdiAttributesUsingStringOnImages() - { - var input = "hello world "; - var expected = "hello world "; - - var result = TemplateUtilities.StripUdiDataAttributes(input); - - Assert.AreEqual(expected, result); - } } -} +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js index 5fad4b944e..bd7cf964d0 100644 --- a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js +++ b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js @@ -146,7 +146,8 @@ Umbraco.Sys.registerNamespace("Umbraco.Application"); sourceUrl: currentMenuNode.childNodesUrl, updateDefinition: function() { throw "'updateDefinition' method is not supported in Umbraco 7, consider upgrading to the new v7 APIs"; - } + }, + expanded: currentMenuNode.expanded === true }; //defined getters that will throw a not implemented/supported exception Object.defineProperty(legacyNode, "menu", { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstep.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstep.directive.js index 08e0a44c0b..2dc0ebdf93 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstep.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstep.directive.js @@ -1,4 +1,17 @@ -(function() { +/** +@ngdoc directive +@name umbraco.directives.directive:umbTourStep +@restrict E +@scope + +@description +Added in Umbraco 7.8. The tour step component is a component that can be used in custom views for tour steps. + +@param {callback} onClose The callback which should be performened when the close button of the tour step is clicked +@param {boolean=} hideClose A boolean indicating if the close button needs to be shown + +**/ +(function () { 'use strict'; function TourStepDirective() { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepcontent.directive.js index 52ed358b61..909f87eac5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepcontent.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepcontent.directive.js @@ -1,4 +1,17 @@ -(function() { +/** +@ngdoc directive +@name umbraco.directives.directive:umbTourStepContent +@restrict E +@scope + +@description +Added in Umbraco 7.8. The tour step content component is a component that can be used in custom views for tour steps. +It's meant to be used in the umb-tour-step directive. +All markup in the body of the directive will be shown after the content attribute + +@param {string} content The content that needs to be shown +**/ +(function () { 'use strict'; function TourStepContentDirective() { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepcounter.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepcounter.directive.js index 7e04ef5d00..2477953580 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepcounter.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepcounter.directive.js @@ -1,4 +1,18 @@ -(function() { +/** +@ngdoc directive +@name umbraco.directives.directive:umbTourStepCounter +@restrict E +@scope + +@description +Added in Umbraco 7.8. The tour step counter component is a component that can be used in custom views for tour steps. +It's meant to be used in the umb-tour-step-footer directive. It will show the progress you have made in a tour eg. step 2/12 + + +@param {int} currentStep The current step the tour is on +@param {int} totalSteps The current step the tour is on +**/ +(function () { 'use strict'; function TourStepCounterDirective() { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepfooter.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepfooter.directive.js index fedb527972..7cfb498394 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepfooter.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepfooter.directive.js @@ -1,4 +1,16 @@ -(function() { +/** +@ngdoc directive +@name umbraco.directives.directive:umbTourStepFooter +@restrict E +@scope + +@description +Added in Umbraco 7.8. The tour step footer component is a component that can be used in custom views for tour steps. It's meant to be used in the umb-tour-step directive. +All markup in the body of the directive will be shown as the footer of the tour step + + +**/ +(function () { 'use strict'; function TourStepFooterDirective() { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepheader.directive.js index 9d32ad87a4..ec6768928f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour/umbtourstepheader.directive.js @@ -1,4 +1,16 @@ -(function() { +/** +@ngdoc directive +@name umbraco.directives.directive:umbTourStepHeader +@restrict E +@scope + +@description +Added in Umbraco 7.8. The tour step header component is a component that can be used in custom views for tour steps. It's meant to be used in the umb-tour-step directive. + + +@param {string} title The title that needs to be shown +**/ +(function () { 'use strict'; function TourStepHeaderDirective() { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js index 4bc6f08eb9..47d1431e13 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js @@ -48,7 +48,7 @@ the directive will use {@link umbraco.directives.directive:umbLockedField umbLoc **/ angular.module("umbraco.directives") - .directive('umbGenerateAlias', function ($timeout, entityResource) { + .directive('umbGenerateAlias', function ($timeout, entityResource, localizationService) { return { restrict: 'E', templateUrl: 'views/components/umb-generate-alias.html', @@ -67,7 +67,21 @@ angular.module("umbraco.directives") var updateAlias = false; scope.locked = true; - scope.placeholderText = "Enter alias..."; + + scope.labels = { + idle: "Enter alias...", + busy: "Generating alias..." + }; + + scope.placeholderText = scope.labels.idle; + + localizationService.localize('placeholders_enterAlias').then(function (value) { + scope.labels.idle = scope.placeholderText = value; + }); + + localizationService.localize('placeholders_generatingAlias').then(function (value) { + scope.labels.busy = value; + }); function generateAlias(value) { @@ -78,7 +92,7 @@ angular.module("umbraco.directives") if( value !== undefined && value !== "" && value !== null) { scope.alias = ""; - scope.placeholderText = "Generating Alias..."; + scope.placeholderText = scope.labels.busy; generateAliasTimeout = $timeout(function () { updateAlias = true; @@ -92,7 +106,7 @@ angular.module("umbraco.directives") } else { updateAlias = true; scope.alias = ""; - scope.placeholderText = "Enter alias..."; + scope.placeholderText = scope.labels.idle; } } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js index b14f8418c5..308ffbf00f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js @@ -125,13 +125,19 @@ Use this directive to generate a thumbnail grid of media items. i--; } - if (scope.includeSubFolders !== 'true') { - if (item.parentId !== parseInt(scope.currentFolderId)) { - scope.items.splice(i, 1); - i--; + + // If subfolder search is not enabled remove the media items that's not needed + // Make sure that includeSubFolder is not undefined since the directive is used + // in contexts where it should not be used. Currently only used when we trigger + // a media picker + if(scope.includeSubFolders !== undefined){ + if (scope.includeSubFolders !== 'true') { + if (item.parentId !== parseInt(scope.currentFolderId)) { + scope.items.splice(i, 1); + i--; + } } } - } @@ -152,7 +158,7 @@ Use this directive to generate a thumbnail grid of media items. } if (!item.isFolder) { - + // handle entity if(item.image) { item.thumbnail = mediaHelper.resolveFileFromEntity(item, true); @@ -161,7 +167,7 @@ Use this directive to generate a thumbnail grid of media items. } else { item.thumbnail = mediaHelper.resolveFile(item, true); item.image = mediaHelper.resolveFile(item, false); - + var fileProp = _.find(item.properties, function (v) { return (v.alias === "umbracoFile"); }); 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 5d2ac1e8b9..9cf96f8e7a 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 @@ -109,11 +109,23 @@ function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) { return umbRequestHelper.resourcePromise( $http.post(umbRequestHelper.getApiUrl("mediaApiBaseUrl", "PostMove"), - { - parentId: args.parentId, - id: args.id + { + parentId: args.parentId, + id: args.id }, {responseType: 'text'}), - 'Failed to move media'); + { + error: function(data){ + var errorMsg = 'Failed to move media'; + + if(data.parentId === data.id){ + errorMsg = 'Media can\'t be moved into itself'; + } + + return { + errorMsg: errorMsg + }; + } + }); }, 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 cb416e3974..15c738638b 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 @@ -646,10 +646,10 @@ function navigationService($rootScope, $route, $routeParams, $log, $location, $q */ hideDialog: function (showMenu) { - setMode("default"); - - if(showMenu){ + if (showMenu) { this.showMenu({ skipDefault: true, node: appState.getMenuState("currentNode") }); + } else { + setMode("default"); } }, /** diff --git a/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js index 1619ca0623..1f99659389 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js @@ -126,12 +126,21 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ /** The default error callback used if one is not supplied in the opts */ function defaultError(data, status, headers, config) { - return { + + var err = { //NOTE: the default error message here should never be used based on the above docs! errorMsg: (angular.isString(opts) ? opts : 'An error occurred!'), data: data, status: status }; + + // if "opts" is a promise, we set "err.errorMsg" to be that promise + if (typeof(opts) == "object" && typeof(opts.then) == "function") { + err.errorMsg = opts; + } + + return err; + } //create the callbacs based on whats been passed in. diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index ac8279e3ab..3100433a4a 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -66,6 +66,7 @@ // Belle styles @import "buttons.less"; @import "forms.less"; +@import "legacydialog.less"; @import "modals.less"; @import "panel.less"; @import "sections.less"; @@ -159,6 +160,7 @@ @import "components/umb-mini-editor.less"; @import "components/users/umb-user-cards.less"; +@import "components/users/umb-user-details.less"; @import "components/users/umb-user-group-picker-list.less"; @import "components/users/umb-user-group-preview.less"; @import "components/users/umb-user-preview.less"; diff --git a/src/Umbraco.Web.UI.Client/src/less/buttons.less b/src/Umbraco.Web.UI.Client/src/less/buttons.less index b1e9671de3..0b21864127 100644 --- a/src/Umbraco.Web.UI.Client/src/less/buttons.less +++ b/src/Umbraco.Web.UI.Client/src/less/buttons.less @@ -63,9 +63,6 @@ .btn-group>.btn+.dropdown-toggle { box-shadow: none; -webkit-box-shadow:none; -} - -.btn-group .btn.dropdown-toggle { border-left-width: 1px; border-left-style: solid; border-color: rgba(0,0,0,0.09); diff --git a/src/Umbraco.Web.UI.Client/src/less/canvas-designer.less b/src/Umbraco.Web.UI.Client/src/less/canvas-designer.less index 78c1616bc6..cbb38a23b1 100644 --- a/src/Umbraco.Web.UI.Client/src/less/canvas-designer.less +++ b/src/Umbraco.Web.UI.Client/src/less/canvas-designer.less @@ -81,9 +81,9 @@ a, a:hover{ .wait { display: block; - height: 280px; + height: 100%; width: 100%; - background: center center url(../img/loader.gif) no-repeat; + background:#fff center center url(../img/loader.gif) no-repeat; } /****************************/ diff --git a/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less b/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less index cc024ca5bb..2c7f07ef26 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less @@ -159,6 +159,7 @@ margin-bottom: 1px; border-radius: 0; border-bottom: 1px solid @gray-9; + padding: 10px; } .umb-help-list-item:last-child { @@ -193,6 +194,7 @@ .umb-help-list-item__title { font-size: 14px; display: block; + margin-left: 26px; } .umb-help-list-item__description { @@ -205,6 +207,7 @@ margin-right: 8px; color: @gray-4; font-size: 18px; + float: left; } .umb-help-list-item__open-icon { @@ -219,4 +222,4 @@ [data-element*="tour-"].umb-help-list-item:hover .umb-help-list-item__title { text-decoration:none; -} \ No newline at end of file +} diff --git a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-toggle.less b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-toggle.less index 73f059b4ee..150963cbb2 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-toggle.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-toggle.less @@ -10,6 +10,10 @@ } } +.umb-toggle:focus .umb-toggle__toggle{ + box-shadow: 0 1px 3px fade(@black, 12%), 0 1px 2px fade(@black, 24%); +} + .umb-toggle__handler { position: absolute; top: 0; @@ -30,6 +34,7 @@ background: @gray-8; border-radius: 90px; position: relative; + transition: box-shadow .3s; } .umb-toggle--checked .umb-toggle__toggle { @@ -43,7 +48,6 @@ /* Labels */ .umb-toggle__label { - font-size: 12px; color: @gray-2; } diff --git a/src/Umbraco.Web.UI.Client/src/less/components/card.less b/src/Umbraco.Web.UI.Client/src/less/components/card.less index e8b8325183..a302ba71b8 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/card.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/card.less @@ -101,11 +101,13 @@ } .umb-card-grid li.-four-in-row { - flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; } .umb-card-grid li.-three-in-row { flex: 0 0 33.33%; + max-width:33.33%; } .umb-card-grid .umb-card-grid-item { 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 a987c5daa3..c6fdf8a7bf 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,8 +3,8 @@ flex-flow: row wrap; .umb-color-box { - border: none; - color: white; + border: 1px solid @gray-8; + color: @white; cursor: pointer; padding: 1px; text-align: center; @@ -19,7 +19,7 @@ justify-content: center; &:hover, &:focus { - box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); + box-shadow: 0 1px 3px fade(@black, 12%), 0 1px 2px fade(@black, 24%); } &.umb-color-box--m { @@ -50,7 +50,7 @@ padding-top: 10px; .umb-color-box__label { - background: #fff; + background: @white; font-size: 14px; display: flex; flex-flow: column wrap; @@ -63,7 +63,8 @@ margin-right: -1px; text-indent: 0; text-align: left; - border: 1px solid @gray-8; + border-top: 1px solid @gray-8; + border-bottom: 1px solid @gray-8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; overflow: hidden; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-multiple-textbox.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-multiple-textbox.less index 21f59a3e2d..52cc7a9aaf 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-multiple-textbox.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-multiple-textbox.less @@ -1,4 +1,17 @@ -.umb-multiple-textbox .textbox-wrapper { +.umb-multiple-textbox{ + &__confirm{ + position: relative; + + &-action{ + margin: 0; + padding: 2px; + background: transparent; + border: 0 none; + } + } +} + +.umb-multiple-textbox .textbox-wrapper { align-items: center; margin-bottom: 15px; } @@ -7,7 +20,7 @@ margin-bottom: 0; } -.umb-multiple-textbox .textbox-wrapper i { +.umb-multiple-textbox .textbox-wrapper i:not(.icon-delete, .icon-check) { margin-right: 5px; } 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 514a73407c..5a11403bb3 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 @@ -1,5 +1,6 @@ .umb-nested-content { text-align: center; + position: relative; } .umb-nested-content--not-supported { @@ -208,11 +209,25 @@ width: 99%; } -.usky-grid.umb-nested-content__node-type-picker .cell-tools-menu { - position: relative; - transform: translate(-50%, -25%); -} +.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 diff --git a/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less new file mode 100644 index 0000000000..837506f312 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less @@ -0,0 +1,122 @@ +.umb-user-details-avtar { + margin-bottom: 20px; + padding-bottom: 20px; + border-bottom: 1px solid #d8d7d9; +} + +div.umb-user-details-actions > div { + margin-bottom: 20px; +} + +.umb-user-details-actions .umb-button { + margin-bottom: 20px; +} + +.umb-user-details-view-title { + font-size: 20px; + font-weight: bold; + color: @black; + margin-bottom: 30px; +} + +.umb-user-details-view-wrapper { + padding: 20px 60px; +} + +@media (max-width: 768px) { + + .umb-user-details-view-wrapper { + padding: 0; + } +} + +.umb-user-details-section { + margin-bottom: 40px; +} +.umb-user-details-details { + display: flex; +} + +a.umb-user-details-details__back-link { + font-weight: bold; + color: @black; +} + +.umb-user-details-details__back-link:hover { + color: @gray-4; + text-decoration: none; +} + + +@sidebarwidth: 350px; // Width of sidebar. Ugly hack because of old version of Less + +.umb-user-details-details__main-content { + flex: 1 1 auto; + margin-right: 30px; + width: calc(~'100%' - ~'@{sidebarwidth}' - ~'30px'); // Make sure that the main content area doesn't gets affected by inline styling +} + +.umb-user-details-details__main-content .umb-node-preview-add { + max-width: 100%; +} + + +.umb-user-details-details__sidebar { + flex: 0 0 @sidebarwidth; +} + +@media (max-width: 768px) { + + .umb-user-details-details { + flex-direction: column; + } + + .umb-user-details-details__main-content { + flex: 1 1 auto; + width: 100%; + margin-bottom: 30px; + margin-right: 0; + } + + .umb-user-details-details__sidebar { + flex: 1 1 auto; + width: 100%; + } +} + +.umb-user-details-details__section { + background: @gray-10; + padding: 20px; + margin-bottom: 20px; + border-radius: 3px; + border: 1px solid @gray-8; +} + +.umb-user-details-details__section-title { + font-size: 17px; + font-weight: bold; + color: @black; + margin-top: 0; + margin-bottom: 15px; +} + +.umb-user-details-details__section-description { + font-size: 12px; + line-height: 1.6em; + margin-bottom: 15px; +} + +.umb-user-details-details__information-item { + margin-bottom: 10px; + font-size: 13px; +} + +.umb-user-details-details__information-item-label { + color: @black; + font-weight: bold; +} + +.umb-user-details-details__information-item-content { + word-break: break-word; +} + diff --git a/src/Umbraco.Web.UI.Client/src/less/forms.less b/src/Umbraco.Web.UI.Client/src/less/forms.less index 6940987290..e3350b4956 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms.less @@ -580,7 +580,7 @@ div.help { text-align: center; text-shadow: 0 1px 0 @white; background-color: @gray-10; - border: 1px solid @gray-8; + border: 1px solid @purple-l3; } .add-on, .btn, diff --git a/src/Umbraco.Web.UI.Client/src/less/hacks.less b/src/Umbraco.Web.UI.Client/src/less/hacks.less index 22e2eb4566..cd32c64782 100644 --- a/src/Umbraco.Web.UI.Client/src/less/hacks.less +++ b/src/Umbraco.Web.UI.Client/src/less/hacks.less @@ -202,7 +202,7 @@ pre { //font-size: @baseFontSize - 1; // 14px to 13px color: @gray-2; line-height: @baseLineHeight; - white-space: pre-line; // 1 + white-space: pre-wrap; // 1 overflow-x: auto; // 1 background-color: @gray-10; border: 1px solid @gray-8; @@ -222,4 +222,4 @@ pre { background-color: transparent; border: 0; } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web.UI.Client/src/less/legacydialog.less b/src/Umbraco.Web.UI.Client/src/less/legacydialog.less new file mode 100644 index 0000000000..ca920d22c2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/legacydialog.less @@ -0,0 +1,58 @@ + +.umb-dialog .propertyItemheader { + width: 140px !Important; +} + +.umb-dialog .diffDropdown { + width: 400px; +} + +.umb-dialog .diffPanel { + height: 400px; +} + + +.umb-dialog .diff { + margin-top: 10px; + height: 100%; + overflow: auto; + border-top: 1px solid #ccc; + border-top: 1px solid #ccc; + padding: 5px; +} + +.umb-dialog .diff table { + width: 95%; + max-width: 95%; + margin: 0 3px; +} + +.umb-dialog .diff table th { + padding: 5px; + width: 25%; + border-bottom: 1px solid #ccc; +} + +.umb-dialog .diff table td { + border-bottom: 1px solid #ccc; + padding: 3px; +} + +.umb-dialog .diff del { + background: rgb(255, 230, 230) none repeat scroll 0%; + -moz-background-clip: -moz-initial; + -moz-background-origin: -moz-initial; + -moz-background-inline-policy: -moz-initial; +} + +.umb-dialog .diff ins { + background: rgb(230, 255, 230) none repeat scroll 0%; + -moz-background-clip: -moz-initial; + -moz-background-origin: -moz-initial; + -moz-background-inline-policy: -moz-initial; +} + +.umb-dialog .diff .diffnotice { + text-align: center; + margin-bottom: 10px; +} diff --git a/src/Umbraco.Web.UI.Client/src/less/panel.less b/src/Umbraco.Web.UI.Client/src/less/panel.less index def6d114ff..912e7d90e2 100644 --- a/src/Umbraco.Web.UI.Client/src/less/panel.less +++ b/src/Umbraco.Web.UI.Client/src/less/panel.less @@ -52,6 +52,16 @@ -webkit-flex: 1; -ms-flex: 1; flex: 1; + + &__toggle{ + margin: 10px 0; + + label{ + margin-right: 10px; + position: relative; + top: -2px; + } + } } .upload-button { 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 198885e6be..27a51bc80c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -120,6 +120,13 @@ div.umb-codeeditor .umb-btn-toolbar { // // RTE // -------------------------------------------------- +.umb-rte { + position: relative; + + .-loading { + position: absolute; + } +} .mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0px !important;} .mce-panel{background: @gray-10 !important; border-color: @gray-8 !important;} .mce-btn-group, .mce-btn{border: none !important; background: none !important;} @@ -142,11 +149,14 @@ div.umb-codeeditor .umb-btn-toolbar { /* pre-value editor */ .control-group.color-picker-preval { .thumbnail { - width: 36px; + width: 34px; + height: 34px; min-width: auto; border: none; cursor: move; border-radius: 3px; + margin-top: auto; + margin-bottom: auto; } .handle { @@ -158,19 +168,19 @@ div.umb-codeeditor .umb-btn-toolbar { div.color-picker-prediv { display: inline-flex; align-items: center; - max-width: 85%; + max-width: 100%; + flex: 1; pre { display: inline-flex; font-family: monospace; - margin-right: 10px; - margin-left: 10px; + margin-left: 15px; + margin-right: 15px; white-space: nowrap; overflow: hidden; margin-bottom: 0; vertical-align: middle; - padding-top: 7px; - padding-bottom: 7px; + padding: 6px 10px; background: #f7f7f7; flex: 0 0 auto; } @@ -199,11 +209,11 @@ div.umb-codeeditor .umb-btn-toolbar { label { border: 1px solid #fff; - padding: 7px 10px; + padding: 6px 10px; font-family: monospace; border: 1px solid #dfdfe1; background: #f7f7f7; - margin: 0 15px 0 0; + margin: 0 15px 0 3px; border-radius: 3px; } } @@ -310,7 +320,7 @@ div.umb-codeeditor .umb-btn-toolbar { .umb-mediapicker .umb-sortable-thumbnails li { flex-direction: column; - margin: 0 5px 5px 0; + margin: 0 0 5px 5px; padding: 5px; } @@ -579,6 +589,16 @@ div.umb-codeeditor .umb-btn-toolbar { } } + .imagecropper .umb-cropper__container .button-drawer { + display: flex; + justify-content: flex-end; + padding: 10px; + + button { + margin-left: 4px; + } + } + .umb-close-cropper { position: absolute; top: 3px; @@ -843,7 +863,20 @@ div.umb-codeeditor .umb-btn-toolbar { // // Nested boolean (e.g. list view bulk action permissions) -// ---------------------=====----------------------------- +// ------------------------------------------------------- .umb-nested-boolean label {margin-bottom: 8px; float: left; width: 320px;} .umb-nested-boolean label span {float: left; width: 80%;} .umb-nested-boolean label input[type='checkbox'] {margin-right: 10px; float: left;} + +// +// Custom styles of property editors in property preview in document type editor +// ----------------------------------------------------------------------------- +.umb-group-builder__property-preview { + .umb-property-editor { + .slider { + .tooltip { + display: none; + } + } + } +} diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.controller.js index c965d16c0d..ac529fc215 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.controller.js @@ -207,7 +207,7 @@ } } - $scope.allowPasswordReset = Umbraco.Sys.ServerVariables.umbracoSettings.allowPasswordReset; + $scope.allowPasswordReset = Umbraco.Sys.ServerVariables.umbracoSettings.canSendRequiredEmail && Umbraco.Sys.ServerVariables.umbracoSettings.allowPasswordReset; $scope.showLogin = function () { $scope.errorMsg = ""; 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 9b563be2df..40f5035d11 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 @@ -151,7 +151,7 @@ angular.module("umbraco") if (folder.id > 0) { entityResource.getAncestors(folder.id, "media") - .then(function(anc) { + .then(function(anc) { $scope.path = _.filter(anc, function(f) { return f.path.indexOf($scope.startNodeId) !== -1; @@ -236,7 +236,10 @@ angular.module("umbraco") $scope.onUploadComplete = function(files) { $scope.gotoFolder($scope.currentFolder).then(function() { if (files.length === 1 && $scope.model.selectedImages.length === 0) { - selectImage($scope.images[$scope.images.length - 1]); + var image = $scope.images[$scope.images.length - 1]; + $scope.target = image; + $scope.target.url = mediaHelper.resolveFile(image); + selectImage(image); } }); }; @@ -305,6 +308,23 @@ angular.module("umbraco") debounceSearchMedia(); }; + /** + * Toggle the $scope.model.allowAsRoot value to either true or false + */ + $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) { $scope.loading = true; $scope.searchOptions.pageNumber = pageNumber; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html b/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html index fc62485521..bc5c114bb6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html @@ -1,4 +1,4 @@ - diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/rename.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/rename.html index 6840e58565..ec93009a4c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/rename.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/rename.html @@ -7,8 +7,10 @@ val-form-manager>
-
{{error.errorMsg}}
-

{{error.data.message}}

+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
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 af3b954c83..6543d7a280 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html @@ -12,13 +12,16 @@
-
{{error.errorMsg}}
-

{{error.data.message}}

+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
-
- {{currentNode.name}} was copied underneath {{target.name}}
+
+ {{currentNode.name}} was copied underneath {{target.name}} +
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.controller.js index 9fae0a6304..5fa70263b9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.controller.js @@ -26,8 +26,8 @@ function DocumentTypesCreateController($scope, $location, navigationService, con $scope.showCreateDocTypeCollection = function () { $scope.model.creatingDoctypeCollection = true; - $scope.model.collectionCreateTemplate = true; - $scope.model.collectionItemCreateTemplate = true; + $scope.model.collectionCreateTemplate = !$scope.model.disableTemplates; + $scope.model.collectionItemCreateTemplate = !$scope.model.disableTemplates; }; $scope.createContainer = function () { 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 917e9147a4..d19b1329d2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.html @@ -16,8 +16,8 @@ - - Document type> + + Document type> @@ -45,8 +45,10 @@ val-form-manager>
-
{{error.errorMsg}}
-

{{error.data.message}}

+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
@@ -69,20 +71,26 @@ val-form-manager>
-
{{error.errorMsg}}
-

{{error.data.message}}

+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
- - + + + + - - + + + + diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js index 7a1a825e46..10c563a289 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js @@ -9,7 +9,7 @@ (function () { "use strict"; - function DocumentTypesEditController($scope, $routeParams, $injector, contentTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q, localizationService, overlayHelper, eventsService) { + function DocumentTypesEditController($scope, $routeParams, $injector, contentTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q, localizationService, overlayHelper, eventsService, angularHelper) { var vm = this; var evts = []; @@ -478,6 +478,15 @@ eventsService.unsubscribe(evts[e]); } }); + + // #3368 - changes on the other "buttons" do not register on the current form, so we manually have to flag the form as dirty + $scope.$watch("vm.contentType.allowedContentTypes.length + vm.contentType.allowAsRoot + vm.contentType.allowedTemplates.length + vm.contentType.isContainer", function (newVal, oldVal) { + if (oldVal === undefined) { + // still initializing, ignore + return; + } + angularHelper.getCurrentForm($scope).$setDirty(); + }); } angular.module("umbraco").controller("Umbraco.Editors.DocumentTypes.EditController", DocumentTypesEditController); 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 379a64fc14..a75c6346c7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html @@ -12,13 +12,16 @@
-
{{error.errorMsg}}
-

{{error.data.message}}

+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
-
- {{currentNode.name}} was moved underneath {{target.name}}
+
+ {{currentNode.name}} was moved underneath {{target.name}} +
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/rename.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/rename.html index f739cadb71..c52b3be6d6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/rename.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/rename.html @@ -6,8 +6,10 @@ val-form-manager>
-
{{error.errorMsg}}
-

{{error.data.message}}

+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
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 8104fcc979..97b21d6645 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html @@ -12,13 +12,16 @@
-
{{error.errorMsg}}
-

{{error.data.message}}

+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
-
- {{currentNode.name}} was copied underneath {{target.name}}
+
+ {{currentNode.name}} was copied underneath {{target.name}} +
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 5d96375b44..d6a8fa4e70 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html @@ -12,12 +12,16 @@
-
{{error.errorMsg}}
-

{{error.data.message}}

+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
-
{{currentNode.name}} was moved underneath {{target.name}}
+
+ {{currentNode.name}} was moved underneath {{target.name}} +
diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/rename.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/rename.html index 5f027cf607..0bc4aa5123 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/rename.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/rename.html @@ -6,8 +6,10 @@ val-form-manager>
-
{{error.errorMsg}}
-

{{error.data.message}}

+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/create.html b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/create.html index b7fcf00bba..36ab0e71c1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/create.html +++ b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/create.html @@ -61,8 +61,10 @@ val-form-manager>
-
{{vm.createFolderError.errorMsg}}
-

{{vm.createFolderError.data.message}}

+
+
{{vm.createFolderError.errorMsg}}
+
{{vm.createFolderError.data.message}}
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviews/create.html b/src/Umbraco.Web.UI.Client/src/views/partialviews/create.html index 4ca34379e6..59c0b0b344 100644 --- a/src/Umbraco.Web.UI.Client/src/views/partialviews/create.html +++ b/src/Umbraco.Web.UI.Client/src/views/partialviews/create.html @@ -51,8 +51,10 @@ val-form-manager>
-
{{vm.createFolderError.errorMsg}}
-

{{vm.createFolderError.data.message}}

+
+
{{vm.createFolderError.errorMsg}}
+
{{vm.createFolderError.data.message}}
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js index 4c8c5f845a..a6ef34f43b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js @@ -1,4 +1,4 @@ -function booleanEditorController($scope, $rootScope, assetsService) { +function booleanEditorController($scope) { function setupViewModel() { $scope.renderModel = { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.html index 443b677790..0f90239b0e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.html @@ -1,6 +1,10 @@
+ on-click="toggle()" + show-labels="{{model.config.labelOn ? 'true': 'false'}}" + label-position="right" + label-on="{{model.config.labelOn}}" + label-off="{{model.config.labelOn}}">
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html index e209d0cb60..c86e7f44f7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html @@ -1,5 +1,6 @@ 
+
You haven't defined any colors
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html index a70ecabf35..1056b45f9d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html @@ -3,18 +3,22 @@
- +
-
+
-
-
#{{item.value}}
{{item.label}}
+
+
+
#{{item.value}}
+ + +
Remove diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js index 7ae728a85a..287a0f48fc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js @@ -5,8 +5,9 @@ var defaultLabel = null; $scope.newColor = defaultColor; - $scope.newLavel = defaultLabel; + $scope.newLabel = defaultLabel; $scope.hasError = false; + $scope.focusOnNew = false; $scope.labels = {}; @@ -104,7 +105,6 @@ }; $scope.add = function (evt) { - evt.preventDefault(); if ($scope.newColor) { @@ -117,7 +117,9 @@ value: $scope.newColor, label: newLabel }); + $scope.newLabel = ""; $scope.hasError = false; + $scope.focusOnNew = true; return; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/datepicker/datepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/datepicker/datepicker.controller.js index 0fb0e75d09..9bed59b0d7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/datepicker/datepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/datepicker/datepicker.controller.js @@ -35,6 +35,22 @@ function dateTimePickerController($scope, notificationsService, assetsService, a } }; + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + if (newVal != oldVal) { + //check for c# System.DateTime.MinValue being passed as the clear indicator + var minDate = moment('0001-01-01'); + var newDate = moment(newVal); + + if (newDate.isAfter(minDate)) { + applyDate({ date: moment(newVal) }); + } else { + $scope.clearDate(); + } + } + }; + //handles the date changing via the date picker function applyDate(e) { angularHelper.safeApply($scope, function() { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index 38e32b7451..7d7405bedb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -285,9 +285,11 @@ angular.module("umbraco") event: event, show: true, submit: function(model) { + if (model.selectedItem) { $scope.addControl(model.selectedItem, area, index); $scope.editorOverlay.show = false; $scope.editorOverlay = null; + } } }; }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/idwithguid/idwithguid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/idwithguid/idwithguid.controller.js new file mode 100644 index 0000000000..1402226f78 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/idwithguid/idwithguid.controller.js @@ -0,0 +1,25 @@ +/** + * @ngdoc controller + * @name Umbraco.Editors.IdWithGuidValueController + * @function + * + * @description + * The controller for the idwithguid property editor, which formats the ID as normal + * with the GUID in smaller text below, as used across the backoffice. +*/ +function IdWithGuidValueController($rootScope, $scope, $filter) { + + function formatDisplayValue() { + if ($scope.model.value.length > 1) { + $scope.displayid = $scope.model.value[0]; + $scope.displayguid = $scope.model.value[1]; + } else { + $scope.displayid = $scope.model.value; + } + } + + //format the display value on init: + formatDisplayValue(); +} + +angular.module('umbraco').controller("Umbraco.PropertyEditors.IdWithGuidValueController", IdWithGuidValueController); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/idwithguid/idwithguid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/idwithguid/idwithguid.html new file mode 100644 index 0000000000..a3d9970cd0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/idwithguid/idwithguid.html @@ -0,0 +1,4 @@ +
+
{{ displayid }}
+ {{ displayguid }} +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js index 04bfe98284..f663f91d85 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js @@ -171,7 +171,7 @@ angular.module('umbraco') }) .run(function (mediaHelper, umbRequestHelper) { if (mediaHelper && mediaHelper.registerFileResolver) { - + //NOTE: The 'entity' can be either a normal media entity or an "entity" returned from the entityResource // they contain different data structures so if we need to query against it we need to be aware of this. mediaHelper.registerFileResolver("Umbraco.ImageCropper", function (property, entity, thumbnail) { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html index 5e920cee01..b4ebaa1f1b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html @@ -2,7 +2,6 @@ ng-controller="Umbraco.PropertyEditors.ImageCropperController"> - - - +
  • diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js index a4b4518fd7..2d411597cf 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js @@ -2,6 +2,9 @@ var backspaceHits = 0; + // Set the visible prompt to -1 to ensure it will not be visible + $scope.promptIsVisible = "-1"; + $scope.sortableOptions = { axis: 'y', containment: 'parent', @@ -89,6 +92,9 @@ }; $scope.remove = function (index) { + // Make sure not to trigger other prompts when remove is triggered + $scope.hidePrompt(); + var remainder = []; for (var x = 0; x < $scope.model.value.length; x++) { if (x !== index) { @@ -98,6 +104,20 @@ $scope.model.value = remainder; }; + $scope.showPrompt = function (idx, item){ + + var i = $scope.model.value.indexOf(item); + + // Make the prompt visible for the clicked tag only + if (i === idx) { + $scope.promptIsVisible = i; + } + } + + $scope.hidePrompt = function(){ + $scope.promptIsVisible = "-1"; + } + } -angular.module("umbraco").controller("Umbraco.PropertyEditors.MultipleTextBoxController", MultipleTextBoxController); \ No newline at end of file +angular.module("umbraco").controller("Umbraco.PropertyEditors.MultipleTextBoxController", MultipleTextBoxController); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html index 71bf24e735..9f45c46a77 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html @@ -5,11 +5,20 @@ - - - + +
    + + + + +
    +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html index 7aa2a14b26..c45e118891 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html @@ -1,5 +1,5 @@
-
Loading...
+
Loading...
+ type="text" + class="input-block-level" + localize="placeholder" + placeholder="@placeholders_enterMessage" + ng-model="model.resendInviteMessage" + rows="4"> +
-
-
+
+
Last login:
-
+
{{ model.user.formattedLastLogin }} {{ model.user.name | umbWordLimit:1 }} has not logged in yet
-
-
+
+
Failed login attempts:
-
+
{{ model.user.failedPasswordAttempts }}
-
-
+
+
Last lockout date:
-
+
{{ model.user.name | umbWordLimit:1 }} hasn't been locked out @@ -363,11 +364,11 @@
-
-
+
+
Password is last changed:
-
+
The password hasn't been changed @@ -375,28 +376,43 @@
-
-
+
+
User is created:
-
+
{{ model.user.formattedCreateDate }}
-
-
+
+
User is last updated:
-
+
{{ model.user.formattedUpdateDate }}
- +
+
+ Id: +
+
+ {{ model.user.id }} +
+
+ {{ model.user.key }} +
+
+ +
+ + +
diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml index 38b178fcfa..fcd375da45 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml @@ -32,7 +32,7 @@ @Html.Partial(Model.PreviewExtendedHeaderView) } -
+
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index e5dfe70db7..e624e22b75 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -145,6 +145,7 @@ Brugeren har tilbagerullet indholdet til en tidligere tilstand Brugeren har sendt indholdet til udgivelse Brugeren har sendt indholdet til oversættelse + Brugeren har sorteret de underliggende sider Kopieret Udgivet Flyttet @@ -154,6 +155,7 @@ Indhold tilbagerullet Sendt til udgivelse Sendt til oversættelse + Sorteret For at skifte det valgte indholds dokumenttype, skal du først vælge en ny dokumenttype, som er gyldig på denne placering. @@ -254,7 +256,7 @@ Klik for at uploade eller klik her for at vælge filer - Du kan trække filer herind for at uploade + Du kan trække filer herind for at uploade. Kan ikke uploade denne fil, den har ikke en godkendt filtype Maks filstørrelse er Medie rod @@ -421,6 +423,8 @@ Indtast din e-mail Indtast en besked... Dit brugernavn er typisk din e-mailadresse + Indtast alias... + Genererer alias... Tilladte typer @@ -530,6 +534,7 @@ Skjul Historik Ikon + Id Importer Indre margen Indsæt @@ -918,6 +923,8 @@ Mange hilsner fra Umbraco robotten Nulstil + Acceptér + Fortryd Nuværende version diff --git a/src/Umbraco.Web.UI/Umbraco/dialogs/protectPage.aspx b/src/Umbraco.Web.UI/Umbraco/dialogs/protectPage.aspx index 7e76240d14..5bcf97310f 100644 --- a/src/Umbraco.Web.UI/Umbraco/dialogs/protectPage.aspx +++ b/src/Umbraco.Web.UI/Umbraco/dialogs/protectPage.aspx @@ -74,15 +74,19 @@ - - + +
+ +
+ +
-
+
@@ -116,74 +120,72 @@ + +
+ - - -
- - - - -
- -
- - - -
- - -

Member name already exists, click Change to use a different name or Update to continue

-
-
- - - -

<%= Services.TextService.Localize("publicAccess/paSelectRoles")%>

-
- - - -
- - - - - - - <%=Services.TextService.Localize("paLoginPageHelp")%> - -
- +
+ + + +
- - - - - - - <%=Services.TextService.Localize("paErrorPageHelp")%> - -
- +
+ + +
- - - + +

Member name already exists, click Change to use a different name or Update to continue

+
+ + + + +

<%= Services.TextService.Localize("publicAccess/paSelectRoles")%>

+
+ + + +
+ + + + + + <%=Services.TextService.Localize("paLoginPageHelp")%> + +
+ +
+ + +
+ + + <%=Services.TextService.Localize("paErrorPageHelp")%> + +
+ +
+ +
+ +
+
- diff --git a/src/Umbraco.Web.UI/Umbraco/dialogs/rollBack.aspx b/src/Umbraco.Web.UI/Umbraco/dialogs/rollBack.aspx index 84b2cc5cb8..9345c74aba 100644 --- a/src/Umbraco.Web.UI/Umbraco/dialogs/rollBack.aspx +++ b/src/Umbraco.Web.UI/Umbraco/dialogs/rollBack.aspx @@ -13,43 +13,6 @@ var submitOnEnter = true; - @@ -63,7 +26,7 @@ ()
- + @@ -76,7 +39,7 @@ - +

@@ -84,7 +47,7 @@

- +
diff --git a/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config b/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config index 32a165399c..442493e3d6 100644 --- a/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config +++ b/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config @@ -124,7 +124,7 @@ - + diff --git a/src/Umbraco.Web.UI/config/EmbeddedMedia.config b/src/Umbraco.Web.UI/config/EmbeddedMedia.config index ac8c5cc901..c466b14f1c 100644 --- a/src/Umbraco.Web.UI/config/EmbeddedMedia.config +++ b/src/Umbraco.Web.UI/config/EmbeddedMedia.config @@ -124,7 +124,7 @@ - + diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index 844855f10f..50319370e9 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -82,9 +82,14 @@ + diff --git a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs index b0cdcb72b9..9dcaa00e14 100644 --- a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs +++ b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs @@ -57,7 +57,7 @@ namespace Umbraco.Web.Editors var keepOnlyKeys = new Dictionary { {"umbracoUrls", new[] {"authenticationApiBaseUrl", "serverVarsJs", "externalLoginsUrl", "currentUserApiBaseUrl"}}, - {"umbracoSettings", new[] {"allowPasswordReset", "imageFileTypes", "maxFileSize", "loginBackgroundImage"}}, + {"umbracoSettings", new[] {"allowPasswordReset", "imageFileTypes", "maxFileSize", "loginBackgroundImage", "canSendRequiredEmail"}}, {"application", new[] {"applicationPath", "cacheBuster"}}, {"isDebuggingEnabled", new string[] { }}, {"features", new [] {"disabledFeatures"}} @@ -326,6 +326,7 @@ namespace Umbraco.Web.Editors {"allowPasswordReset", UmbracoConfig.For.UmbracoSettings().Security.AllowPasswordReset}, {"loginBackgroundImage", UmbracoConfig.For.UmbracoSettings().Content.LoginBackgroundImage}, {"showUserInvite", EmailSender.CanSendRequiredEmail}, + {"canSendRequiredEmail", EmailSender.CanSendRequiredEmail}, } }, { diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index adc2a78804..2986d80b06 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -555,7 +555,7 @@ namespace Umbraco.Web.Editors /// [FileUploadCleanupFilter] [ContentSaveValidation] - public ContentItemDisplay PostSaveBlueprint([ModelBinder(typeof(ContentItemBinder))] ContentItemSave contentItem) + public ContentItemDisplay PostSaveBlueprint([ModelBinder(typeof(BlueprintItemBinder))] ContentItemSave contentItem) { var contentItemDisplay = PostSaveInternal(contentItem, content => @@ -1068,7 +1068,7 @@ namespace Umbraco.Web.Editors var contentService = Services.ContentService; // Save content with new sort order and update content xml in db accordingly - if (contentService.Sort(sorted.IdSortOrder) == false) + if (contentService.Sort(sorted.IdSortOrder, Security.CurrentUser.Id) == false) { Logger.Warn("Content sorting failed, this was probably caused by an event being cancelled"); return Request.CreateValidationErrorResponse("Content sorting failed, this was probably caused by an event being cancelled"); diff --git a/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/DatabaseSchemaValidationHealthCheck.cs b/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/DatabaseSchemaValidationHealthCheck.cs deleted file mode 100644 index d3c60d4b59..0000000000 --- a/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/DatabaseSchemaValidationHealthCheck.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Collections.Generic; -using Umbraco.Core.Logging; -using Umbraco.Core.Migrations.Install; -using Umbraco.Core.Services; - -namespace Umbraco.Web.HealthCheck.Checks.DataIntegrity -{ - /// - /// U4-9544 Health check to detect if the database has any missing indexes or constraints - /// - [HealthCheck( - "0873D589-2064-4EA3-A152-C43417FE00A4", - "Database Schema Validation", - Description = "This checks the Umbraco database by doing a comparison of current indexes and schema items with the current state of the database and returns any problems it found. Useful to detect if the database hasn't been upgraded correctly.", - Group = "Data Integrity")] - public class DatabaseSchemaValidationHealthCheck : HealthCheck - { - private readonly DatabaseBuilder _databaseBuilder; - private readonly ILocalizedTextService _textService; - private readonly ILogger _logger; - - public DatabaseSchemaValidationHealthCheck(DatabaseBuilder databaseBuilder, ILocalizedTextService textService, ILogger logger) - { - _databaseBuilder = databaseBuilder ?? throw new ArgumentNullException(nameof(databaseBuilder)); - _textService = textService ?? throw new ArgumentNullException(nameof(textService)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - } - - public override HealthCheckStatus ExecuteAction(HealthCheckAction action) - { - return CheckDatabase(); - } - - public override IEnumerable GetStatus() - { - //return the statuses - return new[] { CheckDatabase() }; - } - - private HealthCheckStatus CheckDatabase() - { - var results = _databaseBuilder.ValidateDatabaseSchema(); - - _logger.Warn(_textService.Localize("databaseSchemaValidationCheckDatabaseLogMessage")); - - foreach(var error in results.Errors) - { - _logger.Warn("{Error} : {ErrorDetail}", error.Item1, error.Item2); - } - - if(results.Errors.Count > 0) - { - return new HealthCheckStatus(_textService.Localize("healthcheck/databaseSchemaValidationCheckDatabaseErrors", new[] { results.Errors.Count.ToString() })) - { - ResultType = StatusResultType.Error, - View = "Umbraco.Dashboard.DatabaseSchemaValidationController" - }; - } - - return new HealthCheckStatus(_textService.Localize("healthcheck/databaseSchemaValidationCheckDatabaseOk")) - { - ResultType = StatusResultType.Success - }; - } - } -} diff --git a/src/Umbraco.Web/Models/ImageCropMode.cs b/src/Umbraco.Web/Models/ImageCropMode.cs index e36f079c02..03fe6676cb 100644 --- a/src/Umbraco.Web/Models/ImageCropMode.cs +++ b/src/Umbraco.Web/Models/ImageCropMode.cs @@ -2,11 +2,34 @@ namespace Umbraco.Web.Models { public enum ImageCropMode { + /// + /// Resizes the image to the given dimensions. If the set dimensions do not match the aspect ratio of the original image then the output is cropped to match the new aspect ratio. + /// Crop, + + /// + /// Resizes the image to the given dimensions. If the set dimensions do not match the aspect ratio of the original image then the output is resized to the maximum possible value in each direction while aintaining the original aspect ratio. + /// Max, + + /// + /// Resizes the image to the given dimensions. If the set dimensions do not match the aspect ratio of the original image then the output is stretched to match the new aspect ratio. + /// Stretch, + + /// + /// Passing a single dimension will automatically preserve the aspect ratio of the original image. If the requested aspect ratio is different then the image will be padded to fit. + /// Pad, + + /// + /// When upscaling an image the image pixels themselves are not resized, rather the image is padded to fit the given dimensions. + /// BoxPad, + + /// + /// Resizes the image until the shortest side reaches the set given dimension. This will maintain the aspect ratio of the original image. Upscaling is disabled in this mode and the original image will be returned if attempted. + /// Min } } diff --git a/src/Umbraco.Web/Models/Trees/TreeNodeExtensions.cs b/src/Umbraco.Web/Models/Trees/TreeNodeExtensions.cs index 9f8ca9b84d..819d74f8e7 100644 --- a/src/Umbraco.Web/Models/Trees/TreeNodeExtensions.cs +++ b/src/Umbraco.Web/Models/Trees/TreeNodeExtensions.cs @@ -15,7 +15,7 @@ } /// - /// Sets the node style to show that it is currently protected publicly + /// Sets the node style to show that it is a container type /// /// public static void SetContainerStyle(this TreeNode treeNode) diff --git a/src/Umbraco.Web/PropertyEditors/EmailAddressPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/EmailAddressPropertyEditor.cs index 89c3dbf0e0..ea3dbc7144 100644 --- a/src/Umbraco.Web/PropertyEditors/EmailAddressPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/EmailAddressPropertyEditor.cs @@ -5,7 +5,7 @@ using Umbraco.Core.PropertyEditors.Validators; namespace Umbraco.Web.PropertyEditors { - [DataEditor(Constants.PropertyEditors.Aliases.EmailAddress, "Email address", "email", Icon="icon-message")] + [DataEditor(Constants.PropertyEditors.Aliases.EmailAddress, "Email address", "email", IsParameterEditor = true, Icon="icon-message")] public class EmailAddressPropertyEditor : DataEditor { ///
diff --git a/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs index be2bbb66c1..27c72d213b 100644 --- a/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs @@ -19,5 +19,16 @@ namespace Umbraco.Web.PropertyEditors /// protected override IConfigurationEditor CreateConfigurationEditor() => new TrueFalseConfigurationEditor(); + + public TrueFalsePreValueEditor() + { + Fields.Add(new PreValueField() + { + Description = "Write a label text", + Key = "labelOn", + Name = "Label", + View = "textstring" + }); + } } } diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs index 4266edecf1..3c143a6066 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs @@ -34,6 +34,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache private readonly ICacheProvider _cacheProvider; // at snapshot/request level (see PublishedContentCache) private readonly PublishedContentTypeCache _contentTypeCache; + private readonly object _initializeLock = new object(); + private bool _nodeInitialized; private bool _parentInitialized; private bool _childrenInitialized; @@ -66,15 +68,14 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); - if (_childrenInitialized == false) InitializeChildren(); + EnsureNodeInitialized(andChildren: true); return _children; } } public override IPublishedProperty GetProperty(string alias) { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); IPublishedProperty property; return _properties.TryGetValue(alias, out property) ? property : null; } @@ -85,8 +86,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); - if (_parentInitialized == false) InitializeParent(); + EnsureNodeInitialized(andParent: true); return _parent; } } @@ -95,7 +95,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _id; } } @@ -104,7 +104,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _key; } } @@ -113,7 +113,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _template; } } @@ -122,7 +122,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _sortOrder; } } @@ -131,7 +131,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _name; } } @@ -144,7 +144,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _writerName; } } @@ -153,7 +153,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _creatorName; } } @@ -162,7 +162,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _writerId; } } @@ -171,7 +171,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _creatorId; } } @@ -180,7 +180,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _path; } } @@ -189,7 +189,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _createDate; } } @@ -198,7 +198,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _updateDate; } } @@ -207,7 +207,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _urlName; } } @@ -216,7 +216,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _level; } } @@ -225,7 +225,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _isDraft; } } @@ -234,7 +234,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _properties.Values; } } @@ -243,7 +243,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { get { - if (_nodeInitialized == false) InitializeNode(); + EnsureNodeInitialized(); return _contentType; } } @@ -256,10 +256,27 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache if (parent.Attributes?.GetNamedItem("isDoc") != null) _parent = Get(parent, _isPreviewing, _cacheProvider, _contentTypeCache); - // warn: this is not thread-safe... _parentInitialized = true; } + private void EnsureNodeInitialized(bool andChildren = false, bool andParent = false) + { + // In *theory* XmlPublishedContent are a per-request thing, and so should not + // end up being involved into multi-threaded situations - however, it's been + // reported that some users ended up seeing 100% CPU due to infinite loops in + // the properties dictionary in InitializeNode, which would indicate that the + // dictionary *is* indeed involved in some multi-threaded operation. No idea + // what users are doing that cause this, but let's be friendly and use a true + // lock around initialization. + + lock (_initializeLock) + { + if (_nodeInitialized == false) InitializeNode(); + if (andChildren && _childrenInitialized == false) InitializeChildren(); + if (andParent && _parentInitialized == false) InitializeParent(); + } + } + private void InitializeNode() { InitializeNode(this, _xmlNode, _isPreviewing, @@ -268,10 +285,10 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache out _createDate, out _updateDate, out _level, out _isDraft, out _contentType, out _properties, _contentTypeCache.Get); - // warn: this is not thread-safe... _nodeInitialized = true; } + // internal for some benchmarks internal static void InitializeNode(XmlPublishedContent node, XmlNode xmlNode, bool isPreviewing, out int id, out Guid key, out int template, out int sortOrder, out string name, out string writerName, out string urlName, out string creatorName, out int creatorId, out int writerId, out string docTypeAlias, out int docTypeId, out string path, @@ -398,7 +415,6 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache .OrderBy(x => x.SortOrder) .ToList(); - // warn: this is not thread-safe _childrenInitialized = true; } diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs index 9c13429b44..91548e44f1 100644 --- a/src/Umbraco.Web/Templates/TemplateUtilities.cs +++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs @@ -1,6 +1,4 @@ -using HtmlAgilityPack; -using System; -using System.Runtime.CompilerServices; +using System; using System.Text.RegularExpressions; using Umbraco.Core; using Umbraco.Core.Configuration; @@ -38,11 +36,6 @@ namespace Umbraco.Web.Templates { if (urlProvider == null) throw new ArgumentNullException("urlProvider"); - if(string.IsNullOrEmpty(text)) - { - return text; - } - // Parse internal links var tags = LocalLinkPattern.Matches(text); foreach (Match tag in tags) @@ -71,11 +64,6 @@ namespace Umbraco.Web.Templates } } - if (UmbracoConfig.For.UmbracoSettings().Content.StripUdiAttributes) - { - text = StripUdiDataAttributes(text); - } - return text; } @@ -87,9 +75,6 @@ namespace Umbraco.Web.Templates private static readonly Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - private static readonly Regex UdiDataAttributePattern = new Regex("data-udi=\"[^\\\"]*\"", - RegexOptions.IgnoreCase | RegexOptions.Compiled); - /// /// The RegEx matches any HTML attribute values that start with a tilde (~), those that match are passed to ResolveUrl to replace the tilde with the application path. /// @@ -133,21 +118,5 @@ namespace Umbraco.Web.Templates { return text.CleanForXss(ignoreFromClean); } - - /// - /// Strips data-udi attributes from rich text - /// - /// A html string - /// A string stripped from the data-uid attributes - public static string StripUdiDataAttributes(string input) - { - if (string.IsNullOrEmpty(input)) - { - return string.Empty; - } - - - return UdiDataAttributePattern.Replace(input, string.Empty); - } } } diff --git a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs index d1a3cddd52..a2179be75f 100644 --- a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs @@ -116,21 +116,11 @@ namespace Umbraco.Web.Trees if (enableInheritedDocumentTypes) { menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias))); - - //no move action if this is a child doc type - if (parent == null) - { - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionMove.Instance.Alias)), true); - } } - else + //no move action if this is a child doc type + if (parent == null) { - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionMove.Instance.Alias))); - //no move action if this is a child doc type - if (parent == null) - { - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionMove.Instance.Alias)), true); - } + menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionMove.Instance.Alias)), true); } menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionCopy.Instance.Alias))); menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionExport.Instance.Alias)), true); diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 91cd388317..aa30fff0ec 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -916,7 +916,7 @@ namespace Umbraco.Web } /// - /// Will take the first non-null value in the collection and return the value of it. + /// Joins any number of int/string/objects into one string /// public string Concatenate(params object[] args) { diff --git a/src/Umbraco.Web/WebApi/Binders/BlueprintItemBinder.cs b/src/Umbraco.Web/WebApi/Binders/BlueprintItemBinder.cs new file mode 100644 index 0000000000..825c5b01c3 --- /dev/null +++ b/src/Umbraco.Web/WebApi/Binders/BlueprintItemBinder.cs @@ -0,0 +1,28 @@ +using System; +using Umbraco.Core; +using Umbraco.Core.Models; +using Umbraco.Web.Models.ContentEditing; + +namespace Umbraco.Web.WebApi.Binders +{ + internal class BlueprintItemBinder : ContentItemBinder + { + public BlueprintItemBinder(ApplicationContext applicationContext) + : base(applicationContext) + { + } + + /// + /// Constructor + /// + public BlueprintItemBinder() + : this(ApplicationContext.Current) + { + } + + protected override IContent GetExisting(ContentItemSave model) + { + return ApplicationContext.Services.ContentService.GetBlueprintById(Convert.ToInt32(model.Id)); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/dualSelectBox.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/dualSelectBox.cs index 121e290830..6e109b3327 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/dualSelectBox.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/dualSelectBox.cs @@ -45,6 +45,15 @@ namespace umbraco.controls } } + public new int Height + { + set + { + _possibleValues.Height = new Unit(value); + _selectedValues.Height = new Unit(value); + } + } + protected override void CreateChildControls() { _possibleValues.ID = "posVals"; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/FeedProxy.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/FeedProxy.aspx.cs index cfa60b79a4..58d219e0c6 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/FeedProxy.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/FeedProxy.aspx.cs @@ -33,7 +33,7 @@ namespace dashboardUtilities return; var feedProxyXml = XmlHelper.OpenAsXmlDocument(IOHelper.MapPath(SystemFiles.FeedProxyConfig)); - if (feedProxyXml?.SelectSingleNode($"//allow[@host = '{requestUri.Host}']") != null && requestUri.Port == 80) + if (feedProxyXml?.SelectSingleNode($"//allow[@host = '{requestUri.Host}']") != null && (requestUri.Port == 80 || requestUri.Port == 443)) { if (_httpClient == null) _httpClient = new HttpClient(); 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 4da6aab67f..98396f6609 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/protectPage.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/protectPage.aspx.cs @@ -43,7 +43,7 @@ namespace umbraco.presentation.umbraco.dialogs protected void selectMode(object sender, EventArgs e) { p_mode.Visible = false; - p_buttons.Visible = true; + p_setup.Visible = true; if (rb_simple.Checked) { @@ -271,14 +271,15 @@ namespace umbraco.presentation.umbraco.dialogs bt_protect.CommandName = "advanced"; } - p_buttons.Visible = true; p_mode.Visible = false; + p_setup.Visible = true; } } // Load up membergrouops _memberGroups.ID = "Membergroups"; _memberGroups.Width = 175; + _memberGroups.Height = 165; var selectedGroups = ""; // get roles from the membership provider @@ -307,7 +308,7 @@ namespace umbraco.presentation.umbraco.dialogs groupsSelector.Controls.Add(_memberGroups); - bt_protect.Text = Services.TextService.Localize("update"); + bt_protect.Text = Services.TextService.Localize("buttons", "select"); bt_buttonRemoveProtection.Text = Services.TextService.Localize("paRemoveProtection"); // Put user code to initialize the page here @@ -416,38 +417,35 @@ namespace umbraco.presentation.umbraco.dialogs var content = Services.ContentService.GetById(pageId); var text = content == null ? "" : content.Name; - feedback.Text = Services.TextService.Localize("publicAccess/paIsProtected", new[] { text }) + "

" + Services.TextService.Localize("closeThisWindow") + ""; + feedback.Text = Services.TextService.Localize("publicAccess/paIsProtected", new[] { text }); - p_buttons.Visible = false; - pane_advanced.Visible = false; - pane_simple.Visible = false; + p_setup.Visible = false; + p_feedback.Visible = true; //reloads the current node in the tree ClientTools.SyncTree(content.Path, true); //reloads the current node's children in the tree ClientTools.ReloadActionNode(false, true); - feedback.type = global::Umbraco.Web._Legacy.Controls.Feedback.feedbacktype.success; } protected void buttonRemoveProtection_Click(object sender, System.EventArgs e) { int pageId = int.Parse(Request.GetItemAsString("nodeId")); - p_buttons.Visible = false; - pane_advanced.Visible = false; - pane_simple.Visible = false; + p_setup.Visible = false; RemoveProtection(pageId); var content = Services.ContentService.GetById(pageId); var text = content == null ? "" : content.Name; - feedback.Text = Services.TextService.Localize("publicAccess/paIsRemoved", new[] { text }) + "

" + Services.TextService.Localize("closeThisWindow") + ""; + feedback_text.Text = Services.TextService.Localize("publicAccess/paIsRemoved", new[] { text }); + p_feedback.Visible = true; + //reloads the current node in the tree ClientTools.SyncTree(content.Path, true); //reloads the current node's children in the tree ClientTools.ReloadActionNode(false, true); - feedback.type = global::Umbraco.Web._Legacy.Controls.Feedback.feedbacktype.success; } protected CustomValidator SimpleLoginNameValidator; @@ -463,13 +461,13 @@ namespace umbraco.presentation.umbraco.dialogs protected global::System.Web.UI.HtmlControls.HtmlInputHidden tempFile; ///

- /// feedback control. + /// p_feedback control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::Umbraco.Web._Legacy.Controls.Feedback feedback; + protected global::System.Web.UI.WebControls.Panel p_feedback; /// /// p_mode control. @@ -480,6 +478,15 @@ namespace umbraco.presentation.umbraco.dialogs /// protected global::System.Web.UI.WebControls.Panel p_mode; + /// + /// p_setup control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel p_setup; + /// /// pane_chooseMode control. /// @@ -615,15 +622,6 @@ namespace umbraco.presentation.umbraco.dialogs /// protected global::System.Web.UI.WebControls.PlaceHolder groupsSelector; - /// - /// p_buttons control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel p_buttons; - /// /// pane_pages control. /// @@ -732,6 +730,15 @@ namespace umbraco.presentation.umbraco.dialogs /// protected global::System.Web.UI.WebControls.PlaceHolder js; + /// + /// feedback_text control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal feedback_text; + } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx index 88f106d269..766e3fb30c 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx @@ -13,44 +13,7 @@ var submitOnEnter = true; - +