V8/feature/ab4550 segments ui variant picker (#7614)

* Fixes incorrect property inheritance logic

* Fixes crash in canVariantPublish when variant.language is null

* Adds variant display name in dropdown

* Logic for invariant properties updated to also support segment invariance

* Properties varied by segment only now properly saved when multiple variants are saved/published

* Logic for disabling property editors moved to function and corrected for all cases of culture/segment properties

* Fixes syntax error in less file
This commit is contained in:
Daniël Knippers
2020-02-10 09:16:03 +01:00
committed by GitHub
parent 21ea8e3b8b
commit 124bc27921
6 changed files with 70 additions and 32 deletions

View File

@@ -137,6 +137,24 @@
}
}
);
$scope.propertyEditorDisabled = function (property) {
if (property.unlockInvariantValue) {
return false;
}
var contentLanguage = $scope.content.language;
var canEditCulture = !contentLanguage ||
// If the property culture equals the content culture it can be edited
property.culture === contentLanguage.culture ||
// A culture-invariant property can only be edited by the default language variant
(property.culture == null && contentLanguage.isDefault);
var canEditSegment = property.segment === $scope.content.segment;
return !canEditCulture || !canEditSegment;
}
}
var directive = {

View File

@@ -394,40 +394,59 @@
*/
formatContentGetData: function(displayModel) {
//We need to check for invariant properties among the variant variants.
//When we detect this, we want to make sure that the property object instance is the
//same reference object between all variants instead of a copy (which it will be when
//return from the JSON structure).
// We need to check for invariant properties among the variant variants,
// as the value of an invariant property is shared between different variants.
// A property can be culture invariant, segment invariant, or both.
// When we detect this, we want to make sure that the property object instance is the
// same reference object between all variants instead of a copy (which it will be when
// return from the JSON structure).
if (displayModel.variants && displayModel.variants.length > 1) {
// Collect all invariant properties from the variants that are either the
// default language variant or the default segment variant.
var defaultVariants = _.filter(displayModel.variants, function (variant) {
var isDefaultLanguage = variant.language && variant.language.isDefault;
var isDefaultSegment = variant.segment == null;
var invariantProperties = [];
//collect all invariant properties on the first first variant
var firstVariant = displayModel.variants[0];
_.each(firstVariant.tabs, function(tab, tabIndex) {
_.each(tab.properties, function (property, propIndex) {
//in theory if there's more than 1 variant, that means they would all have a language
//but we'll do our safety checks anyways here
if (firstVariant.language && !property.culture && !property.segment) {
invariantProperties.push({
tabIndex: tabIndex,
propIndex: propIndex,
property: property
});
}
});
return isDefaultLanguage || isDefaultSegment;
});
if (defaultVariants.length > 0) {
_.each(defaultVariants, function (defaultVariant) {
var invariantProps = [];
//now assign this same invariant property instance to the same index of the other variants property array
for (var j = 1; j < displayModel.variants.length; j++) {
var variant = displayModel.variants[j];
_.each(defaultVariant.tabs, function (tab, tabIndex) {
_.each(tab.properties, function (property, propIndex) {
// culture == null -> property is culture invariant
// segment == null -> property is *possibly* segment invariant
if (!property.culture || !property.segment) {
invariantProps.push({
tabIndex: tabIndex,
propIndex: propIndex,
property: property
});
}
});
});
_.each(invariantProperties, function (invProp) {
var tab = variant.tabs[invProp.tabIndex];
var otherVariants = _.filter(displayModel.variants, function (variant) {
return variant !== defaultVariant;
});
tab.properties[invProp.propIndex] = invProp.property;
// now assign this same invariant property instance to the same index of the other variants property array
_.each(otherVariants, function (variant) {
_.each(invariantProps, function (invProp) {
var tab = variant.tabs[invProp.tabIndex];
var prop = tab.properties[invProp.propIndex];
var inheritsCulture = prop.culture === invProp.property.culture && prop.segment == null && invProp.property.segment == null;
var inheritsSegment = prop.segment === invProp.property.segment && !prop.culture;
if (inheritsCulture || inheritsSegment) {
tab.properties[invProp.propIndex] = invProp.property;
}
});
});
});
}
}

View File

@@ -11,13 +11,13 @@
data-element="property-{{property.alias}}"
ng-repeat="property in group.properties track by property.alias"
property="property"
show-inherit="variantNodeModel.variants.length > 1 && ((!content.language.isDefault && !property.culture) || (content.segment && !property.segment)) && !property.unlockInvariantValue"
show-inherit="propertyEditorDisabled(property)"
inherits-from="defaultVariant.language.name">
<div ng-class="{'o-40 cursor-not-allowed': variantNodeModel.variants.length > 1 && ((!content.language.isDefault && !property.culture) || (content.segment && !property.segment)) && !property.unlockInvariantValue}">
<div ng-class="{'o-40 cursor-not-allowed': propertyEditorDisabled(property) }">
<umb-property-editor
model="property"
preview="variantNodeModel.variants.length > 1 && ((!content.language.isDefault && !property.culture) || (content.segment && !property.segment)) && !property.unlockInvariantValue">
preview="propertyEditorDisabled(property)">
</umb-property-editor>
</div>

View File

@@ -60,7 +60,7 @@
<i class="icon icon-navigation-right" ng-if="!entry.open"></i>
</button>
<button type="button" class="umb-variant-switcher__name-wrapper umb-outline" ng-click="selectVariant($event, entry.variant)" prevent-default>
<span class="umb-variant-switcher__name" ng-bind="entry.variant.language ? entry.variant.language.name : entry.variant.segment"></span>
<span class="umb-variant-switcher__name" ng-bind="getVariantDisplayName(entry.variant)"></span>
<umb-variant-state variant="entry.variant" class="umb-variant-switcher__state"></umb-variant-state>
</button>
<div ng-if="splitViewOpen !== true && !entry.variant.active" class="umb-variant-switcher__split-view" ng-click="openInSplitView($event, entry.variant)">Open in split view</div>

View File

@@ -39,7 +39,7 @@
var published = !(variant.state === "NotCreated" || variant.state === "Draft");
// is this variant mandatory:
if (variant.language.isMandatory && !published && !variant.publish) {
if (variant.language && variant.language.isMandatory && !published && !variant.publish) {
//if a mandatory variant isn't published or set to be published
//then we cannot continue

View File

@@ -1874,7 +1874,8 @@ namespace Umbraco.Web.Editors
? variant.PropertyCollectionDto
: new ContentPropertyCollectionDto
{
Properties = variant.PropertyCollectionDto.Properties.Where(x => !x.Culture.IsNullOrWhiteSpace())
Properties = variant.PropertyCollectionDto.Properties.Where(
x => !x.Culture.IsNullOrWhiteSpace() || !x.Segment.IsNullOrWhiteSpace())
};
//for each variant, map the property values