Gets property json paths working in complex editors, next lets see if we can make it work for validation.
This commit is contained in:
+89
-31
@@ -7,94 +7,94 @@
|
||||
|
||||
var evts = [];
|
||||
var allowedNumberOfVisibleEditors = 3;
|
||||
|
||||
|
||||
scope.editors = [];
|
||||
|
||||
|
||||
function addEditor(editor) {
|
||||
|
||||
|
||||
editor.inFront = true;
|
||||
editor.moveRight = true;
|
||||
editor.level = 0;
|
||||
editor.styleIndex = 0;
|
||||
|
||||
|
||||
// push the new editor to the dom
|
||||
scope.editors.push(editor);
|
||||
|
||||
|
||||
$timeout(() => {
|
||||
editor.moveRight = false;
|
||||
})
|
||||
|
||||
|
||||
editor.animating = true;
|
||||
setTimeout(revealEditorContent.bind(this, editor), 400);
|
||||
|
||||
|
||||
updateEditors();
|
||||
|
||||
}
|
||||
|
||||
|
||||
function removeEditor(editor) {
|
||||
|
||||
|
||||
editor.moveRight = true;
|
||||
|
||||
|
||||
editor.animating = true;
|
||||
setTimeout(removeEditorFromDOM.bind(this, editor), 400);
|
||||
|
||||
|
||||
updateEditors(-1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function revealEditorContent(editor) {
|
||||
|
||||
|
||||
editor.animating = false;
|
||||
|
||||
|
||||
scope.$digest();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function removeEditorFromDOM(editor) {
|
||||
|
||||
|
||||
// push the new editor to the dom
|
||||
var index = scope.editors.indexOf(editor);
|
||||
if (index !== -1) {
|
||||
scope.editors.splice(index, 1);
|
||||
}
|
||||
|
||||
|
||||
updateEditors();
|
||||
|
||||
|
||||
scope.$digest();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** update layer positions. With ability to offset positions, needed for when an item is moving out, then we dont want it to influence positions */
|
||||
function updateEditors(offset) {
|
||||
|
||||
|
||||
offset = offset || 0;// fallback value.
|
||||
|
||||
|
||||
var len = scope.editors.length;
|
||||
var calcLen = len + offset;
|
||||
var ceiling = Math.min(calcLen, allowedNumberOfVisibleEditors);
|
||||
var origin = Math.max(calcLen-1, 0)-ceiling;
|
||||
var origin = Math.max(calcLen - 1, 0) - ceiling;
|
||||
var i = 0;
|
||||
while(i<len) {
|
||||
while (i < len) {
|
||||
var iEditor = scope.editors[i];
|
||||
iEditor.styleIndex = Math.min(i+1, allowedNumberOfVisibleEditors);
|
||||
iEditor.level = Math.max(i-origin, -1);
|
||||
iEditor.styleIndex = Math.min(i + 1, allowedNumberOfVisibleEditors);
|
||||
iEditor.level = Math.max(i - origin, -1);
|
||||
iEditor.inFront = iEditor.level >= ceiling;
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
evts.push(eventsService.on("appState.editors.open", function (name, args) {
|
||||
addEditor(args.editor);
|
||||
}));
|
||||
|
||||
evts.push(eventsService.on("appState.editors.close", function (name, args) {
|
||||
// remove the closed editor
|
||||
if(args && args.editor) {
|
||||
if (args && args.editor) {
|
||||
removeEditor(args.editor);
|
||||
}
|
||||
// close all editors
|
||||
if(args && !args.editor && args.editors.length === 0) {
|
||||
if (args && !args.editor && args.editors.length === 0) {
|
||||
scope.editors = [];
|
||||
}
|
||||
}));
|
||||
@@ -119,6 +119,64 @@
|
||||
|
||||
}
|
||||
|
||||
// This directive allows for us to run a custom $compile for the view within the repeater which allows
|
||||
// us to maintain a $scope hierarchy with the rendered view based on the $scope that initiated the
|
||||
// infinite editing. The retain the $scope hiearchy a special $parentScope property is passed in to the model.
|
||||
function EditorRepeaterDirective($http, $templateCache, $compile) {
|
||||
function link(scope, el, attr, ctrl) {
|
||||
|
||||
var editor = scope && scope.$parent ? scope.$parent.model : null;
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
var unsubscribe = [];
|
||||
|
||||
//if a custom parent scope is defined then we need to manually compile the view
|
||||
if (editor.$parentScope) {
|
||||
var element = el.find(".scoped-view");
|
||||
$http.get(editor.view, { cache: $templateCache })
|
||||
.then(function (response) {
|
||||
var templateScope = editor.$parentScope.$new();
|
||||
|
||||
unsubscribe.push(function () {
|
||||
templateScope.$destroy();
|
||||
});
|
||||
|
||||
// NOTE: the 'model' name here directly affects the naming convention used in infinite editors, this why you access the model
|
||||
// like $scope.model.If this is changed, everything breaks.This is because we are entirely reliant upon ng - include and inheriting $scopes.
|
||||
// by default without a $parentScope used for infinite editing the 'model' propety will be set because the view creates the scopes in
|
||||
// ng-repeat by ng-repeat="model in editors"
|
||||
templateScope.model = editor;
|
||||
|
||||
element.html(response.data);
|
||||
element.show();
|
||||
$compile(element.contents())(templateScope);
|
||||
});
|
||||
}
|
||||
|
||||
scope.$on('$destroy', function () {
|
||||
for (var i = 0; i < unsubscribe.length; i++) {
|
||||
unsubscribe[i]();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var directive = {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
scope: {
|
||||
editors: "="
|
||||
},
|
||||
template: "<div ng-transclude></div>",
|
||||
link: link
|
||||
};
|
||||
|
||||
return directive;
|
||||
}
|
||||
|
||||
angular.module('umbraco.directives').directive('umbEditors', EditorsDirective);
|
||||
angular.module('umbraco.directives').directive('umbEditorRepeater', EditorRepeaterDirective);
|
||||
|
||||
})();
|
||||
|
||||
+23
-13
@@ -4,44 +4,54 @@
|
||||
|
||||
/**
|
||||
* @ngdoc component
|
||||
* @name Umbraco.umbBlockListBlockContent
|
||||
* @name umbraco.umbNestedProperty
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* The component for a style-inheriting block of the block list property editor.
|
||||
* Used to have nested property editors within complex editors in order to generate jsonpath for them to be used in validation
|
||||
*/
|
||||
angular
|
||||
.module("umbraco")
|
||||
.component("umbNestedProperty", {
|
||||
transclude: true,
|
||||
template: '<div ng-transclude></div>',
|
||||
template: '<div><pre>{{vm.getValidationPath()}}</pre><div ng-transclude></div></div>',
|
||||
controller: NestedPropertyController,
|
||||
controllerAs: 'vm',
|
||||
bindings: {
|
||||
propertyTypeAlias: "@",
|
||||
elementTypeIndex: "@"
|
||||
elementTypeIndex: "<",
|
||||
findInScopeChain: "<" // TODO: Use/enable this
|
||||
},
|
||||
require: {
|
||||
umbNestedProperty: "?^^umbNestedProperty"
|
||||
umbNestedProperty: "?^^"
|
||||
}
|
||||
});
|
||||
|
||||
function NestedPropertyController($scope) {
|
||||
function NestedPropertyController($scope, angularHelper) {
|
||||
var vm = this;
|
||||
vm.$onInit = function () {
|
||||
|
||||
if (!vm.propertyTypeAlias) {
|
||||
throw "no propertyTypeAlias specified for umbNestedProperty";
|
||||
}
|
||||
};
|
||||
|
||||
vm.$postLink = function () {
|
||||
// if directive inheritance (DOM) doesn't find one, then check scope inheritance
|
||||
if (!vm.umbNestedProperty/* && findInScopeChain*/) {
|
||||
var found = angularHelper.traverseScopeChain($scope, s => s.vm && s.vm.constructor.name == "NestedPropertyController");
|
||||
if (found) {
|
||||
vm.umbNestedProperty = found.vm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns a jsonpath for where this property is located in a hierarchy
|
||||
// this will call into all hierarchical parents
|
||||
vm.getValidationPath = function () {
|
||||
|
||||
var path = vm.umbNestedProperty ? vm.umbNestedProperty.getValidationPath() : "$";
|
||||
if (vm.propertyTypeAlias && vm.elementTypeIndex) {
|
||||
path += ".[nestedValidation].[" + vm.elementTypeIndex + "].[" + vm.propertyTypeAlias + "]";
|
||||
return path;
|
||||
}
|
||||
return null;
|
||||
var path = vm.umbNestedProperty ? vm.umbNestedProperty.getValidationPath() : "$";
|
||||
path += ".[nestedValidation].[" + vm.elementTypeIndex + "].[" + vm.propertyTypeAlias + "]";
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@
|
||||
scope: {
|
||||
ngModel: '=',
|
||||
tabAlias: '=',
|
||||
itemIndex: '@'
|
||||
itemIndex: '='
|
||||
},
|
||||
link: link
|
||||
};
|
||||
|
||||
@@ -9,6 +9,23 @@
|
||||
function angularHelper($q) {
|
||||
return {
|
||||
|
||||
/**
|
||||
* Will traverse up the $scope chain to all ancestors until the predicate matches for the current scope or until it's at the root.
|
||||
* @param {any} scope
|
||||
* @param {any} predicate
|
||||
*/
|
||||
traverseScopeChain: function (scope, predicate) {
|
||||
var s = scope.$parent;
|
||||
while (s) {
|
||||
var result = predicate(s);
|
||||
if (result === true) {
|
||||
return s;
|
||||
}
|
||||
s = s.$parent;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method used to re-run the $parsers for a given ngModel
|
||||
* @param {} scope
|
||||
|
||||
+16
-16
@@ -4,21 +4,19 @@ angular.module("umbraco")
|
||||
function ($scope, localizationService, formHelper) {
|
||||
var vm = this;
|
||||
|
||||
// TODO: Why are we assigning content/setting separately when we already have vm.model?
|
||||
vm.content = $scope.model.content;
|
||||
vm.settings = $scope.model.settings;
|
||||
|
||||
vm.settings = $scope.model.settings;
|
||||
vm.model = $scope.model;
|
||||
vm.tabs = [];
|
||||
localizationService.localizeMany([
|
||||
$scope.model.liveEditing ? "prompt_discardChanges" : "general_close",
|
||||
$scope.model.liveEditing ? "buttons_confirmActionConfirm" : "buttons_submitChanges"
|
||||
vm.model.liveEditing ? "prompt_discardChanges" : "general_close",
|
||||
vm.model.liveEditing ? "buttons_confirmActionConfirm" : "buttons_submitChanges"
|
||||
]).then(function (data) {
|
||||
vm.closeLabel = data[0];
|
||||
vm.submitLabel = data[1];
|
||||
});
|
||||
|
||||
vm.model = $scope.model;
|
||||
|
||||
vm.tabs = [];
|
||||
|
||||
if (vm.content && vm.content.variants) {
|
||||
|
||||
var apps = vm.content.apps;
|
||||
@@ -27,11 +25,12 @@ angular.module("umbraco")
|
||||
|
||||
// replace view of content app.
|
||||
var contentApp = apps.find(entry => entry.alias === "umbContent");
|
||||
if(contentApp) {
|
||||
if (contentApp) {
|
||||
// TODO: This is strange, why does this render a view from somewhere else and this is the only place where that view is used?
|
||||
contentApp.view = "views/common/infiniteeditors/elementeditor/elementeditor.content.html";
|
||||
if($scope.model.hideContent) {
|
||||
if(vm.model.hideContent) {
|
||||
apps.splice(apps.indexOf(contentApp), 1);
|
||||
} else if ($scope.model.openSettings !== true) {
|
||||
} else if (vm.model.openSettings !== true) {
|
||||
contentApp.active = true;
|
||||
}
|
||||
}
|
||||
@@ -49,10 +48,11 @@ angular.module("umbraco")
|
||||
"name": settingsName,
|
||||
"alias": "settings",
|
||||
"icon": "icon-settings",
|
||||
// TODO: This is strange, why does this render a view from somewhere else and this is the only place where that view is used?
|
||||
"view": "views/common/infiniteeditors/elementeditor/elementeditor.settings.html"
|
||||
};
|
||||
vm.tabs.push(settingsTab);
|
||||
if ($scope.model.openSettings) {
|
||||
if (vm.model.openSettings) {
|
||||
settingsTab.active = true;
|
||||
}
|
||||
}
|
||||
@@ -60,17 +60,17 @@ angular.module("umbraco")
|
||||
}
|
||||
|
||||
vm.submitAndClose = function () {
|
||||
if ($scope.model && $scope.model.submit) {
|
||||
if (vm.model && vm.model.submit) {
|
||||
if (formHelper.submitForm({ scope: $scope })) {
|
||||
$scope.model.submit($scope.model);
|
||||
vm.model.submit(vm.model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.close = function() {
|
||||
if ($scope.model && $scope.model.close) {
|
||||
if (vm.model && vm.model.close) {
|
||||
// TODO: If content has changed, we should notify user.
|
||||
$scope.model.close($scope.model);
|
||||
vm.model.close(vm.model);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-12
@@ -9,19 +9,23 @@
|
||||
</div>
|
||||
|
||||
<div class="umb-group-panel__content">
|
||||
<umb-property
|
||||
data-element="property-{{property.alias}}"
|
||||
ng-repeat="property in group.properties track by property.alias"
|
||||
property="property"
|
||||
show-inherit="vm.model.variants.length > 1 && !property.culture && !activeVariant.language.isDefault"
|
||||
inherits-from="defaultVariant.language.name">
|
||||
|
||||
<div ng-class="{'o-40 cursor-not-allowed': vm.model.variants.length > 1 && !activeVariant.language.isDefault && !property.culture && !property.unlockInvariantValue}">
|
||||
<umb-property-editor
|
||||
model="property"
|
||||
preview="vm.model.variants.length > 1 && !activeVariant.language.isDefault && !property.culture && !property.unlockInvariantValue">
|
||||
</umb-property-editor>
|
||||
</div>
|
||||
<umb-property data-element="property-{{property.alias}}"
|
||||
ng-repeat="property in group.properties track by property.alias"
|
||||
property="property"
|
||||
show-inherit="vm.model.variants.length > 1 && !property.culture && !activeVariant.language.isDefault"
|
||||
inherits-from="defaultVariant.language.name">
|
||||
|
||||
<umb-nested-property property-type-alias="{{property.alias}}"
|
||||
element-type-index="vm.itemIndex">
|
||||
|
||||
<div ng-class="{'o-40 cursor-not-allowed': vm.model.variants.length > 1 && !activeVariant.language.isDefault && !property.culture && !property.unlockInvariantValue}">
|
||||
<umb-property-editor model="property"
|
||||
preview="vm.model.variants.length > 1 && !activeVariant.language.isDefault && !property.culture && !property.unlockInvariantValue">
|
||||
</umb-property-editor>
|
||||
</div>
|
||||
|
||||
</umb-nested-property>
|
||||
|
||||
</umb-property>
|
||||
</div>
|
||||
|
||||
+6
-1
@@ -1,6 +1,8 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
// TODO: Add docs - this component is used to render a content item based on an Element Type as a nested editor
|
||||
|
||||
angular
|
||||
.module('umbraco.directives')
|
||||
.component('umbElementEditorContent', {
|
||||
@@ -8,7 +10,10 @@
|
||||
controller: ElementEditorContentComponentController,
|
||||
controllerAs: 'vm',
|
||||
bindings: {
|
||||
model: '='
|
||||
model: '=',
|
||||
// As this component is used for creating nested editors based on an element type, we need to know the index of this nested
|
||||
// editor so that validation works. For example, if this is used in the block editor, this is the index of the block being rendered.
|
||||
itemIndex: '<'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
<div>
|
||||
<umb-element-editor-content model="model.content"></umb-element-editor-content>
|
||||
<umb-element-editor-content model="model.content" item-index="model.index"></umb-element-editor-content>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
<umb-element-editor-content model="model.settings"></umb-element-editor-content>
|
||||
<umb-element-editor-content model="model.settings" item-index="model.index"></umb-element-editor-content>
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
<div class="umb-editors">
|
||||
|
||||
<div class="umb-editor"
|
||||
ng-repeat="model in editors"
|
||||
ng-class="{'umb-editor--small': model.size === 'small',
|
||||
'umb-editor--medium': model.size === 'medium',
|
||||
'umb-editor--animating': model.animating,
|
||||
'umb-editor--notInFront': model.inFront !== true,
|
||||
'umb-editor--infiniteMode': model.infiniteMode,
|
||||
'umb-editor--moveRight': model.moveRight,
|
||||
'umb-editor--n0': model.styleIndex === 0,
|
||||
'umb-editor--n1': model.styleIndex === 1,
|
||||
'umb-editor--n2': model.styleIndex === 2,
|
||||
'umb-editor--n3': model.styleIndex === 3,
|
||||
'umb-editor--outOfRange': model.level === -1,
|
||||
'umb-editor--level0': model.level === 0,
|
||||
'umb-editor--level1': model.level === 1,
|
||||
'umb-editor--level2': model.level === 2,
|
||||
'umb-editor--level3': model.level === 3}"
|
||||
>
|
||||
<umb-editor-repeater class="umb-editor"
|
||||
ng-repeat="model in editors"
|
||||
ng-class="{'umb-editor--small': model.size === 'small',
|
||||
'umb-editor--medium': model.size === 'medium',
|
||||
'umb-editor--animating': model.animating,
|
||||
'umb-editor--notInFront': model.inFront !== true,
|
||||
'umb-editor--infiniteMode': model.infiniteMode,
|
||||
'umb-editor--moveRight': model.moveRight,
|
||||
'umb-editor--n0': model.styleIndex === 0,
|
||||
'umb-editor--n1': model.styleIndex === 1,
|
||||
'umb-editor--n2': model.styleIndex === 2,
|
||||
'umb-editor--n3': model.styleIndex === 3,
|
||||
'umb-editor--outOfRange': model.level === -1,
|
||||
'umb-editor--level0': model.level === 0,
|
||||
'umb-editor--level1': model.level === 1,
|
||||
'umb-editor--level2': model.level === 2,
|
||||
'umb-editor--level3': model.level === 3}">
|
||||
|
||||
<div ng-if="!model.view && !model.animating" ng-transclude></div>
|
||||
<div ng-if="model.view && !model.animating" ng-include="model.view"></div>
|
||||
|
||||
<div ng-if="model.view && !model.animating && !model.$parentScope" ng-include="model.view"></div>
|
||||
<div ng-show="model.$parentScope" class="scoped-view"></div>
|
||||
<div class="umb-editor__overlay"></div>
|
||||
</div>
|
||||
|
||||
</umb-editor-repeater>
|
||||
|
||||
</div>
|
||||
|
||||
+2
@@ -1,6 +1,8 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
// TODO: Does this belong in the property editors folder?
|
||||
|
||||
angular
|
||||
.module("umbraco")
|
||||
.component("umbBlockCard", {
|
||||
|
||||
+14
-2
@@ -19,7 +19,7 @@
|
||||
bindings: {
|
||||
view: "@",
|
||||
block: "=",
|
||||
api: "=",
|
||||
api: "=", // Should this be a one way bind?
|
||||
index: "<"
|
||||
}
|
||||
}
|
||||
@@ -27,10 +27,22 @@
|
||||
|
||||
function BlockListBlockContentController($scope) {
|
||||
var model = this;
|
||||
model.$onInit = function() {
|
||||
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.
|
||||
// It also means we need to watch for changes and upate the $scope values.
|
||||
|
||||
$scope.block = model.block;
|
||||
$scope.api = model.api;
|
||||
$scope.index = model.index;
|
||||
};
|
||||
model.$onChanges = function (changes) {
|
||||
if (changes.index) {
|
||||
$scope.index = changes.index.currentValue;
|
||||
}
|
||||
|
||||
// TODO: Wouldn't we need to watch for any changes to model.block/api here too?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+32
-30
@@ -8,31 +8,36 @@
|
||||
|
||||
<div ng-repeat="layout in vm.layout track by layout.$block.key">
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn-reset umb-block-list__block--create-button"
|
||||
ng-click="vm.showCreateDialog($index, $event)"
|
||||
ng-controller="Umbraco.PropertyEditors.BlockListPropertyEditor.CreateButtonController as inlineCreateButtonCtrl"
|
||||
ng-mousemove="inlineCreateButtonCtrl.onMouseMove($event)"
|
||||
>
|
||||
<button type="button"
|
||||
class="btn-reset umb-block-list__block--create-button"
|
||||
ng-click="vm.showCreateDialog($index, $event)"
|
||||
ng-controller="Umbraco.PropertyEditors.BlockListPropertyEditor.CreateButtonController as inlineCreateButtonCtrl"
|
||||
ng-mousemove="inlineCreateButtonCtrl.onMouseMove($event)">
|
||||
<div class="__plus" ng-style="{'left':inlineCreateButtonCtrl.plusPosX}">+</div>
|
||||
</button>
|
||||
|
||||
<div class="umb-block-list__block" ng-class="{'--active':layout.$block.active}">
|
||||
|
||||
<umb-nested-property property-type-alias="{{property.propertyAlias}}"
|
||||
element-type-index="{{$index}}">
|
||||
|
||||
|
||||
<umb-block-list-scoped-block-content ng-if="layout.$block.config.stylesheet" class="umb-block-list__block--content blockelement__draggable-element" view="{{layout.$block.view}}" stylesheet="/{{::layout.$block.config.stylesheet}}" api="vm.blockEditorApi" block="layout.$block" index="$index">
|
||||
<umb-block-list-scoped-block-content ng-if="layout.$block.config.stylesheet"
|
||||
class="umb-block-list__block--content blockelement__draggable-element"
|
||||
view="{{layout.$block.view}}"
|
||||
stylesheet="/{{::layout.$block.config.stylesheet}}"
|
||||
api="vm.blockEditorApi"
|
||||
block="layout.$block"
|
||||
index="$index">
|
||||
</umb-block-list-scoped-block-content>
|
||||
<umb-block-list-block-content ng-if="!layout.$block.config.stylesheet" class="umb-block-list__block--content" view="{{layout.$block.view}}" api="vm.blockEditorApi" block="layout.$block" index="$index">
|
||||
<umb-block-list-block-content ng-if="!layout.$block.config.stylesheet"
|
||||
class="umb-block-list__block--content"
|
||||
view="{{layout.$block.view}}"
|
||||
api="vm.blockEditorApi"
|
||||
block="layout.$block"
|
||||
index="$index">
|
||||
</umb-block-list-block-content>
|
||||
|
||||
</umb-nested-property>
|
||||
|
||||
<div class="umb-block-list__block--actions">
|
||||
<button type="button" class="btn-reset umb-outline action --settings" localize="title" title="actions_editSettings" ng-click="vm.blockEditorApi.openSettingsForBlock(layout.$block);" ng-if="layout.$block.showSettings === true">
|
||||
<button type="button" class="btn-reset umb-outline action --settings" localize="title" title="actions_editSettings"
|
||||
ng-click="vm.blockEditorApi.openSettingsForBlock(layout.$block, $index);"
|
||||
ng-if="layout.$block.showSettings === true">
|
||||
<i class="icon icon-settings" aria-hidden="true"></i>
|
||||
<span class="sr-only">
|
||||
<localize key="general_settings">Settings</localize>
|
||||
@@ -56,14 +61,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
ng-if="vm.loading !== true"
|
||||
id="{{vm.model.alias}}"
|
||||
type="button"
|
||||
class="btn-reset umb-block-list__create-button umb-outline"
|
||||
ng-class="{ '--disabled': vm.availableBlockTypes.length === 0 }"
|
||||
ng-click="vm.showCreateDialog(vm.layout.length, $event)"
|
||||
>
|
||||
<button ng-if="vm.loading !== true"
|
||||
id="{{vm.model.alias}}"
|
||||
type="button"
|
||||
class="btn-reset umb-block-list__create-button umb-outline"
|
||||
ng-class="{ '--disabled': vm.availableBlockTypes.length === 0 }"
|
||||
ng-click="vm.showCreateDialog(vm.layout.length, $event)">
|
||||
<localize key="grid_addElement"></localize>
|
||||
</button>
|
||||
|
||||
@@ -82,12 +85,11 @@
|
||||
|
||||
</div>
|
||||
|
||||
<umb-overlay
|
||||
ng-if="vm.blockTypePicker.show"
|
||||
position="target"
|
||||
size="vm.blockTypePicker.size"
|
||||
view="vm.blockTypePicker.view"
|
||||
model="vm.blockTypePicker">
|
||||
<umb-overlay ng-if="vm.blockTypePicker.show"
|
||||
position="target"
|
||||
size="vm.blockTypePicker.size"
|
||||
view="vm.blockTypePicker.view"
|
||||
model="vm.blockTypePicker">
|
||||
</umb-overlay>
|
||||
|
||||
|
||||
|
||||
+14
-8
@@ -131,6 +131,7 @@
|
||||
// Append the blockObjects to our layout.
|
||||
vm.layout.forEach(entry => {
|
||||
if (entry.$block === undefined || entry.$block === null) {
|
||||
|
||||
var block = getBlockObject(entry);
|
||||
|
||||
// If this entry was not supported by our property-editor it would return 'null'.
|
||||
@@ -221,7 +222,12 @@
|
||||
});
|
||||
}
|
||||
|
||||
function editBlock(blockObject, openSettings) {
|
||||
function editBlock(blockObject, openSettings, blockIndex) {
|
||||
|
||||
// this must be set
|
||||
if (blockIndex === undefined) {
|
||||
throw "blockIndex was not specified on call to editBlock";
|
||||
}
|
||||
|
||||
var wasNotActiveBefore = blockObject.active !== true;
|
||||
blockObject.active = true;
|
||||
@@ -239,12 +245,14 @@
|
||||
}
|
||||
|
||||
var hideContent = (openSettings === true && inlineEditing === true);
|
||||
|
||||
|
||||
var blockEditorModel = {
|
||||
$parentScope: $scope, // pass in a $parentScope, this maintains the scope inheritance in infinite editing
|
||||
hideContent: hideContent,
|
||||
openSettings: openSettings === true,
|
||||
liveEditing: liveEditing,
|
||||
title: blockObject.label,
|
||||
index: blockIndex,
|
||||
view: "views/common/infiniteeditors/blockeditor/blockeditor.html",
|
||||
size: blockObject.config.editorSize || "medium",
|
||||
submit: function(blockEditorModel) {
|
||||
@@ -326,7 +334,7 @@
|
||||
if(!(mouseEvent.ctrlKey || mouseEvent.metaKey)) {
|
||||
editorService.close();
|
||||
if (added && vm.layout.length > createIndex) {
|
||||
editBlock(vm.layout[createIndex].$block);
|
||||
editBlock(vm.layout[createIndex].$block, false, createIndex);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -471,18 +479,16 @@
|
||||
});
|
||||
}
|
||||
|
||||
function openSettingsForBlock(block) {
|
||||
editBlock(block, true);
|
||||
function openSettingsForBlock(block, blockIndex) {
|
||||
editBlock(block, true, blockIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
vm.blockEditorApi = {
|
||||
editBlock: editBlock,
|
||||
requestCopyBlock: requestCopyBlock,
|
||||
requestDeleteBlock: requestDeleteBlock,
|
||||
deleteBlock: deleteBlock,
|
||||
openSettingsForBlock: openSettingsForBlock
|
||||
openSettingsForBlock: openSettingsForBlock
|
||||
}
|
||||
|
||||
vm.sortableOptions = {
|
||||
|
||||
+16
-2
@@ -19,7 +19,7 @@
|
||||
stylesheet: "@",
|
||||
view: "@",
|
||||
block: "=",
|
||||
api: "=",
|
||||
api: "=", // Should this be a one way bind?
|
||||
index: "<"
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,15 @@
|
||||
|
||||
function BlockListScopedBlockContentController($compile, $element, $scope) {
|
||||
var model = this;
|
||||
model.$onInit = function() {
|
||||
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.
|
||||
// It also means we need to watch for changes and upate the $scope values.
|
||||
|
||||
$scope.block = model.block;
|
||||
$scope.api = model.api;
|
||||
$scope.index = model.index;
|
||||
|
||||
var shadowRoot = $element[0].attachShadow({mode:'open'});
|
||||
shadowRoot.innerHTML = `
|
||||
<style>
|
||||
@@ -39,6 +45,14 @@
|
||||
`;
|
||||
$compile(shadowRoot)($scope);
|
||||
}
|
||||
|
||||
model.$onChanges = function (changes) {
|
||||
if (changes.index) {
|
||||
$scope.index = changes.index.currentValue;
|
||||
}
|
||||
|
||||
// TODO: Wouldn't we need to watch for any changes to model.block/api here too?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@
|
||||
<span>{{block.label}}</span>
|
||||
</button>
|
||||
<div class="blockelement-inlineblock-editor__inner" ng-class="{'--singleGroup':block.content.variants[0].tabs.length === 1}" ng-if="block.active === true">
|
||||
<umb-element-editor-content model="block.content"></umb-element-editor-content>
|
||||
<!-- NOTE: The 'index' is passed to this via it's scope which is set on the outer component: umbBlockListBlockContent -->
|
||||
<umb-element-editor-content model="block.content" item-index="index"></umb-element-editor-content>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+4
-1
@@ -1,4 +1,7 @@
|
||||
<button type="button" class="btn-reset umb-outline blockelement-labelblock-editor blockelement__draggable-element" ng-click="api.editBlock(block)" ng-focus="block.focus" ng-class="{'--active':block.active}">
|
||||
<button type="button" class="btn-reset umb-outline blockelement-labelblock-editor blockelement__draggable-element"
|
||||
ng-click="api.editBlock(block, false, index)"
|
||||
ng-focus="block.focus"
|
||||
ng-class="{'--active':block.active}">
|
||||
<i class="icon {{block.content.icon}}"></i>
|
||||
<span>{{block.label}}</span>
|
||||
</button>
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
data-element="property-{{property.alias}}">
|
||||
|
||||
<umb-nested-property property-type-alias="{{property.propertyAlias}}"
|
||||
element-type-index="{{itemIndex}}">
|
||||
element-type-index="itemIndex">
|
||||
<umb-property-editor model="property"></umb-property-editor>
|
||||
</umb-nested-property>
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@
|
||||
</div>
|
||||
|
||||
<div class="umb-nested-content__content" ng-if="vm.currentNode.key === node.key && !vm.sorting">
|
||||
<umb-nested-content-editor ng-model="node" item-index="{{$index}}" tab-alias="ncTabAlias" />
|
||||
<umb-nested-content-editor ng-model="node" item-index="$index" tab-alias="ncTabAlias" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user