Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better sorting of variants in variant picker and publishing dialogs #9797

Merged
merged 8 commits into from
Feb 15, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(function () {
'use strict';

function EditorContentHeader(serverValidationManager, localizationService, editorState) {
function EditorContentHeader(serverValidationManager, localizationService, editorState, contentEditingHelper) {
function link(scope) {

var unsubscribe = [];
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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 () {
Expand Down Expand Up @@ -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 () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
maxlength="255" />
</ng-form>

<button type="button" ng-if="vm.hasVariants === true && hideChangeVariant !== true" class="umb-variant-switcher__toggle umb-outline" ng-click="vm.dropdownOpen = !vm.dropdownOpen" ng-class="{'--error': vm.errorsOnOtherVariants}" aria-haspopup="true" aria-expanded="{{vm.dropdownOpen}}">
<button type="button" ng-if="vm.hasVariants === true && hideChangeVariant !== true" class="umb-variant-switcher__toggle umb-outline" ng-click="toggleDropdown()" ng-class="{'--error': vm.errorsOnOtherVariants}" aria-haspopup="true" aria-expanded="{{vm.dropdownOpen}}">
<span ng-bind="editor.content.displayName"></span>
<umb-icon icon="{{vm.dropdownOpen ? 'icon-navigation-up' : 'icon-navigation-down'}}" class="umb-variant-switcher__expand" ng-class="{'icon-navigation-down': !vm.dropdownOpen, 'icon-navigation-up': vm.dropdownOpen}">&nbsp;</umb-icon>
</button>
Expand All @@ -51,7 +51,7 @@

<umb-dropdown ng-if="vm.dropdownOpen" class="umb-variant-switcher" ng-class="{'--has-sub-variants': vm.hasSubVariants === true}" on-close="vm.dropdownOpen = false" umb-keyboard-list>
<umb-dropdown-item
ng-repeat-start="entry in vm.variantMenu | orderBy:'variant.displayName' track by entry.key"
ng-repeat-start="entry in vm.variantMenu track by entry.key"
class="umb-variant-switcher__item"
ng-class="{'--current': entry.variant === editor.content, '--active': entry.variant.active && vm.dropdownOpen, '--error': entry.variant.active !== true && entry.variant.hasError, '--state-notCreated':entry.variant.state==='NotCreated' && entry.variant.name == null, '--state-draft':entry.variant.state==='Draft' || (entry.variant.state==='NotCreated' && entry.variant.name != null)}"
>
Expand All @@ -60,7 +60,11 @@
</button>
<button type="button" class="umb-variant-switcher__name-wrapper umb-outline" ng-click="selectVariant($event, entry.variant)">
<span class="umb-variant-switcher__name" ng-bind="entry.variant.displayName"></span>
<umb-variant-state variant="entry.variant" class="umb-variant-switcher__state"></umb-variant-state>
<span class="umb-variant-switcher__state">
<umb-variant-state variant="entry.variant"></umb-variant-state>
<span ng-if="entry.variant.language.isMandatory"> - <localize key="general_mandatory"></localize></span>
<span ng-if="entry.variant.language.isDefault"> - <localize key="general_default"></localize></span>
</span>
</button>
<div ng-if="splitViewOpen !== true && !entry.variant.active" class="umb-variant-switcher__split-view umb-outline" ng-click="openInSplitView($event, entry.variant)">Open in split view</div>
</umb-dropdown-item>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(function () {
"use strict";

function PublishController($scope, localizationService) {
function PublishController($scope, localizationService, contentEditingHelper) {

var vm = this;
vm.loading = true;
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<span class="umb-variant-selector-entry__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
<umb-variant-state variant="variant"></umb-variant-state>
<span ng-if="variant.isMandatory"> - </span>
<span ng-if="variant.isMandatory" ng-class="{'text-error': (variant.state !== 'Published' && variant.state !== 'PublishedPendingChanges' && variant.publish === false) }"><localize key="languages_mandatoryLanguage"></localize></span>
<span ng-if="variant.isMandatory" ng-class="{'text-error': (variant.state !== 'Published' && variant.state !== 'PublishedPendingChanges' && variant.publish === false) }"><localize key="general_mandatory"></localize></span>
</span>
<span class="umb-variant-selector-entry__description" ng-messages="publishVariantSelectorForm.publishVariantSelector.$error" show-validation-on-submit>
<span class="text-error" ng-message="valServerField">{{publishVariantSelectorForm.publishVariantSelector.errorMsg}}</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
<span class="umb-variant-selector-entry__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
<umb-variant-state variant="variant"></umb-variant-state>
<span ng-if="variant.isMandatory"> - </span>
<span ng-if="variant.isMandatory" ng-class="{'text-error': (variant.publish === false) }"><localize key="languages_mandatoryLanguage"></localize></span>
<span ng-if="variant.isMandatory" ng-class="{'text-error': (variant.publish === false) }"><localize key="general_mandatory"></localize></span>
</span>
<span class="umb-variant-selector-entry__description" ng-messages="publishVariantSelectorForm.publishVariantSelector.$error" show-validation-on-submit>
<span class="text-error" ng-message="valServerField">{{publishVariantSelectorForm.publishVariantSelector.errorMsg}}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<span class="umb-variant-selector-entry__description" ng-if="!saveVariantSelectorForm.saveVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
<umb-variant-state variant="variant"></umb-variant-state>
<span ng-if="variant.isMandatory"> - </span>
<span ng-if="variant.isMandatory" ng-class="{'text-error': (variant.publish === false) }"><localize key="languages_mandatoryLanguage"></localize></span>
<span ng-if="variant.isMandatory" ng-class="{'text-error': (variant.publish === false) }"><localize key="general_mandatory"></localize></span>
</span>
<span class="umb-variant-selector-entry__description" ng-messages="saveVariantSelectorForm.saveVariantSelector.$error" show-validation-on-submit>
<span class="text-error" ng-message="valServerField">{{saveVariantSelectorForm.saveVariantSelector.errorMsg}}</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
<span class="umb-variant-selector-entry__description"
ng-if="!scheduleSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
<umb-variant-state variant="variant"></umb-variant-state>
<span ng-show="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
<span ng-show="variant.language.isMandatory"> - <localize key="general_mandatory"></localize></span>
</span>

</umb-checkbox>
Expand Down
Loading