block list editor copy paste feature
This commit is contained in:
@@ -5,9 +5,13 @@
|
||||
function blockEditorService($interpolate, udiService) {
|
||||
|
||||
|
||||
function mapToEditingModel(editingModel, contentModel) {
|
||||
/**
|
||||
* Simple mapping from property model content entry to editing model,
|
||||
* needs to stay simple to avoid deep watching.
|
||||
*/
|
||||
function mapToElementTypeModel(elementTypeModel, contentModel) {
|
||||
|
||||
var variant = editingModel.variants[0];
|
||||
var variant = elementTypeModel.variants[0];
|
||||
|
||||
for (var t = 0; t < variant.tabs.length; t++) {
|
||||
var tab = variant.tabs[t];
|
||||
@@ -21,9 +25,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
function mapToPropertyModel(editingModel, contentModel) {
|
||||
/**
|
||||
* Simple mapping from elementTypeModel to property model content entry,
|
||||
* needs to stay simple to avoid deep watching.
|
||||
*/
|
||||
function mapToPropertyModel(elementTypeModel, contentModel) {
|
||||
|
||||
var variant = editingModel.variants[0];
|
||||
var variant = elementTypeModel.variants[0];
|
||||
|
||||
for (var t = 0; t < variant.tabs.length; t++) {
|
||||
var tab = variant.tabs[t];
|
||||
@@ -31,7 +39,7 @@
|
||||
for (var p = 0; p < tab.properties.length; p++) {
|
||||
var prop = tab.properties[p];
|
||||
if (prop.value) {
|
||||
contentModel[prop.propertyAlias] = prop.value;
|
||||
contentModel[prop.alias] = prop.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,12 +103,19 @@
|
||||
return Promise.all(tasks);
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrive a list of aliases that are available for content of blocks in this property editor, does not contain aliases of block settings.
|
||||
* @return {Array} array of strings representing alias.
|
||||
*/
|
||||
getAvailableAliasesForBlockContent: function() {
|
||||
return this.blockConfigurations.map(blockConfiguration => blockConfiguration.contentTypeAlias);
|
||||
},
|
||||
|
||||
getAvailableBlocksForItemPicker: function() {
|
||||
|
||||
var blocks = [];
|
||||
|
||||
this.blockConfigurations.forEach(blockConfiguration => {
|
||||
|
||||
var scaffold = this.getScaffoldFor(blockConfiguration.contentTypeAlias);
|
||||
if(scaffold) {
|
||||
blocks.push({
|
||||
@@ -148,7 +163,7 @@
|
||||
editingModel.content = angular.copy(scaffold);
|
||||
editingModel.content.udi = udi;
|
||||
|
||||
mapToEditingModel(editingModel.content, contentModel);
|
||||
mapToElementTypeModel(editingModel.content, contentModel);
|
||||
|
||||
editingModel.contentModel = contentModel;
|
||||
editingModel.layoutModel = layoutEntry;
|
||||
@@ -168,17 +183,15 @@
|
||||
|
||||
var udi = editingModel.content.key;
|
||||
|
||||
var contentModel = this.getContentByUdi(udi);
|
||||
|
||||
mapToPropertyModel(editingModel.content, contentModel);
|
||||
mapToPropertyModel(editingModel.content, editingModel.contentModel);
|
||||
|
||||
// TODO: sync settings to layout entry.
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve layout data
|
||||
* @return layout object.
|
||||
* Retrieve the layout object for this specific property editor.
|
||||
* @return {Object} Layout object.
|
||||
*/
|
||||
getLayout: function() {
|
||||
if (!this.value.layout[this.propertyEditorAlias]) {
|
||||
@@ -188,13 +201,16 @@
|
||||
},
|
||||
|
||||
/**
|
||||
* Create layout entry
|
||||
* @param {object} blockConfiguration
|
||||
* @return layout entry, to be added in the layout.
|
||||
* Create a empty layout entry
|
||||
* @param {Object} blockConfiguration
|
||||
* @return {Object} Layout entry object, to be inserted at a decired location in the layout object.
|
||||
*/
|
||||
createLayoutEntry: function(contentTypeAlias) {
|
||||
create: function(contentTypeAlias) {
|
||||
|
||||
var blockConfiguration = this.getBlockConfiguration(contentTypeAlias);
|
||||
if(blockConfiguration === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var entry = {
|
||||
udi: this.createContent(contentTypeAlias)
|
||||
@@ -222,16 +238,42 @@
|
||||
// private
|
||||
removeContent: function(entry) {
|
||||
const index = this.value.data.indexOf(entry)
|
||||
if (index > -1) {
|
||||
if (index !== -1) {
|
||||
this.value.splice(index, 1);
|
||||
}
|
||||
},
|
||||
|
||||
removeContentByUdi: function(udi) {
|
||||
const index = this.value.data.findIndex(o => o.udi === udi);
|
||||
if (index > -1) {
|
||||
if (index !== -1) {
|
||||
this.value.splice(index, 1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Insert data from ElementType Model
|
||||
* @return {Object} Layout entry object, to be inserted at a decired location in the layout object.
|
||||
*/
|
||||
createFromElementType: function(elementTypeContentModel) {
|
||||
|
||||
elementTypeContentModel = angular.copy(elementTypeContentModel);
|
||||
|
||||
var contentTypeAlias = elementTypeContentModel.contentTypeAlias;
|
||||
|
||||
var layoutEntry = this.create(contentTypeAlias);
|
||||
if(layoutEntry === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var contentModel = this.getContentByUdi(layoutEntry.udi);
|
||||
|
||||
mapToPropertyModel(elementTypeContentModel, contentModel);
|
||||
|
||||
console.log(elementTypeContentModel)
|
||||
console.log(contentModel)
|
||||
|
||||
return layoutEntry;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<button type="button" class="btn-reset umb-outline blockelement-imageblock-editor blockelement__draggable-element" focus-when="{{vm.focusThis}}" ng-click="vm.blockEditorApi.editBlock(vm.block)">
|
||||
<img src="{{vm.block.content.temp_image}}">
|
||||
<button type="button" class="btn-reset umb-outline blockelement-imageblock-editor blockelement__draggable-element" focus-when="{{blockvm.focusThis}}" ng-click="vm.blockEditorApi.editBlock(blockItem)">
|
||||
<img src="{{blockItem.content.temp_image}}">
|
||||
</button>
|
||||
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
<div class="blockelement-inlineblock-editor" ng-class="{'--open': bc.isOpen}" ng-controller="Umbraco.PropertyEditors.BlockEditor.InlineBlockEditor as bc">
|
||||
<button type="button" class="btn-reset umb-outline blockelement__draggable-element" ng-click="bc.openBlock(block)" focus-when="{{vm.focusThis}}">
|
||||
<button type="button" class="btn-reset umb-outline blockelement__draggable-element" ng-click="bc.openBlock(blockItem)" focus-when="{{blockvm.focusThis}}">
|
||||
<span class="caret"></span>
|
||||
<i class="icon {{vm.block.content.icon}}"></i>
|
||||
<span>{{vm.block.label}}</span>
|
||||
<i class="icon {{blockItem.content.icon}}"></i>
|
||||
<span>{{blockItem.label}}</span>
|
||||
</button>
|
||||
<div class="blockelement-inlineblock-editor__inner" ng-if="bc.isOpen === true">
|
||||
<umb-element-content-editor content="vm.block.content"></umb-element-content-editor>
|
||||
<umb-element-content-editor content="blockItem.content"></umb-element-content-editor>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<button type="button" class="btn-reset umb-outline blockelement-labelblock-editor blockelement__draggable-element" ng-click="vm.blockEditorApi.editBlock(vm.block)" focus-when="{{vm.focusThis}}">
|
||||
<i class="icon {{vm.block.content.icon}}"></i>
|
||||
<span>{{vm.block.label}}</span>
|
||||
<button type="button" class="btn-reset umb-outline blockelement-labelblock-editor blockelement__draggable-element" ng-click="vm.blockEditorApi.editBlock(blockItem)" focus-when="{{vm.focusThis}}">
|
||||
<i class="icon {{blockItem.content.icon}}"></i>
|
||||
<span>{{blockItem.label}}</span>
|
||||
</button>
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ angular.module("umbraco")
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.firstProperty = $scope.block.content.variants[0].tabs[0].properties[0];
|
||||
vm.firstProperty = $scope.blockItem.content.variants[0].tabs[0].properties[0];
|
||||
/*
|
||||
vm.onBlur = function() {
|
||||
if (vm.firstProperty.value === null || vm.firstProperty.value === "") {
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
ng-model="vm.firstProperty.value"
|
||||
ng-keypress="vm.submitOnEnter($event)"
|
||||
ng-blur="vm.onBlur()"
|
||||
focus-when="{{moveFocusToBlock === block}}"
|
||||
focus-when="{{blockvm.focusThis}}"
|
||||
>
|
||||
</textarea>
|
||||
|
||||
|
||||
+2
-17
@@ -1,20 +1,5 @@
|
||||
<div class="umb-block-list__block">
|
||||
<div class="umb-block-list__block--content" ng-if="vm.block.view" ng-include="vm.block.view">
|
||||
</div>
|
||||
<div class="{{::vm.class}}">
|
||||
|
||||
<div class="umb-block-list__block--actions">
|
||||
<button type="button" class="btn-reset action --copy" localize="title" title="general_copy" ng-click="vm.blockEditorApi.requestCopyBlock(vm.block);" ng-if="vm.showCopy">
|
||||
<i class="icon icon-documents" aria-hidden="true"></i>
|
||||
<span class="sr-only">
|
||||
<localize key="general_copy">Copy</localize>
|
||||
</span>
|
||||
</button>
|
||||
<button type="button" class="btn-reset action --delete" localize="title" title="general_delete" ng-click="vm.blockEditorApi.requestDeleteBlock(vm.block);">
|
||||
<i class="icon icon-trash" aria-hidden="true"></i>
|
||||
<span class="sr-only">
|
||||
<localize key="general_delete">Delete</localize>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<ng-transclude></ng-transclude>
|
||||
|
||||
</div>
|
||||
|
||||
+9
-4
@@ -4,12 +4,15 @@
|
||||
.module("umbraco")
|
||||
.component("blockListPropertyEditorBlock", {
|
||||
templateUrl: "views/propertyeditors/blocklist/blocklist.block.component.html",
|
||||
transclude: true,
|
||||
controller: BlockListBlockController,
|
||||
controllerAs: "vm",
|
||||
bindings: {
|
||||
block: "=",
|
||||
blockEditorApi: "=",
|
||||
focusThisBlock: "<?"
|
||||
blockEditorApi: "<",
|
||||
focusThisBlock: "<?",
|
||||
class: "@",
|
||||
showCopy: "@?"
|
||||
}
|
||||
});
|
||||
|
||||
@@ -30,7 +33,9 @@
|
||||
var prop = tab.properties[p];
|
||||
|
||||
// Sadly we need to deep watch, cause its our only way to make sure that complex values gets synced. Alternative solution would be to sync on a broadcasted event, fired on Save and Copy eventually more.
|
||||
unsubscribe.push($scope.$watch("vm.block.content.variants[0].tabs["+t+"].properties["+p+"].value", createPropWatcher(prop), true));
|
||||
// But to minimize the watch we only watch the value of properties. But because we are deep watching it means that we are watching everything of nested block editors, so this would only have a performance improvement for first levels of block editors.
|
||||
// New thoughts, since the value of a property editors is just a pointer (if not primative) then we could properly live without deep watching? cause they reference the same?.. Lets investigate..
|
||||
unsubscribe.push($scope.$watch("vm.block.content.variants[0].tabs["+t+"].properties["+p+"].value", createPropWatcher(prop)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,7 +47,7 @@
|
||||
// sync data:
|
||||
vm.block.contentModel[prop.alias] = prop.value;
|
||||
|
||||
vm.blockEditorApi.sync();
|
||||
//vm.blockEditorApi.sync();
|
||||
|
||||
// update label:
|
||||
updateLabel();
|
||||
|
||||
+18
-1
@@ -14,7 +14,24 @@
|
||||
>
|
||||
</button>
|
||||
|
||||
<block-list-property-editor-block block="blockItem" block-editor-api="vm.blockEditorApi" focus-this-block="false">
|
||||
<block-list-property-editor-block block="blockItem" focus-this-block="vm.moveFocusToBlock === blockItem" block-editor-api="vm.blockEditorApi" show-copy="vm.showCopy" class="umb-block-list__block">
|
||||
<div class="umb-block-list__block--content" ng-if="blockItem.view" ng-include="blockItem.view">
|
||||
</div>
|
||||
|
||||
<div class="umb-block-list__block--actions">
|
||||
<button type="button" class="btn-reset action --copy" localize="title" title="actions_copy" ng-click="vm.blockEditorApi.requestCopyBlock(blockItem);" ng-if="vm.showCopy">
|
||||
<i class="icon icon-documents" aria-hidden="true"></i>
|
||||
<span class="sr-only">
|
||||
<localize key="general_copy">Copy</localize>
|
||||
</span>
|
||||
</button>
|
||||
<button type="button" class="btn-reset action --delete" localize="title" title="actions_delete" ng-click="vm.blockEditorApi.requestDeleteBlock(blockItem);">
|
||||
<i class="icon icon-trash" aria-hidden="true"></i>
|
||||
<span class="sr-only">
|
||||
<localize key="general_delete">Delete</localize>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</block-list-property-editor-block>
|
||||
|
||||
</div>
|
||||
|
||||
+204
-62
@@ -12,59 +12,95 @@
|
||||
propertyForm: "="
|
||||
},
|
||||
require: {
|
||||
umbProperty: "?^umbProperty"
|
||||
umbProperty: "?^umbProperty",
|
||||
umbVariantContent: '?^^umbVariantContent'
|
||||
}
|
||||
});
|
||||
|
||||
function BlockListController($scope, $interpolate, editorService, clipboardService, localizationService, overlayService, blockEditorService, contentResource) {
|
||||
function BlockListController($scope, $interpolate, editorService, clipboardService, localizationService, overlayService, blockEditorService, contentResource, eventsService) {
|
||||
|
||||
var modelObject;
|
||||
var unsubscribe = [];
|
||||
var vm = this;
|
||||
|
||||
vm.moveFocusToBlock = null;
|
||||
vm.showCopy = clipboardService.isSupported();
|
||||
vm.showPaste = false;
|
||||
|
||||
vm.layout = [];// Property models layout object specific to this Block Editor.
|
||||
vm.blocks = [];// Runtime model of editing models, needs to be synced to property model on form submit.
|
||||
vm.availableBlockTypes = [];// Available block entries of this property editor.
|
||||
|
||||
var labels = {};
|
||||
vm.labels = labels;
|
||||
localizationService.localizeMany(["grid_addElement", "content_createEmpty"]).then(function (data) {
|
||||
labels.grid_addElement = data[0];
|
||||
labels.content_createEmpty = data[1];
|
||||
});
|
||||
|
||||
function checkAbilityToPasteContent() {
|
||||
vm.showPaste = clipboardService.hasEntriesOfType("elementType", vm.availableContentTypes) || clipboardService.hasEntriesOfType("elementTypeArray", vm.availableContentTypes);
|
||||
}
|
||||
eventsService.on("clipboardService.storageUpdate", checkAbilityToPasteContent);
|
||||
|
||||
|
||||
var copyAllBlocksAction;
|
||||
var deleteAllBlocksAction;
|
||||
|
||||
|
||||
vm.$onInit = function() {
|
||||
|
||||
vm.validationLimit = vm.model.config.validationLimit;
|
||||
|
||||
|
||||
vm.model.value = vm.model.value || {};
|
||||
|
||||
modelObject = blockEditorService.createModelObject(vm.model.value, vm.model.editor, vm.model.config.blocks);
|
||||
modelObject.loadScaffolding(contentResource).then(loaded);
|
||||
|
||||
vm.layout = [];// Property models layout object specific to this Block Editor.
|
||||
vm.blocks = [];// Runtime model of editing models, needs to be synced to property model on form submit.
|
||||
vm.availableBlockTypes = [];// Available block entries of this property editor.
|
||||
|
||||
var copyAllEntriesAction = {
|
||||
copyAllBlocksAction = {
|
||||
labelKey: "clipboard_labelForCopyAllEntries",
|
||||
labelTokens: [vm.model.label],
|
||||
icon: "documents",
|
||||
method: function () {},
|
||||
method: requestCopyAllBlocks,
|
||||
isDisabled: true
|
||||
}
|
||||
|
||||
deleteAllBlocksAction = {
|
||||
labelKey: 'clipboard_labelForRemoveAllEntries',
|
||||
labelTokens: [],
|
||||
icon: 'trash',
|
||||
method: requestDeleteAllBlocks,
|
||||
isDisabled: true
|
||||
}
|
||||
|
||||
var propertyActions = [
|
||||
copyAllEntriesAction
|
||||
copyAllBlocksAction,
|
||||
deleteAllBlocksAction
|
||||
];
|
||||
|
||||
if (this.umbProperty) {
|
||||
this.umbProperty.setPropertyActions(propertyActions);
|
||||
if (vm.umbProperty) {
|
||||
vm.umbProperty.setPropertyActions(propertyActions);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function setDirty() {
|
||||
if (vm.propertyForm) {
|
||||
vm.propertyForm.$setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
function loaded() {
|
||||
|
||||
vm.layout = modelObject.getLayout();
|
||||
mapToBlocks();
|
||||
|
||||
vm.availableContentTypes = modelObject.getAvailableAliasesForBlockContent();
|
||||
vm.availableBlockTypes = modelObject.getAvailableBlocksForItemPicker();
|
||||
|
||||
checkAbilityToPasteContent();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -117,36 +153,35 @@
|
||||
$scope.$emit("blockEditorValueUpdated");
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
function syncBlockData(block) {
|
||||
modelObject.setDataFromEditingModel(block);
|
||||
}
|
||||
|
||||
function setDirty() {
|
||||
if (vm.propertyForm) {
|
||||
vm.propertyForm.$setDirty();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
function addNewBlock(index, contentTypeAlias) {
|
||||
|
||||
// Create layout entry. (not added to property model jet.)
|
||||
var layoutEntry = modelObject.createLayoutEntry(contentTypeAlias);
|
||||
var layoutEntry = modelObject.create(contentTypeAlias);
|
||||
if (layoutEntry === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// make editing object
|
||||
var blockEditingObject = getEditingModel(layoutEntry);
|
||||
|
||||
if (blockEditingObject !== null) {
|
||||
|
||||
// add layout entry at the decired location in layout.
|
||||
vm.layout.splice(index, 0, layoutEntry);
|
||||
|
||||
// apply editing model at decired location in editing model.
|
||||
vm.blocks.splice(index, 0, blockEditingObject);
|
||||
|
||||
vm.moveFocusToBlock = blockEditingObject;
|
||||
|
||||
if (blockEditingObject === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// add layout entry at the decired location in layout.
|
||||
vm.layout.splice(index, 0, layoutEntry);
|
||||
|
||||
// apply editing model at decired location in editing model.
|
||||
vm.blocks.splice(index, 0, blockEditingObject);
|
||||
|
||||
vm.moveFocusToBlock = blockEditingObject;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@@ -157,18 +192,22 @@
|
||||
if(index !== -1) {
|
||||
vm.blocks.splice(index, 1);
|
||||
|
||||
var layoutIndex = this.layout.findIndex(entry => entry.udi === block.udi);
|
||||
var layoutIndex = vm.layout.findIndex(entry => entry.udi === block.udi);
|
||||
if(layoutIndex !== -1) {
|
||||
vm.layout.splice(layoutIndex, 1);
|
||||
vm.layout.splice(index, 1);
|
||||
}
|
||||
|
||||
this.modelObject.removeContentByUdi(block.udi);
|
||||
modelObject.removeContentByUdi(block.udi);
|
||||
}
|
||||
}
|
||||
|
||||
function deleteAllBlocks() {
|
||||
vm.blocks.forEach(deleteBlock);
|
||||
}
|
||||
|
||||
function editBlock(blockModel) {
|
||||
|
||||
// TODO: make a clone to ensure edits arent made directly.
|
||||
// make a clone to avoid editing model directly.
|
||||
var blockContentModelClone = angular.copy(blockModel.content);
|
||||
|
||||
var elementEditorModel = {
|
||||
@@ -178,6 +217,8 @@
|
||||
size: blockModel.config.overlaySize || "medium",
|
||||
submit: function(elementEditorModel) {
|
||||
blockModel.content = elementEditorModel.content;
|
||||
// TODO, investigate if we need to call a sync, for this scenario to work.. Concern is regarding wether the property-value watcher will pick this up.
|
||||
//modelObject.setDataFromEditingModel(block);
|
||||
editorService.close();
|
||||
},
|
||||
close: function() {
|
||||
@@ -201,13 +242,26 @@
|
||||
}
|
||||
|
||||
vm.blockTypePicker = {
|
||||
show: true,
|
||||
show: false,
|
||||
size: vm.availableBlockTypes.length < 7 ? "small" : "medium",
|
||||
filter: vm.availableBlockTypes.length > 12 ? true : false,
|
||||
orderBy: "$index",
|
||||
view: "itempicker",
|
||||
event: $event,
|
||||
availableItems: vm.availableBlockTypes,
|
||||
clickPasteItem: function(item) {
|
||||
if (item.type === "elementTypeArray") {
|
||||
var indexIncrementor = 0;
|
||||
item.data.forEach(function (entry) {
|
||||
if (requestPasteFromClipboard(createIndex + indexIncrementor, entry)) {
|
||||
indexIncrementor++;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
requestPasteFromClipboard(createIndex, item.data);
|
||||
}
|
||||
vm.blockTypePicker.close();
|
||||
},
|
||||
submit: function (model) {
|
||||
if (model && model.selectedItem) {
|
||||
addNewBlock(createIndex, model.selectedItem.alias);
|
||||
@@ -220,12 +274,97 @@
|
||||
}
|
||||
};
|
||||
|
||||
vm.blockTypePicker.pasteItems = [];
|
||||
|
||||
var singleEntriesForPaste = clipboardService.retriveEntriesOfType("elementType", vm.availableContentTypes);
|
||||
singleEntriesForPaste.forEach(function (entry) {
|
||||
vm.blockTypePicker.pasteItems.push({
|
||||
type: "elementType",
|
||||
name: entry.label,
|
||||
data: entry.data,
|
||||
icon: entry.icon
|
||||
});
|
||||
});
|
||||
|
||||
var arrayEntriesForPaste = clipboardService.retriveEntriesOfType("elementTypeArray", vm.availableContentTypes);
|
||||
arrayEntriesForPaste.forEach(function (entry) {
|
||||
vm.blockTypePicker.pasteItems.push({
|
||||
type: "elementTypeArray",
|
||||
name: entry.label,
|
||||
data: entry.data,
|
||||
icon: entry.icon
|
||||
});
|
||||
});
|
||||
|
||||
vm.blockTypePicker.title = vm.blockTypePicker.pasteItems.length > 0 ? labels.grid_addElement : labels.content_createEmpty;
|
||||
|
||||
vm.blockTypePicker.clickClearPaste = function ($event) {
|
||||
$event.stopPropagation();
|
||||
$event.preventDefault();
|
||||
clipboardService.clearEntriesOfType("elementType", vm.availableContentTypes);
|
||||
clipboardService.clearEntriesOfType("elementTypeArray", vm.availableContentTypes);
|
||||
vm.blockTypePicker.pasteItems = [];// This dialog is not connected via the clipboardService events, so we need to update manually.
|
||||
};
|
||||
|
||||
vm.blockTypePicker.show = true;
|
||||
|
||||
};
|
||||
|
||||
function requestCopyBlock(block) {
|
||||
console.log("copy still needs to be done.")
|
||||
clipboardService.copy("elementTypeArray", block.content.contentTypeAlias, block.content, block.label);
|
||||
}
|
||||
function requestDeleteBlock (block) {
|
||||
|
||||
var requestCopyAllBlocks = function() {
|
||||
|
||||
// list aliases
|
||||
var aliases = vm.blocks.map(block => block.content.contentTypeAlias);
|
||||
|
||||
// remove dublicates
|
||||
aliases = aliases.filter((item, index) => aliases.indexOf(item) === index);
|
||||
|
||||
var contentNodeName = "";
|
||||
if(vm.umbVariantContent) {
|
||||
contentNodeName = vm.umbVariantContent.editor.content.name;
|
||||
}
|
||||
|
||||
var elementTypesToCopy = vm.blocks.map(block => block.content);
|
||||
|
||||
localizationService.localize("clipboard_labelForArrayOfItemsFrom", [vm.model.label, contentNodeName]).then(function(localizedLabel) {
|
||||
clipboardService.copyArray("elementTypeArray", aliases, elementTypesToCopy, localizedLabel, "icon-thumbnail-list", vm.model.id);
|
||||
});
|
||||
}
|
||||
function requestCopyBlock(block) {
|
||||
clipboardService.copy("elementType", block.content.contentTypeAlias, block.content, block.label);
|
||||
}
|
||||
function requestPasteFromClipboard(index, pasteEntry) {
|
||||
|
||||
if (pasteEntry === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var layoutEntry = modelObject.createFromElementType(pasteEntry);
|
||||
if (layoutEntry === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// make editing object
|
||||
var blockEditingObject = getEditingModel(layoutEntry);
|
||||
if (blockEditingObject === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// add layout entry at the decired location in layout.
|
||||
vm.layout.splice(index, 0, layoutEntry);
|
||||
|
||||
// apply editing model at decired location in editing model.
|
||||
vm.blocks.splice(index, 0, blockEditingObject);
|
||||
|
||||
vm.moveFocusToBlock = blockEditingObject;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
function requestDeleteBlock(block) {
|
||||
localizationService.localizeMany(["general_delete", "blockEditor_confirmDeleteBlockMessage", "contentTypeEditor_yesDelete"]).then(function (data) {
|
||||
const overlay = {
|
||||
title: data[0],
|
||||
@@ -243,8 +382,22 @@
|
||||
overlayService.confirmDelete(overlay);
|
||||
});
|
||||
}
|
||||
function requestDeleteAllBlocks() {
|
||||
localizationService.localizeMany(["content_nestedContentDeleteAllItems", "general_delete"]).then(function (data) {
|
||||
overlayService.confirmDelete({
|
||||
title: data[1],
|
||||
content: data[0],
|
||||
close: function () {
|
||||
overlayService.close();
|
||||
},
|
||||
submit: function () {
|
||||
deleteAllBlocks();
|
||||
overlayService.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
vm.showCopy = clipboardService.isSupported();
|
||||
|
||||
var runtimeSortVars = {};
|
||||
|
||||
@@ -289,12 +442,17 @@
|
||||
editBlock: editBlock,
|
||||
requestCopyBlock: requestCopyBlock,
|
||||
requestDeleteBlock: requestDeleteBlock,
|
||||
deleteBlock: deleteBlock,
|
||||
syncBlockData: syncBlockData
|
||||
deleteBlock: deleteBlock
|
||||
}
|
||||
|
||||
|
||||
function validateLimits() {
|
||||
function onAmountOfBlocksChanged() {
|
||||
|
||||
// enable/disable property actions
|
||||
copyAllBlocksAction.isDisabled = vm.blocks.length === 0;
|
||||
deleteAllBlocksAction.isDisabled = vm.blocks.length === 0;
|
||||
|
||||
// validate limits:
|
||||
if (vm.validationLimit.min !== null) {
|
||||
if (vm.blocks.length < vm.validationLimit.min) {
|
||||
vm.propertyForm.minCount.$setValidity("minCount", false);
|
||||
@@ -314,24 +472,8 @@
|
||||
|
||||
|
||||
|
||||
// TODO: We need to investigate if we can do a specific watch on each block, so we dont re-render all blocks.
|
||||
unsubscribe.push($scope.$watch(() => vm.blocks.length, onAmountOfBlocksChanged));
|
||||
/*
|
||||
unsubscribe.push($scope.$watch("vm.blocks[0]", onBlocksUpdated, true));
|
||||
function onBlocksUpdated(newVal, oldVal) {
|
||||
|
||||
console.log("blocks update", oldVal, " > ", newVal);
|
||||
//setDirty();
|
||||
|
||||
var labelIndex = 1;
|
||||
for(const block of vm.blocks) {
|
||||
block.label = blockEditorService.getBlockLabel(block, labelIndex++);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
unsubscribe.push($scope.$watch(() => vm.blocks.length, validateLimits));
|
||||
/*
|
||||
unsubscribe.push($scope.$on("formSubmitting", function (ev, args) {
|
||||
|
||||
console.log("formSubmitting is happening, we need to make sure sub property editors are synced first.")
|
||||
@@ -340,7 +482,7 @@
|
||||
|
||||
//sync();
|
||||
}));
|
||||
*/
|
||||
*/
|
||||
$scope.$on("$destroy", function () {
|
||||
for (const subscription of unsubscribe) {
|
||||
subscription();
|
||||
|
||||
Reference in New Issue
Block a user