diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tabs/umbtabsnav.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tabs/umbtabsnav.directive.js index 890acf3d6f..50c4775ef9 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tabs/umbtabsnav.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tabs/umbtabsnav.directive.js @@ -43,7 +43,8 @@ templateUrl: "views/components/tabs/umb-tabs-nav.html", scope: { model: "=", - tabdrop: "=" + tabdrop: "=", + idSuffix: "@" }, link: link }; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umblaunchminieditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umblaunchminieditor.directive.js index 91212a82f8..11b934ce96 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umblaunchminieditor.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umblaunchminieditor.directive.js @@ -7,7 +7,7 @@ * Used on a button to launch a mini content editor editor dialog **/ angular.module("umbraco.directives") - .directive('umbLaunchMiniEditor', function (dialogService, editorState, fileManager, contentEditingHelper) { + .directive('umbLaunchMiniEditor', function (miniEditorHelper) { return { restrict: 'A', replace: false, @@ -16,69 +16,8 @@ angular.module("umbraco.directives") }, link: function(scope, element, attrs) { - var launched = false; - element.click(function() { - - if (launched === true) { - return; - } - - launched = true; - - //We need to store the current files selected in the file manager locally because the fileManager - // is a singleton and is shared globally. The mini dialog will also be referencing the fileManager - // and we don't want it to be sharing the same files as the main editor. So we'll store the current files locally here, - // clear them out and then launch the dialog. When the dialog closes, we'll reset the fileManager to it's previous state. - var currFiles = _.groupBy(fileManager.getFiles(), "alias"); - fileManager.clearFiles(); - - //We need to store the original editorState entity because it will need to change when the mini editor is loaded so that - // any property editors that are working with editorState get given the correct entity, otherwise strange things will - // start happening. - var currEditorState = editorState.getCurrent(); - - dialogService.open({ - template: "views/common/dialogs/content/edit.html", - id: scope.node.id, - closeOnSave: true, - tabFilter: ["Generic properties"], - callback: function (data) { - - //set the node name back - scope.node.name = data.name; - - //reset the fileManager to what it was - fileManager.clearFiles(); - _.each(currFiles, function (val, key) { - fileManager.setFiles(key, _.map(currFiles['upload'], function (i) { return i.file; })); - }); - - //reset the editor state - editorState.set(currEditorState); - - //Now we need to check if the content item that was edited was actually the same content item - // as the main content editor and if so, update all property data - if (data.id === currEditorState.id) { - var changed = contentEditingHelper.reBindChangedProperties(currEditorState, data); - } - - launched = false; - }, - closeCallback: function () { - //reset the fileManager to what it was - fileManager.clearFiles(); - _.each(currFiles, function (val, key) { - fileManager.setFiles(key, _.map(currFiles['upload'], function (i) { return i.file; })); - }); - - //reset the editor state - editorState.set(currEditorState); - - launched = false; - } - }); - + miniEditorHelper.launchMiniEditor(scope.node); }); } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js new file mode 100644 index 0000000000..77f6f06a30 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js @@ -0,0 +1,122 @@ +/** +@ngdoc directive +@name umbraco.directives.directive:umbNodePreview +@restrict E +@scope + +@description +Added in Umbraco v. 7.6: Use this directive to render a node preview. + +
++ ++ ++++ ++ +
+ (function () {
+ "use strict";
+
+ function Controller() {
+
+ var vm = this;
+
+ vm.allowRemove = true;
+ vm.allowOpen = true;
+ vm.sortable = true;
+
+ vm.nodes = [
+ {
+ "icon": "icon-document",
+ "name": "My node 1",
+ "published": true,
+ "description": "A short description of my node"
+ },
+ {
+ "icon": "icon-document",
+ "name": "My node 2",
+ "published": true,
+ "description": "A short description of my node"
+ }
+ ];
+
+ vm.remove = remove;
+ vm.open = open;
+
+ function remove(index, nodes) {
+ alert("remove node");
+ }
+
+ function open(node) {
+ alert("open node");
+ }
+
+ }
+
+ angular.module("umbraco").controller("My.NodePreviewController", Controller);
+
+ })();
+
+
+@param {string} icon (binding): The node icon.
+@param {string} name (binding): The node name.
+@param {boolean} published (binding): The node pusblished state.
+@param {string} description (binding): A short description.
+@param {boolean} sortable (binding): Will add a move cursor on the node preview. Can used in combination with ui-sortable.
+@param {boolean} allowRemove (binding): Show/Hide the remove button.
+@param {boolean} allowOpen (binding): Show/Hide the open button.
+@param {function} onRemove (expression): Callback function when the remove button is clicked.
+@param {function} onOpen (expression): Callback function when the open button is clicked.
+**/
+
+(function () {
+ 'use strict';
+
+ function NodePreviewDirective() {
+
+ function link(scope, el, attr, ctrl) {
+
+ }
+
+ var directive = {
+ restrict: 'E',
+ replace: true,
+ templateUrl: 'views/components/umb-node-preview.html',
+ scope: {
+ icon: "=?",
+ name: "=",
+ description: "=?",
+ published: "=?",
+ sortable: "=?",
+ allowOpen: "=?",
+ allowRemove: "=?",
+ onOpen: "&?",
+ onRemove: "&?"
+ },
+ link: link
+ };
+
+ return directive;
+
+ }
+
+ angular.module('umbraco.directives').directive('umbNodePreview', NodePreviewDirective);
+
+})();
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js
index fc60781375..8c03679183 100644
--- a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js
+++ b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js
@@ -33,6 +33,15 @@ angular.module('umbraco.mocks').
return [200, nodes, null];
}
+ function returnEntityUrl() {
+
+ if (!mocksUtils.checkAuth()) {
+ return [401, null, null];
+ }
+
+ return [200, "url", null];
+
+ }
return {
register: function () {
@@ -48,6 +57,10 @@ angular.module('umbraco.mocks').
$httpBackend
.whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetById?'))
.respond(returnEntitybyId);
+
+ $httpBackend
+ .whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetUrl?'))
+ .respond(returnEntityUrl);
}
};
}]);
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js
index 914b601249..5e0f5deada 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js
@@ -56,7 +56,7 @@ function entityResource($q, $http, umbRequestHelper) {
*
* ##usage
*
- * entityResource.getPath(id)
+ * entityResource.getPath(id, type)
* .then(function(pathArray) {
* alert('its here!');
* });
@@ -77,6 +77,37 @@ function entityResource($q, $http, umbRequestHelper) {
'Failed to retrieve path for id:' + id);
},
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.entityResource#getUrl
+ * @methodOf umbraco.resources.entityResource
+ *
+ * @description
+ * Returns a url, given a node ID and type
+ *
+ * ##usage
+ *
+ * entityResource.getUrl(id, type)
+ * .then(function(url) {
+ * alert('its here!');
+ * });
+ *
+ *
+ * @param {Int} id Id of node to return the public url to
+ * @param {string} type Object type name
+ * @returns {Promise} resourcePromise object containing the url.
+ *
+ */
+ getUrl: function(id, type) {
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "entityApiBaseUrl",
+ "GetUrl",
+ [{ id: id }, {type: type }])),
+ 'Failed to retrieve url for id:' + id);
+ },
+
/**
* @ngdoc method
* @name umbraco.resources.entityResource#getById
@@ -140,7 +171,7 @@ function entityResource($q, $http, umbRequestHelper) {
query += "ids=" + item + "&";
});
- // if ids array is empty we need a empty variable in the querystring otherwise the service returns a error
+ // if ids array is empty we need a empty variable in the querystring otherwise the service returns a error
if (ids.length === 0) {
query += "ids=&";
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/minieditorhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/minieditorhelper.service.js
new file mode 100644
index 0000000000..693457c7e8
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/common/services/minieditorhelper.service.js
@@ -0,0 +1,89 @@
+(function () {
+ 'use strict';
+
+ function miniEditorHelper(dialogService, editorState, fileManager, contentEditingHelper, $q) {
+
+ var launched = false;
+
+ function launchMiniEditor(node) {
+
+ var deferred = $q.defer();
+
+ launched = true;
+
+ //We need to store the current files selected in the file manager locally because the fileManager
+ // is a singleton and is shared globally. The mini dialog will also be referencing the fileManager
+ // and we don't want it to be sharing the same files as the main editor. So we'll store the current files locally here,
+ // clear them out and then launch the dialog. When the dialog closes, we'll reset the fileManager to it's previous state.
+ var currFiles = _.groupBy(fileManager.getFiles(), "alias");
+ fileManager.clearFiles();
+
+ //We need to store the original editorState entity because it will need to change when the mini editor is loaded so that
+ // any property editors that are working with editorState get given the correct entity, otherwise strange things will
+ // start happening.
+ var currEditorState = editorState.getCurrent();
+
+ dialogService.open({
+ template: "views/common/dialogs/content/edit.html",
+ id: node.id,
+ closeOnSave: true,
+ tabFilter: ["Generic properties"],
+ callback: function (data) {
+
+ //set the node name back
+ node.name = data.name;
+
+ //reset the fileManager to what it was
+ fileManager.clearFiles();
+ _.each(currFiles, function (val, key) {
+ fileManager.setFiles(key, _.map(currFiles['upload'], function (i) { return i.file; }));
+ });
+
+ //reset the editor state
+ editorState.set(currEditorState);
+
+ //Now we need to check if the content item that was edited was actually the same content item
+ // as the main content editor and if so, update all property data
+ if (data.id === currEditorState.id) {
+ var changed = contentEditingHelper.reBindChangedProperties(currEditorState, data);
+ }
+
+ launched = false;
+
+ deferred.resolve(data);
+
+ },
+ closeCallback: function () {
+ //reset the fileManager to what it was
+ fileManager.clearFiles();
+ _.each(currFiles, function (val, key) {
+ fileManager.setFiles(key, _.map(currFiles['upload'], function (i) { return i.file; }));
+ });
+
+ //reset the editor state
+ editorState.set(currEditorState);
+
+ launched = false;
+
+ deferred.reject();
+
+ }
+ });
+
+ return deferred.promise;
+
+ }
+
+ var service = {
+ launchMiniEditor: launchMiniEditor
+ };
+
+ return service;
+
+ }
+
+
+ angular.module('umbraco.services').factory('miniEditorHelper', miniEditorHelper);
+
+
+})();
diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less
index c988f9edbb..6fbf12e815 100644
--- a/src/Umbraco.Web.UI.Client/src/less/belle.less
+++ b/src/Umbraco.Web.UI.Client/src/less/belle.less
@@ -125,6 +125,8 @@
@import "components/notifications/umb-notifications.less";
@import "components/umb-file-dropzone.less";
+@import "components/umb-node-preview.less";
+@import "components/umb-mini-editor.less";
// Utilities
@import "utilities/_flexbox.less";
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-mini-editor.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-mini-editor.less
new file mode 100644
index 0000000000..53e0dcd6b3
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-mini-editor.less
@@ -0,0 +1,33 @@
+.umb-modal .umb-mini-editor {
+
+ .umb-panel-header {
+ padding: 20px;
+ background: @grayLighter;
+ border-bottom: 1px solid @grayLight;
+ height: 59px;
+
+ .umb-headline {
+ margin-left: 0;
+ margin-right: 0;
+ margin-bottom: 0;
+ margin-top: 3px;
+ }
+ }
+
+ .umb-panel-body {
+ padding-left: 0;
+ padding-right: 0;
+ }
+
+ .umb-panel-body.with-footer {
+ bottom: 52px;
+ }
+
+ .umb-panel-footer {
+ background: @grayLighter;
+ border-top: 1px solid @grayLight;
+ height: 51px;
+ padding: 0 20px;
+ }
+
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less
new file mode 100644
index 0000000000..5b96492b48
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less
@@ -0,0 +1,98 @@
+.umb-node-preview {
+ padding: 5px 15px;
+ margin-bottom: 5px;
+ background: @grayLighter;
+ border-radius: 3px;
+ display: flex;
+ align-items: center;
+ max-width: 66.6%;
+ box-sizing: border-box;
+}
+
+.umb-node-preview--sortable {
+ cursor: move;
+}
+
+.umb-node-preview--sortable:hover {
+ border-color: #d9d9d9;
+}
+
+.umb-node-preview--unpublished {
+ .umb-node-preview__icon,
+ .umb-node-preview__name,
+ .umb-node-preview__description {
+ opacity: 0.6;
+ }
+}
+
+.umb-node-preview__icon {
+ display: flex;
+ width: 25px;
+ height: 25px;
+ justify-content: center;
+ align-items: center;
+ font-size: 20px;
+ margin-right: 10px;
+ flex: 0 0 auto;
+}
+
+.umb-node-preview__content {
+ flex: 1 1 auto;
+}
+
+.umb-node-preview__name {
+ font-size: 13px;
+ font-weight: bold;
+ color: @black;
+}
+
+.umb-node-preview__description {
+ font-size: 11px;
+ line-height: 1.5em;
+}
+
+.umb-node-preview__actions {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+}
+
+.umb-node-preview__action {
+ margin-left: 5px;
+ margin-right: 5px;
+ font-size: 13px;
+ font-weight: bold;
+ opacity: 0.5;
+}
+
+.umb-node-preview__action:hover {
+ color: @blue;
+ text-decoration: none;
+ opacity: 1;
+}
+
+.umb-node-preview-add {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px dashed #d9d9d9;
+ color: @blue;
+ font-weight: bold;
+ padding: 5px 15px;
+ max-width: 66.6%;
+ box-sizing: border-box;
+}
+
+.umb-node-preview-add:hover {
+ color: @blue;
+}
+
+.umb-overlay,
+.umb-modal {
+ .umb-node-preview {
+ max-width: none;
+ }
+ .umb-node-preview-add {
+ max-width: none;
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/less/forms.less b/src/Umbraco.Web.UI.Client/src/less/forms.less
index d046ac7104..5b6e97ad71 100644
--- a/src/Umbraco.Web.UI.Client/src/less/forms.less
+++ b/src/Umbraco.Web.UI.Client/src/less/forms.less
@@ -190,7 +190,7 @@ input[type="tel"],
input[type="color"],
.uneditable-input {
display: inline-block;
- height: @baseLineHeight;
+ height: 30px;
padding: 4px 6px;
margin-bottom: @baseLineHeight / 2;
font-size: @baseFontSize;
@@ -198,6 +198,7 @@ input[type="color"],
color: @gray;
.border-radius(@inputBorderRadius);
vertical-align: middle;
+ box-sizing: border-box;
}
input.-full-width-input {
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/content/edit.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/content/edit.html
index 55e0cad2e7..eef28aefa1 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/content/edit.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/content/edit.html
@@ -2,7 +2,8 @@
ng-controller="Umbraco.Dialogs.Content.EditController"
ng-show="loaded"
ng-submit="save()"
- val-form-manager>
+ val-form-manager
+ class="umb-mini-editor">
@@ -12,15 +13,33 @@
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/tabs/umb-tabs-nav.html b/src/Umbraco.Web.UI.Client/src/views/components/tabs/umb-tabs-nav.html
index 8522bc3b6a..808822e138 100644
--- a/src/Umbraco.Web.UI.Client/src/views/components/tabs/umb-tabs-nav.html
+++ b/src/Umbraco.Web.UI.Client/src/views/components/tabs/umb-tabs-nav.html
@@ -1,5 +1,5 @@
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-node-preview.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-node-preview.html
new file mode 100644
index 0000000000..f31f595a88
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-node-preview.html
@@ -0,0 +1,12 @@
+
+
+
+ {{ name }}
+ {{ description }}
+
+
+ Open
+ Remove
+
+
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
index 667dfd0f22..ba29b92477 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
@@ -1,7 +1,7 @@
//this controller simply tells the dialogs service to open a mediaPicker window
//with a specified callback, this callback will receive an object with a selection on it
-function contentPickerController($scope, dialogService, entityResource, editorState, $log, iconHelper, $routeParams, fileManager, contentEditingHelper, angularHelper, navigationService, $location) {
+function contentPickerController($scope, entityResource, editorState, iconHelper, $routeParams, angularHelper, navigationService, $location, miniEditorHelper) {
function trim(str, chr) {
var rgxtrim = (!chr) ? new RegExp('^\\s+|\\s+$', 'g') : new RegExp('^' + chr + '+|' + chr + '+$', 'g');
@@ -39,6 +39,9 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
else {
$scope.contentPickerForm.maxCount.$setValidity("maxCount", true);
}
+
+ setSortingState($scope.renderModel);
+
});
}
@@ -59,6 +62,14 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
}
};
+ // sortable options
+ $scope.sortableOptions = {
+ distance: 10,
+ tolerance: "pointer",
+ scroll: true,
+ zIndex: 6000
+ };
+
if ($scope.model.config) {
//merge the server config on top of the default config, then set the server config to use the result
$scope.model.config = angular.extend(defaultConfig, $scope.model.config);
@@ -75,8 +86,9 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
: $scope.model.config.startNode.type === "media"
? "Media"
: "Document";
- $scope.allowOpenButton = entityType === "Document" || entityType === "Media";
+ $scope.allowOpenButton = entityType === "Document";
$scope.allowEditButton = entityType === "Document";
+ $scope.allowRemoveButton = true;
//the dialog options for the picker
var dialogOptions = {
@@ -192,14 +204,26 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
});
if (currIds.indexOf(item.id) < 0) {
- item.icon = iconHelper.convertFromLegacyIcon(item.icon);
- $scope.renderModel.push({ name: item.name, id: item.id, icon: item.icon, path: item.path });
+ setEntityUrl(item);
}
};
$scope.clear = function () {
$scope.renderModel = [];
};
+
+ $scope.openMiniEditor = function(node) {
+ miniEditorHelper.launchMiniEditor(node).then(function(updatedNode){
+ // update the node
+ node.name = updatedNode.name;
+ node.published = updatedNode.hasPublishedVersion;
+ if(entityType !== "Member") {
+ entityResource.getUrl(updatedNode.id, entityType).then(function(data){
+ node.url = data;
+ });
+ }
+ });
+ };
var unsubscribe = $scope.$on("formSubmitting", function (ev, args) {
var currIds = _.map($scope.renderModel, function (i) {
@@ -215,26 +239,83 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
//load current data
var modelIds = $scope.model.value ? $scope.model.value.split(',') : [];
+
entityResource.getByIds(modelIds, entityType).then(function (data) {
- //Ensure we populate the render model in the same order that the ids were stored!
_.each(modelIds, function (id, i) {
var entity = _.find(data, function (d) {
return d.id == id;
});
-
+
if (entity) {
- entity.icon = iconHelper.convertFromLegacyIcon(entity.icon);
- $scope.renderModel.push({ name: entity.name, id: entity.id, icon: entity.icon, path: entity.path });
+ setEntityUrl(entity);
}
-
- });
+ });
//everything is loaded, start the watch on the model
startWatch();
});
+
+ function setEntityUrl(entity) {
+ // get url for content and media items
+ if(entityType !== "Member") {
+ entityResource.getUrl(entity.id, entityType).then(function(data){
+ // update url
+ entity.url = data;
+
+ // push item to render model
+ addSelectedItem(entity);
+ });
+ } else {
+ addSelectedItem(entity);
+ }
+ }
+
+ function addSelectedItem(item) {
+
+ // set icon
+ if(item.icon) {
+ item.icon = iconHelper.convertFromLegacyIcon(item.icon);
+ }
+
+ // set default icon
+ if (!item.icon) {
+ switch (entityType) {
+ case "Document":
+ item.icon = "icon-document";
+ break;
+ case "Media":
+ item.icon = "icon-picture";
+ break;
+ case "Member":
+ item.icon = "icon-user";
+ break;
+ }
+ }
+
+ $scope.renderModel.push({
+ "name": item.name,
+ "id": item.id,
+ "icon": item.icon,
+ "path": item.path,
+ "url": item.url,
+ "published": (item.metaData && item.metaData.IsPublished === false && entityType === "Document") ? false : true
+ // only content supports published/unpublished content so we set everything else to published so the UI looks correct
+ });
+
+ }
+
+ function setSortingState(items) {
+ // disable sorting if the list only consist of one item
+ if(items.length > 1) {
+ $scope.sortableOptions.disabled = false;
+ } else {
+ $scope.sortableOptions.disabled = true;
+ }
+ }
+
}
angular.module('umbraco').controller("Umbraco.PropertyEditors.ContentPickerController", contentPickerController);
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.html
index 9f5f3fb60f..900cf6b416 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.html
@@ -2,32 +2,28 @@
-
-
-
+
+
+
+
+
+
+ Add
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.controller.js
index 5ebbd37217..aa20a9c43b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.controller.js
@@ -8,6 +8,7 @@ function memberGroupPicker($scope, dialogService){
}
$scope.renderModel = [];
+ $scope.allowRemove = true;
if ($scope.model.value) {
var modelIds = $scope.model.value.split(',');
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.html
index 5258968c00..60ae9cb202 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.html
@@ -1,27 +1,22 @@
+
+
+
+
-
- -
-
-
-
-
-
-
- {{node.name}}
-
-
-
-
-
- -
-
-
Add
-
-
-
+
+ Add
+
-
-
-
+
+ Add
+
+ /// Gets the url of an entity
+ ///
+ /// Int id of the entity to fetch URL for
+ /// The tpye of entity such as Document, Media, Member
+ /// The URL or path to the item
+ public HttpResponseMessage GetUrl(int id, UmbracoEntityTypes type)
+ {
+ var returnUrl = string.Empty;
+
+ if (type == UmbracoEntityTypes.Document)
+ {
+ var foundUrl = Umbraco.Url(id);
+ if (string.IsNullOrEmpty(foundUrl) == false && foundUrl != "#")
+ {
+ returnUrl = foundUrl;
+
+ return new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent(returnUrl)
+ };
+ }
+ }
+
+ var ancestors = GetAncestors(id, type);
+
+ //if content, skip the first node for replicating NiceUrl defaults
+ if(type == UmbracoEntityTypes.Document) {
+ ancestors = ancestors.Skip(1);
+ }
+
+ returnUrl = "/" + string.Join("/", ancestors.Select(x => x.Name));
+
+ return new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent(returnUrl)
+ };
+ }
+
///
/// Gets an entity by it's unique id if the entity supports that
///
diff --git a/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs
index 4d58060164..be10cd83e2 100644
--- a/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs
@@ -33,17 +33,12 @@ namespace Umbraco.Web.PropertyEditors
internal class ContentPickerPreValueEditor : PreValueEditor
{
- [PreValueField("showOpenButton", "Show open button", "boolean")]
+ [PreValueField("showOpenButton", "Show open button (this feature is in preview!)", "boolean", Description = " Opens the node in a dialog")]
public string ShowOpenButton { get; set; }
-
- [PreValueField("showEditButton", "Show edit button (this feature is in preview!)", "boolean")]
- public string ShowEditButton { get; set; }
[PreValueField("startNodeId", "Start node", "treepicker")]
public int StartNodeId { get; set; }
- [PreValueField("showPathOnHover", "Show path when hovering items", "boolean")]
- public bool ShowPathOnHover { get; set; }
}
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/PropertyEditors/MultiNodeTreePickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultiNodeTreePickerPropertyEditor.cs
index b3d3f02448..82daf80e34 100644
--- a/src/Umbraco.Web/PropertyEditors/MultiNodeTreePickerPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/MultiNodeTreePickerPropertyEditor.cs
@@ -45,16 +45,9 @@ namespace Umbraco.Web.PropertyEditors
[PreValueField("maxNumber", "Maximum number of items", "number")]
public string MaxNumber { get; set; }
-
- [PreValueField("showOpenButton", "Show open button", "boolean")]
+ [PreValueField("showOpenButton", "Show open button (this feature is in preview!)", "boolean", Description = " Opens the node in a dialog")]
public string ShowOpenButton { get; set; }
- [PreValueField("showEditButton", "Show edit button (this feature is in preview!)", "boolean")]
- public string ShowEditButton { get; set; }
-
- [PreValueField("showPathOnHover", "Show path when hovering items", "boolean")]
- public bool ShowPathOnHover { get; set; }
-
///
/// This ensures the multiPicker pre-val is set based on the maxNumber of nodes set
///