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:
@@ -36,6 +36,7 @@
|
||||
<key alias="restore" version="7.3.0">Restore</key>
|
||||
<key alias="chooseWhereToCopy">Choose where to copy</key>
|
||||
<key alias="chooseWhereToMove">Choose where to move</key>
|
||||
<key alias="chooseWhereToImport">Choose where to import</key>
|
||||
<key alias="toInTheTreeStructureBelow">to in the tree structure below</key>
|
||||
<key alias="infiniteEditorChooseWhereToCopy">Choose where to copy the selected item(s)</key>
|
||||
<key alias="infiniteEditorChooseWhereToMove">Choose where to move the selected item(s)</key>
|
||||
@@ -569,9 +570,14 @@
|
||||
<key alias="deletingALayout">Modifying layout will result in loss of data for any existing content that is based on this configuration.</key>
|
||||
</area>
|
||||
<area alias="dictionary">
|
||||
<key alias="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)
|
||||
</key>
|
||||
<key alias="itemDoesNotExists">Dictionary item does not exist.</key>
|
||||
<key alias="parentDoesNotExists">Parent item does not exist.</key>
|
||||
<key alias="noItems">There are no dictionary items.</key>
|
||||
<key alias="noItemsInFile">There are no dictionary items in this file.</key>
|
||||
<key alias="createNew">Create dictionary item</key>
|
||||
</area>
|
||||
<area alias="dictionaryItem">
|
||||
@@ -1592,6 +1598,9 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
|
||||
<key alias="resendInviteSuccess">Invitation has been re-sent to %0%</key>
|
||||
<key alias="documentTypeExportedSuccess">Document Type was exported to file</key>
|
||||
<key alias="documentTypeExportedError">An error occurred while exporting the Document Type</key>
|
||||
<key alias="dictionaryItemExportedSuccess">Dictionary item(s) was exported to file</key>
|
||||
<key alias="dictionaryItemExportedError">An error occurred while exporting the dictionary item(s)</key>
|
||||
<key alias="dictionaryItemImported">The following dictionary item(s) has been imported!</key>
|
||||
<key alias="publishWithNoDomains">Domains are not configured for multilingual site, please contact an administrator,
|
||||
see log for more information
|
||||
</key>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<key alias="restore" version="7.3.0">Restore</key>
|
||||
<key alias="chooseWhereToCopy">Choose where to copy</key>
|
||||
<key alias="chooseWhereToMove">Choose where to move</key>
|
||||
<key alias="chooseWhereToImport">Choose where to import</key>
|
||||
<key alias="toInTheTreeStructureBelow">to in the tree structure below</key>
|
||||
<key alias="infiniteEditorChooseWhereToCopy">Choose where to copy the selected item(s)</key>
|
||||
<key alias="infiniteEditorChooseWhereToMove">Choose where to move the selected item(s)</key>
|
||||
@@ -579,9 +580,14 @@
|
||||
<key alias="deletingALayout">Modifying layout will result in loss of data for any existing content that is based on this configuration.</key>
|
||||
</area>
|
||||
<area alias="dictionary">
|
||||
<key alias="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)
|
||||
</key>
|
||||
<key alias="itemDoesNotExists">Dictionary item does not exist.</key>
|
||||
<key alias="parentDoesNotExists">Parent item does not exist.</key>
|
||||
<key alias="noItems">There are no dictionary items.</key>
|
||||
<key alias="noItemsInFile">There are no dictionary items in this file.</key>
|
||||
<key alias="createNew">Create dictionary item</key>
|
||||
</area>
|
||||
<area alias="dictionaryItem">
|
||||
@@ -1629,6 +1635,9 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
|
||||
<key alias="contentCultureValidationError">Validation failed for language '%0%'</key>
|
||||
<key alias="documentTypeExportedSuccess">Document Type was exported to file</key>
|
||||
<key alias="documentTypeExportedError">An error occurred while exporting the Document Type</key>
|
||||
<key alias="dictionaryItemExportedSuccess">Dictionary item(s) was exported to file</key>
|
||||
<key alias="dictionaryItemExportedError">An error occurred while exporting the dictionary item(s)</key>
|
||||
<key alias="dictionaryItemImported">The following dictionary item(s) has been imported!</key>
|
||||
<key alias="scheduleErrReleaseDate1">The release date cannot be in the past</key>
|
||||
<key alias="scheduleErrReleaseDate2">Cannot schedule the document for publishing since the required '%0%' is not
|
||||
published
|
||||
|
||||
14
src/Umbraco.Core/Models/DictionaryImportModel.cs
Normal file
14
src/Umbraco.Core/Models/DictionaryImportModel.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models
|
||||
{
|
||||
[DataContract(Name = "dictionaryImportModel")]
|
||||
public class DictionaryImportModel
|
||||
{
|
||||
[DataMember(Name = "dictionaryItems")]
|
||||
public List<DictionaryPreviewImportModel>? DictionaryItems { get; set; }
|
||||
|
||||
[DataMember(Name = "tempFileName")]
|
||||
public string? TempFileName { get; set; }
|
||||
}
|
||||
}
|
||||
14
src/Umbraco.Core/Models/DictionaryPreviewImportModel.cs
Normal file
14
src/Umbraco.Core/Models/DictionaryPreviewImportModel.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models
|
||||
{
|
||||
[DataContract(Name = "dictionaryPreviewImportModel")]
|
||||
public class DictionaryPreviewImportModel
|
||||
{
|
||||
[DataMember(Name = "name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[DataMember(Name = "level")]
|
||||
public int Level { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1355,6 +1355,12 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
return ImportDictionaryItems(dictionaryItemElementList, languages, null, userId);
|
||||
}
|
||||
|
||||
public IEnumerable<IDictionaryItem> ImportDictionaryItem(XElement dictionaryItemElement, int userId, Guid? parentId)
|
||||
{
|
||||
var languages = _localizationService.GetAllLanguages().ToList();
|
||||
return ImportDictionaryItem(dictionaryItemElement, languages, parentId, userId);
|
||||
}
|
||||
|
||||
private IReadOnlyList<IDictionaryItem> ImportDictionaryItems(IEnumerable<XElement> dictionaryItemElementList,
|
||||
List<ILanguage> languages, Guid? parentId, int userId)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -14,12 +15,16 @@ using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.Common.Attributes;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Cms.Infrastructure.Packaging;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
{
|
||||
@@ -42,6 +47,9 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly ILocalizedTextService _localizedTextService;
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
private readonly IEntityXmlSerializer _serializer;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
private readonly PackageDataInstallation _packageDataInstallation;
|
||||
|
||||
public DictionaryController(
|
||||
ILogger<DictionaryController> logger,
|
||||
@@ -49,7 +57,10 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
IOptionsSnapshot<GlobalSettings> globalSettings,
|
||||
ILocalizedTextService localizedTextService,
|
||||
IUmbracoMapper umbracoMapper
|
||||
IUmbracoMapper umbracoMapper,
|
||||
IEntityXmlSerializer serializer,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
PackageDataInstallation packageDataInstallation
|
||||
)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
@@ -58,6 +69,9 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
_globalSettings = globalSettings.Value ?? throw new ArgumentNullException(nameof(globalSettings));
|
||||
_localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService));
|
||||
_umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper));
|
||||
_serializer = serializer ?? throw new ArgumentNullException(nameof(serializer));
|
||||
_hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
|
||||
_packageDataInstallation = packageDataInstallation ?? throw new ArgumentNullException(nameof(packageDataInstallation));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -354,6 +368,126 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
public IActionResult ExportDictionary(int id, bool includeChildren = false)
|
||||
{
|
||||
var dictionaryItem = _localizationService.GetDictionaryItemById(id);
|
||||
if (dictionaryItem == null)
|
||||
throw new NullReferenceException("No dictionary item found with id " + id);
|
||||
|
||||
var xml = _serializer.Serialize(dictionaryItem, includeChildren);
|
||||
|
||||
var fileName = $"{dictionaryItem.ItemKey}.udt";
|
||||
// Set custom header so umbRequestHelper.downloadFile can save the correct filename
|
||||
HttpContext.Response.Headers.Add("x-filename", fileName);
|
||||
|
||||
return File(Encoding.UTF8.GetBytes(xml.ToDataString()), MediaTypeNames.Application.Octet, fileName);
|
||||
}
|
||||
|
||||
public IActionResult ImportDictionary(string file, int parentId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(file))
|
||||
return NotFound();
|
||||
|
||||
var filePath = Path.Combine(_hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.Data), file);
|
||||
if (!System.IO.File.Exists(filePath))
|
||||
return NotFound();
|
||||
|
||||
var xd = new XmlDocument { XmlResolver = null };
|
||||
xd.Load(filePath);
|
||||
|
||||
var userId = _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? 0;
|
||||
var element = XElement.Parse(xd.InnerXml);
|
||||
|
||||
var parentDictionaryItem = _localizationService.GetDictionaryItemById(parentId);
|
||||
var dictionaryItems = _packageDataInstallation.ImportDictionaryItem(element, userId, parentDictionaryItem?.Key);
|
||||
|
||||
// Try to clean up the temporary file.
|
||||
try
|
||||
{
|
||||
System.IO.File.Delete(filePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error cleaning up temporary udt file in {File}", filePath);
|
||||
}
|
||||
|
||||
var model = _umbracoMapper.Map<IDictionaryItem, DictionaryDisplay>(dictionaryItems.FirstOrDefault());
|
||||
return Content(model!.Path, MediaTypeNames.Text.Plain, Encoding.UTF8);
|
||||
}
|
||||
|
||||
public ActionResult<DictionaryImportModel> Upload(IFormFile file)
|
||||
{
|
||||
|
||||
if (file == null)
|
||||
return ValidationProblem(
|
||||
_localizedTextService.Localize("media", "failedFileUpload"),
|
||||
_localizedTextService.Localize("speechBubbles", "fileErrorNotFound"));
|
||||
|
||||
var fileName = file.FileName.Trim(Constants.CharArrays.DoubleQuote);
|
||||
var ext = fileName.Substring(fileName.LastIndexOf('.') + 1).ToLower();
|
||||
var root = _hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.TempFileUploads);
|
||||
var tempPath = Path.Combine(root, fileName);
|
||||
|
||||
if (!Path.GetFullPath(tempPath).StartsWith(Path.GetFullPath(root)))
|
||||
return ValidationProblem(
|
||||
_localizedTextService.Localize("media", "failedFileUpload"),
|
||||
_localizedTextService.Localize("media", "invalidFileName"));
|
||||
|
||||
if (!ext.InvariantEquals("udt"))
|
||||
return ValidationProblem(
|
||||
_localizedTextService.Localize("media", "failedFileUpload"),
|
||||
_localizedTextService.Localize("media", "disallowedFileType"));
|
||||
|
||||
using (var stream = System.IO.File.Create(tempPath))
|
||||
{
|
||||
file.CopyToAsync(stream).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
var xd = new XmlDocument
|
||||
{
|
||||
XmlResolver = null
|
||||
};
|
||||
xd.Load(tempPath);
|
||||
|
||||
if (xd.DocumentElement == null)
|
||||
return ValidationProblem(
|
||||
_localizedTextService.Localize("media", "failedFileUpload"),
|
||||
_localizedTextService.Localize("speechBubbles", "fileErrorNotFound"));
|
||||
|
||||
DictionaryImportModel model = new DictionaryImportModel()
|
||||
{
|
||||
TempFileName = tempPath,
|
||||
DictionaryItems = new List<DictionaryPreviewImportModel>()
|
||||
};
|
||||
|
||||
int level = 1;
|
||||
string curentParrent = string.Empty;
|
||||
foreach (XmlNode dictionaryItem in xd.GetElementsByTagName("DictionaryItem"))
|
||||
{
|
||||
var name = dictionaryItem.Attributes?.GetNamedItem("Name")?.Value ?? string.Empty;
|
||||
var parentKey = dictionaryItem?.ParentNode?.Attributes?.GetNamedItem("Key")?.Value ?? string.Empty;
|
||||
|
||||
if (parentKey != curentParrent || level == 1)
|
||||
{
|
||||
level += 1;
|
||||
curentParrent = parentKey;
|
||||
}
|
||||
|
||||
model.DictionaryItems.Add(new DictionaryPreviewImportModel()
|
||||
{
|
||||
Level = level,
|
||||
Name = name
|
||||
});
|
||||
}
|
||||
|
||||
if (!model.DictionaryItems.Any())
|
||||
return ValidationProblem(
|
||||
_localizedTextService.Localize("media", "failedFileUpload"),
|
||||
_localizedTextService.Localize("dictionary", "noItemsInFile"));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
private static Func<IDictionaryItem, string> ItemSort() => item => item.ItemKey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,8 +130,25 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
|
||||
if (id != Constants.System.RootString)
|
||||
{
|
||||
menu.Items.Add<ActionDelete>(LocalizedTextService, true, opensDialog: true, useLegacyIcon: false);
|
||||
menu.Items.Add<ActionMove>(LocalizedTextService, true, opensDialog: true, useLegacyIcon: false);
|
||||
menu.Items.Add(new MenuItem("export", LocalizedTextService)
|
||||
{
|
||||
Icon = "icon-download-alt",
|
||||
SeparatorBefore = true,
|
||||
OpensDialog = true,
|
||||
UseLegacyIcon = false
|
||||
});
|
||||
menu.Items.Add<ActionDelete>(LocalizedTextService, true, opensDialog: true, useLegacyIcon: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.Items.Add(new MenuItem("import", LocalizedTextService)
|
||||
{
|
||||
Icon = "icon-page-up",
|
||||
SeparatorBefore = true,
|
||||
OpensDialog = true,
|
||||
UseLegacyIcon = false
|
||||
});
|
||||
}
|
||||
|
||||
menu.Items.Add(new RefreshNode(LocalizedTextService, true));
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
});
|
||||
17
src/Umbraco.Web.UI.Client/src/views/dictionary/export.html
Normal file
17
src/Umbraco.Web.UI.Client/src/views/dictionary/export.html
Normal 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>
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
});
|
||||
81
src/Umbraco.Web.UI.Client/src/views/dictionary/import.html
Normal file
81
src/Umbraco.Web.UI.Client/src/views/dictionary/import.html
Normal 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>
|
||||
Reference in New Issue
Block a user