Add "Move" option for deleted items in the content tree (#3772)

This commit is contained in:
Kenn Jacobsen
2018-12-19 18:19:51 +01:00
committed by Sebastiaan Janssen
parent d01dfb4ba6
commit 97f9151473
6 changed files with 189 additions and 51 deletions

View File

@@ -1,22 +1,95 @@
angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController",
function ($scope, relationResource, contentResource, navigationService, appState, treeService, localizationService) {
function ($scope, relationResource, contentResource, navigationService, appState, treeService, userService) {
var dialogOptions = $scope.dialogOptions;
var node = dialogOptions.currentNode;
$scope.source = _.clone(dialogOptions.currentNode);
$scope.error = null;
$scope.loading = true;
$scope.moving = false;
$scope.success = false;
relationResource.getByChildId(node.id, "relateParentDocumentOnDelete").then(function (data) {
$scope.dialogTreeEventHandler = $({});
$scope.searchInfo = {
showSearch: false,
results: [],
selectedSearchResults: []
}
$scope.treeModel = {
hideHeader: false
}
userService.getCurrentUser().then(function (userData) {
$scope.treeModel.hideHeader = userData.startContentIds.length > 0 && userData.startContentIds.indexOf(-1) == -1;
});
if (data.length == 0) {
$scope.success = false;
$scope.error = {
errorMsg: localizationService.localize('recycleBin_itemCannotBeRestored'),
data: {
Message: localizationService.localize('recycleBin_noRestoreRelation')
function nodeSelectHandler(ev, args) {
if (args && args.event) {
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;
}
function nodeExpandedHandler(ev, args) {
// open mini list view for list views
if (args.node.metaData.isContainer) {
openMiniListView(args.node);
}
}
$scope.hideSearch = function () {
$scope.searchInfo.showSearch = false;
$scope.searchInfo.results = [];
}
// method to select a search result
$scope.selectResult = function (evt, result) {
result.selected = result.selected === true ? false : true;
nodeSelectHandler(evt, { event: evt, node: result });
};
//callback when there are search results
$scope.onSearchResults = function (results) {
$scope.searchInfo.results = results;
$scope.searchInfo.showSearch = true;
};
$scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler);
$scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler);
$scope.$on('$destroy', function () {
$scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler);
$scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler);
});
// Mini list view
$scope.selectListViewNode = function (node) {
node.selected = node.selected === true ? false : true;
nodeSelectHandler({}, { node: node });
};
$scope.closeMiniListView = function () {
$scope.miniListView = undefined;
};
function openMiniListView(node) {
$scope.miniListView = node;
}
relationResource.getByChildId($scope.source.id, "relateParentDocumentOnDelete").then(function (data) {
$scope.loading = false;
if (!data.length) {
$scope.moving = true;
return;
}
@@ -26,38 +99,36 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController"
$scope.target = { id: -1, name: "Root" };
} else {
$scope.loading = true;
contentResource.getById($scope.relation.parentId).then(function (data) {
$scope.loading = false;
$scope.target = data;
// make sure the target item isn't in the recycle bin
if($scope.target.path.indexOf("-20") !== -1) {
$scope.error = {
errorMsg: localizationService.localize('recycleBin_itemCannotBeRestored'),
data: {
Message: localizationService.localize('recycleBin_restoreUnderRecycled').then(function (value) {
value.replace('%0%', $scope.target.name);
})
if ($scope.target.path.indexOf("-20") !== -1) {
$scope.moving = true;
$scope.target = null;
}
};
$scope.success = false;
}
}, function (err) {
$scope.success = false;
$scope.loading = false;
$scope.error = err;
});
}
}, function (err) {
$scope.success = false;
$scope.loading = false;
$scope.error = err;
});
$scope.restore = function () {
$scope.loading = true;
// this code was copied from `content.move.controller.js`
contentResource.move({ parentId: $scope.target.id, id: node.id })
contentResource.move({ parentId: $scope.target.id, id: $scope.source.id })
.then(function (path) {
$scope.loading = false;
$scope.success = true;
//first we need to remove the node that launched the dialog
@@ -78,7 +149,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController"
});
}, function (err) {
$scope.success = false;
$scope.loading = false;
$scope.error = err;
});
};

View File

@@ -1,26 +1,92 @@
<div ng-controller="Umbraco.Editors.Content.RestoreController">
<div class="umb-dialog-body">
<div class="umb-dialog-body" ng-cloak>
<umb-pane>
<umb-load-indicator
ng-if="loading">
</umb-load-indicator>
<p class="abstract" ng-hide="error != null || success == true">
<localize key="actions_restore">Restore</localize> <strong>{{currentNode.name}}</strong> <localize key="general_under">under</localize> <strong>{{target.name}}</strong>?
</p>
<div class="alert alert-error" ng-show="error != null">
<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>
<span ng-hide="moving"><localize key="recycleBin_wasRestored">was restored under</localize></span>
<span ng-show="moving"><localize key="editdatatype_wasMoved">was moved underneath</localize></span>
<strong>{{target.name}}</strong>
</div>
<button class="btn btn-primary" ng-click="nav.hideDialog()">Ok</button>
</div>
<div ng-hide="moving || loading || success">
<p class="abstract" ng-hide="error || success">
<localize key="actions_restore">Restore</localize> <strong>{{source.name}}</strong> <localize key="general_under">under</localize> <strong>{{target.name}}</strong>?
</p>
</div>
<div ng-hide="!moving || loading || success">
<div>
<div class="alert alert-info">
<div><strong><localize key="recycleBin_itemCannotBeRestored">Cannot automatically restore this item</localize></strong></div>
<div><localize key="recycleBin_itemCannotBeRestoredHelpText">There is no location where this item can be automatically restored. You can move the item manually using the tree below.</localize></div>
</div>
</div>
<div ng-hide="miniListView">
<umb-tree-search-box
hide-search-callback="hideSearch"
search-callback="onSearchResults"
show-search="{{searchInfo.showSearch}}"
section="content">
</umb-tree-search-box>
<br />
<umb-tree-search-results
ng-if="searchInfo.showSearch"
results="searchInfo.results"
select-result-callback="selectResult">
</umb-tree-search-results>
<div ng-hide="searchInfo.showSearch">
<umb-tree
section="content"
hideheader="{{treeModel.hideHeader}}"
hideoptions="true"
isdialog="true"
eventhandler="dialogTreeEventHandler"
enablelistviewexpand="true"
enablecheckboxes="true">
</umb-tree>
</div>
</div>
<umb-mini-list-view
ng-if="miniListView"
node="miniListView"
entity-type="Document"
on-select="selectListViewNode(node)"
on-close="closeMiniListView()">
</umb-mini-list-view>
<div class="alert alert-success" ng-show="success == true">
<p><strong>{{currentNode.name}}</strong> <localize key="editdatatype_wasMoved">was moved underneath</localize> <strong>{{target.name}}</strong></p>
<button class="btn btn-primary" ng-click="nav.hideDialog()"><localize key="general_ok">OK</localize></button>
</div>
</umb-pane>
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success == true">
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="loading || moving || success">
<a class="btn btn-link" ng-click="nav.hideDialog()"><localize key="general_cancel">Cancel</localize></a>
<button class="btn btn-primary" ng-click="restore()" ng-show="error == null"><localize key="actions_restore">Restore</localize></button>
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="loading || !moving || success">
<a class="btn btn-link" ng-click="nav.hideDialog()"><localize key="general_cancel">Cancel</localize></a>
<button class="btn btn-primary" ng-click="restore()" ng-show="error == null" ng-disabled="!target"><localize key="actions_move">Move</localize></button>
</div>
</div>

View File

@@ -1622,8 +1622,8 @@ Mange hilsner fra Umbraco robotten
<area alias="recycleBin">
<key alias="contentTrashed">Slettet indhold med Id: {0} Relateret til original "parent" med id: {1}</key>
<key alias="mediaTrashed">Slettet medie med Id: {0} relateret til original "parent" / mappe med id: {1}</key>
<key alias="itemCannotBeRestored">Kan ikke automatisk genoprette dette dokument/medie</key>
<key alias="noRestoreRelation">Der findes ikke nogen "Genopret" relation for dette dokument/medie. Brug "Flyt" muligheden fra menuen for at flytte det manuelt.</key>
<key alias="restoreUnderRecycled">Det dokument/medie du ønsker at genoprette under ('%0%') er i skraldespanden. Brug "Flyt" muligheden fra menuen for at flytte det manuelt.</key>
<key alias="itemCannotBeRestored">Kan ikke automatisk genoprette dette element</key>
<key alias="itemCannotBeRestoredHelpText">Der er ikke nogen placering hvor dette element automatisk kan genoprettes. Du kan flytte elementet manuelt i træet nedenfor.</key>
<key alias="wasRestored">blev genoprettet under</key>
</area>
</language>

View File

@@ -2224,7 +2224,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="contentTrashed">Trashed content with Id: {0} related to original parent content with Id: {1}</key>
<key alias="mediaTrashed">Trashed media with Id: {0} related to original parent media item with Id: {1}</key>
<key alias="itemCannotBeRestored">Cannot automatically restore this item</key>
<key alias="noRestoreRelation">There is no 'restore' relation found for this node. Use the Move menu item to move it manually.</key>
<key alias="restoreUnderRecycled">The item you want to restore it under ('%0%') is in the recycle bin. Use the Move menu item to move the item manually.</key>
<key alias="itemCannotBeRestoredHelpText">There is no location where this item can be automatically restored. You can move the item manually using the tree below.</key>
<key alias="wasRestored">was restored under</key>
</area>
</language>

View File

@@ -2217,8 +2217,8 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="contentTrashed">Trashed content with Id: {0} related to original parent content with Id: {1}</key>
<key alias="mediaTrashed">Trashed media with Id: {0} related to original parent media item with Id: {1}</key>
<key alias="itemCannotBeRestored">Cannot automatically restore this item</key>
<key alias="noRestoreRelation">There is no 'restore' relation found for this node. Use the Move menu item to move it manually.</key>
<key alias="restoreUnderRecycled">The item you want to restore it under ('%0%') is in the recycle bin. Use the Move menu item to move the item manually.</key>
<key alias="itemCannotBeRestoredHelpText">There is no location where this item can be automatically restored. You can move the item manually using the tree below.</key>
<key alias="wasRestored">was restored under</key>
</area>
<area alias="notify">
<key alias="notifySet">Select your notifications for</key>

View File

@@ -255,6 +255,7 @@ namespace Umbraco.Web.Trees
{
var menu = new MenuItemCollection();
menu.Items.Add<ActionRestore>(ui.Text("actions", ActionRestore.Instance.Alias));
menu.Items.Add<ActionMove>(ui.Text("actions", ActionMove.Instance.Alias));
menu.Items.Add<ActionDelete>(ui.Text("actions", ActionDelete.Instance.Alias));
menu.Items.Add<RefreshNode, ActionRefresh>(ui.Text("actions", ActionRefresh.Instance.Alias), true);