Skip to content

Commit

Permalink
Copy member type (umbraco#10020)
Browse files Browse the repository at this point in the history
* Add copy dialog for member type

* Implement copy action for member type

* Create specific localization for content type, media type and member type

* Handle "foldersonly" querystring

* Add button type attribute

* Add a few missing changes of anchor to button element
  • Loading branch information
bjarnef authored Mar 21, 2021
1 parent 691c5d3 commit 046d635
Show file tree
Hide file tree
Showing 18 changed files with 221 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -432,13 +432,15 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter, loca
throw "args.id cannot be null";
}

var promise = localizationService.localize("contentType_moveFailed");

return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostMove"),
{
parentId: args.parentId,
id: args.id
}, { responseType: 'text' }),
'Failed to move content');
promise);
},

/**
Expand Down Expand Up @@ -475,13 +477,15 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter, loca
throw "args.id cannot be null";
}

var promise = localizationService.localize("contentType_copyFailed");

return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostCopy"),
{
parentId: args.parentId,
id: args.id
}, { responseType: 'text' }),
'Failed to copy content');
promise);
},

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter, locali
throw "args.id cannot be null";
}

var promise = localizationService.localize("media_moveFailed");
var promise = localizationService.localize("mediaType_moveFailed");

return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostMove"),
Expand All @@ -230,7 +230,7 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter, locali
throw "args.id cannot be null";
}

var promise = localizationService.localize("media_copyFailed");
var promise = localizationService.localize("mediaType_copyFailed");

return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostCopy"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @name umbraco.resources.memberTypeResource
* @description Loads in data for member types
**/
function memberTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
function memberTypeResource($q, $http, umbRequestHelper, umbDataFormatter, localizationService) {

return {

Expand Down Expand Up @@ -102,8 +102,29 @@ function memberTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("memberTypeApiBaseUrl", "PostSave"), saveModel),
'Failed to save data for member type id ' + contentType.id);
}
},

copy: function (args) {
if (!args) {
throw "args cannot be null";
}
if (!args.parentId) {
throw "args.parentId cannot be null";
}
if (!args.id) {
throw "args.id cannot be null";
}

var promise = localizationService.localize("memberType_copyFailed");

return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("memberTypeApiBaseUrl", "PostCopy"),
{
parentId: args.parentId,
id: args.id
}, { responseType: 'text' }),
promise);
}
};
}
angular.module('umbraco.resources').factory('memberTypeResource', memberTypeResource);
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<div class="alert alert-success">
<strong>{{source.name}}</strong> <localize key="contentTypeEditor_copiedUnderneath">was copied underneath</localize>&nbsp;<strong>{{target.name}}</strong>
</div>
<button class="btn btn-primary" ng-click="close()">Ok</button>
<button type="button" class="btn btn-primary" ng-click="close()">Ok</button>
</div>

<div ng-hide="success">
Expand Down
4 changes: 2 additions & 2 deletions src/Umbraco.Web.UI.Client/src/views/documenttypes/export.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div class="umb-dialog umb-pane" ng-controller="Umbraco.Editors.DocumentTypes.ExportController">
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
<a class="btn btn-link" ng-click="cancel()">
<button type="button" class="btn btn-link" ng-click="cancel()">
<localize key="general_cancel">Cancel</localize>
</a>
</button>
<button class="btn btn-primary" ng-click="export()">
<localize key="actions_export">Export</localize>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@

<localize key="general_or">or</localize>

<a class="btn-link" ng-click="close()">
<button type="button" class="btn-link" ng-click="close()">
<localize key="cancel">Cancel</localize>
</a>
</button>
</form>

<div ng-if="importDoctype.file.$error.pattern">Please choose a .udt file to import</div>



</div>
<div ng-if="vm.state === 'confirm'">
<strong>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<div class="alert alert-success">
<strong>{{source.name}}</strong> <localize key="contentTypeEditor_movedUnderneath">was moved underneath</localize>&nbsp;<strong>{{target.name}}</strong>
</div>
<button class="btn btn-primary" ng-click="close()">Ok</button>
<button type="button" class="btn btn-primary" ng-click="close()">Ok</button>
</div>

<div ng-hide="success">
Expand Down
2 changes: 1 addition & 1 deletion src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<div class="alert alert-success">
<strong>{{source.name}}</strong> <localize key="contentTypeEditor_copiedUnderneath">was copied underneath</localize>&nbsp;<strong>{{target.name}}</strong>
</div>
<button class="btn btn-primary" ng-click="close()">Ok</button>
<button type="button" class="btn btn-primary" ng-click="close()">Ok</button>
</div>

