Yay! gets sub editor validation works - was actually totally broken before too, refactors how the sub views get made so this done during the scaffold processing

This commit is contained in:
Shannon
2020-07-24 15:05:59 +10:00
parent 9e9f8863c2
commit 5aba8190ae
5 changed files with 106 additions and 56 deletions

View File

@@ -1,36 +1,49 @@
/**
* @ngdoc directive
* @name umbraco.directives.directive:valSubView
* @restrict A
* @description Used to show validation warnings for a editor sub view to indicate that the section content has validation errors in its data.
* In order for this directive to work, the valFormManager directive must be placed on the containing form.
* @ngdoc directive
* @name umbraco.directives.directive:valSubView
* @restrict A
* @description Used to show validation warnings for a editor sub view (used in conjunction with:
* umb-editor-sub-view or umb-editor-sub-views) to indicate that the section content has validation errors in its data.
* In order for this directive to work, the valFormManager directive must be placed on the containing form.
* When applied to
**/
(function () {
'use strict';
// Since this is a directive applied as an attribute, the value of that attribtue is the 'model' object property
// of the current inherited scope that the hasError/errorClass properties will apply to.
// This directive cannot have it's own scope because it's an attribute applied to another scoped directive.
// Due to backwards compatibility we can't really change this, ideally this would have it's own scope/properties.
function valSubViewDirective() {
function controller($scope, $element) {
function controller($scope, $element, $attrs) {
var model = $scope.model; // this is the default and required for backwards compat
if ($attrs && $attrs.valSubView) {
// get the property to use
model = $scope[$attrs.valSubView];
}
//expose api
return {
valStatusChanged: function (args) {
// TODO: Verify this is correct, does $scope.model ever exist?
if ($scope.model) {
if (model) {
if (!args.form.$valid) {
var subViewContent = $element.find(".ng-invalid");
if (subViewContent.length > 0) {
$scope.model.hasError = true;
$scope.model.errorClass = args.showValidation ? 'show-validation' : null;
model.hasError = true;
model.errorClass = args.showValidation ? 'show-validation' : null;
} else {
$scope.model.hasError = false;
$scope.model.errorClass = null;
model.hasError = false;
model.errorClass = null;
}
}
else {
$scope.model.hasError = false;
$scope.model.errorClass = null;
model.hasError = false;
model.errorClass = null;
}
}
}
@@ -40,12 +53,18 @@
function link(scope, el, attr, ctrl) {
//if there are no containing form or valFormManager controllers, then we do nothing
if (!ctrl || !Utilities.isArray(ctrl) || ctrl.length !== 2 || !ctrl[0] || !ctrl[1]) {
if (!ctrl[1]) {
return;
}
var model = scope.model; // this is the default and required for backwards compat
if (attr && attr.valSubView) {
// get the property to use
model = scope[attr.valSubView];
}
var valFormManager = ctrl[1];
scope.model.hasError = false;
model.hasError = false;
//listen for form validation changes
valFormManager.onValidationStatusChanged(function (evt, args) {
@@ -54,14 +73,14 @@
var subViewContent = el.find(".ng-invalid");
if (subViewContent.length > 0) {
scope.model.hasError = true;
model.hasError = true;
} else {
scope.model.hasError = false;
model.hasError = false;
}
}
else {
scope.model.hasError = false;
model.hasError = false;
}
});

View File

@@ -14,7 +14,7 @@
'use strict';
function blockEditorModelObjectFactory($interpolate, udiService, contentResource) {
function blockEditorModelObjectFactory($interpolate, udiService, contentResource, localizationService) {
/**
* Simple mapping from property model content entry to editing model,
@@ -214,6 +214,17 @@
return dataItems.find(entry => entry.udi === udi) || null;
}
/**
* Set the udi and key property for the content item
* @param {any} contentData
* @param {any} udi
*/
function ensureUdiAndKey(contentData, udi) {
contentData.udi = udi;
// Change the content.key to the GUID part of the udi, else it's just random which we don't want, it must be consistent
contentData.key = udiService.getKey(udi);
}
/**
* Used to highlight unsupported properties for the user, changes unsupported properties into a unsupported-property.
*/
@@ -222,7 +233,15 @@
"Umbraco.UploadField",
"Umbraco.ImageCropper"
];
function replaceUnsupportedProperties(scaffold) {
/**
* Formats the content apps and ensures unsupported property's have the notsupported view
* @param {any} scaffold
*/
function formatScaffoldData(scaffold) {
// deal with not supported props
scaffold.variants.forEach((variant) => {
variant.tabs.forEach((tab) => {
tab.properties.forEach((property) => {
@@ -232,7 +251,34 @@
});
});
});
return scaffold;
// replace view of content app
var contentApp = scaffold.apps.find(entry => entry.alias === "umbContent");
if (contentApp) {
contentApp.view = "views/common/infiniteeditors/blockeditor/blockeditor.content.html";
}
// remove info app
var infoAppIndex = scaffold.apps.findIndex(entry => entry.alias === "umbInfo");
if (infoAppIndex >= 0) {
scaffold.apps.splice(infoAppIndex, 1);
}
// add the settings app
return localizationService.localize("blockEditor_tabBlockSettings").then(
function (settingsName) {
var settingsTab = {
"name": settingsName,
"alias": "settings",
"icon": "icon-settings",
"view": "views/common/infiniteeditors/blockeditor/blockeditor.settings.html",
"hasError": false
};
scaffold.apps.push(settingsTab);
return scaffold;
}
);
}
/**
@@ -337,7 +383,10 @@
tasks.push(contentResource.getScaffoldByKey(-20, contentTypeKey).then(scaffold => {
// this.scaffolds might not exists anymore, this happens if this instance has been destroyed before the load is complete.
if (this.scaffolds) {
this.scaffolds.push(replaceUnsupportedProperties(scaffold));
return formatScaffoldData(scaffold).then(s => this.scaffolds.push(s));
}
else {
return Promise.resolve();
}
}));
}));
@@ -483,9 +532,7 @@
// make basics from scaffold
blockObject.content = Utilities.copy(contentScaffold);
blockObject.content.udi = contentUdi;
// Change the content.key to the GUID part of the udi, else it's just random which we don't want, it must be consistent
blockObject.content.key = udiService.getKey(contentUdi);
ensureUdiAndKey(blockObject.content, contentUdi);
mapToElementModel(blockObject.content, dataModel);
@@ -514,9 +561,7 @@
// make basics from scaffold
blockObject.settings = Utilities.copy(settingsScaffold);
blockObject.settings.udi = settingsUdi;
// Change the settings.key to the GUID part of the udi, else it's just random which we don't want, it must be consistent
blockObject.settings.key = udiService.getKey(settingsUdi);
ensureUdiAndKey(blockObject.settings, settingsUdi);
mapToElementModel(blockObject.settings, settingsData);
}

View File

@@ -3,9 +3,9 @@ angular.module("umbraco")
function ($scope, localizationService, formHelper) {
var vm = this;
vm.model = $scope.model;
vm.model = $scope.model;
vm.tabs = [];
localizationService.localizeMany([
vm.model.liveEditing ? "prompt_discardChanges" : "general_close",
vm.model.liveEditing ? "buttons_confirmActionConfirm" : "buttons_submitChanges"
@@ -14,16 +14,13 @@ angular.module("umbraco")
vm.submitLabel = data[1];
});
if ($scope.model.content && $scope.model.content.variants) {
if (vm.model.content && vm.model.content.variants) {
var apps = $scope.model.content.apps;
var apps = vm.model.content.apps;
vm.tabs = apps;
// replace view of content app.
// configure the content app based on settings
var contentApp = apps.find(entry => entry.alias === "umbContent");
if (contentApp) {
contentApp.view = "views/common/infiniteeditors/blockeditor/blockeditor.content.html";
if (vm.model.hideContent) {
apps.splice(apps.indexOf(contentApp), 1);
} else if (vm.model.openSettings !== true) {
@@ -31,27 +28,16 @@ angular.module("umbraco")
}
}
// remove info app:
var infoAppIndex = apps.findIndex(entry => entry.alias === "umbInfo");
apps.splice(infoAppIndex, 1);
}
if (vm.model.settings && vm.model.settings.variants) {
localizationService.localize("blockEditor_tabBlockSettings").then(
function (settingsName) {
var settingsTab = {
"name": settingsName,
"alias": "settings",
"icon": "icon-settings",
"view": "views/common/infiniteeditors/blockeditor/blockeditor.settings.html"
};
vm.tabs.push(settingsTab);
if (vm.model.settings && vm.model.settings.variants) {
var settingsApp = apps.find(entry => entry.alias === "settings");
if (settingsApp) {
if (vm.model.openSettings) {
settingsTab.active = true;
settingsApp.active = true;
}
}
);
}
vm.tabs = apps;
}
vm.submitAndClose = function () {

View File

@@ -1,6 +1,6 @@
<div class="umb-editor-sub-view"
ng-class="'sub-view-' + model.name"
val-sub-view>
val-sub-view="model">
<div
class="umb-editor-sub-view__content"

View File

@@ -5,7 +5,7 @@
class="umb-editor-sub-view"
ng-repeat="subView in subViews track by subView.alias"
ng-class="'sub-view-' + subView.name"
val-sub-view>
val-sub-view="subView">
<div class="umb-editor-sub-view__content"
ng-show="subView.active === true"