No need for 2x the same component, we just change how we $compile, fixes up showing the validation border

This commit is contained in:
Shannon
2020-07-17 13:37:36 +10:00
parent 4d06094696
commit b57545a9b0
7 changed files with 40 additions and 79 deletions

View File

@@ -42,7 +42,7 @@ function valFormManager(serverValidationManager, $rootScope, $timeout, $location
}));
};
this.showValidation = $scope.showValidation === true;
this.isShowingValidation = () => $scope.showValidation === true;
this.notify = function () {
notify($scope);
@@ -136,7 +136,7 @@ function valFormManager(serverValidationManager, $rootScope, $timeout, $location
var isSavingNewItem = false;
//we should show validation if there are any msgs in the server validation collection
if (serverValidationManager.items.length > 0 || (parentFormMgr && parentFormMgr.showValidation)) {
if (serverValidationManager.items.length > 0 || (parentFormMgr && parentFormMgr.isShowingValidation())) {
element.addClass(SHOW_VALIDATION_CLASS_NAME);
scope.showValidation = true;
notifySubView();

View File

@@ -1,6 +1,6 @@
<div class="blockelement-inlineblock-editor"
ng-controller="Umbraco.PropertyEditors.BlockEditor.InlineBlockEditor as vm"
ng-class="{ '--error': blockRowForm.$invalid }">
ng-class="{ '--error': parentForm.$invalid && valFormManager.isShowingValidation() }">
<button type="button" class="btn-reset umb-outline blockelement__draggable-element"
ng-click="vm.openBlock(block)"
ng-focus="block.focus">

View File

@@ -1,7 +1,7 @@
<button type="button" class="btn-reset umb-outline blockelement-labelblock-editor blockelement__draggable-element"
ng-click="api.editBlock(block, block.hideContentInOverlay, index, parentForm)"
ng-focus="block.focus"
ng-class="{ '--active': block.active, '--error': blockRowForm.$invalid }"
ng-class="{ '--active': block.active, '--error': parentForm.$invalid && valFormManager.isShowingValidation() }"
val-server-property-class="">
<i class="icon {{block.content.icon}}"></i>
<span>{{block.label}}</span>

View File

@@ -1,16 +1,7 @@
<ng-form name="vm.blockRowForm" val-server-match="{ 'contains' : vm.layout.$block.content.key }">
<div class="umb-block-list__block" ng-class="{'--active':vm.layout.$block.active}">
<umb-block-list-scoped-block ng-if="vm.layout.$block.config.stylesheet"
class="umb-block-list__block--content blockelement__draggable-element"
view="{{vm.layout.$block.view}}"
stylesheet="/{{::vm.layout.$block.config.stylesheet}}"
api="vm.blockEditorApi"
block="vm.layout.$block"
index="vm.index"
parent-form="vm.blockRowForm">
</umb-block-list-scoped-block>
<umb-block-list-block ng-if="!vm.layout.$block.config.stylesheet"
<umb-block-list-block stylesheet="{{::vm.layout.$block.config.stylesheet}}"
class="umb-block-list__block--content"
view="{{vm.layout.$block.view}}"
api="vm.blockEditorApi"

View File

@@ -198,7 +198,8 @@
});
});
}
// TODO: Why is there a '/' prefixed? that means this will never work with virtual directories
block.view = (block.config.view ? "/" + block.config.view : getDefaultViewForBlock(block));
block.hideContentInOverlay = block.config.forceHideContentEditorInOverlay === true || inlineEditing === true;

View File

@@ -5,35 +5,63 @@
* @ngdoc directive
* @name umbraco.directives.directive:umbBlockListBlock
* @description
* The component for a style-inheriting block of the block list property editor.
* The component to render the view for a block.
* If a stylesheet is used then this uses a ShadowDom to make a scoped element.
* This way the backoffice styling does not collide with the block style.
*/
angular
.module("umbraco")
.component("umbBlockListBlock", {
template: '<div ng-include="model.view"></div>',
controller: BlockListBlockController,
controllerAs: "model",
bindings: {
stylesheet: "@",
view: "@",
block: "=",
api: "<",
index: "<",
parentForm: "<"
},
require: {
valFormManager: "^^valFormManager"
}
}
);
function BlockListBlockController($scope) {
function BlockListBlockController($scope, $compile, $element) {
var model = this;
model.$onInit = function () {
// Ugh, due to the way we work with angularjs and property editors not being components and needing to use ng-include,
// it means we need to expose things directly on the $scope so they can use them.
// This is ugly and is only necessary because we are not using components and instead
// relying on ng-include. It is definitely possible to compile the contents
// of the view into the DOM using $templateCache and $http instead of using
// ng - include which means that the controllerAs flows directly to the view.
// This would mean that any custom components would need to be updated instead of relying on $scope.
// Guess we'll leave it for now but means all things need to be copied to the $scope and then all
// primitives need to be watched.
$scope.block = model.block;
$scope.api = model.api;
$scope.index = model.index;
$scope.parentForm = model.parentForm;
$scope.valFormManager = model.valFormManager;
if (model.stylesheet) {
// TODO: Not sure why this needs a prefixed /? this means it will never work in a virtual directory
model.stylesheet = "/" + model.stylesheet;
var shadowRoot = $element[0].attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `
<style>
@import "${model.stylesheet}"
</style>
<div ng-include="'${model.view}'"></div>
`;
$compile(shadowRoot)($scope);
}
else {
$element.append($compile('<div ng-include="model.view"></div>')($scope));
}
};
// We need to watch for changes on primitive types and upate the $scope values.

View File

@@ -1,59 +0,0 @@
(function () {
"use strict";
/**
* @ngdoc directive
* @name umbraco.directives.directive:umbBlockListScopedBlock
* @description
* The component for a style-scoped block of the block list property editor.
* Uses a ShadowDom to make a scoped element.
* This way the backoffice styling does not collide with the block style.
*/
angular
.module("umbraco")
.component("umbBlockListScopedBlock", {
controller: BlockListScopedBlockController,
controllerAs: "model",
bindings: {
stylesheet: "@",
view: "@",
block: "=",
api: "<",
index: "<",
parentForm: "<"
}
}
);
function BlockListScopedBlockController($compile, $element, $scope) {
var model = this;
model.$onInit = function() {
// Ugh, due to the way we work with angularjs and property editors not being components and needing to use ng-include,
// it means we need to expose things directly on the $scope so they can use them.
$scope.block = model.block;
$scope.api = model.api;
$scope.index = model.index;
$scope.parentForm = model.parentForm;
var shadowRoot = $element[0].attachShadow({mode:'open'});
shadowRoot.innerHTML = `
<style>
@import "${model.stylesheet}"
</style>
<div ng-include="'${model.view}'"></div>
`;
$compile(shadowRoot)($scope);
}
// We need to watch for changes on primitive types and upate the $scope values.
model.$onChanges = function (changes) {
if (changes.index) {
$scope.index = changes.index.currentValue;
}
}
}
})();