<div ng-hide="success">
Expand Down
2 changes: 1 addition & 1 deletion src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<div class="alert alert-success">
<strong>{{source.name}}</strong> <localize key="contentTypeEditor_movedUnderneath">was moved underneath</localize>&nbsp;<strong>{{target.name}}</strong>
</div>
<button class="btn btn-primary" ng-click="close()">Ok</button>
<button type="button" class="btn btn-primary" ng-click="close()">Ok</button>
</div>

<div ng-hide="success">
Expand Down
61 changes: 61 additions & 0 deletions src/Umbraco.Web.UI.Client/src/views/membertypes/copy.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
angular.module("umbraco")
.controller("Umbraco.Editors.MemberTypes.CopyController",
function ($scope, memberTypeResource, treeService, navigationService, notificationsService, appState, eventsService) {

$scope.dialogTreeApi = {};
$scope.source = _.clone($scope.currentNode);

function nodeSelectHandler(args) {
args.event.preventDefault();
args.event.stopPropagation();

if ($scope.target) {
//un-select if there's a current one selected
$scope.target.selected = false;
}

$scope.target = args.node;
$scope.target.selected = true;
}

$scope.copy = function () {

$scope.busy = true;
$scope.error = false;

memberTypeResource.copy({ parentId: $scope.target.id, id: $scope.source.id })
.then(function (path) {
$scope.error = false;
$scope.success = true;
$scope.busy = false;

//get the currently edited node (if any)
var activeNode = appState.getTreeState("selectedNode");

//we need to do a double sync here: first sync to the copied content - but don't activate the node,
//then sync to the currenlty edited content (note: this might not be the content that was copied!!)

navigationService.syncTree({ tree: "memberTypes", path: path, forceReload: true, activate: false }).then(function (args) {
if (activeNode) {
var activeNodePath = treeService.getPath(activeNode).join();
//sync to this node now - depending on what was copied this might already be synced but might not be
navigationService.syncTree({ tree: "memberTypes", path: activeNodePath, forceReload: false, activate: true });
}
});

}, function (err) {
$scope.success = false;
$scope.error = err;
$scope.busy = false;
});
};

$scope.onTreeInit = function () {
$scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler);
};

$scope.close = function() {
navigationService.hideDialog();
};

});
53 changes: 53 additions & 0 deletions src/Umbraco.Web.UI.Client/src/views/membertypes/copy.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<div class="umb-dialog" ng-controller="Umbraco.Editors.MemberTypes.CopyController">

<div class="umb-dialog-body">
<div class="umb-pane">

<p class="abstract" ng-hide="success">
<localize key="contentTypeEditor_folderToCopy">Select the folder to copy</localize> <strong>{{source.name}}</strong>&nbsp;<localize key="contentTypeEditor_structureBelow">to in the tree structure below</localize>
</p>

<umb-loader ng-show="busy"></umb-loader>

<div ng-show="error">
<div class="alert alert-error">
<div><strong>{{error.errorMsg}}</strong></div>
<div>{{error.data.message}}</div>
</div>
</div>

<div ng-show="success">
<div class="alert alert-success">
<strong>{{source.name}}</strong> <localize key="contentTypeEditor_copiedUnderneath">was copied underneath</localize>&nbsp;<strong>{{target.name}}</strong>
</div>
<button type="button" class="btn btn-primary" ng-click="close()">Ok</button>
</div>

<div ng-hide="success">

<div>
<umb-tree section="settings"
treealias="memberTypes"
customtreeparams="foldersonly=1"
hideheader="false"
hideoptions="true"
isdialog="true"
api="dialogTreeApi"
on-init="onTreeInit()"
enablecheckboxes="true">
</umb-tree>
</div>

</div>
</div>
</div>

