Merge remote-tracking branch 'origin/v8/feature/block-editor-list' into v8/feature/block-editor-list-validation
# Conflicts: # src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/blockeditor/blockeditor.controller.js # src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/elementeditor/elementeditor.content.html # src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-block.component.js # src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-property-editor.html
This commit is contained in:
-2
@@ -50,8 +50,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Some property editors need to performe an action after all property editors have reacted to the formSubmitting.
|
||||
$scope.$broadcast("postFormSubmitting", { scope: $scope });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.services.udiService#parse
|
||||
* @name umbraco.services.udiService#create
|
||||
* @methodOf umbraco.services.udiService
|
||||
* @function
|
||||
*
|
||||
|
||||
@@ -200,9 +200,9 @@
|
||||
|
||||
|
||||
// Property Editors
|
||||
@import "../views/propertyeditors/blockeditor/blockcard/umb-block-card-grid.less";
|
||||
@import "../views/propertyeditors/blockeditor/blockcard/blockcard.component.less";
|
||||
@import "../views/propertyeditors/blocklist/blocklist.component.less";
|
||||
@import "../views/components/blockcard/umb-block-card-grid.less";
|
||||
@import "../views/components/blockcard/umb-block-card.less";
|
||||
@import "../views/propertyeditors/blocklist/umb-block-list-property-editor.less";
|
||||
@import "../views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.less";
|
||||
@import "../views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.less";
|
||||
@import "../views/propertyeditors/notsupported/notsupported.less";
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
<umb-element-editor-content model="model.content"></umb-element-editor-content>
|
||||
+7
-12
@@ -1,12 +1,9 @@
|
||||
//used for the media picker dialog
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.Editors.BlockEditorController",
|
||||
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.model = $scope.model;
|
||||
vm.model = $scope.model;
|
||||
vm.tabs = [];
|
||||
localizationService.localizeMany([
|
||||
@@ -17,17 +14,16 @@ angular.module("umbraco")
|
||||
vm.submitLabel = data[1];
|
||||
});
|
||||
|
||||
if (vm.content && vm.content.variants) {
|
||||
if ($scope.model.content && $scope.model.content.variants) {
|
||||
|
||||
var apps = vm.content.apps;
|
||||
var apps = $scope.model.content.apps;
|
||||
|
||||
vm.tabs = apps;
|
||||
|
||||
// replace view of content app.
|
||||
var contentApp = apps.find(entry => entry.alias === "umbContent");
|
||||
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";
|
||||
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) {
|
||||
@@ -41,15 +37,14 @@ angular.module("umbraco")
|
||||
|
||||
}
|
||||
|
||||
if (vm.settings && vm.settings.variants) {
|
||||
if (vm.model.settings && vm.model.settings.variants) {
|
||||
localizationService.localize("blockEditor_tabBlockSettings").then(
|
||||
function (settingsName) {
|
||||
var settingsTab = {
|
||||
"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"
|
||||
"view": "views/common/infiniteeditors/blockeditor/blockeditor.settings.html"
|
||||
};
|
||||
vm.tabs.push(settingsTab);
|
||||
if (vm.model.openSettings) {
|
||||
@@ -69,7 +64,7 @@ angular.module("umbraco")
|
||||
|
||||
vm.close = function() {
|
||||
if (vm.model && vm.model.close) {
|
||||
// TODO: If content has changed, we should notify user.
|
||||
// TODO: check if content/settings has changed and ask user if they are sure.
|
||||
vm.model.close(vm.model);
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
//used for the media picker dialog
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.Editors.BlockPickerController",
|
||||
function ($scope, localizationService) {
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
<div>
|
||||
<umb-element-editor-content model="model.content" item-index="model.index"></umb-element-editor-content>
|
||||
</div>
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
|
||||
<div class="__showcase" ng-style="{'background-color':vm.blockConfigModel.backgroundColor, 'background-image': vm.blockConfigModel.thumbnail ? 'url('+vm.blockConfigModel.thumbnail+')' : 'transparent'}">
|
||||
<div class="__showcase" ng-style="{'background-color':vm.blockConfigModel.backgroundColor, 'background-image': vm.blockConfigModel.thumbnail ? 'url('+vm.blockConfigModel.thumbnail+'?upscale=false&width=400)' : 'transparent'}">
|
||||
<i ng-if="vm.blockConfigModel.thumbnail == null && vm.elementTypeModel.icon" class="__icon {{ vm.elementTypeModel.icon }}" ng-style="{'color':vm.blockConfigModel.iconColor}" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="__info">
|
||||
+2
@@ -59,6 +59,8 @@ umb-block-card {
|
||||
|
||||
background-size: cover;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
.__icon {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
angular
|
||||
.module("umbraco")
|
||||
.component("umbBlockCard", {
|
||||
templateUrl: "views/propertyeditors/blockeditor/blockcard/blockcard.component.html",
|
||||
templateUrl: "views/components/blockcard/umb-block-card.html",
|
||||
controller: BlockCardController,
|
||||
controllerAs: "vm",
|
||||
transclude: true,
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
angular
|
||||
.module('umbraco.directives')
|
||||
.component('umbElementEditorContent', {
|
||||
templateUrl: 'views/common/infiniteeditors/elementeditor/elementEditor.content.component.html',
|
||||
templateUrl: 'views/components/elementeditor/umb-element-editor-content.component.html',
|
||||
controller: ElementEditorContentComponentController,
|
||||
controllerAs: 'vm',
|
||||
bindings: {
|
||||
@@ -1,9 +0,0 @@
|
||||
(function () {
|
||||
|
||||
function NumberRangeController($scope) {
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PrevalueEditors.NumberRangeController", NumberRangeController);
|
||||
})();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="umb-property-editor umb-prevalues-numberrange" ng-controller="Umbraco.PrevalueEditors.NumberRangeController">
|
||||
<div class="umb-property-editor umb-prevalues-numberrange">
|
||||
<ng-form name="prevalueNumberRangeForm">
|
||||
<input name="numberFieldMin" class="__min-input"
|
||||
type="number"
|
||||
|
||||
@@ -1 +1 @@
|
||||
<block-list-property-editor property-form="propertyForm" model="model"/>
|
||||
<umb-block-list-property-editor property-form="propertyForm" model="model"/>
|
||||
|
||||
+21
-6
@@ -16,10 +16,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
function BlockConfigurationController($scope, elementTypeResource, overlayService, localizationService, editorService) {
|
||||
function BlockConfigurationController($scope, elementTypeResource, overlayService, localizationService, editorService, eventsService) {
|
||||
|
||||
var unsubscribe = [];
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.openBlock = null;
|
||||
|
||||
function onInit() {
|
||||
@@ -38,6 +39,16 @@
|
||||
});
|
||||
}
|
||||
|
||||
function updateUsedElementTypes(event, args) {
|
||||
var key = args.documentType.key;
|
||||
for (var i = 0; i<vm.elementTypes.length; i++) {
|
||||
if (vm.elementTypes[i].key === key) {
|
||||
vm.elementTypes[i] = args.documentType;
|
||||
}
|
||||
}
|
||||
}
|
||||
unsubscribe.push(eventsService.on("editors.documentType.saved", updateUsedElementTypes));
|
||||
|
||||
vm.requestRemoveBlockByIndex = function (index) {
|
||||
localizationService.localizeMany(["general_delete", "blockEditor_confirmDeleteBlockMessage", "blockEditor_confirmDeleteBlockNotice"]).then(function (data) {
|
||||
var contentElementType = vm.getElementTypeByKey($scope.model.value[index].contentTypeKey);
|
||||
@@ -77,9 +88,11 @@
|
||||
};
|
||||
|
||||
vm.getElementTypeByKey = function(key) {
|
||||
return _.find(vm.elementTypes, function (type) {
|
||||
return type.key === key;
|
||||
});
|
||||
if (vm.elementTypes) {
|
||||
return vm.elementTypes.find(function (type) {
|
||||
return type.key === key;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
vm.openAddDialog = function ($event, entry) {
|
||||
@@ -193,7 +206,9 @@
|
||||
|
||||
};
|
||||
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
unsubscribe.forEach(u => { u(); });
|
||||
});
|
||||
|
||||
onInit();
|
||||
|
||||
|
||||
+38
-8
@@ -10,7 +10,9 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function BlockConfigurationOverlayController($scope, overlayService, localizationService, editorService, elementTypeResource) {
|
||||
function BlockConfigurationOverlayController($scope, overlayService, localizationService, editorService, elementTypeResource, eventsService) {
|
||||
|
||||
var unsubscribe = [];
|
||||
|
||||
var vm = this;
|
||||
vm.block = $scope.model.block;
|
||||
@@ -20,11 +22,14 @@
|
||||
function loadElementTypes() {
|
||||
return elementTypeResource.getAll().then(function (elementTypes) {
|
||||
vm.elementTypes = elementTypes;
|
||||
|
||||
vm.contentPreview = vm.getElementTypeByKey(vm.block.contentTypeKey);
|
||||
vm.settingsPreview = vm.getElementTypeByKey(vm.block.settingsElementTypeKey);
|
||||
});
|
||||
}
|
||||
|
||||
vm.getElementTypeByKey = function(key) {
|
||||
return _.find(vm.elementTypes, function (type) {
|
||||
return vm.elementTypes.find(function (type) {
|
||||
return type.key === key;
|
||||
});
|
||||
};
|
||||
@@ -34,7 +39,6 @@
|
||||
const editor = {
|
||||
id: elementTypeId,
|
||||
submit: function (model) {
|
||||
loadElementTypes();
|
||||
editorService.close();
|
||||
},
|
||||
close: function () {
|
||||
@@ -50,9 +54,7 @@
|
||||
infiniteMode: true,
|
||||
isElement: true,
|
||||
submit: function (model) {
|
||||
loadElementTypes().then( function () {
|
||||
callback(model.documentTypeKey);
|
||||
});
|
||||
callback(model.documentTypeKey);
|
||||
editorService.close();
|
||||
},
|
||||
close: function () {
|
||||
@@ -123,6 +125,26 @@
|
||||
};
|
||||
|
||||
|
||||
function updateUsedElementTypes(event, args) {
|
||||
var key = args.documentType.key;
|
||||
for (var i = 0; i<vm.elementTypes.length; i++) {
|
||||
if (vm.elementTypes[i].key === key) {
|
||||
vm.elementTypes[i] = args.documentType;
|
||||
}
|
||||
}
|
||||
if (vm.contentPreview.key === key) {
|
||||
vm.contentPreview = args.documentType;
|
||||
$scope.$evalAsync();
|
||||
}
|
||||
if (vm.settingsPreview.key === key) {
|
||||
vm.settingsPreview = args.documentType;
|
||||
$scope.$evalAsync();
|
||||
}
|
||||
|
||||
}
|
||||
unsubscribe.push(eventsService.on("editors.documentType.saved", updateUsedElementTypes));
|
||||
|
||||
|
||||
vm.addViewForBlock = function(block) {
|
||||
localizationService.localize("blockEditor_headlineSelectView").then(function(localizedTitle) {
|
||||
|
||||
@@ -132,8 +154,10 @@
|
||||
treeAlias: "files",
|
||||
entityType: "file",
|
||||
isDialog: true,
|
||||
filter: function (i) {
|
||||
return !(i.name.indexOf(".html") !== -1);
|
||||
},
|
||||
select: function (node) {
|
||||
console.log(node)
|
||||
const filepath = decodeURIComponent(node.id.replace(/\+/g, " "));
|
||||
block.view = filepath;
|
||||
editorService.close();
|
||||
@@ -176,6 +200,9 @@
|
||||
treeAlias: "files",
|
||||
entityType: "file",
|
||||
isDialog: true,
|
||||
filter: function (i) {
|
||||
return !(i.name.indexOf(".css") !== -1);
|
||||
},
|
||||
select: function (node) {
|
||||
const filepath = decodeURIComponent(node.id.replace(/\+/g, " "));
|
||||
block.stylesheet = filepath;
|
||||
@@ -250,11 +277,14 @@
|
||||
|
||||
vm.close = function() {
|
||||
if ($scope.model && $scope.model.close) {
|
||||
// TODO: If content has changed, we should notify user.
|
||||
$scope.model.close($scope.model);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
unsubscribe.forEach(u => { u(); });
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.BlockList.BlockConfigurationOverlayController", BlockConfigurationOverlayController);
|
||||
|
||||
+2
-4
@@ -107,8 +107,7 @@
|
||||
<label class="control-label"><localize key="blockEditor_labelContentElementType">Content ElementType</localize></label>
|
||||
<div class="controls">
|
||||
<div class="__settings-input --hasValue" ng-if="vm.block.contentTypeKey !== null" >
|
||||
{{ contentPreview = vm.getElementTypeByKey(vm.block.contentTypeKey); "" }}
|
||||
<umb-node-preview icon="contentPreview.icon" name="contentPreview.name"></umb-node-preview>
|
||||
<umb-node-preview icon="vm.contentPreview.icon" name="vm.contentPreview.name" alias="vm.contentPreview.alias"></umb-node-preview>
|
||||
<div class="__control-actions">
|
||||
<button type="button" class="btn-reset __control-actions-btn --open umb-outline" ng-click="vm.openElementType(vm.block.contentTypeKey)">
|
||||
<i class="icon icon-edit"></i>
|
||||
@@ -125,8 +124,7 @@
|
||||
<label class="control-label"><localize key="blockEditor_labelSettingsElementType">Settings Element Type</localize></label>
|
||||
<div class="controls">
|
||||
<div class="__settings-input --hasValue" ng-if="vm.block.settingsElementTypeKey !== null">
|
||||
{{ settingsPreview = vm.getElementTypeByKey(vm.block.settingsElementTypeKey); "" }}
|
||||
<umb-node-preview icon="settingsPreview.icon" name="settingsPreview.name"></umb-node-preview>
|
||||
<umb-node-preview icon="vm.settingsPreview.icon" name="vm.settingsPreview.name" alias="vm.settingsPreview.alias"></umb-node-preview>
|
||||
<div class="__control-actions">
|
||||
<button type="button" class="btn-reset __control-actions-btn --open umb-outline" ng-click="vm.openElementType(vm.block.settingsElementTypeKey)">
|
||||
<i class="icon icon-edit"></i>
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
bindings: {
|
||||
view: "@",
|
||||
block: "=",
|
||||
api: "=", // Should this be a one way bind?
|
||||
api: "<",
|
||||
index: "<"
|
||||
}
|
||||
}
|
||||
+17
-15
@@ -1,6 +1,6 @@
|
||||
<div class="umb-block-list">
|
||||
|
||||
<umb-load-indicator style="margin-bottom:20px;" ng-if="vm.loading"></umb-load-indicator>
|
||||
<umb-load-indicator ng-if="vm.loading"></umb-load-indicator>
|
||||
|
||||
<div class="umb-block-list__wrapper" ng-style="vm.listWrapperStyles">
|
||||
|
||||
@@ -18,20 +18,22 @@
|
||||
|
||||
<div class="umb-block-list__block" ng-class="{'--active':layout.$block.active}">
|
||||
|
||||
<umb-block-list-scoped-block 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
|
||||
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>
|
||||
<umb-block-list-block 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
|
||||
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>
|
||||
|
||||
<div class="umb-block-list__block--actions">
|
||||
@@ -43,7 +45,7 @@
|
||||
<localize key="general_settings">Settings</localize>
|
||||
</span>
|
||||
</button>
|
||||
<button type="button" class="btn-reset umb-outline action --copy" localize="title" title="actions_copy" ng-click="vm.blockEditorApi.requestCopyBlock(layout.$block);" ng-if="layout.$block.showCopy === true">
|
||||
<button type="button" class="btn-reset umb-outline action --copy" localize="title" title="actions_copy" ng-click="vm.blockEditorApi.copyBlock(layout.$block);" ng-if="layout.$block.showCopy === true">
|
||||
<i class="icon icon-documents" aria-hidden="true"></i>
|
||||
<span class="sr-only">
|
||||
<localize key="general_copy">Copy</localize>
|
||||
+4
@@ -4,6 +4,10 @@
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
.umb-block-list .umb-load-indicator {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
.umb-block-list__wrapper {
|
||||
position: relative;
|
||||
max-width: 1024px;
|
||||
+2
@@ -6,6 +6,8 @@
|
||||
* @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
|
||||
+5
-9
@@ -4,7 +4,7 @@
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:blockListPropertyEditor
|
||||
* @name umbraco.directives.directive:umbBlockListPropertyEditor
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
@@ -12,8 +12,8 @@
|
||||
*/
|
||||
angular
|
||||
.module("umbraco")
|
||||
.component("blockListPropertyEditor", {
|
||||
templateUrl: "views/propertyeditors/blocklist/blocklist.component.html",
|
||||
.component("umbBlockListPropertyEditor", {
|
||||
templateUrl: "views/propertyeditors/blocklist/umb-block-list-property-editor.html",
|
||||
controller: BlockListController,
|
||||
controllerAs: "vm",
|
||||
bindings: {
|
||||
@@ -391,10 +391,6 @@
|
||||
|
||||
};
|
||||
|
||||
function requestCopyBlock(block) {
|
||||
clipboardService.copy("elementTypeArray", block.content.contentTypeAlias, block.content, block.label);
|
||||
}
|
||||
|
||||
var requestCopyAllBlocks = function() {
|
||||
|
||||
var elementTypesToCopy = vm.layout.filter(entry => entry.$block.config.unsupported !== true).map(entry => entry.$block.content);
|
||||
@@ -416,7 +412,7 @@
|
||||
clipboardService.copyArray("elementTypeArray", aliases, elementTypesToCopy, localizedLabel, "icon-thumbnail-list", vm.model.id);
|
||||
});
|
||||
}
|
||||
function requestCopyBlock(block) {
|
||||
function copyBlock(block) {
|
||||
clipboardService.copy("elementType", block.content.contentTypeAlias, block.content, block.label);
|
||||
}
|
||||
function requestPasteFromClipboard(index, pasteEntry) {
|
||||
@@ -487,7 +483,7 @@
|
||||
|
||||
vm.blockEditorApi = {
|
||||
editBlock: editBlock,
|
||||
requestCopyBlock: requestCopyBlock,
|
||||
copyBlock: copyBlock,
|
||||
requestDeleteBlock: requestDeleteBlock,
|
||||
deleteBlock: deleteBlock,
|
||||
openSettingsForBlock: openSettingsForBlock
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
angular
|
||||
.module("umbraco")
|
||||
.controller("Umbraco.PropertyEditors.BlockListPropertyEditor.CreateButtonController",
|
||||
function BlockListController($scope) {
|
||||
function Controller($scope) {
|
||||
|
||||
var vm = this;
|
||||
vm.plusPosX = 0;
|
||||
+2
-1
@@ -480,7 +480,8 @@
|
||||
var notSupported = [
|
||||
"Umbraco.Tags",
|
||||
"Umbraco.UploadField",
|
||||
"Umbraco.ImageCropper"
|
||||
"Umbraco.ImageCropper",
|
||||
"Umbraco.BlockList"
|
||||
];
|
||||
|
||||
// Initialize
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
]
|
||||
};
|
||||
|
||||
describe('init blockEditoModelObject', function () {
|
||||
describe('init blockEditorModelObject', function () {
|
||||
|
||||
it('fail if no model value', function () {
|
||||
function createWithNoModelValue() {
|
||||
|
||||
Reference in New Issue
Block a user