More work on save and publish overlays
This commit is contained in:
@@ -27,11 +27,6 @@
|
||||
|
||||
// add all editors to an editors array to support split view
|
||||
$scope.editors = [];
|
||||
$scope.splitView = {
|
||||
"leftIsOpen": true,
|
||||
"rightIsOpen": false
|
||||
};
|
||||
|
||||
$scope.initVariant = initVariant;
|
||||
$scope.splitViewChanged = splitViewChanged;
|
||||
|
||||
@@ -70,6 +65,41 @@
|
||||
$scope.$broadcast("editors.content.splitViewChanged", { editors: $scope.editors });
|
||||
}
|
||||
|
||||
function countDirtyVariants() {
|
||||
var count = 0;
|
||||
for (var i = 0; i < $scope.content.variants.length; i++) {
|
||||
var v = $scope.content.variants[i];
|
||||
if (v.isDirty) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Returns true if the save dialog should be shown when pressing save */
|
||||
function showSaveDialog() {
|
||||
|
||||
//show the dialog if split view is open
|
||||
if ($scope.editors.length > 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//if there are more than one dirty variants
|
||||
if (countDirtyVariants() > 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//if there is a dirty variant that is not the currently selected variant
|
||||
for (var i = 0; i < $scope.content.variants.length; i++) {
|
||||
var v = $scope.content.variants[i];
|
||||
if (v.isDirty && v.language.culture !== $scope.editors[0].content.language.culture) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The content item(s) are loaded into an array and this will set the active content item based on the current culture (query string).
|
||||
* If the content item is invariant, then only one item exists in the array.
|
||||
@@ -429,7 +459,7 @@
|
||||
if (formHelper.submitForm({ scope: $scope, action: "publish" })) {
|
||||
|
||||
var dialog = {
|
||||
view: "publish",
|
||||
view: "views/content/overlays/publish.html",
|
||||
variants: $scope.content.variants, //set a model property for the dialog
|
||||
skipFormValidation: true, //when submitting the overlay form, skip any client side validation
|
||||
submitButtonLabel: "Publish",
|
||||
@@ -456,7 +486,7 @@
|
||||
var keys = _.keys(err.data.ModelState);
|
||||
var foundVariantError = _.find(keys,
|
||||
function (k) {
|
||||
return k.startsWith("publish_variant_");
|
||||
return k.startsWith("_content_variant_");
|
||||
});
|
||||
if (!foundVariantError) {
|
||||
//no variant errors, close the dialog
|
||||
@@ -483,7 +513,7 @@
|
||||
$scope.save = function () {
|
||||
|
||||
// TODO: Add "..." to save button label if there are more than one variant to publish - currently it just adds the elipses if there's more than 1 variant
|
||||
if ($scope.content.variants.length > 1) {
|
||||
if (showSaveDialog()) {
|
||||
//before we launch the dialog we want to execute all client side validations first
|
||||
if (formHelper.submitForm({ scope: $scope, action: "save" })) {
|
||||
|
||||
@@ -515,7 +545,7 @@
|
||||
var keys = _.keys(err.data.ModelState);
|
||||
var foundVariantError = _.find(keys,
|
||||
function (k) {
|
||||
return k.startsWith("publish_variant_");
|
||||
return k.startsWith("_content_variant_");
|
||||
});
|
||||
if (!foundVariantError) {
|
||||
//no variant errors, close the dialog
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div ng-switch="variant.state">
|
||||
<div ng-switch="vm.variant.state">
|
||||
<div class="umb-permission__description" ng-switch-when="NotCreated"><localize key="content_notCreated"></localize></div>
|
||||
<div class="umb-permission__description" ng-switch-when="Draft"><localize key="content_unpublished"></localize></div>
|
||||
<div class="umb-permission__description" ng-switch-when="PublishedPendingChanges"><localize key="content_publishedPendingChanges"></localize></div>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
return v.language.id === oldVal[i].language.id;
|
||||
});
|
||||
if (found) {
|
||||
found.publish = oldVal[i].publish;
|
||||
found.selected = oldVal[i].selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
function changeSelection(variant) {
|
||||
var firstSelected = _.find(vm.variants, function (v) {
|
||||
return v.publish;
|
||||
return v.selected;
|
||||
});
|
||||
$scope.model.disableSubmitButton = !firstSelected; //disable submit button if there is none selected
|
||||
}
|
||||
@@ -63,7 +63,7 @@
|
||||
_.each(vm.variants,
|
||||
function (variant) {
|
||||
variant.compositeId = variant.language.culture + "_" + (variant.segment ? variant.segment : "");
|
||||
variant.htmlId = "publish_variant_" + variant.compositeId;
|
||||
variant.htmlId = "_content_variant_" + variant.compositeId;
|
||||
|
||||
//check for pristine variants
|
||||
if (!vm.hasPristineVariants) {
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
if (active) {
|
||||
//ensure that the current one is selected
|
||||
active.publish = true;
|
||||
active.selected = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -16,14 +16,14 @@
|
||||
<input id="{{variant.htmlId}}"
|
||||
name="publishVariantSelector"
|
||||
type="checkbox"
|
||||
ng-model="variant.publish"
|
||||
ng-model="variant.selected"
|
||||
ng-change="vm.changeSelection(variant)"
|
||||
ng-disabled="variant.active === true"
|
||||
style="margin-right: 8px;"
|
||||
val-server-field="{{variant.htmlId}}" />
|
||||
<div>
|
||||
<label for="{{variant.htmlId}}">
|
||||
<span ng-class="{'bold': variant.published}" style="margin-bottom: 2px;">{{ variant.language.name }}</span>
|
||||
<span style="margin-bottom: 2px;">{{ variant.language.name }}</span>
|
||||
</label>
|
||||
|
||||
<div ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid">
|
||||
@@ -49,8 +49,8 @@
|
||||
|
||||
<div class="umb-list-item" ng-repeat="variant in vm.variants | filter:vm.pristineVariantFilter">
|
||||
<div>
|
||||
<div ng-class="{'bold': variant.published}" style="margin-bottom: 2px;">{{ variant.language.name }}</div>
|
||||
<div class="umb-permission__description">{{ variant.state }}</div>
|
||||
<div style="margin-bottom: 2px;">{{ variant.language.name }}</div>
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -22,7 +22,7 @@
|
||||
return v.language.id === oldVal[i].language.id;
|
||||
});
|
||||
if (found) {
|
||||
found.publish = oldVal[i].publish;
|
||||
found.selected = oldVal[i].selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,19 +31,17 @@
|
||||
|
||||
function changeSelection(variant) {
|
||||
var firstSelected = _.find(vm.variants, function (v) {
|
||||
return v.publish;
|
||||
return v.selected;
|
||||
});
|
||||
$scope.model.disableSubmitButton = !firstSelected; //disable submit button if there is none selected
|
||||
}
|
||||
|
||||
function dirtyVariantFilter(variant) {
|
||||
//determine a variant is 'dirty' (meaning it will show up as publish-able) if it's
|
||||
//determine a variant is 'dirty' (meaning it will show up as save-able) if it's
|
||||
// * the active one
|
||||
// * it's editor is in a $dirty state
|
||||
// * it has pending saves
|
||||
// * it is unpublished
|
||||
// * it is in NotCreated state
|
||||
return (variant.active || variant.isDirty || variant.state === "Draft" || variant.state === "PublishedPendingChanges" || variant.state === "NotCreated");
|
||||
return (variant.active || variant.isDirty || variant.state === "NotCreated");
|
||||
}
|
||||
|
||||
function pristineVariantFilter(variant) {
|
||||
@@ -63,8 +61,7 @@
|
||||
_.each(vm.variants,
|
||||
function (variant) {
|
||||
variant.compositeId = variant.language.culture + "_" + (variant.segment ? variant.segment : "");
|
||||
//TODO: Change this prefix on both this and the publish dialog
|
||||
variant.htmlId = "publish_variant_" + variant.compositeId;
|
||||
variant.htmlId = "_content_variant_" + variant.compositeId;
|
||||
|
||||
//check for pristine variants
|
||||
if (!vm.hasPristineVariants) {
|
||||
@@ -84,11 +81,11 @@
|
||||
|
||||
if (active) {
|
||||
//ensure that the current one is selected
|
||||
active.publish = true;
|
||||
active.selected = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
//disable Publish button if we have nothing to publish
|
||||
//disable save button if we have nothing to save
|
||||
$scope.model.disableSubmitButton = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,27 +11,27 @@
|
||||
<div class="umb-list umb-list--condensed" ng-if="!vm.loading">
|
||||
|
||||
<div class="umb-list-item" ng-repeat="variant in vm.variants | filter:vm.dirtyVariantFilter track by variant.compositeId">
|
||||
<ng-form name="publishVariantSelectorForm">
|
||||
<ng-form name="saveVariantSelectorForm">
|
||||
<div class="flex">
|
||||
<input id="{{variant.htmlId}}"
|
||||
name="publishVariantSelector"
|
||||
name="saveVariantSelector"
|
||||
type="checkbox"
|
||||
ng-model="variant.publish"
|
||||
ng-model="variant.selected"
|
||||
ng-change="vm.changeSelection(variant)"
|
||||
ng-disabled="variant.active === true"
|
||||
style="margin-right: 8px;"
|
||||
val-server-field="{{variant.htmlId}}" />
|
||||
<div>
|
||||
<label for="{{variant.htmlId}}">
|
||||
<span ng-class="{'bold': variant.published}" style="margin-bottom: 2px;">{{ variant.language.name }}</span>
|
||||
<span style="margin-bottom: 2px;">{{ variant.language.name }}</span>
|
||||
</label>
|
||||
|
||||
<div ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid">
|
||||
<div ng-if="!saveVariantSelectorForm.saveVariantSelector.$invalid">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
</div>
|
||||
|
||||
<div ng-messages="publishVariantSelectorForm.publishVariantSelector.$error" show-validation-on-submit>
|
||||
<div class="umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{publishVariantSelectorForm.publishVariantSelector.errorMsg}}</div>
|
||||
<div ng-messages="saveVariantSelectorForm.saveVariantSelector.$error" show-validation-on-submit>
|
||||
<div class="umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{saveVariantSelectorForm.saveVariantSelector.errorMsg}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -49,8 +49,8 @@
|
||||
|
||||
<div class="umb-list-item" ng-repeat="variant in vm.variants | filter:vm.pristineVariantFilter">
|
||||
<div>
|
||||
<div ng-class="{'bold': variant.published}" style="margin-bottom: 2px;">{{ variant.language.name }}</div>
|
||||
<div class="umb-permission__description">{{ variant.state }}</div>
|
||||
<div style="margin-bottom: 2px;">{{ variant.language.name }}</div>
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -779,8 +779,7 @@ namespace Umbraco.Web.Editors
|
||||
//cannot continue publishing since a required language that is not currently being published isn't published
|
||||
if (!contentItem.PersistedContent.IsCulturePublished(lang.IsoCode))
|
||||
{
|
||||
var errMsg = Services.TextService.Localize("speechBubbles/contentReqCulturePublishError", new[] { allLangs[lang.IsoCode].CultureName });
|
||||
ModelState.AddModelError("publish_variant_" + lang.IsoCode + "_", errMsg);
|
||||
AddCultureValidationError(lang.IsoCode, allLangs, "speechBubbles/contentReqCulturePublishError");
|
||||
canPublish = false;
|
||||
}
|
||||
}
|
||||
@@ -823,7 +822,7 @@ namespace Umbraco.Web.Editors
|
||||
var valid = persistentContent.PublishCulture(variant.Culture);
|
||||
if (!valid)
|
||||
{
|
||||
AddCultureValidationError(variant.Culture, allLangs);
|
||||
AddCultureValidationError(variant.Culture, allLangs, "speechBubbles/contentCultureValidationError");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -836,11 +835,12 @@ namespace Umbraco.Web.Editors
|
||||
/// </summary>
|
||||
/// <param name="culture"></param>
|
||||
/// <param name="allLangs"></param>
|
||||
private void AddCultureValidationError(string culture, IDictionary<string, ILanguage> allLangs)
|
||||
/// <param name="localizationKey"></param>
|
||||
private void AddCultureValidationError(string culture, IDictionary<string, ILanguage> allLangs, string localizationKey)
|
||||
{
|
||||
var key = "publish_variant_" + culture + "_";
|
||||
var key = "_content_variant_" + culture + "_";
|
||||
if (ModelState.ContainsKey(key)) return;
|
||||
var errMsg = Services.TextService.Localize("speechBubbles/contentCultureValidationError", new[] { allLangs[culture].CultureName });
|
||||
var errMsg = Services.TextService.Localize(localizationKey, new[] { allLangs[culture].CultureName });
|
||||
ModelState.AddModelError(key, errMsg);
|
||||
}
|
||||
|
||||
@@ -1235,7 +1235,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
foreach (var cultureError in cultureErrors)
|
||||
{
|
||||
AddCultureValidationError(cultureError, allLangs);
|
||||
AddCultureValidationError(cultureError, allLangs, "speechBubbles/contentCultureValidationError");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user