<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success">
<button type="button" class="btn btn-link" ng-click="close()" ng-show="!busy">
<localize key="general_cancel">Cancel</localize>
</button>
<button class="btn btn-primary" ng-click="copy()" ng-disabled="busy || !target">
<localize key="actions_copy">Copy</localize>
</button>
</div>
</div>
11 changes: 11 additions & 0 deletions src/Umbraco.Web.UI/Umbraco/config/lang/da.xml
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,17 @@
<key alias="allMembers">Alle medlemmer</key>
<key alias="memberGroupNoProperties">Medlemgrupper har ingen yderligere egenskaber til redigering.</key>
</area>
<area alias="contentType">
<key alias="copyFailed">Kopiering af indholdstypen fejlede</key>
<key alias="moveFailed">Flytning af indholdstypen fejlede</key>
</area>
<area alias="mediaType">
<key alias="copyFailed">Kopiering af medietypen fejlede</key>
<key alias="moveFailed">Flytning af medietypen fejlede</key>
</area>
<area alias="memberType">
<key alias="copyFailed">Kopiering af medlemstypen fejlede</key>
</area>
<area alias="create">
<key alias="chooseNode">Hvor ønsker du at oprette den nye %0%</key>
<key alias="createUnder">Opret under</key>
Expand Down
11 changes: 11 additions & 0 deletions src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,17 @@
<key alias="allMembers">All Members</key>
<key alias="memberGroupNoProperties">Member groups have no additional properties for editing.</key>
</area>
<area alias="contentType">
<key alias="copyFailed">Failed to copy content type</key>
<key alias="moveFailed">Failed to move content type</key>
</area>
<area alias="mediaType">
<key alias="copyFailed">Failed to copy media type</key>
<key alias="moveFailed">Failed to move media type</key>
</area>
<area alias="memberType">
<key alias="copyFailed">Failed to copy member type</key>
</area>
<area alias="create">
<key alias="chooseNode">Where do you want to create the new %0%</key>
<key alias="createUnder">Create an item under</key>
Expand Down
11 changes: 11 additions & 0 deletions src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,17 @@
<key alias="allMembers">All Members</key>
<key alias="memberGroupNoProperties">Member groups have no additional properties for editing.</key>
</area>
<area alias="contentType">
<key alias="copyFailed">Failed to copy content type</key>
<key alias="moveFailed">Failed to move content type</key>
</area>
<area alias="mediaType">
<key alias="copyFailed">Failed to copy media type</key>
<key alias="moveFailed">Failed to move media type</key>
</area>
<area alias="memberType">
<key alias="copyFailed">Failed to copy member type</key>
</area>
<area alias="create">
<key alias="chooseNode">Where do you want to create the new %0%</key>
<key alias="createUnder">Create an item under</key>
Expand Down
11 changes: 11 additions & 0 deletions src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,17 @@
<key alias="allMembers">Tous les membres</key>
<key alias="memberGroupNoProperties">Les groupes de membres n'ont pas de propriétés supplémentaires modifiables.</key>
</area>
<area alias="contentType">
<key alias="copyFailed">Echec de la copie du type de contenu</key>
<key alias="moveFailed">Echec du déplacement du type de contenu</key>
</area>
<area alias="mediaType">
<key alias="copyFailed">Echec de la copie du type de media</key>
<key alias="moveFailed">Echec du déplacement du type de media</key>
</area>
<area alias="memberType">
<key alias="copyFailed">Echec de la copie du type de membre</key>
</area>
<area alias="create">
<key alias="chooseNode">Où voulez-vous créer le nouveau %0%</key>
<key alias="createUnder">Créer un élément sous</key>
Expand Down
12 changes: 12 additions & 0 deletions src/Umbraco.Web/Editors/MemberTypeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,18 @@ public MemberTypeDisplay PostSave(MemberTypeSave contentTypeSave)
return display;
}

/// <summary>
/// Copy the member type
/// </summary>
/// <param name="copy"></param>
/// <returns></returns>
public HttpResponseMessage PostCopy(MoveOrCopy copy)
{
return PerformCopy(
copy,
getContentType: i => Services.MemberTypeService.Get(i),
doCopy: (type, i) => Services.MemberTypeService.Copy(type, i));
}

}
}
12 changes: 11 additions & 1 deletion src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ public abstract class MemberTypeAndGroupTreeControllerBase : TreeController
protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
{
var nodes = new TreeNodeCollection();

// if the request is for folders only then just return
if (queryStrings["foldersonly"].IsNullOrWhiteSpace() == false && queryStrings["foldersonly"] == "1") return nodes;

nodes.AddRange(GetTreeNodesFromService(id, queryStrings));
return nodes;
}
Expand All @@ -30,7 +34,13 @@ protected override MenuItemCollection GetMenuForNode(string id, FormDataCollecti
}
else
{
//delete member type/group
var memberType = Services.MemberTypeService.Get(int.Parse(id));
if (memberType != null)
{
menu.Items.Add<ActionCopy>(Services.TextService, opensDialog: true);
}

// delete member type/group
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
}

Expand Down
1 change: 1 addition & 0 deletions src/Umbraco.Web/Trees/MemberTypeTreeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ protected override TreeNode CreateRootNode(FormDataCollection queryStrings)
root.HasChildren = Services.MemberTypeService.GetAll().Any();
return root;
}

protected override IEnumerable<TreeNode> GetTreeNodesFromService(string id, FormDataCollection queryStrings)
{
return Services.MemberTypeService.GetAll()
Expand Down

0 comments on commit 046d635

Please sign in to comment.