Added dictionary import/export (#12378)

* Added dictionary import/export

* Added umb tree to dictionary import & level for displaying preview dictionary import

* Indented dictionaries for import, added new text for choosing where to import dictionary items

* Removed console.log for dictionary/import.controller.js

Co-authored-by: Michael <michael@crossingpaths.be>
This commit is contained in:
Johannes Lantz
2022-06-17 10:21:01 +02:00
committed by GitHub
parent 2f4feb925a
commit d42a695e8a
12 changed files with 461 additions and 2 deletions

View File

@@ -160,6 +160,77 @@ function dictionaryResource($q, $http, $location, umbRequestHelper, umbDataForma
"Failed to save data for dictionary id " + dictionary.id);
}
/**
* @ngdoc method
* @name umbraco.resources.dictionaryResource#export
* @methodOf umbraco.resources.dictionaryResource
*
* @description
* Export dictionary items of a given id.
*
* ##usage
* <pre>
* dictionaryResource.exportItem(1234){
* .then(function() {
* Do stuff..
* });
* </pre>
*
* @param {Int} id the ID of the dictionary item so export
* @param {Bool?} includeChildren if children should also be exported
* @returns {Promise} resourcePromise object.
*
*/
function exportItem(id, includeChildren) {
if (!id) {
throw "id cannot be null";
}
var url = umbRequestHelper.getApiUrl("dictionaryApiBaseUrl", "ExportDictionary", { id: id, includeChildren: includeChildren });
return umbRequestHelper.downloadFile(url).then(function () {
localizationService.localize("speechBubbles_dictionaryItemExportedSuccess").then(function(value) {
notificationsService.success(value);
});
}, function (data) {
localizationService.localize("speechBubbles_dictionaryItemExportedError").then(function(value) {
notificationsService.error(value);
});
});
}
/**
* @ngdoc method
* @name umbraco.resources.dictionaryResource#import
* @methodOf umbraco.resources.dictionaryResource
*
* @description
* Import a dictionary item from a file
*
* ##usage
* <pre>
* dictionaryResource.importItem("path to file"){
* .then(function() {
* Do stuff..
* });
* </pre>
*
* @param {String} file path of the file to import
* @param {Int?} parentId the int of the parent dictionary item to move incomming dictionary items to
* @returns {Promise} resourcePromise object.
*
*/
function importItem(file, parentId) {
if (!file) {
throw "file cannot be null";
}
return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("dictionaryApiBaseUrl", "ImportDictionary", { file: file, parentId: parentId })),
"Failed to import dictionary item " + file
);
}
/**
* @ngdoc method
* @name umbraco.resources.dictionaryResource#getList
@@ -194,6 +265,8 @@ function dictionaryResource($q, $http, $location, umbRequestHelper, umbDataForma
getById: getById,
save: save,
move: move,
exportItem: exportItem,
importItem: importItem,
getList : getList
};

View File

@@ -0,0 +1,18 @@
angular.module("umbraco")
.controller("Umbraco.Editors.Dictionary.ExportController",
function ($scope, dictionaryResource, navigationService) {
$scope.includeChildren = false;
$scope.toggleHandler = function () {
$scope.includeChildren = !$scope.includeChildren
};
$scope.export = function () {
dictionaryResource.exportItem($scope.currentNode.id, $scope.includeChildren);
navigationService.hideMenu();
};
$scope.cancel = function () {
navigationService.hideDialog();
};
});

View File

@@ -0,0 +1,17 @@
<div class="umb-dialog umb-pane" ng-controller="Umbraco.Editors.Dictionary.ExportController">
<div class="umb-dialog-body form-horizontal" ng-cloak>
<umb-pane>
<umb-control-group localize="label" label="@defaultdialogs_includeDescendants">
<umb-toggle checked="includeChildren" on-click="toggleHandler()"></umb-toggle>
</umb-control-group>
</umb-pane>
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
<button type="button" class="btn btn-link" ng-click="cancel()">
<localize key="general_cancel">Cancel</localize>
</button>
<button class="btn btn-primary" ng-click="export()">
<localize key="actions_export">Export</localize>
</button>
</div>
</div>

View File

@@ -0,0 +1,67 @@
angular.module("umbraco")
.controller("Umbraco.Editors.Dictionary.ImportController",
function ($scope, dictionaryResource, notificationsService, navigationService, Upload, umbRequestHelper) {
var vm = this;
vm.state = "upload";
vm.model = {};
vm.uploadStatus = "";
vm.cancelButtonLabel = "cancel";
$scope.dialogTreeApi = {};
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.handleFiles = function (files, event, invalidFiles) {
if (files && files.length > 0) {
$scope.upload(files[0]);
}
};
$scope.upload = function (file) {
Upload.upload({
url: umbRequestHelper.getApiUrl("dictionaryApiBaseUrl", "Upload"),
fields: {},
file: file
}).then(function (response) {
vm.model = response.data;
vm.state = "confirm";
vm.uploadStatus = "done";
}, function (err) {
notificationsService.error(err.data.notifications[0].header, err.data.notifications[0].message);
});
};
$scope.import = function () {
var parentId = $scope.target !== undefined ? $scope.target.id : 0;
dictionaryResource.importItem(vm.model.tempFileName, parentId).then(function (path) {
navigationService.syncTree({ tree: "dictionary", path: path, forceReload: true, activate: false });
vm.state = "done";
vm.cancelButtonLabel = "general_close";
});
};
$scope.onTreeInit = function () {
$scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler);
};
$scope.close = function () {
navigationService.hideDialog();
};
});

View File

@@ -0,0 +1,81 @@
<div class="umb-dialog" ng-controller="Umbraco.Editors.Dictionary.ImportController as vm">
<div class="umb-dialog-body with-footer">
<div class="umb-pane">
<div ng-if="vm.state === 'upload'">
<p>
<localize key="dictionary_importDictionaryItemHelp">
To import a Dictionary item, find the '.udt' file on your computer by clicking the 'Import' button (you'll be
asked for confirmation on the next screen)
</localize>
</p>
<form name="importDictionaryItem">
<!-- Select files -->
<button accept=".udt"
class="btn btn-action"
name="file"
ng-model="filesHolder"
ngf-change="handleFiles($files, $event, $invalidFiles)"
ngf-multiple="true"
ngf-pattern="*.udt"
ngf-select>
<localize key="general_import">Import</localize>
</button>
</form>
</div>
<div ng-if="vm.state === 'confirm'">
<strong>
<localize key="dictionaryListCaption">Dictionary items</localize>
:
</strong>
<div ng-repeat="dictionaryItem in vm.model.dictionaryItems" style="padding-left:{{dictionaryItem.level * 20}}px;">{{dictionaryItem.name}}</div>
<br />
<br />
<div>
<hr />
<p>
<strong>
<localize key="actions_chooseWhereToImport">Chose where to import</localize>
<localize key="dictionaryListCaption">dictionary items</localize>.
</strong>
(optinal)
</p>
<umb-tree section="translation"
treealias="dictionary"
customtreeparams="foldersonly=1"
hideheader="false"
hideoptions="true"
isdialog="true"
api="dialogTreeApi"
on-init="onTreeInit()"
enablecheckboxes="true">
</umb-tree>
</div>
<button class="btn btn-primary" ng-click="import()">
<localize key="general_import">Import</localize>
</button>
</div>
<div ng-if="vm.state === 'done'">
<strong>
<localize key="speechBubbles_dictionaryItemImported">The following dictionary item(s) has been imported!</localize>
</strong>
<div ng-repeat="dictionaryItem in vm.model.dictionaryItems" style="padding-left:{{dictionaryItem.level * 20}}px;">{{dictionaryItem.name}}</div>
</div>
</div>
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
<umb-button action="close()"
button-style="link"
label-key="{{vm.cancelButtonLabel}}"
type="button">
</umb-button>
</div>
</div>