diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index 5a9f30fe24e6..0892a892d264 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -223,7 +223,6 @@ //we are editing so get the content item from the server return $scope.getMethod()($scope.contentId) .then(function (data) { - $scope.content = data; appendRuntimeData(); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js index 846d5c85fe53..31e51fe1150d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - function EditorContentHeader(serverValidationManager, localizationService, editorState) { + function EditorContentHeader(serverValidationManager, localizationService, editorState, contentEditingHelper) { function link(scope) { var unsubscribe = []; @@ -92,7 +92,6 @@ } function onInit() { - // find default + check if we have variants. scope.content.variants.forEach(function (variant) { if (variant.language !== null && variant.language.isDefault) { @@ -115,11 +114,13 @@ if (scope.vm.hasCulture) { scope.content.variants.forEach((v) => { if (v.language !== null && v.segment === null) { + const subVariants = scope.content.variants.filter((subVariant) => subVariant.language.culture === v.language.culture && subVariant.segment !== null).sort(contentEditingHelper.sortVariants); + var variantMenuEntry = { key: String.CreateGuid(), open: v.language && v.language.culture === scope.editor.culture, variant: v, - subVariants: scope.content.variants.filter((subVariant) => subVariant.language.culture === v.language.culture && subVariant.segment !== null) + subVariants }; scope.vm.variantMenu.push(variantMenuEntry); } @@ -147,7 +148,12 @@ } unsubscribe.push(serverValidationManager.subscribe(null, variant.language !== null ? variant.language.culture : null, null, onVariantValidation, variant.segment)); }); + + scope.vm.variantMenu.sort(sortVariantsMenu); + } + function sortVariantsMenu (a, b) { + return contentEditingHelper.sortVariants(a.variant, b.variant); } scope.goBack = function () { @@ -200,6 +206,14 @@ return false; } + scope.toggleDropdown = function () { + scope.vm.dropdownOpen = !scope.vm.dropdownOpen; + + if (scope.vm.dropdownOpen) { + scope.vm.variantMenu.sort(sortVariantsMenu); + } + }; + onInit(); scope.$on('$destroy', function () { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js index 46bbe2de2331..f19ba5424489 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js @@ -759,6 +759,59 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, editorSt //don't add a browser history for this $location.replace(); return true; + }, + + /** + * @ngdoc function + * @name umbraco.services.contentEditingHelper#sortVariants + * @methodOf umbraco.services.contentEditingHelper + * @function + * + * @description + * Sorts the variants so default language is shown first. Mandatory languages are shown next and all other underneath. Both Mandatory and non mandatory languages are + * sorted in the following groups 'Published', 'Draft', 'Not Created'. Within each of those groups the variants are + * sorted by the language display name. + * + */ + sortVariants: function (a, b) { + const statesOrder = {'PublishedPendingChanges':1, 'Published': 1, 'Draft': 2, 'NotCreated': 3}; + const compareDefault = (a,b) => (!a.language.isDefault ? 1 : -1) - (!b.language.isDefault ? 1 : -1); + + // Make sure mandatory variants goes on top, unless they are published, cause then they already goes to the top and then we want to mix them with other published variants. + const compareMandatory = (a,b) => (a.state === 'PublishedPendingChanges' || a.state === 'Published') ? 0 : (!a.language.isMandatory ? 1 : -1) - (!b.language.isMandatory ? 1 : -1); + const compareState = (a, b) => (statesOrder[a.state] || 99) - (statesOrder[b.state] || 99); + const compareName = (a, b) => a.displayName.localeCompare(b.displayName); + + return compareDefault(a, b) || compareMandatory(a, b) || compareState(a, b) || compareName(a, b); + }, + + /** + * @ngdoc function + * @name umbraco.services.contentEditingHelper#getSortedVariantsAndSegments + * @methodOf umbraco.services.contentEditingHelper + * @function + * + * @description + * Returns an array of variants and segments sorted by the rules in the sortVariants method. + * A variant language is followed by its segments in the array. If a segment doesn't have a parent variant it is + * added to the end of the array. + * + */ + getSortedVariantsAndSegments: function (variantsAndSegments) { + const sortedVariants = variantsAndSegments.filter(variant => !variant.segment).sort(this.sortVariants); + let segments = variantsAndSegments.filter(variant => variant.segment); + let sortedAvailableVariants = []; + + sortedVariants.forEach((variant) => { + const sortedMatchedSegments = segments.filter(segment => segment.language.culture === variant.language.culture).sort(this.sortVariants); + segments = segments.filter(segment => segment.language.culture !== variant.language.culture); + sortedAvailableVariants = [...sortedAvailableVariants, ...[variant], ...sortedMatchedSegments]; + }) + + // if we have segments without a parent language variant we need to add the remaining segments to the array + sortedAvailableVariants = [...sortedAvailableVariants, ...segments.sort(this.sortVariants)]; + + return sortedAvailableVariants; } }; } diff --git a/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-variant-switcher.less b/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-variant-switcher.less index 95625d9e73bd..9d2782f184c8 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-variant-switcher.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-variant-switcher.less @@ -196,10 +196,6 @@ button.umb-variant-switcher__toggle { .umb-variant-switcher__item.--current { color: @ui-light-active-type; - //background-color: @pinkExtraLight; - .umb-variant-switcher__name-wrapper { - border-left: 4px solid @ui-active; - } .umb-variant-switcher__name { //color: @ui-light-active-type; font-weight: 700; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html index 687c8ef24ebd..6978672e9984 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html @@ -40,7 +40,7 @@ maxlength="255" /> - @@ -51,7 +51,7 @@ @@ -60,7 +60,11 @@
Open in split view
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.controller.js index b924793fcd61..4e3496cde135 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function PublishController($scope, localizationService) { + function PublishController($scope, localizationService, contentEditingHelper) { var vm = this; vm.loading = true; @@ -143,25 +143,7 @@ }); if (vm.availableVariants.length !== 0) { - vm.availableVariants.sort((a, b) => { - if (a.language && b.language) { - if (a.language.name < b.language.name) { - return -1; - } - if (a.language.name > b.language.name) { - return 1; - } - } - if (a.segment && b.segment) { - if (a.segment < b.segment) { - return -1; - } - if (a.segment > b.segment) { - return 1; - } - } - return 0; - }); + vm.availableVariants = contentEditingHelper.getSortedVariantsAndSegments(vm.availableVariants); } $scope.model.disableSubmitButton = !canPublish(); diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html index c3e0b90f5f09..888b6ab0f2ee 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html @@ -30,7 +30,7 @@ - - + {{publishVariantSelectorForm.publishVariantSelector.errorMsg}} diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publishdescendants.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publishdescendants.controller.js index f6fd6cb3cb0a..f9ad2eade85e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publishdescendants.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publishdescendants.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function PublishDescendantsController($scope, localizationService) { + function PublishDescendantsController($scope, localizationService, contentEditingHelper) { var vm = this; vm.includeUnpublished = $scope.model.includeUnpublished || false; @@ -38,25 +38,7 @@ if (vm.variants.length > 1) { - vm.displayVariants.sort((a, b) => { - if (a.language && b.language) { - if (a.language.name < b.language.name) { - return -1; - } - if (a.language.name > b.language.name) { - return 1; - } - } - if (a.segment && b.segment) { - if (a.segment < b.segment) { - return -1; - } - if (a.segment > b.segment) { - return 1; - } - } - return 0; - }); + vm.displayVariants = contentEditingHelper.getSortedVariantsAndSegments(vm.displayVariants); var active = vm.variants.find(v => v.active); diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publishdescendants.html b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publishdescendants.html index 61fd78a0357e..bb1d20c32123 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publishdescendants.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publishdescendants.html @@ -60,7 +60,7 @@ - - + {{publishVariantSelectorForm.publishVariantSelector.errorMsg}} diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.controller.js index aa0d3797d4a4..bfde6afbe3f6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.controller.js @@ -85,25 +85,7 @@ active.save = true; } - vm.availableVariants.sort((a, b) => { - if (a.language && b.language) { - if (a.language.name < b.language.name) { - return -1; - } - if (a.language.name > b.language.name) { - return 1; - } - } - if (a.segment && b.segment) { - if (a.segment < b.segment) { - return -1; - } - if (a.segment > b.segment) { - return 1; - } - } - return 0; - }); + vm.availableVariants = contentEditingHelper.getSortedVariantsAndSegments(vm.availableVariants); } else { //disable save button if we have nothing to save diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.html b/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.html index 661dd4162edc..fa9ab8c43777 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.html @@ -36,7 +36,7 @@ - - + {{saveVariantSelectorForm.saveVariantSelector.errorMsg}} diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/schedule.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/overlays/schedule.controller.js index 8bf23ae6d5b4..2de526b503de 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/schedule.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/schedule.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function ScheduleContentController($scope, $timeout, localizationService, dateHelper, userService) { + function ScheduleContentController($scope, $timeout, localizationService, dateHelper, userService, contentEditingHelper) { var vm = this; @@ -43,26 +43,7 @@ // Check for variants: if a node is invariant it will still have the default language in variants // so we have to check for length > 1 if (vm.variants.length > 1) { - - vm.displayVariants.sort((a, b) => { - if (a.language && b.language) { - if (a.language.name < b.language.name) { - return -1; - } - if (a.language.name > b.language.name) { - return 1; - } - } - if (a.segment && b.segment) { - if (a.segment < b.segment) { - return -1; - } - if (a.segment > b.segment) { - return 1; - } - } - return 0; - }); + vm.displayVariants = contentEditingHelper.getSortedVariantsAndSegments(vm.displayVariants); vm.variants.forEach(v => { if (v.active) { diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/schedule.html b/src/Umbraco.Web.UI.Client/src/views/content/overlays/schedule.html index e854f727173b..563793862d79 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/schedule.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/schedule.html @@ -107,7 +107,7 @@ - - + - diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/sendtopublish.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/overlays/sendtopublish.controller.js index d91d8148863f..dd9960d352d6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/sendtopublish.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/sendtopublish.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function SendToPublishController($scope, localizationService) { + function SendToPublishController($scope, localizationService, contentEditingHelper) { var vm = this; vm.loading = true; @@ -27,25 +27,7 @@ if (vm.availableVariants.length !== 0) { - vm.availableVariants.sort((a, b) => { - if (a.language && b.language) { - if (a.language.name < b.language.name) { - return -1; - } - if (a.language.name > b.language.name) { - return 1; - } - } - if (a.segment && b.segment) { - if (a.segment < b.segment) { - return -1; - } - if (a.segment > b.segment) { - return 1; - } - } - return 0; - }); + vm.availableVariants = contentEditingHelper.getSortedVariantsAndSegments(vm.availableVariants); vm.availableVariants.forEach(v => { if(v.active) { diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/sendtopublish.html b/src/Umbraco.Web.UI.Client/src/views/content/overlays/sendtopublish.html index abf39c654253..8217da5752f0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/sendtopublish.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/sendtopublish.html @@ -32,7 +32,7 @@ - - + {{publishVariantSelectorForm.publishVariantSelector.errorMsg}} diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.controller.js index 63c5b2da263a..936ab3b1049e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function UnpublishController($scope, localizationService) { + function UnpublishController($scope, localizationService, contentEditingHelper) { var vm = this; var autoSelectedVariants = []; @@ -27,25 +27,7 @@ // node has variants if (vm.variants.length !== 1) { - vm.unpublishableVariants.sort((a, b) => { - if (a.language && b.language) { - if (a.language.name < b.language.name) { - return -1; - } - if (a.language.name > b.language.name) { - return 1; - } - } - if (a.segment && b.segment) { - if (a.segment < b.segment) { - return -1; - } - if (a.segment > b.segment) { - return 1; - } - } - return 0; - }); + vm.unpublishableVariants = contentEditingHelper.getSortedVariantsAndSegments(vm.unpublishableVariants); var active = vm.variants.find(v => v.active); diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.html b/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.html index 5ab32abf001f..dc3862879a51 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.html @@ -36,7 +36,7 @@ - - + {{publishVariantSelectorForm.publishVariantSelector.errorMsg}}