Compare commits

..

13 Commits

Author SHA1 Message Date
swcs b686dc6362 disable "Add" button in Nested Content config when no available docTypes are left 2019-08-11 14:25:43 +02:00
swcs ab0c4d2700 add+delete anchors in Nested Content config should be <button/> elements 2019-08-11 14:19:09 +02:00
swcs 8b8a8c0ccb display docType alias in Nested Content property editor when necessary 2019-08-11 14:16:54 +02:00
Kenn Jacobsen 2f84e76952 Use mculture in content editor for multilingual content 2019-08-09 16:58:35 +02:00
Kenn Jacobsen 12a30d3ffd Always open the selected content template in infinite editing 2019-08-09 16:56:04 +02:00
Kenn Jacobsen 7e1f90fb3b Clear the content type "common" cache when deleting templates 2019-08-09 16:54:52 +02:00
Kenn Jacobsen feb5567621 Fix the disabled upload button in media picker (#6082) 2019-08-09 16:36:38 +02:00
Rachel Breeze ab3202b560 V8: Accessibility improvements for page name entry (#5760) 2019-08-09 16:25:51 +02:00
Kenn Jacobsen e10ce234db Fix "infinityMode" typo 2019-08-09 15:59:37 +02:00
Shannon 84554101f2 Merge branch 'v8/dev' of https://github.com/umbraco/Umbraco-CMS into v8/dev 2019-08-09 15:54:38 +10:00
Shannon 8a3b2e038c adds note 2019-08-09 15:54:21 +10:00
amitch17 296d7964ae Corrected comments to change usage examples
Corrected usage examples for entityResource.js

My first Umbraco commit! yay!
2019-08-08 18:55:38 +02:00
Steve Megson ed5effd190 Sorting of images in multiple media picker 2019-08-08 16:00:21 +02:00
41 changed files with 156 additions and 871 deletions
@@ -36,11 +36,6 @@ namespace Umbraco.Core
/// </summary>
public static class Aliases
{
/// <summary>
/// Block Editor.
/// </summary>
public const string BlockEditor = "Umbraco.BlockEditor";
/// <summary>
/// CheckBox List.
/// </summary>
@@ -268,7 +268,7 @@ AnotherContentFinder
public void GetDataEditors()
{
var types = _typeLoader.GetDataEditors();
Assert.AreEqual(39, types.Count());
Assert.AreEqual(38, types.Count());
}
/// <summary>
+44 -25
View File
@@ -1222,7 +1222,7 @@
"arraybuffer.slice": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
"integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=",
"integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==",
"dev": true
},
"asap": {
@@ -1284,7 +1284,7 @@
"async-limiter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
"integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=",
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
"dev": true
},
"asynckit": {
@@ -1535,7 +1535,7 @@
},
"bl": {
"version": "1.2.2",
"resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"dev": true,
"requires": {
@@ -2516,7 +2516,7 @@
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
"dev": true
},
"continuable-cache": {
@@ -4045,7 +4045,7 @@
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
@@ -4081,7 +4081,7 @@
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
@@ -4476,7 +4476,7 @@
"eventemitter3": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
"integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=",
"integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==",
"dev": true
},
"exec-buffer": {
@@ -5309,7 +5309,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@@ -5330,12 +5331,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -5350,17 +5353,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -5477,7 +5483,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@@ -5489,6 +5496,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -5503,6 +5511,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -5510,12 +5519,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -5534,6 +5545,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -5614,7 +5626,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -5626,6 +5639,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@@ -5711,7 +5725,8 @@
"safe-buffer": {
"version": "5.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -5747,6 +5762,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -5766,6 +5782,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -5809,12 +5826,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},
@@ -7556,7 +7575,7 @@
"has-binary2": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
"integrity": "sha1-d3asYn8+p3JQz8My2rfd9eT10R0=",
"integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
"dev": true,
"requires": {
"isarray": "2.0.1"
@@ -7759,7 +7778,7 @@
"http-proxy": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
"integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=",
"integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
"dev": true,
"requires": {
"eventemitter3": "^3.0.0",
@@ -13597,7 +13616,7 @@
"qjobs": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
"integrity": "sha1-xF6cYYAL0IfviNfiVkI73Unl0HE=",
"integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
"dev": true
},
"qs": {
@@ -14768,7 +14787,7 @@
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
@@ -15841,7 +15860,7 @@
"type-is": {
"version": "1.6.16",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
"integrity": "sha1-+JzjQVQcZysl7nrjxz3uOyvlAZQ=",
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
"dev": true,
"requires": {
"media-typer": "0.3.0",
@@ -15883,7 +15902,7 @@
"ultron": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
"integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=",
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
"dev": true
},
"unc-path-regex": {
@@ -16486,7 +16505,7 @@
"ws": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
"integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=",
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
"dev": true,
"requires": {
"async-limiter": "~1.0.0",
@@ -1,65 +0,0 @@
(function () {
"use strict";
/**
* A component used to render a list of blocks
*/
var umbBlockList = {
templateUrl: 'views/components/blockeditor/umb-block-list.html',
bindings: {
blocks: "<",
config: "<",
scaffolds: "<",
onEdit: "&",
onRemove: "&",
onSettings: "&",
onSort: "&?"
},
controllerAs: 'vm',
controller: umbBlockListController
};
function umbBlockListController() {
var vm = this;
vm.sortableOptions = {
axis: "y",
cursor: "move",
handle: ".handle",
tolerance: 'pointer',
update: function (e, ui) {
if (vm.onSort) {
vm.onSort({ e: e, ui: ui });
}
}
};
vm.editContent = function (block) {
var scaffold = _.findWhere(vm.scaffolds, {
udi: block.udi
});
var element = angular.copy(scaffold);
_.each(element.variants[0].tabs, function (tab) {
_.each(tab.properties, function (property) {
if (block.content[property.alias]) {
property.value = block.content[property.alias];
}
});
});
vm.onEdit({ element: element, block: block });
}
vm.remove = function (block) {
// this should be replaced by a custom dialog (pending some PRs)
if (confirm("TODO: Are you sure?")) {
vm.onRemove({ block: block });
}
}
}
angular.module('umbraco').component('umbBlockList', umbBlockList);
})();
@@ -1,7 +1,7 @@
(function () {
'use strict';
function ContentNodeInfoDirective($timeout, logResource, eventsService, userService, localizationService, dateHelper, editorService, redirectUrlsResource, overlayService) {
function ContentNodeInfoDirective($timeout, logResource, eventsService, userService, localizationService, dateHelper, editorService, redirectUrlsResource, overlayService, entityResource) {
function link(scope) {
@@ -16,8 +16,12 @@
scope.disableTemplates = Umbraco.Sys.ServerVariables.features.disabledFeatures.disableTemplates;
scope.allowChangeDocumentType = false;
scope.allowChangeTemplate = false;
scope.allTemplates = [];
function onInit() {
entityResource.getAll("Template").then(function (templates) {
scope.allTemplates = templates;
});
// set currentVariant
scope.currentVariant = _.find(scope.node.variants, (v) => v.active);
@@ -158,8 +162,12 @@
}
scope.openTemplate = function () {
var template = _.findWhere(scope.allTemplates, {alias: scope.node.template})
if (!template) {
return;
}
var templateEditor = {
id: scope.node.templateId,
id: template.id,
submit: function (model) {
editorService.close();
},
@@ -1,7 +1,7 @@
(function () {
'use strict';
function EditorContentHeader(serverValidationManager) {
function EditorContentHeader(serverValidationManager, localizationService, editorState) {
function link(scope, el, attr, ctrl) {
@@ -13,7 +13,24 @@
if (!scope.serverValidationAliasField) {
scope.serverValidationAliasField = "Alias";
}
scope.isNew = scope.content.state == "NotCreated";
localizationService.localizeMany([
scope.isNew ? "placeholders_a11yCreateItem" : "placeholders_a11yEdit",
"placeholders_a11yName"]
).then(function (data) {
scope.a11yMessage = data[0];
scope.a11yName = data[1];
if (!scope.isNew) {
scope.a11yMessage += " " + scope.content.name;
} else {
var name = editorState.current.contentTypeName;
scope.a11yMessage += " " + name;
scope.a11yName = name + " " + scope.a11yName;
}
});
scope.vm = {};
scope.vm.dropdownOpen = false;
scope.vm.currentVariant = "";
@@ -16,9 +16,7 @@
editor.moveRight = true;
editor.level = 0;
editor.styleIndex = 0;
editor.infinityMode = true;
// push the new editor to the dom
scope.editors.push(editor);
@@ -509,20 +509,6 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
});
},
getScaffoldByUdi: function (parentId, udi) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"contentApiBaseUrl",
"GetEmpty",
[{ udi: udi }, { parentId: parentId }])),
'Failed to retrieve data for empty content item with udi ' + udi)
.then(function (result) {
return $q.when(umbDataFormatter.formatContentGetData(result));
});
},
getBlueprintScaffold: function (parentId, blueprintId) {
return umbRequestHelper.resourcePromise(
@@ -133,7 +133,7 @@ function entityResource($q, $http, umbRequestHelper) {
* ##usage
* <pre>
* //get media by id
* entityResource.getEntityById(0, "Media")
* entityResource.getById(0, "Media")
* .then(function(ent) {
* var myDoc = ent;
* alert('its here!');
@@ -204,7 +204,7 @@ function entityResource($q, $http, umbRequestHelper) {
* ##usage
* <pre>
* //Get templates for ids
* entityResource.getEntitiesByIds( [1234,2526,28262], "Template")
* entityResource.getByIds( [1234,2526,28262], "Template")
* .then(function(templateArray) {
* var myDoc = contentArray;
* alert('they are here!');
@@ -17,7 +17,7 @@
z-index: @zIndexEditor;
}
.umb-editor--infinityMode {
.umb-editor--infiniteMode {
transform: none;
will-change: transform;
transition: transform 400ms ease-in-out;
@@ -132,10 +132,6 @@
&.umb-overlay--medium {
width: 480px;
}
&.umb-overlay--large {
width:640px;
}
}
.umb-overlay.umb-overlay-target .umb-overlay-header {
@@ -268,7 +268,7 @@ angular.module("umbraco")
// also make sure the node is not trashed
if (nodePath.indexOf($scope.startNodeId.toString()) !== -1 && node.trashed === false) {
$scope.gotoFolder({ id: $scope.lastOpenedNode, name: "Media", icon: "icon-folder" });
$scope.gotoFolder({ id: $scope.lastOpenedNode, name: "Media", icon: "icon-folder", path: node.path });
return true;
} else {
$scope.gotoFolder({ id: $scope.startNodeId, name: "Media", icon: "icon-folder" });
@@ -1,18 +0,0 @@
<ul class="unstyled" ui-sortable="vm.sortableOptions" ng-model="vm.blocks">
<li ng-repeat="block in vm.blocks">
<div class="handle">
<div class="umb-node-preview umb-node-preview--sortable">
<i ng-if="block.icon" class="umb-node-preview__icon {{ block.icon }}"></i>
<div class="umb-node-preview__content">
<div class="umb-node-preview__name" ng-attr-title="{{block.alias}}">TODO: Figure out how to name a block</div>
<div class="umb-node-preview__description" ng-if="block.description">{{ block.description }}</div>
</div>
<div class="umb-node-preview__actions">
<a class="umb-node-preview__action" title="Edit" href="" ng-click="vm.editContent(block)"><localize key="general_edit">Edit</localize></a>
<a class="umb-node-preview__action" title="Settings" href="" ng-click="vm.onSettings({block: block})"><localize key="general_settings">Settings</localize></a>
<a class="umb-node-preview__action umb-node-preview__action--red" title="Remove" ng-href="" ng-click="vm.remove(block)"><localize key="general_remove">Remove</localize></a>
</div>
</div>
</div>
</li>
</ul>
@@ -11,24 +11,30 @@
<div class="flex items-center" style="flex: 1;">
<div id="nameField" class="umb-editor-header__name-and-description" style="flex: 1 1 auto;">
<div>
<p tabindex="0" class="sr-only">
{{a11yMessage}}
</p>
</div>
<div class="umb-editor-header__name-wrapper">
<label for="headerName" class="sr-only">{{a11yName}}</label>
<ng-form name="headerNameForm">
<input
data-element="editor-name-field"
type="text"
class="umb-editor-header__name-input"
localize="placeholder"
placeholder="@placeholders_entername"
name="headerName"
ng-model="name"
ng-class="{'name-is-empty': $parent.name===null || $parent.name===''}"
ng-disabled="nameDisabled"
umb-auto-focus
val-server-field="{{serverValidationNameField}}"
required
aria-required="true"
aria-invalid="{{contentForm.headerNameForm.headerName.$invalid ? true : false}}"
autocomplete="off" maxlength="255" />
<input data-element="editor-name-field"
type="text"
class="umb-editor-header__name-input"
localize="placeholder"
placeholder="@placeholders_entername"
name="headerName"
id="headerName"
ng-model="name"
ng-class="{'name-is-empty': $parent.name===null || $parent.name===''}"
ng-disabled="nameDisabled"
umb-auto-focus
val-server-field="{{serverValidationNameField}}"
required
aria-required="true"
aria-invalid="{{contentForm.headerNameForm.headerName.$invalid ? true : false}}"
autocomplete="off" maxlength="255" />
</ng-form>
<a ng-if="content.variants.length > 0 && hideChangeVariant !== true" class="umb-variant-switcher__toggle" href="" ng-click="vm.dropdownOpen = !vm.dropdownOpen" ng-class="{'--error': vm.errorsOnOtherVariants}">
@@ -5,7 +5,7 @@
ng-class="{'umb-editor--small': model.size === 'small',
'umb-editor--animating': model.animating,
'--notInFront': model.inFront !== true,
'umb-editor--infinityMode': model.infinityMode,
'umb-editor--infiniteMode': model.infiniteMode,
'moveRight': model.moveRight,
'umb-editor--n0': model.styleIndex === 0,
'umb-editor--n1': model.styleIndex === 1,
@@ -24,7 +24,7 @@ function ContentEditController($scope, $routeParams, contentResource) {
$scope.page = $routeParams.page;
$scope.isNew = infiniteMode ? $scope.model.create : $routeParams.create;
//load the default culture selected in the main tree if any
$scope.culture = $routeParams.cculture ? $routeParams.cculture : ($routeParams.mculture === "true");
$scope.culture = $routeParams.cculture ? $routeParams.cculture : $routeParams.mculture;
//Bind to $routeUpdate which will execute anytime a location changes but the route is not triggered.
//This is so we can listen to changes on the cculture parameter since that will not cause a route change
@@ -1,90 +0,0 @@
<div>
<umb-editor-view>
<umb-editor-header name="model.title"
name-locked="true"
hide-alias="true"
hide-icon="true"
hide-description="true">
</umb-editor-header>
<umb-editor-container class="block-form">
<umb-box>
<umb-box-content>
<div class="content-type-editor-dialog edit-property-settings">
<div class="umb-control-group" ng-if="!model.property.locked">
<div class="control-group">
<textarea class="editor-label"
data-element="property-name"
name="propertyLabel"
ng-model="model.property.label"
localize="placeholder"
placeholder="@placeholders_entername"
umb-auto-focus
focus-on-filled="true"
umb-auto-resize
required
ng-keypress="submitOnEnter($event)">
</textarea>
</div>
<div class="control-group -no-margin">
<umb-generate-alias enable-lock="true" alias-from="model.property.label" alias="model.property.alias"></umb-generate-alias>
</div>
</div>
<div class="editor-wrapper umb-control-group control-group" ng-model="model.property.editor" val-require-component ng-if="!model.property.locked">
<a data-element="editor-add" href="" ng-if="!model.property.editor" class="editor-placeholder" hotkey="alt+shift+e" ng-click="openDataTypePicker(model.property)">
<localize key="shortcuts_addEditor"></localize>
</a>
<div class="editor clearfix" ng-if="model.property.editor">
<a href="" class="editor-icon-wrapper" ng-click="openDataTypePicker(model.property)">
<i class="icon {{ model.property.dataTypeIcon }}" ng-class="{'icon-autofill': model.property.dataTypeIcon == null}"></i>
</a>
<div class="editor-details">
<a href="" class="editor-name" ng-click="openDataTypePicker(model.property)" ng-bind="model.property.dataTypeName"></a>
<a href="" class="editor-editor" ng-click="openDataTypePicker(model.property)" ng-bind="model.property.editor"></a>
</div>
<a href class="editor-settings-icon pull-right"
ng-click="vm.openDataTypeSettings(model.property)"
hotkey="alt+shift+d"
ng-if="model.property.editor">
<i class="icon icon-settings"></i>
</a>
</div>
</div>
</div>
</umb-box-content>
</umb-box>
</umb-editor-container>
<umb-editor-footer>
<umb-editor-footer-content-right>
<umb-button type="button"
button-style="link"
label-key="general_close"
shortcut="esc"
action="close()">
</umb-button>
<umb-button type="button"
button-style="success"
label-key="general_submit"
state="saveButtonState"
action="submit(model)">
</umb-button>
</umb-editor-footer-content-right>
</umb-editor-footer>
</umb-editor-view>
</div>
@@ -1,204 +0,0 @@
(function () {
"use strict";
function BlockEditorController($scope, contentResource, editorService, iconHelper, clipboardService) {
var vm = this;
vm.scaffolds = [];
vm.loading = true;
let allowedElements = [];
// it would be awesome if we could load all scaffolds in one go... however we need to have an eye out for performance,
// oddly enough it's been shown to actually be slower to load them all at once instead of one at a time
var scaffoldsLoaded = 0;
function init() {
_.each($scope.model.config.blocks, function (config) {
contentResource.getScaffoldByUdi(-20, config.elementType).then(function (scaffold) {
if (scaffold.isElement) {
// the scaffold udi is not the same as the element type udi, but we need it to be for comparison
scaffold.udi = config.elementType;
vm.scaffolds.push(scaffold);
}
scaffoldsLoaded++;
initIfAllScaffoldsHaveLoaded();
}, function (error) {
scaffoldsLoaded++;
initIfAllScaffoldsHaveLoaded();
});
});
}
function initIfAllScaffoldsHaveLoaded() {
// Initialize when all scaffolds have loaded
if ($scope.model.config.blocks.length === scaffoldsLoaded) {
vm.scaffolds = _.sortBy(vm.scaffolds, function (scaffold) {
return _.findIndex($scope.model.config.blocks, function (blockConfig) {
return blockConfig.elementType === scaffold.udi;
});
});
_.each($scope.model.value, function (block) {
applyFakeSettings(block);
});
allowedElements = vm.scaffolds.map(x => x.contentTypeAlias);
vm.loading = false;
}
}
vm.openNodeTypePicker = function ($event) {
vm.overlayMenu = {
show: false,
style: {},
filter: vm.scaffolds.length > 12 ? true : false,
orderBy: "$index",
view: "itempicker",
event: $event,
clickPasteItem: function (item) {
vm.pasteFromClipboard(item.data);
vm.overlayMenu.show = false;
vm.overlayMenu = null;
},
submit: function (model) {
if (model && model.selectedItem) {
vm.add(vm.scaffolds.filter(x => x.contentTypeAlias === model.selectedItem.alias)[0]);
}
vm.overlayMenu.show = false;
vm.overlayMenu = null;
},
close: function () {
vm.overlayMenu.show = false;
vm.overlayMenu = null;
}
};
// this could be used for future limiting on node types
vm.overlayMenu.availableItems = [];
vm.scaffolds.forEach(function (scaffold) {
vm.overlayMenu.availableItems.push({
alias: scaffold.contentTypeAlias,
name: scaffold.contentTypeName,
icon: iconHelper.convertFromLegacyIcon(scaffold.icon),
description: scaffold.documentType.description
});
});
if (vm.overlayMenu.availableItems.length === 0) {
return;
}
//TODO: If we support larger thumbnails of some sort one day, this could be large
vm.overlayMenu.size = vm.overlayMenu.availableItems.length > 6 ? "medium" : "small";
vm.overlayMenu.pasteItems = [];
var availableNodesForPaste = clipboardService.retriveDataOfType("elementType", allowedElements);
availableNodesForPaste.forEach(function (node) {
vm.overlayMenu.pasteItems.push({
alias: node.contentTypeAlias,
name: node.name, //contentTypeName
data: node,
icon: iconHelper.convertFromLegacyIcon(node.icon)
});
});
vm.overlayMenu.clickClearPaste = function ($event) {
$event.stopPropagation();
$event.preventDefault();
clipboardService.clearEntriesOfType("elementType", allowedElements);
vm.overlayMenu.pasteItems = []; // This dialog is not connected via the clipboardService events, so we need to update manually.
};
if (vm.overlayMenu.availableItems.length === 1 && vm.overlayMenu.pasteItems.length === 0) {
// only one scaffold type - no need to display the picker
vm.add(vm.scaffolds[0]);
return;
}
vm.overlayMenu.show = true;
}
vm.add = function (scaffold) {
var element = angular.copy(scaffold);
var block = {
udi: element.udi,
icon: element.icon,
description: element.documentType.description, // probably don't want to persist these.
content: {},
settings: {
view: 'views/propertyeditors/blockeditor/blockeditor.block.html'
}
};
openContent(element, block);
}
vm.editSettings = function (block) {
var options = {
settings: block.settings,
title: "Edit settings",
view: "views/propertyeditors/blockeditor/blockeditor.editsettings.html",
size: "small",
submit: function (model) {
editorService.close();
},
close: function () {
editorService.close();
}
};
editorService.open(options);
}
vm.onRemove = function (block) {
$scope.model.value.splice($scope.model.value.indexOf(block), 1);
}
vm.onEdit = function (element, block) {
openContent(element, block);
}
function openContent(element, block) {
var options = {
element: element,
title: 'Edit block',
//fixme: This isn't really a component if its strongly tied to views in the property editor :/
view: "views/propertyeditors/blockeditor/blockeditor.editcontent.html",
submit: function (model) {
_.each(element.variants[0].tabs, function (tab) {
_.each(tab.properties, function (property) {
block.content[property.alias] = property.value;
});
});
if ($scope.model.value.indexOf(block) < 0) {
$scope.model.value.push(block);
applyFakeSettings(block);
}
editorService.close();
},
close: function () {
editorService.close();
}
};
editorService.open(options);
}
// TODO: remove this (only for testing)
// currently pushes random values for setting a css grid location
function applyFakeSettings(block) {
block.settings["col"] = 1 + Math.floor(Math.random() * 7);
block.settings["row"] = 1 + Math.floor(Math.random() * 7);
block.settings["w"] = 1 + Math.floor(Math.random() * 3);
block.settings["h"] = 1 + Math.floor(Math.random() * 3);
}
init();
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.BlockEditorController", BlockEditorController);
})();
@@ -1,34 +0,0 @@
/**
* @ngdoc controller
* @name Umbraco.PropertyEditors.BlockEditor.EditContentController
* @function
*
* @description
* The controller for editing content with the block editor
*/
function BlockEditorEditContentController($scope) {
var vm = this;
vm.submit = submit;
vm.close = close;
vm.content = $scope.model.element.variants[0];
function init() {
}
function submit() {
if($scope.model.submit) {
$scope.model.submit($scope.model);
}
}
function close() {
if($scope.model.close) {
$scope.model.close();
}
}
init();
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.BlockEditor.EditContentController", BlockEditorEditContentController);
@@ -1,38 +0,0 @@
<div ng-controller="Umbraco.PropertyEditors.BlockEditor.EditContentController as vm">
<umb-editor-view>
<umb-editor-header name="model.title"
name-locked="true"
hide-alias="true"
hide-icon="true"
hide-description="true">
</umb-editor-header>
<umb-editor-container>
<umb-load-indicator ng-if="vm.loading" />
<div ng-if="!loading">
<ng-form name="editBlockForm" val-form-manager>
<umb-tabbed-content content="vm.content" />
</ng-form>
</div>
</umb-editor-container>
<umb-editor-footer>
<umb-editor-footer-content-right>
<umb-button type="button"
button-style="link"
label-key="general_cancel"
shortcut="esc"
action="vm.close()">
</umb-button>
<umb-button type="button"
button-style="success"
label-key="general_ok"
action="vm.submit()">
</umb-button>
</umb-editor-footer-content-right>
</umb-editor-footer>
</umb-editor-view>
</div>
@@ -1,26 +0,0 @@
/**
* @ngdoc controller
* @name Umbraco.PropertyEditors.BlockEditor.EditSettingsController
* @function
*
* @description
* The controller for editing the configuration of an individual block
*/
//fixme: Need to figure out the name of a block settings, is it block config or block settings?
function BlockEditorEditSettingsController($scope) {
this.submit = () => {
if($scope.model.submit) {
$scope.model.submit($scope.model);
}
}
this.close = () => {
if($scope.model.close) {
$scope.model.close();
}
}
}
angular.module("umbraco")
.controller("Umbraco.PropertyEditors.BlockEditor.EditSettingsController", ['$scope', BlockEditorEditSettingsController]);
@@ -1,44 +0,0 @@
<div ng-controller="Umbraco.PropertyEditors.BlockEditor.EditSettingsController as vm">
<umb-editor-view>
<umb-editor-header name="model.title"
name-locked="true"
hide-alias="true"
hide-icon="true"
hide-description="true">
</umb-editor-header>
<umb-editor-container>
<umb-load-indicator ng-if="vm.loading" />
<div ng-if="!loading">
<umb-box>
<umb-box-content>
<ng-form name="editBlockForm" class="form-horizontal" val-form-manager>
<umb-control-group label="{{key}}" description="" ng-repeat="(key, value) in model.settings">
<input type="text" ng-model="model.settings[key]" ng-model-options="{ debounce: 5000 }"/>
</umb-control-group>
</ng-form>
</umb-box-content>
</umb-box>
</div>
</umb-editor-container>
<umb-editor-footer>
<umb-editor-footer-content-right>
<umb-button type="button"
button-style="link"
label-key="general_cancel"
shortcut="esc"
action="vm.close()">
</umb-button>
<umb-button type="button"
button-style="success"
label-key="general_ok"
action="vm.submit()">
</umb-button>
</umb-editor-footer-content-right>
</umb-editor-footer>
</umb-editor-view>
</div>
@@ -1,31 +0,0 @@
<div ng-controller="Umbraco.PropertyEditors.BlockEditorController as vm">
<div style="position:relative" ng-if="vm.loading">
<umb-load-indicator />
</div>
<div ng-if="!vm.loading">
<umb-block-list blocks="model.value"
config="model.config.blocks"
scaffolds="vm.scaffolds"
on-edit="vm.onEdit(element, block)"
on-remove="vm.onRemove(element, block)"
on-settings="vm.editSettings(block)">
</umb-block-list>
</div>
<div ng-if="!vm.loading" class="umb-nested-content__footer-bar">
<a href class="umb-nested-content__add-content" ng-class="{ '--disabled': !vm.scaffolds.length }" ng-click="vm.openNodeTypePicker($event)" prevent-default>
<localize key="grid_addElement" ng-if="vm.scaffolds.length > 1"></localize>
<span ng-if="vm.scaffolds.length === 1">
<localize key="general_add"></localize> {{ vm.scaffolds[0].contentTypeName }}
</span>
</a>
</div>
<umb-overlay ng-if="vm.overlayMenu.show"
position="target"
size="vm.overlayMenu.size"
view="vm.overlayMenu.view"
model="vm.overlayMenu">
</umb-overlay>
</div>
@@ -1,96 +0,0 @@
/**
* @ngdoc controller
* @name Umbraco.PropertyEditors.BlockEditor.SettingsController
* @function
*
* @description
* The controller for the block editor's data type configuration
*/
//fixme: Rename this! it shouldn't be called Settings, it should be called Configuration because that is what we call pre-values in v8 (data type config)
angular.module("umbraco")
.controller("Umbraco.PropertyEditors.BlockEditor.SettingsController", [
"$scope",
"contentTypeResource",
"editorService",
function ($scope, contentTypeResource, editorService) {
$scope.blocks = [];
$scope.elementTypes = [];
if ($scope.model.value) {
$scope.blocks = $scope.model.value;
} else {
$scope.model.value = [];
}
contentTypeResource.getAll()
.then(function (contentType) {
$scope.elementTypes.push(contentType);
});
$scope.$on("formSubmitting", function () {
$scope.model.value = $scope.blocks;
});
//fixme: This shouldn't be a method, using methods to return values in angular is a performance issue
$scope.getBlockName = function(udi) {
return 'TODO: Get block name from somewhere...';
}
$scope.addBlock = function () {
var block = {};
var pickerOptions = {
title: "Pick an element type",
view: "views/common/infiniteeditors/treepicker/treepicker.html",
size: "small",
multiPicker: false,
section: "settings",
treeAlias: "documentTypes",
entityType: "documentType",
submit: function (model) {
_.each(model.selection, function (elementType) {
block.elementType = elementType.udi;
block.settings = {
view: 'views/propertyeditors/blockeditor/blockeditor.block.html'
}
$scope.model.value.push(block);
});
editorService.close();
},
close: function () {
editorService.close();
}
};
editorService.open(pickerOptions);
}
$scope.removeBlock = function (index) {
$scope.model.value.splice(index, 1);
};
//fixme: This currently doesn't work or do anything
$scope.editSettings = function (block) {
var pickerOptions = {
title: "Block settings",
//fixme: This file needs to be renamed since it's inconsistent with other blockeditor file names, probably blockeditor.blocksettings.html
view: "views/propertyeditors/blockeditor/block.settings.html",
size: "small",
submit: function (model) {
block.settings = model;
editorService.close();
},
close: function () {
editorService.close();
}
};
editorService.open(pickerOptions);
}
}
]);
@@ -1,20 +0,0 @@
<div ng-controller="Umbraco.PropertyEditors.BlockEditor.SettingsController">
<umb-node-preview ng-repeat="block in blocks"
name="getBlockName(block)"
alias="block.elementType"
icon="icon-folder"
allow-edit="true"
on-edit="editSettings(block)"
allow-remove="true"
on-remove="removeBlock($index)">
</umb-node-preview>
<a href="" class="umb-node-preview-add" ng-click="addBlock()">
<localize key="general_add">Add</localize>
</a>
<hr />
<pre>{{model.value | json}}</pre>
</div>
@@ -1,9 +0,0 @@
function BlockEditorSimpleListController($scope) {
$scope.sortableOptions = {
axis: "y",
cursor: "move",
handle: ".handle",
tolerance: 'pointer'
};
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.BlockEditor.SimpleListController", ['$scope', BlockEditorSimpleListController]);
@@ -1,3 +1,4 @@
//TODO: What is this file? Is it used?? I don't think so
var uSkyGridConfig = [
{
@@ -307,22 +307,22 @@ angular.module("umbraco")
$scope.openEditorOverlay = function (event, area, index, key) {
var title = "";
localizationService.localize("grid_insertControl").then(function (value) {
title = value;
$scope.editorOverlay = {
view: "itempicker",
filter: area.$allowedEditors.length > 15,
title: title,
availableItems: area.$allowedEditors,
event: event,
show: true,
submit: function (model) {
if (model.selectedItem) {
$scope.addControl(model.selectedItem, area, index);
$scope.editorOverlay.show = false;
$scope.editorOverlay = null;
}
title = value;
$scope.editorOverlay = {
view: "itempicker",
filter: area.$allowedEditors.length > 15,
title: title,
availableItems: area.$allowedEditors,
event: event,
show: true,
submit: function (model) {
if (model.selectedItem) {
$scope.addControl(model.selectedItem, area, index);
$scope.editorOverlay.show = false;
$scope.editorOverlay = null;
}
};
}
};
});
};
@@ -229,7 +229,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
$scope.sortableOptions = {
disabled: !$scope.isMultiPicker,
disabled: !multiPicker,
items: "li:not(.add-wrapper)",
cancel: ".unsortable",
update: function (e, ui) {
@@ -15,10 +15,14 @@
});
}
$scope.canAdd = function () {
return !$scope.model.docTypes || !$scope.model.value || $scope.model.value.length < $scope.model.docTypes.length;
}
$scope.remove = function (index) {
$scope.model.value.splice(index, 1);
}
$scope.sortableOptions = {
axis: "y",
cursor: "move",
@@ -57,10 +61,20 @@
ncResources.getContentTypes().then(function (docTypes) {
$scope.model.docTypes = docTypes;
// Count doctype name occurrences
var docTypeNameOccurrences = _.countBy(docTypes, 'name');
// Populate document type tab dictionary
// And append alias to name if multiple doctypes have the same name
docTypes.forEach(function (value) {
$scope.docTypeTabs[value.alias] = value.tabs;
value.displayName = value.name;
if (docTypeNameOccurrences[value.name] > 1) {
value.displayName += " (" + value.alias + ")";
}
});
});
@@ -184,8 +198,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
$scope.overlayMenu.availableItems.push({
alias: scaffold.contentTypeAlias,
name: scaffold.contentTypeName,
icon: iconHelper.convertFromLegacyIcon(scaffold.icon),
description: scaffold.documentType.description
icon: iconHelper.convertFromLegacyIcon(scaffold.icon)
});
});
@@ -193,7 +206,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
return;
}
$scope.overlayMenu.size = $scope.overlayMenu.availableItems.length > 6 ? "medium" : "small";
$scope.overlayMenu.size = $scope.overlayMenu.availableItems.length > 6 ? "medium" : "small";
$scope.overlayMenu.pasteItems = [];
var availableNodesForPaste = clipboardService.retriveDataOfType("elementType", contentTypeAliases);
@@ -23,7 +23,7 @@
</td>
<td>
<select id="{{model.alias}}_doctype_select"
ng-options="dt.alias as dt.name for dt in selectableDocTypesFor(config) | orderBy: 'name'"
ng-options="dt.alias as dt.displayName for dt in selectableDocTypesFor(config) | orderBy: 'name'"
ng-model="config.ncAlias" required></select>
</td>
<td>
@@ -35,17 +35,17 @@
<input type="text" ng-model="config.nameTemplate" />
</td>
<td>
<a class="btn btn-danger" ng-click="remove($index)">
<button type="button" class="btn btn-danger" ng-click="remove($index)">
<localize key="general_delete">Delete</localize>
</a>
</button>
</td>
</tr>
</tbody>
</table>
<div>
<a class="btn" ng-click="add()">
<button type="button" class="btn" ng-click="add()" ng-disabled="!canAdd()">
<localize key="general_add">Add</localize>
</a>
</button>
<i class="icon icon-help-alt medium umb-nested-content__help-icon" ng-click="showHelpText = !showHelpText"></i>
</div>
</div>
@@ -40,8 +40,7 @@
<div class="umb-nested-content__footer-bar" ng-hide="hasContentTypes === false || nodes.length >= maxItems">
<a href class="umb-nested-content__add-content" ng-class="{ '--disabled': !scaffolds.length }" ng-click="openNodeTypePicker($event)" prevent-default>
<localize key="grid_addElement" ng-if="scaffolds.length > 1"></localize>
<span ng-if="scaffolds.length === 1"><localize key="general_add"></localize> {{ scaffolds[0].contentTypeName }}</span>
<localize key="grid_addElement"></localize>
</a>
</div>
@@ -527,6 +527,9 @@
<key alias="anchor">#value or ?key=value</key>
<key alias="enterAlias">Enter alias...</key>
<key alias="generatingAlias">Generating alias...</key>
<key alias="a11yCreateItem">Create item</key>
<key alias="a11yEdit">Edit</key>
<key alias="a11yName">Name</key>
</area>
<area alias="editcontenttype">
<key alias="createListView" version="7.2">Create custom list view</key>
@@ -530,6 +530,9 @@
<key alias="anchor">#value or ?key=value</key>
<key alias="enterAlias">Enter alias...</key>
<key alias="generatingAlias">Generating alias...</key>
<key alias="a11yCreateItem">Create item</key>
<key alias="a11yEdit">Edit</key>
<key alias="a11yName">Name</key>
</area>
<area alias="editcontenttype">
<key alias="createListView" version="7.2">Create custom list view</key>
@@ -60,7 +60,7 @@
<security>
<!-- set to true to auto update login interval (and there by disabling the lock screen -->
<keepUserLoggedIn>true</keepUserLoggedIn>
<keepUserLoggedIn>false</keepUserLoggedIn>
<!-- by default this is true and if not specified in config will be true. set to false to always show a separate username field in the back office user editor -->
<usernameIsEmail>true</usernameIsEmail>
<!-- change in 4.8: Disabled users are now showed dimmed and last in the tree. If you prefer not to display them set this to true -->
@@ -1,6 +1,7 @@
using System;
using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Services;
namespace Umbraco.Web.Cache
@@ -8,11 +9,13 @@ namespace Umbraco.Web.Cache
public sealed class TemplateCacheRefresher : CacheRefresherBase<TemplateCacheRefresher>
{
private readonly IdkMap _idkMap;
private readonly IContentTypeCommonRepository _contentTypeCommonRepository;
public TemplateCacheRefresher(AppCaches appCaches, IdkMap idkMap)
public TemplateCacheRefresher(AppCaches appCaches, IdkMap idkMap, IContentTypeCommonRepository contentTypeCommonRepository)
: base(appCaches)
{
_idkMap = idkMap;
_contentTypeCommonRepository = contentTypeCommonRepository;
}
#region Define
@@ -45,6 +48,7 @@ namespace Umbraco.Web.Cache
// it has an associated template.
ClearAllIsolatedCacheByEntityType<IContent>();
ClearAllIsolatedCacheByEntityType<IContentType>();
_contentTypeCommonRepository.ClearCache();
base.Remove(id);
}
+1 -23
View File
@@ -354,34 +354,12 @@ namespace Umbraco.Web.Editors
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return EmptyContent(parentId, contentType);
}
/// <summary>
/// Gets an empty content item for the
/// </summary>
/// <param name="udi"></param>
/// <param name="parentId"></param>
[OutgoingEditorModelEvent]
public ContentItemDisplay GetEmpty(GuidUdi udi, int parentId)
{
var contentType = Services.ContentTypeService.Get(udi.Guid);
if(contentType == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return EmptyContent(parentId, contentType);
}
private ContentItemDisplay EmptyContent(int parentId, IContentType contentType)
{
var emptyContent = Services.ContentService.Create("", parentId, contentType.Alias, Security.GetUserId().ResultOr(0));
var mapped = MapToDisplay(emptyContent);
// translate the content type name if applicable
mapped.ContentTypeName = Services.TextService.UmbracoDictionaryTranslate(mapped.ContentTypeName);
// if your user type doesn't have access to the Settings section it would not get this property mapped
if(mapped.DocumentType != null)
if (mapped.DocumentType != null)
mapped.DocumentType.Name = Services.TextService.UmbracoDictionaryTranslate(mapped.DocumentType.Name);
//remove the listview app if it exists
@@ -1,36 +0,0 @@
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
public class BlockEditorConfiguration
{
[ConfigurationField("blocks", "Blocks", "views/propertyeditors/blockeditor/blockeditor.settings.html")]
public Block[] Blocks { get; set; }
[ConfigurationField("view", "View", "textstring", Description = "The path to a custom view for rendering the editor")]
public string View { get; set; }
public class Block
{
[JsonProperty("elementType")]
public Udi ElementType { get; set; }
[JsonProperty("settings")]
public BlockSetting Settings { get; set; }
}
public class BlockSetting
{
[JsonProperty("label")]
public string Label { get; set; }
[JsonProperty("alias")]
public string Alias { get; set; }
[JsonProperty("dataType")]
public Udi DataType { get; set; }
}
}
}
@@ -1,9 +0,0 @@
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
public class BlockEditorConfigurationEditor : ConfigurationEditor<BlockEditorConfiguration>
{
}
}
@@ -1,18 +0,0 @@
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
[DataEditor(Constants.PropertyEditors.Aliases.BlockEditor, EditorType.PropertyValue , "Block Editor", "blockeditor", ValueType = ValueTypes.Json, Group="rich content", Icon="icon-application-window-alt")]
public class BlockEditorPropertyEditor : DataEditor
{
public BlockEditorPropertyEditor(ILogger logger)
: base(logger)
{ }
protected override IConfigurationEditor CreateConfigurationEditor() => new BlockEditorConfigurationEditor();
protected override IDataValueEditor CreateValueEditor() => base.CreateValueEditor();
}
}
-3
View File
@@ -222,9 +222,6 @@
<Compile Include="Mvc\HttpUmbracoFormRouteStringException.cs" />
<Compile Include="Mvc\ModelBindingExceptionFilter.cs" />
<Compile Include="Mvc\SurfaceControllerTypeCollectionBuilder.cs" />
<Compile Include="PropertyEditors\BlockEditorConfiguration.cs" />
<Compile Include="PropertyEditors\BlockEditorConfigurationEditor.cs" />
<Compile Include="PropertyEditors\BlockEditorPropertyEditor.cs" />
<Compile Include="Mvc\ValidateUmbracoFormRouteStringAttribute.cs" />
<Compile Include="Profiling\WebProfilingController.cs" />
<Compile Include="PublishedCache\NuCache\PublishedSnapshotServiceOptions.cs" />