From 1d2272f5364a3b3bbced4f4477e650dfb035f0ae Mon Sep 17 00:00:00 2001 From: Patrick de Mooij Date: Thu, 7 Oct 2021 20:40:47 +0200 Subject: [PATCH] Content app for dictionary items --- .../DictionaryContentAppFactory.cs | 32 +++ .../UmbracoBuilder.Collections.cs | 3 +- .../Manifest/ManifestContentAppFactory.cs | 6 +- .../ContentEditing/DictionaryDisplay.cs | 9 +- .../Models/Mapping/CommonMapper.cs | 4 +- .../Models/Mapping/DictionaryMapDefinition.cs | 7 +- .../dictionary/dictionary.edit.controller.js | 203 +++++++++--------- .../src/views/dictionary/edit.html | 106 ++++----- .../dictionary/views/content/content.html | 20 ++ 9 files changed, 221 insertions(+), 169 deletions(-) create mode 100644 src/Umbraco.Core/ContentApps/DictionaryContentAppFactory.cs create mode 100644 src/Umbraco.Web.UI.Client/src/views/dictionary/views/content/content.html diff --git a/src/Umbraco.Core/ContentApps/DictionaryContentAppFactory.cs b/src/Umbraco.Core/ContentApps/DictionaryContentAppFactory.cs new file mode 100644 index 000000000000..b1fb31d2aac6 --- /dev/null +++ b/src/Umbraco.Core/ContentApps/DictionaryContentAppFactory.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.ContentEditing; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Core.ContentApps +{ + internal class DictionaryContentAppFactory : IContentAppFactory + { + private const int Weight = -100; + + private ContentApp _dictionaryApp; + + public ContentApp GetContentAppFor(object source, IEnumerable userGroups) + { + switch (source) + { + case IDictionaryItem _: + return _dictionaryApp ??= new ContentApp + { + Alias = "dictionaryContent", + Name = "Content", + Icon = "icon-document", + View = "views/dictionary/views/content/content.html", + Weight = Weight + }; + default: + return null; + } + } + } +} diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Collections.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Collections.cs index 1d66e874be6c..7241704e62fd 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Collections.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Collections.cs @@ -44,7 +44,8 @@ internal static void AddAllCoreCollectionBuilders(this IUmbracoBuilder builder) .Append() .Append() .Append() - .Append(); + .Append() + .Append(); // all built-in finders in the correct order, // devs can then modify this list on application startup diff --git a/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs b/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs index d865bb01aac4..0bb555f16f09 100644 --- a/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs +++ b/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; @@ -70,6 +70,10 @@ public ContentApp GetContentAppFor(object o,IEnumerable user partA = "contentType"; partB = contentType.Alias; break; + case IDictionaryItem _: + partA = "dictionary"; + partB = "*"; //Not really a different type for dictionary items + break; default: return null; diff --git a/src/Umbraco.Core/Models/ContentEditing/DictionaryDisplay.cs b/src/Umbraco.Core/Models/ContentEditing/DictionaryDisplay.cs index 41e49ba34deb..d8cfaf110462 100644 --- a/src/Umbraco.Core/Models/ContentEditing/DictionaryDisplay.cs +++ b/src/Umbraco.Core/Models/ContentEditing/DictionaryDisplay.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Runtime.Serialization; @@ -17,6 +17,7 @@ public DictionaryDisplay() { Notifications = new List(); Translations = new List(); + ContentApps = new List(); } /// @@ -37,5 +38,11 @@ public DictionaryDisplay() /// [DataMember(Name = "translations")] public List Translations { get; private set; } + + /// + /// Apps for the dictionary item + /// + [DataMember(Name = "apps")] + public List ContentApps { get; private set; } } } diff --git a/src/Umbraco.Core/Models/Mapping/CommonMapper.cs b/src/Umbraco.Core/Models/Mapping/CommonMapper.cs index 3cfcc8908559..45c3c2598f8e 100644 --- a/src/Umbraco.Core/Models/Mapping/CommonMapper.cs +++ b/src/Umbraco.Core/Models/Mapping/CommonMapper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Umbraco.Cms.Core.ContentApps; @@ -47,7 +47,7 @@ public ContentTypeBasic GetContentType(IContentBase source, MapperContext contex return contentTypeBasic; } - public IEnumerable GetContentApps(IUmbracoEntity source) + public IEnumerable GetContentApps(IEntity source) { var apps = _contentAppDefinitions.GetContentAppsFor(source).ToArray(); diff --git a/src/Umbraco.Core/Models/Mapping/DictionaryMapDefinition.cs b/src/Umbraco.Core/Models/Mapping/DictionaryMapDefinition.cs index 4c000f0173b9..96c1aef21db2 100644 --- a/src/Umbraco.Core/Models/Mapping/DictionaryMapDefinition.cs +++ b/src/Umbraco.Core/Models/Mapping/DictionaryMapDefinition.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Umbraco.Cms.Core.Mapping; @@ -14,10 +14,12 @@ namespace Umbraco.Cms.Core.Models.Mapping public class DictionaryMapDefinition : IMapDefinition { private readonly ILocalizationService _localizationService; + private readonly CommonMapper _commonMapper; - public DictionaryMapDefinition(ILocalizationService localizationService) + public DictionaryMapDefinition(ILocalizationService localizationService, CommonMapper commonMapper) { _localizationService = localizationService; + _commonMapper = commonMapper; } public void DefineMaps(IUmbracoMapper mapper) @@ -44,6 +46,7 @@ private void Map(IDictionaryItem source, DictionaryDisplay target, MapperContext target.Name = source.ItemKey; target.ParentId = source.ParentId ?? Guid.Empty; target.Udi = Udi.Create(Constants.UdiEntityType.DictionaryItem, source.Key); + target.ContentApps.AddRange(_commonMapper.GetContentApps(source)); // build up the path to make it possible to set active item in tree // TODO: check if there is a better way diff --git a/src/Umbraco.Web.UI.Client/src/views/dictionary/dictionary.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/dictionary/dictionary.edit.controller.js index 416d2c3a6536..2f6fb2d3a81f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dictionary/dictionary.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dictionary/dictionary.edit.controller.js @@ -1,4 +1,4 @@ -/** +/** * @ngdoc controller * @name Umbraco.Editors.Dictionary.EditController * @function @@ -7,128 +7,131 @@ * The controller for editing dictionary items */ function DictionaryEditController($scope, $routeParams, $location, dictionaryResource, navigationService, appState, editorState, contentEditingHelper, formHelper, notificationsService, localizationService) { - - var vm = this; - - //setup scope vars - vm.nameDirty = false; - vm.header = {}; - vm.header.editorfor = "template_insertDictionaryItem"; - vm.header.setPageTitle = true; - - vm.page = {}; - vm.page.loading = false; - vm.page.nameLocked = false; - vm.page.menu = {}; - vm.page.menu.currentSection = appState.getSectionState("currentSection"); - vm.page.menu.currentNode = null; - vm.description = ""; - vm.showBackButton = true; - vm.maxlength = 1000; - - vm.save = saveDictionary; - vm.back = back; - vm.change = change; - - function loadDictionary() { - - vm.page.loading = true; - - //we are editing so get the content item from the server - dictionaryResource.getById($routeParams.id) - .then(function (data) { - bindDictionary(data); - vm.page.loading = false; - }); - } - function createTranslationProperty(translation) { - return { - alias: translation.isoCode, - label: translation.displayName, - hideLabel : false - } + var vm = this; + + //setup scope vars + vm.nameDirty = false; + vm.header = {}; + vm.header.editorfor = "template_insertDictionaryItem"; + vm.header.setPageTitle = true; + + vm.page = {}; + vm.page.navigation = {}; + vm.page.loading = false; + vm.page.nameLocked = false; + vm.page.menu = {}; + vm.page.menu.currentSection = appState.getSectionState("currentSection"); + vm.page.menu.currentNode = null; + vm.description = ""; + vm.showBackButton = true; + vm.maxlength = 1000; + + vm.save = saveDictionary; + vm.back = back; + vm.change = change; + + function loadDictionary() { + + vm.page.loading = true; + + //we are editing so get the content item from the server + dictionaryResource.getById($routeParams.id) + .then(function (data) { + bindDictionary(data); + vm.page.navigation = data.apps; + data.apps[0].active = true; + vm.page.loading = false; + }); + } + + function createTranslationProperty(translation) { + return { + alias: translation.isoCode, + label: translation.displayName, + hideLabel: false } + } - function bindDictionary(data) { - localizationService.localize("dictionaryItem_description").then(function (value) { - vm.description = value.replace("%0%", data.name); - }); + function bindDictionary(data) { + localizationService.localize("dictionaryItem_description").then(function (value) { + vm.description = value.replace("%0%", data.name); + }); - // create data for umb-property displaying - for (var i = 0; i < data.translations.length; i++) { - data.translations[i].property = createTranslationProperty(data.translations[i]); - change(data.translations[i]); - } + // create data for umb-property displaying + for (var i = 0; i < data.translations.length; i++) { + data.translations[i].property = createTranslationProperty(data.translations[i]); + change(data.translations[i]); + } - contentEditingHelper.handleSuccessfulSave({ - scope: $scope, - savedContent: data - }); + contentEditingHelper.handleSuccessfulSave({ + scope: $scope, + savedContent: data + }); - // set content - vm.content = data; + // set content + vm.content = data; - //share state - editorState.set(vm.content); + //share state + editorState.set(vm.content); - navigationService.syncTree({ tree: "dictionary", path: data.path, forceReload: true }).then(function (syncArgs) { - vm.page.menu.currentNode = syncArgs.node; - }); - } + navigationService.syncTree({ tree: "dictionary", path: data.path, forceReload: true }).then(function (syncArgs) { + vm.page.menu.currentNode = syncArgs.node; + }); + } - function onInit() { - loadDictionary(); - } + function onInit() { + loadDictionary(); + } + + function saveDictionary() { + if (formHelper.submitForm({ scope: $scope, statusMessage: "Saving..." })) { - function saveDictionary() { - if (formHelper.submitForm({ scope: $scope, statusMessage: "Saving..." })) { + vm.page.saveButtonState = "busy"; - vm.page.saveButtonState = "busy"; + dictionaryResource.save(vm.content, vm.nameDirty) + .then(function (data) { - dictionaryResource.save(vm.content, vm.nameDirty) - .then(function (data) { + formHelper.resetForm({ scope: $scope }); - formHelper.resetForm({ scope: $scope }); + bindDictionary(data); - bindDictionary(data); + vm.page.saveButtonState = "success"; + }, + function (err) { - vm.page.saveButtonState = "success"; - }, - function (err) { + formHelper.resetForm({ scope: $scope, hasErrors: true }); - formHelper.resetForm({ scope: $scope, hasErrors: true }); + contentEditingHelper.handleSaveError({ + err: err + }); - contentEditingHelper.handleSaveError({ - err: err - }); - - notificationsService.error(err.data.message); + notificationsService.error(err.data.message); - vm.page.saveButtonState = "error"; - }); - } - } - - function back() { - $location.path(vm.page.menu.currentSection + "/dictionary/list"); + vm.page.saveButtonState = "error"; + }); } + } - function change(translation) { - if (translation.translation) { - var charsCount = translation.translation.length; - translation.nearMaxLimit = charsCount > Math.max(vm.maxlength * .8, vm.maxlength - 50); - } + function back() { + $location.path(vm.page.menu.currentSection + "/dictionary/list"); + } + + function change(translation) { + if (translation.translation) { + var charsCount = translation.translation.length; + translation.nearMaxLimit = charsCount > Math.max(vm.maxlength * .8, vm.maxlength - 50); } + } - $scope.$watch("vm.content.name", function (newVal, oldVal) { - //when the value changes, we need to set the name dirty - if (newVal && (newVal !== oldVal) && typeof(oldVal) !== "undefined") { - vm.nameDirty = true; - } - }); + $scope.$watch("vm.content.name", function (newVal, oldVal) { + //when the value changes, we need to set the name dirty + if (newVal && (newVal !== oldVal) && typeof (oldVal) !== "undefined") { + vm.nameDirty = true; + } + }); - onInit(); + onInit(); } angular.module("umbraco").controller("Umbraco.Editors.Dictionary.EditController", DictionaryEditController); diff --git a/src/Umbraco.Web.UI.Client/src/views/dictionary/edit.html b/src/Umbraco.Web.UI.Client/src/views/dictionary/edit.html index f59491c69396..01c3a628e968 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dictionary/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/dictionary/edit.html @@ -1,63 +1,45 @@ -
- - -
- - - - - - - - -

- - - -
-

- {{ translation.displayName }} - %0% characters left. -

-
-
-
-
-
- - - - - - - - - - - -
-
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/dictionary/views/content/content.html b/src/Umbraco.Web.UI.Client/src/views/dictionary/views/content/content.html new file mode 100644 index 000000000000..4e97626c4fba --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/dictionary/views/content/content.html @@ -0,0 +1,20 @@ + + +

+ + + +
+

+ {{ translation.displayName }} + %0% characters left. +

+
+
+
+