From f41c9bf7aa2a69d853b42676fdc0886ff3348984 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 20 Jul 2020 12:15:19 +0100 Subject: [PATCH 01/30] Incremented version number, v1.3.0-develop --- VERSION | 2 +- src/Umbraco.Community.Contentment/Properties/VersionInfo.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index 867e5243..89cddd5e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.0 \ No newline at end of file +1.3.0-develop \ No newline at end of file diff --git a/src/Umbraco.Community.Contentment/Properties/VersionInfo.cs b/src/Umbraco.Community.Contentment/Properties/VersionInfo.cs index 03756b6b..8716556b 100644 --- a/src/Umbraco.Community.Contentment/Properties/VersionInfo.cs +++ b/src/Umbraco.Community.Contentment/Properties/VersionInfo.cs @@ -1,5 +1,5 @@ using System.Reflection; -[assembly: AssemblyVersion("1.2")] -[assembly: AssemblyFileVersion("1.2.0")] -[assembly: AssemblyInformationalVersion("1.2.0")] +[assembly: AssemblyVersion("1.3")] +[assembly: AssemblyFileVersion("1.3.0")] +[assembly: AssemblyInformationalVersion("1.3.0-develop")] From d11e0b0863bf081b0e1e0502b261506e297c4369 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 20 Jul 2020 14:24:19 +0100 Subject: [PATCH 02/30] Added "Code Editor" back in for v1.3.0 This reverts commit a119fe3cc00369ce7305965a274acd653ece930b. --- .../CodeEditorConfigurationEditor.cs | 97 ++++++++++++++++++- .../CodeEditor/CodeEditorDataEditor.cs | 21 +++- .../CodeEditor/CodeEditorValueConverter.cs | 19 ++++ .../DataEditors/CodeEditor/README.md | 7 +- .../DataEditors/CodeEditor/code-editor.js | 1 + .../Umbraco.Community.Contentment.csproj | 1 + 6 files changed, 138 insertions(+), 8 deletions(-) create mode 100644 src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorValueConverter.cs diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs index 77e85714..60d9550f 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs @@ -3,13 +3,108 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +using System.Collections.Generic; +using System.IO; +using Umbraco.Core; +using Umbraco.Core.IO; +using Umbraco.Core.PropertyEditors; + namespace Umbraco.Community.Contentment.DataEditors { - internal sealed class CodeEditorConfigurationEditor + internal sealed class CodeEditorConfigurationEditor : ConfigurationEditor { internal const string FontSize = "fontSize"; internal const string Mode = "mode"; internal const string Theme = "theme"; internal const string UseWrapMode = "useWrapMode"; + + public CodeEditorConfigurationEditor() + : base() + { + var targetPath = "~/umbraco/lib/ace-builds/src-min-noconflict/"; + + Fields.Add(new NotesConfigurationField($@"
+

This property editor makes use of AWS Cloud 9's Ace editor that is distributed with Umbraco. By default, Umbraco ships a streamlined set of programming language modes and themes.

+

If you would like to add more modes and themes, you can do this by downloading the latest pre-packaged version of the Ace editor and copy any of the mode-* or theme-* files from the src-min-noconflict folder over to the {targetPath} folder in this Umbraco installation.

+

When you reload this screen, the new programming language modes and themes will appear in the dropdown options below.

+
")); + + var aceEditorPath = IOHelper.MapPath(targetPath); + if (Directory.Exists(aceEditorPath)) + { + var aceEditorFiles = Directory.GetFiles(aceEditorPath, "*.js"); + if (aceEditorFiles != null && aceEditorFiles.Length > 0) + { + var modes = new List(); + var themes = new List(); + + foreach (var file in aceEditorFiles) + { + var filename = Path.GetFileNameWithoutExtension(file); + if (filename.StartsWith("mode-")) + { + var mode = filename.Replace("mode-", string.Empty).ToLower(); + modes.Add(new DataListItem { Name = mode.ToFirstUpper(), Value = mode }); + } + + if (filename.StartsWith("theme-")) + { + var theme = filename.Replace("theme-", string.Empty).ToLower(); + themes.Add(new DataListItem { Name = theme.ToFirstUpper(), Value = theme }); + } + } + + if (modes.Count > 0) + { + DefaultConfiguration.Add(Mode, "razor"); + Fields.Add( + Mode, + "Programming language mode", + "Select the programming language mode. By default, 'Razor' mode will be used.", + IOHelper.ResolveUrl(DropdownListDataListEditor.DataEditorViewPath), + new Dictionary + { + { DropdownListDataListEditor.AllowEmpty, Constants.Values.False }, + { Constants.Conventions.ConfigurationFieldAliases.Items, modes }, + }); + } + + if (themes.Count > 0) + { + DefaultConfiguration.Add(Theme, "chrome"); + Fields.Add( + Theme, + nameof(Theme), + "Set the theme for the code editor. By default, 'Chrome' theme will be used.", + IOHelper.ResolveUrl(DropdownListDataListEditor.DataEditorViewPath), + new Dictionary + { + { DropdownListDataListEditor.AllowEmpty, Constants.Values.False }, + { Constants.Conventions.ConfigurationFieldAliases.Items, themes }, + }); + } + } + } + + DefaultConfiguration.Add(FontSize, "14px"); + Fields.Add(FontSize, "Font size", "Set the font size. The value must be a valid CSS font-size. The default value is '14px'.", "textstring"); + + Fields.Add(UseWrapMode, "Word wrapping", "Select to enable word wrapping.", "boolean"); + + // NOTE: [LK:2019-06-07] Hidden the advanced options (for now), need to review. + //Fields.Add("showGutter", "Show gutter?", "Select to show the left-hand side gutter in the code editor.", "boolean"); // TODO: Tempted to reverse the logic here, then use ToValueEditor to negate it? [LK] + //Fields.Add("firstLineNumber", "First Line Number", "[A friendly description]", "number"); + //Fields.Add("showInvisibles", "showInvisibles", "[A friendly description]", "boolean");// showInvisibles: 0, + //Fields.Add("showIndentGuides", "showIndentGuides", "[A friendly description]", "boolean");// showIndentGuides: 0, + //Fields.Add("useSoftTabs", "useSoftTabs", "[A friendly description]", "boolean");// useSoftTabs: 1, + //Fields.Add("showPrintMargin", "showPrintMargin", "[A friendly description]", "boolean");// showPrintMargin: 0, + //Fields.Add("disableSearch", "disableSearch", "[A friendly description]", "boolean");// disableSearch: 0, + //Fields.Add("enableSnippets", "enableSnippets", "[A friendly description]", "boolean");// enableSnippets: 0, + //Fields.Add("enableBasicAutocompletion", "enableBasicAutocompletion", "[A friendly description]", "boolean");// enableBasicAutocompletion: 0, + //Fields.Add("enableLiveAutocompletion", "enableLiveAutocompletion", "[A friendly description]", "boolean");// enableLiveAutocompletion: 0, + //Fields.Add("readonly", "readonly", "[A friendly description]", "boolean");// readonly: 0, + //Fields.Add("minLines", "minLines", "[A friendly description]", "number"); // minLines: undefined + //Fields.Add("maxLines", "maxLines", "[A friendly description]", "number"); // maxLines: undefined + } } } diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorDataEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorDataEditor.cs index 43c3822e..e4675264 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorDataEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorDataEditor.cs @@ -3,13 +3,30 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +using Umbraco.Core.Logging; +using Umbraco.Core.PropertyEditors; + namespace Umbraco.Community.Contentment.DataEditors { - internal sealed class CodeEditorDataEditor + [DataEditor( + DataEditorAlias, + EditorType.PropertyValue, + DataEditorName, + DataEditorViewPath, + ValueType = ValueTypes.Text, + Group = Constants.Conventions.PropertyGroups.Code, + Icon = DataEditorIcon)] + internal sealed class CodeEditorDataEditor : DataEditor { internal const string DataEditorAlias = Constants.Internals.DataEditorAliasPrefix + "CodeEditor"; internal const string DataEditorName = Constants.Internals.DataEditorNamePrefix + "Code Editor"; internal const string DataEditorViewPath = Constants.Internals.EditorsPathRoot + "code-editor.html"; - internal const string DataEditorIcon = "icon-code"; + internal const string DataEditorIcon = "icon-fa fa-code"; + + public CodeEditorDataEditor(ILogger logger) + : base(logger) + { } + + protected override IConfigurationEditor CreateConfigurationEditor() => new CodeEditorConfigurationEditor(); } } diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorValueConverter.cs b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorValueConverter.cs new file mode 100644 index 00000000..2c331f35 --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorValueConverter.cs @@ -0,0 +1,19 @@ +/* Copyright © 2020 Lee Kelleher. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using System; +using Umbraco.Core; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Community.Contentment.DataEditors +{ + internal sealed class CodeEditorValueConverter : PropertyValueConverterBase + { + public override bool IsConverter(IPublishedPropertyType propertyType) => propertyType.EditorAlias.InvariantEquals(CodeEditorDataEditor.DataEditorAlias); + + public override Type GetPropertyValueType(IPublishedPropertyType propertyType) => typeof(string); + } +} diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/README.md b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/README.md index 9844960d..730e2bf7 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/README.md +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/README.md @@ -1,10 +1,7 @@ ## Code Editor +Code Editor is a property-editor that uses Umbraco's ACE editor implementation as a input for code (as content). + ### Used interally by Code Editor is used in the configuration editors of a couple of Data List providers, namely SQL data source and Templated List editor. - - -### Future scope - -It has future scope to be a standalone property-editor. diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.js b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.js index 2da7a0d1..c5d9132b 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.js +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.js @@ -35,6 +35,7 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. function init() { vm.readonly = Object.toBoolean(config.readonly); + vm.options = { autoFocus: false, showGutter: Object.toBoolean(config.showGutter), diff --git a/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj b/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj index 86f92521..660c39d1 100644 --- a/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj +++ b/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj @@ -301,6 +301,7 @@ + From ea14b21d549b1778374257bd5c2d722e0fccc22d Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 20 Jul 2020 15:32:18 +0100 Subject: [PATCH 03/30] TIL about `TextOnlyValueEditor` https://github.com/umbraco/Umbraco-CMS/blob/release-8.6.1/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs Turns out that if the CodeEditor was editing JSON (text), once it is saved to the database, it would be returned to the property-editor as a JSON object, rather than a string. Caused all sorts of problems. The `TextOnlyValueEditor` class will workaround that issue. --- .../DataEditors/CodeEditor/CodeEditorDataEditor.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorDataEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorDataEditor.cs index e4675264..bc0331de 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorDataEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorDataEditor.cs @@ -5,6 +5,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; +using Umbraco.Web.PropertyEditors; namespace Umbraco.Community.Contentment.DataEditors { @@ -28,5 +29,7 @@ public CodeEditorDataEditor(ILogger logger) { } protected override IConfigurationEditor CreateConfigurationEditor() => new CodeEditorConfigurationEditor(); + + protected override IDataValueEditor CreateValueEditor() => new TextOnlyValueEditor(Attribute); } } From 165ca4ffe096d848a7bb5d3ca8558b7ad4cc02c1 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 23 Jul 2020 12:00:54 +0100 Subject: [PATCH 04/30] CodeEditor - limits editor width When using it along with other pickers, editors, it looks neater limited to max 800px width. --- .../DataEditors/CodeEditor/code-editor.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.html b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.html index eb2d54d8..6b86223a 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.html +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.html @@ -3,6 +3,6 @@ - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at https://mozilla.org/MPL/2.0/. --> -
+
From 67c61c1d4c1f79c067fd6e946c9743825e62456c Mon Sep 17 00:00:00 2001 From: leekelleher Date: Sun, 4 Oct 2020 18:55:55 +0100 Subject: [PATCH 05/30] Code Editor - config for min/max lines --- .../CodeEditor/CodeEditorConfigurationEditor.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs index 60d9550f..8e33fa4b 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs @@ -23,7 +23,7 @@ public CodeEditorConfigurationEditor() { var targetPath = "~/umbraco/lib/ace-builds/src-min-noconflict/"; - Fields.Add(new NotesConfigurationField($@"
+ Fields.Add(new NotesConfigurationField($@"

This property editor makes use of AWS Cloud 9's Ace editor that is distributed with Umbraco. By default, Umbraco ships a streamlined set of programming language modes and themes.

If you would like to add more modes and themes, you can do this by downloading the latest pre-packaged version of the Ace editor and copy any of the mode-* or theme-* files from the src-min-noconflict folder over to the {targetPath} folder in this Umbraco installation.

When you reload this screen, the new programming language modes and themes will appear in the dropdown options below.

@@ -44,13 +44,13 @@ public CodeEditorConfigurationEditor() if (filename.StartsWith("mode-")) { var mode = filename.Replace("mode-", string.Empty).ToLower(); - modes.Add(new DataListItem { Name = mode.ToFirstUpper(), Value = mode }); + modes.Add(new DataListItem { Name = mode.ToFirstUpperInvariant(), Value = mode }); } if (filename.StartsWith("theme-")) { var theme = filename.Replace("theme-", string.Empty).ToLower(); - themes.Add(new DataListItem { Name = theme.ToFirstUpper(), Value = theme }); + themes.Add(new DataListItem { Name = theme.ToFirstUpperInvariant(), Value = theme }); } } @@ -87,7 +87,7 @@ public CodeEditorConfigurationEditor() } DefaultConfiguration.Add(FontSize, "14px"); - Fields.Add(FontSize, "Font size", "Set the font size. The value must be a valid CSS font-size. The default value is '14px'.", "textstring"); + Fields.Add(FontSize, "Font size", "Set the font size. The value must be a valid CSS font-size. The default value is 14 pixels.", "textstring"); Fields.Add(UseWrapMode, "Word wrapping", "Select to enable word wrapping.", "boolean"); @@ -103,8 +103,12 @@ public CodeEditorConfigurationEditor() //Fields.Add("enableBasicAutocompletion", "enableBasicAutocompletion", "[A friendly description]", "boolean");// enableBasicAutocompletion: 0, //Fields.Add("enableLiveAutocompletion", "enableLiveAutocompletion", "[A friendly description]", "boolean");// enableLiveAutocompletion: 0, //Fields.Add("readonly", "readonly", "[A friendly description]", "boolean");// readonly: 0, - //Fields.Add("minLines", "minLines", "[A friendly description]", "number"); // minLines: undefined - //Fields.Add("maxLines", "maxLines", "[A friendly description]", "number"); // maxLines: undefined + + DefaultConfiguration.Add("minLines", 12); + Fields.Add("minLines", "Minimum lines", "Set the minimum number of lines that the editor will be. The default value is 12 lines.", IOHelper.ResolveUrl(NumberInputDataEditor.DataEditorViewPath)); + + DefaultConfiguration.Add("maxLines", 30); + Fields.Add("maxLines", "Maximum lines", "Set the maximum number of lines that the editor can be. If left empty, the editor will not auto-scale.", IOHelper.ResolveUrl(NumberInputDataEditor.DataEditorViewPath)); } } } From c5a14401b230a4febbb8ae6f17f398d940cc7e48 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 16 Dec 2020 12:01:07 +0000 Subject: [PATCH 06/30] Added doc stubs for Code Editor --- .github/ROADMAP.md | 2 +- docs/editors/code-editor.md | 19 +++++++++++++++++++ src/Umbraco.Community.Contentment.sln | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 docs/editors/code-editor.md diff --git a/.github/ROADMAP.md b/.github/ROADMAP.md index 386e080d..4c83f1c0 100644 --- a/.github/ROADMAP.md +++ b/.github/ROADMAP.md @@ -35,7 +35,7 @@ Property Editors are: ### v1.3 -- Code Editor _(using ACE bundled with Umbraco)_ +- [Code Editor](../docs/editors/code-editor.md) _(using ACE bundled with Umbraco)_ - Data List: Preview _(a real time preview of the configured Data Source and List Editor)_ - Data List: Tags _(list editor, visually similar to Umbraco Tags editor)_ diff --git a/docs/editors/code-editor.md b/docs/editors/code-editor.md new file mode 100644 index 00000000..db15ca0e --- /dev/null +++ b/docs/editors/code-editor.md @@ -0,0 +1,19 @@ +Contentment for Umbraco logo + +## Contentment for Umbraco + +### Code Editor + + + +### How to configure the editor? + + + +### How to use the editor? + + + +### How to get the value? + + diff --git a/src/Umbraco.Community.Contentment.sln b/src/Umbraco.Community.Contentment.sln index b485ab86..d03ab422 100644 --- a/src/Umbraco.Community.Contentment.sln +++ b/src/Umbraco.Community.Contentment.sln @@ -41,6 +41,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Editors", "Editors", "{A5294B30-2ED5-4BBA-A2DE-A07103DAE78F}" ProjectSection(SolutionItems) = preProject ..\docs\editors\bytes.md = ..\docs\editors\bytes.md + ..\docs\editors\code-editor.md = ..\docs\editors\code-editor.md ..\docs\editors\content-blocks.md = ..\docs\editors\content-blocks.md ..\docs\editors\data-list.md = ..\docs\editors\data-list.md ..\docs\editors\icon-picker.md = ..\docs\editors\icon-picker.md From 8f13143757bc7dab79438c1a9114c2adae944c33 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 16 Dec 2020 12:36:45 +0000 Subject: [PATCH 07/30] CodeEditor - refactored config notes --- .../CodeEditorConfigurationEditor.cs | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs index 8e33fa4b..ef44d572 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs @@ -22,14 +22,8 @@ public CodeEditorConfigurationEditor() : base() { var targetPath = "~/umbraco/lib/ace-builds/src-min-noconflict/"; - - Fields.Add(new NotesConfigurationField($@"
-

This property editor makes use of AWS Cloud 9's Ace editor that is distributed with Umbraco. By default, Umbraco ships a streamlined set of programming language modes and themes.

-

If you would like to add more modes and themes, you can do this by downloading the latest pre-packaged version of the Ace editor and copy any of the mode-* or theme-* files from the src-min-noconflict folder over to the {targetPath} folder in this Umbraco installation.

-

When you reload this screen, the new programming language modes and themes will appear in the dropdown options below.

-
")); - var aceEditorPath = IOHelper.MapPath(targetPath); + if (Directory.Exists(aceEditorPath)) { var aceEditorFiles = Directory.GetFiles(aceEditorPath, "*.js"); @@ -59,8 +53,8 @@ public CodeEditorConfigurationEditor() DefaultConfiguration.Add(Mode, "razor"); Fields.Add( Mode, - "Programming language mode", - "Select the programming language mode. By default, 'Razor' mode will be used.", + "Language mode", + "Select the programming language mode. The default mode is 'Razor'.", IOHelper.ResolveUrl(DropdownListDataListEditor.DataEditorViewPath), new Dictionary { @@ -75,7 +69,7 @@ public CodeEditorConfigurationEditor() Fields.Add( Theme, nameof(Theme), - "Set the theme for the code editor. By default, 'Chrome' theme will be used.", + "Set the theme for the code editor. The default theme is 'Chrome'.", IOHelper.ResolveUrl(DropdownListDataListEditor.DataEditorViewPath), new Dictionary { @@ -83,11 +77,24 @@ public CodeEditorConfigurationEditor() { Constants.Conventions.ConfigurationFieldAliases.Items, themes }, }); } + + if (modes.Count > 0 || themes.Count > 0) + { + Fields.Add(new NotesConfigurationField($@"
+Would you like to add more language modes and themes? +
+

This property editor makes use of AWS Cloud 9's Ace editor library that is distributed with Umbraco. By default, Umbraco ships a streamlined set of programming language modes and themes.

+

If you would like to add more modes and themes, you can do this by downloading the latest pre-packaged version of the Ace editor and copy any of the mode-* or theme-* files from the src-min-noconflict folder over to the {targetPath} folder in this Umbraco installation.

+

When you reload this screen, the new programming language modes and themes will appear in the dropdown options above.

+
+
", true)); + } } } DefaultConfiguration.Add(FontSize, "14px"); - Fields.Add(FontSize, "Font size", "Set the font size. The value must be a valid CSS font-size. The default value is 14 pixels.", "textstring"); + // TODO: [LK:2020-12-16] I dislike the use of "textstring" for the font-size input. + Fields.Add(FontSize, "Font size", "Set the font size. The value must be a valid CSS font-size. The default size is 14 pixels.", "textstring"); Fields.Add(UseWrapMode, "Word wrapping", "Select to enable word wrapping.", "boolean"); @@ -105,7 +112,7 @@ public CodeEditorConfigurationEditor() //Fields.Add("readonly", "readonly", "[A friendly description]", "boolean");// readonly: 0, DefaultConfiguration.Add("minLines", 12); - Fields.Add("minLines", "Minimum lines", "Set the minimum number of lines that the editor will be. The default value is 12 lines.", IOHelper.ResolveUrl(NumberInputDataEditor.DataEditorViewPath)); + Fields.Add("minLines", "Minimum lines", "Set the minimum number of lines that the editor will be. The default is 12 lines.", IOHelper.ResolveUrl(NumberInputDataEditor.DataEditorViewPath)); DefaultConfiguration.Add("maxLines", 30); Fields.Add("maxLines", "Maximum lines", "Set the maximum number of lines that the editor can be. If left empty, the editor will not auto-scale.", IOHelper.ResolveUrl(NumberInputDataEditor.DataEditorViewPath)); From c86685119bbe1f0b873653bf20c32f6691f50cd8 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Tue, 9 Mar 2021 13:58:20 +0000 Subject: [PATCH 08/30] CodeEditor - added hints for font-size Sets default font-size to "small". The default for ACE is 14px, slightly larger than default "small", but felt that "small" fitted the editor more comfortably. --- .../CodeEditorConfigurationEditor.cs | 28 ++++++++++++++++--- .../DataEditors/CodeEditor/code-editor.js | 2 +- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs index ef44d572..e019ea07 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs @@ -92,14 +92,34 @@ public CodeEditorConfigurationEditor() } } - DefaultConfiguration.Add(FontSize, "14px"); - // TODO: [LK:2020-12-16] I dislike the use of "textstring" for the font-size input. - Fields.Add(FontSize, "Font size", "Set the font size. The value must be a valid CSS font-size. The default size is 14 pixels.", "textstring"); + DefaultConfiguration.Add(FontSize, "small"); + Fields.Add( + FontSize, + "Font size", + @"Set the font size. The value must be a valid CSS font-size value. The default size is 'small'.", + IOHelper.ResolveUrl(TextInputDataEditor.DataEditorViewPath), + new Dictionary + { + { Constants.Conventions.ConfigurationFieldAliases.Items, new[] { + new DataListItem { Name = "Extra extra small", Value = "xx-small" }, + new DataListItem { Name = "Extra small", Value = "x-small" }, + new DataListItem { Name = "Small", Value = "small" }, + new DataListItem { Name = "Medium", Value = "medium" }, + new DataListItem { Name = "Large", Value = "large" }, + new DataListItem { Name = "Extra large", Value = "x-large" }, + new DataListItem { Name = "Extra extra large", Value = "xx-large" }, + new DataListItem { Name = "Extra extra extra large", Value = "xxx-large" }, + new DataListItem { Name = "Use pixels?", Value = "14px" }, + new DataListItem { Name = "Use percentage?", Value = "80%" }, + new DataListItem { Name = "Use ems?", Value = "0.8em" }, + new DataListItem { Name = "Use rems?", Value = "1.2rem" }, + } }, + }); Fields.Add(UseWrapMode, "Word wrapping", "Select to enable word wrapping.", "boolean"); // NOTE: [LK:2019-06-07] Hidden the advanced options (for now), need to review. - //Fields.Add("showGutter", "Show gutter?", "Select to show the left-hand side gutter in the code editor.", "boolean"); // TODO: Tempted to reverse the logic here, then use ToValueEditor to negate it? [LK] + //Fields.Add("showGutter", "Show gutter?", "Select to show the left-hand side gutter in the code editor.", "boolean"); //Fields.Add("firstLineNumber", "First Line Number", "[A friendly description]", "number"); //Fields.Add("showInvisibles", "showInvisibles", "[A friendly description]", "boolean");// showInvisibles: 0, //Fields.Add("showIndentGuides", "showIndentGuides", "[A friendly description]", "boolean");// showIndentGuides: 0, diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.js b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.js index c5d9132b..406cb867 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.js +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/code-editor.js @@ -20,7 +20,7 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. theme: "chrome", mode: "javascript", firstLineNumber: 1, - fontSize: "14px", + fontSize: "small", enableSnippets: 0, enableBasicAutocompletion: 0, enableLiveAutocompletion: 0, From 8dce37d204f9ab80a274d414240d7939d2b8bfce Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 9 Dec 2019 15:48:17 +0000 Subject: [PATCH 09/30] Data List - "Tags" list editor --- .../DataEditors/Tags/TagsDataListEditor.cs | 43 +++++ .../DataEditors/Tags/tags.css | 20 ++ .../DataEditors/Tags/tags.html | 31 ++++ .../DataEditors/Tags/tags.js | 172 ++++++++++++++++++ .../Umbraco.Community.Contentment.csproj | 4 + .../UI/App_Plugins/Contentment/lang/en.xml | 1 + 6 files changed, 271 insertions(+) create mode 100644 src/Umbraco.Community.Contentment/DataEditors/Tags/TagsDataListEditor.cs create mode 100644 src/Umbraco.Community.Contentment/DataEditors/Tags/tags.css create mode 100644 src/Umbraco.Community.Contentment/DataEditors/Tags/tags.html create mode 100644 src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js diff --git a/src/Umbraco.Community.Contentment/DataEditors/Tags/TagsDataListEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/Tags/TagsDataListEditor.cs new file mode 100644 index 00000000..cd71543a --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/Tags/TagsDataListEditor.cs @@ -0,0 +1,43 @@ +/* Copyright © 2021 Lee Kelleher. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using System.Collections.Generic; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Community.Contentment.DataEditors +{ + internal sealed class TagsDataListEditor : IDataListEditor + { + internal const string DataEditorViewPath = Constants.Internals.EditorsPathRoot + "tags.html"; + + public string Name => "Tags"; + + public string Description => "Select items from an Umbraco Tags-like interface."; + + public string Icon => "icon-fa fa-tags"; + + public IEnumerable Fields => new ConfigurationField[] + { + new ShowIconsConfigurationField(), + new ConfigurationField + { + Key ="confirmRemoval", + Name = "Confirm removals?", + Description = "Select to enable a confirmation prompt when removing an item.", + View = "boolean", + } + }; + + public Dictionary DefaultValues => default; + + public Dictionary DefaultConfig => default; + + public bool HasMultipleValues(Dictionary config) => true; + + public OverlaySize OverlaySize => OverlaySize.Small; + + public string View => DataEditorViewPath; + } +} diff --git a/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.css b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.css new file mode 100644 index 00000000..7621e854 --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.css @@ -0,0 +1,20 @@ +/* Copyright © 2021 Lee Kelleher. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +.contentment .umb-tags .tag { + user-select: text; +} + + .contentment .umb-tags .tag .icon { + color: white !important; + } + + .contentment .umb-tags .tag .btn-reset { + line-height: 14px; + } + + .contentment .umb-tags .tag .icon-trash { + bottom: 0; + } diff --git a/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.html b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.html new file mode 100644 index 00000000..cf76f598 --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.html @@ -0,0 +1,31 @@ + + +
+
+ +
+ + + + + + +
+
+
diff --git a/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js new file mode 100644 index 00000000..ed31ddd1 --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js @@ -0,0 +1,172 @@ +/* Copyright © 2021 Lee Kelleher. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.Tags.Controller", [ + "$rootScope", + "$scope", + "$element", + "angularHelper", + "assetsService", + "localizationService", + "overlayService", + function ($rootScope, $scope, $element, angularHelper, assetsService, localizationService, overlayService) { + + //console.log("tags.model", $scope.model); + + var defaultConfig = { + confirmRemoval: 0, + defaultValue: [], + items: [], + showIcons: 0, + }; + var config = Object.assign({}, defaultConfig, $scope.model.config); + + var vm = this; + + function init() { + + $scope.model.value = $scope.model.value || config.defaultValue; + + if (Array.isArray($scope.model.value) === false) { + $scope.model.value = [$scope.model.value]; + } + + config.confirmRemoval = Object.toBoolean(config.confirmRemoval); + + vm.items = []; + + vm.showIcons = Object.toBoolean(config.showIcons); + + vm.uniqueId = [$scope.model.alias, $scope.model.dataTypeKey.substring(0, 8)].join("-"); + + vm.add = add; + vm.keyDown = keyDown; + vm.keyUp = keyUp; + vm.remove = remove; + + vm.loading = true; + + assetsService.loadJs("lib/typeahead.js/typeahead.bundle.min.js").then(function () { + + $scope.model.value.forEach(function (v) { + var item = config.items.find(x => x.value === v); + if (item) { + vm.items.push(Object.assign({}, item)); + } + }); + + vm.loading = false; + + var engine = new Bloodhound({ + datumTokenizer: Bloodhound.tokenizers.obj.whitespace("value"), + queryTokenizer: Bloodhound.tokenizers.whitespace, + initialize: false, + local: config.items.filter(x => !x.disabled), // TODO: Review the `filter`, is there a better way? + identify: d => d.value, + }); + + engine.initialize().then(function () { + + var opts = { + hint: true, + highlight: true, + minLength: 1 + }; + + var sources = { + display: "name", + minLength: 0, + source: function (q, sync) { + if (q && q.length > 0) { + engine.search(q, sync); + } else { + sync(engine.all()); + } + } + }; + + vm.editor = $element.find("input.typeahead") + .typeahead(opts, sources) + .bind("typeahead:select", add) + .bind("typeahead:autocomplete", add); + }); + + }); + + }; + + function add($event, item) { + angularHelper.safeApply($rootScope, function () { + + vm.items.push(Object.assign({}, item)); + + $scope.model.value.push(item.value); + + vm.editor.typeahead("val", ""); + + setDirty(); + }); + }; + + function keyDown($event) { + if ($event.keyCode == 13) { + var tt = vm.editor.data("ttTypeahead"); + if (tt && tt.menu && tt.menu.isOpen() === true) { + var selection = tt.menu.getActiveSelectable() || tt.menu.getTopSelectable(); + tt.menu.trigger("selectableClicked", selection); + $event.preventDefault(); + } + } + }; + + function keyUp($event, $index) { + console.log("keyUp", $event.keyCode, $index); + if ($event.keyCode === 8 || $event.keyCode === 46) { + remove($index); + } + }; + + function remove($index) { + if (config.confirmRemoval === true) { + var keys = ["contentment_removeItemMessage", "general_remove", "general_cancel", "contentment_removeItemButton"]; + localizationService.localizeMany(keys).then(function (data) { + overlayService.open({ + title: data[1], + content: data[0], + closeButtonLabel: data[2], + submitButtonLabel: data[3], + submitButtonStyle: "danger", + submit: function () { + removeItem($index); + overlayService.close(); + }, + close: function () { + overlayService.close(); + } + }); + }); + } else { + removeItem($index); + } + }; + + function removeItem($index) { + + vm.items.splice($index, 1); + + $scope.model.value.splice($index, 1); + + setDirty(); + }; + + function setDirty() { + if ($scope.propertyForm) { + $scope.propertyForm.$setDirty(); + } + }; + + init(); + } +]); diff --git a/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj b/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj index 660c39d1..abcd22fb 100644 --- a/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj +++ b/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj @@ -322,6 +322,7 @@ + @@ -446,6 +447,9 @@ + + + diff --git a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml index 903036df..74872d63 100644 --- a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml +++ b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml @@ -25,5 +25,6 @@ Select and configure a data source Select and configure a list editor + Type to select an item... From 3cfc35fbe4fe68162ef606c6f9df67d99112a499 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Fri, 20 Nov 2020 17:32:01 +0000 Subject: [PATCH 10/30] Preview for Data List editor When configuring the data-type, a preview panel will appear at the bottom, displaying the rendered list-editor and a table of the data-source items. --- .../configuration-editor.js | 11 ++- .../DataList/DataListApiController.cs | 45 ++++++++++ .../DataList/DataListConfigurationEditor.cs | 6 ++ .../DataList/DataListDataEditor.cs | 1 + .../DataList/data-list.preview.css | 17 ++++ .../DataList/data-list.preview.html | 59 +++++++++++++ .../DataEditors/DataList/data-list.preview.js | 87 +++++++++++++++++++ .../Umbraco.Community.Contentment.csproj | 4 + .../UI/App_Plugins/Contentment/lang/da.xml | 3 + .../UI/App_Plugins/Contentment/lang/en.xml | 3 + .../UI/App_Plugins/Contentment/lang/pt-br.xml | 3 + 11 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Community.Contentment/DataEditors/DataList/DataListApiController.cs create mode 100644 src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.css create mode 100644 src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html create mode 100644 src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js diff --git a/src/Umbraco.Community.Contentment/DataEditors/ConfigurationEditor/configuration-editor.js b/src/Umbraco.Community.Contentment/DataEditors/ConfigurationEditor/configuration-editor.js index f98dbda0..61160f8d 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/ConfigurationEditor/configuration-editor.js +++ b/src/Umbraco.Community.Contentment/DataEditors/ConfigurationEditor/configuration-editor.js @@ -6,11 +6,13 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.ConfigurationEditor.Controller", [ "$scope", "$interpolate", + "$timeout", "editorService", + "eventsService", "localizationService", "overlayService", "Umbraco.Community.Contentment.Services.DevMode", - function ($scope, $interpolate, editorService, localizationService, overlayService, devModeService) { + function ($scope, $interpolate, $timeout, editorService, eventsService, localizationService, overlayService, devModeService) { // console.log("config-editor.model", $scope.model); @@ -102,6 +104,8 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. }); } + // NOTE: Must wait, otherwise the preview may not be ready to receive the event. + $timeout(function () { emit(); }, 100); }; function add() { @@ -167,6 +171,10 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. }); }; + function emit() { + eventsService.emit("contentment.config-editor.model", $scope.model); + }; + function populate(item, $index, propertyName) { var label = ""; @@ -232,6 +240,7 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. if ($scope.propertyForm) { $scope.propertyForm.$setDirty(); } + emit(); }; init(); diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListApiController.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListApiController.cs new file mode 100644 index 00000000..26b23625 --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListApiController.cs @@ -0,0 +1,45 @@ +/* Copyright © 2020 Lee Kelleher. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Web.Http; +using Newtonsoft.Json.Linq; +using Umbraco.Core.PropertyEditors; +using Umbraco.Web.Editors; +using Umbraco.Web.Mvc; +using Umbraco.Web.WebApi; + +namespace Umbraco.Community.Contentment.DataEditors +{ + [PluginController(Constants.Internals.PluginControllerName), IsBackOffice] + public sealed class DataListApiController : UmbracoAuthorizedJsonController + { + private readonly PropertyEditorCollection _propertyEditors; + + public DataListApiController(PropertyEditorCollection propertyEditors) + { + _propertyEditors = propertyEditors; + } + + [HttpPost] + public HttpResponseMessage GetPreview([FromBody] JObject data) + { + var config = data.ToObject>(); + + if (_propertyEditors.TryGet(DataListDataEditor.DataEditorAlias, out var propertyEditor) == true) + { + var configurationEditor = propertyEditor.GetConfigurationEditor(); + var valueEditorConfig = configurationEditor.ToValueEditor(config); + var valueEditor = propertyEditor.GetValueEditor(config); + + return Request.CreateResponse(HttpStatusCode.OK, new { config = valueEditorConfig, view = valueEditor.View }); + } + + return Request.CreateResponse(HttpStatusCode.NotFound); + } + } +} diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs index beaec048..7ccfba3c 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs @@ -60,6 +60,12 @@ public DataListConfigurationEditor(ConfigurationEditorUtility utility) { Constants.Conventions.ConfigurationFieldAliases.AddButtonLabelKey, "contentment_configureListEditor" }, { Constants.Conventions.ConfigurationFieldAliases.Items, listEditors } }); + + Fields.Add( + "preview", + "Preview", + null, + IOHelper.ResolveUrl(DataListDataEditor.DataEditorPreviewViewPath)); } public override IDictionary ToValueEditor(object configuration) diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListDataEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListDataEditor.cs index 22137f86..6105a94c 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListDataEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListDataEditor.cs @@ -15,6 +15,7 @@ public sealed class DataListDataEditor : IDataEditor internal const string DataEditorAlias = Constants.Internals.DataEditorAliasPrefix + "DataList"; internal const string DataEditorName = Constants.Internals.DataEditorNamePrefix + "Data List"; internal const string DataEditorViewPath = Constants.Internals.EditorsPathRoot + "_empty.html"; + internal const string DataEditorPreviewViewPath = Constants.Internals.EditorsPathRoot + "data-list.preview.html"; internal const string DataEditorIcon = "icon-fa fa-list-ul"; private readonly ConfigurationEditorUtility _utility; diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.css b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.css new file mode 100644 index 00000000..17c8a8e5 --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.css @@ -0,0 +1,17 @@ +/* Copyright © 2021 Lee Kelleher. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +/* "Well" container - limiting the width, to match property width limit. */ +.contentment .well.well--limit-width { + max-width: 760px; +} + +.contentment .well.well-small.well--limit-width { + max-width: 780px; +} + +.contentment .well.well-large.well--limit-width { + max-width: 760px; +} diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html new file mode 100644 index 00000000..f8c1ea50 --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html @@ -0,0 +1,59 @@ + + +
+
+
+ Please select and configure a data source and list editor. +
+
+ Please select and configure a list editor. +
+
+ Please select and configure a data source. +
+
+ +
+
+ + + + +
+
+ +
+
+
+
+
+
+
Name
+
Value
+
Description
+
Enabled
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js new file mode 100644 index 00000000..8d0a488e --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js @@ -0,0 +1,87 @@ +/* Copyright © 2020 Lee Kelleher. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.DataList.Preview.Controller", [ + "$scope", + "$http", + "eventsService", + "umbRequestHelper", + function ($scope, $http, eventsService, umbRequestHelper) { + + //console.log("data-list.preview.model", $scope.model); + + var config = Object.assign({}, $scope.model.config); + var vm = this; + + function init() { + + vm.property = {}; + vm.state = "loading"; + + vm.tabs = [{ + label: "Editor preview", + alias: "listEditor", + active: false, + }, { + label: "Data source items", + alias: "dataSource", + active: false, + }]; + + // set the first tab to active + vm.tabs[0].active = true; + vm.activeTab = vm.tabs[0].alias; + + vm.changeTab = function (tab) { + vm.tabs.forEach(function (x) { x.active = false; }); + vm.activeTab = tab.alias; + tab.active = true; + }; + + var events = []; + + events.push(eventsService.on("contentment.config-editor.model", function (event, args) { + config[args.alias] = args.value; + fetch(); + })); + + $scope.$on("$destroy", function () { + for (var event in events) { + eventsService.unsubscribe(events[event]); + } + }); + + }; + + function fetch() { + if (_.isEmpty(config.dataSource) === false && _.isEmpty(config.listEditor) === false) { + + vm.state = "loading"; + vm.property = null; + + umbRequestHelper.resourcePromise( + $http.post("backoffice/Contentment/DataListApi/GetPreview", config), + "Failed to retrieve data list preview.") + .then(function (result) { + + vm.property = result; + vm.state = "loaded"; + + }); + } + else if (_.isEmpty(config.dataSource) === false) { + vm.state = "dataSourceConfigured"; + } + else if (_.isEmpty(config.listEditor) === false) { + vm.state = "listEditorConfigured"; + } + else { + vm.state = "init"; + } + }; + + init(); + } +]); diff --git a/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj b/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj index abcd22fb..f9927038 100644 --- a/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj +++ b/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj @@ -312,6 +312,7 @@ + @@ -433,6 +434,9 @@ + + + diff --git a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/da.xml b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/da.xml index e6f693f7..54dc95b8 100644 --- a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/da.xml +++ b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/da.xml @@ -24,6 +24,9 @@ Vælg og konfigurer en datakilde Vælg og konfigurer en liste + Vælg og konfigurer en datakilde og en listeeditor, tak. + Vælg og konfigurer en datakilde, tak. + Vælg og konfigurer en liste, tak. diff --git a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml index 74872d63..eb6558d7 100644 --- a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml +++ b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml @@ -24,6 +24,9 @@ Select and configure a data source Select and configure a list editor + Please select and configure a data source and list editor. + Please select and configure a data source. + Please select and configure a list editor. Type to select an item... diff --git a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/pt-br.xml b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/pt-br.xml index b749c22a..7587ccbf 100644 --- a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/pt-br.xml +++ b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/pt-br.xml @@ -24,6 +24,9 @@ Selecionar e configurar a origem dos dados Selecionar e configurar o editor de lista + Selecionar e configurar a origem dos dados e o editor de lista, por favor. + Selecionar e configurar a origem dos dados, por favor. + Selecionar e configurar o editor de lista, por favor. From 91947d63b09e5aaeed0fe59c459725dfc56a37bb Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 11 Mar 2021 10:25:05 +0000 Subject: [PATCH 11/30] Umbraco icon temp CSS fix Thanks to @bjarnef for the CSS amend (for issue #77) ref: https://github.com/leekelleher/umbraco-contentment/issues/77#issuecomment-796269154 --- src/Umbraco.Community.Contentment/Web/UI/backoffice-ui-shim.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Community.Contentment/Web/UI/backoffice-ui-shim.css b/src/Umbraco.Community.Contentment/Web/UI/backoffice-ui-shim.css index 0555aa78..c4d74d22 100644 --- a/src/Umbraco.Community.Contentment/Web/UI/backoffice-ui-shim.css +++ b/src/Umbraco.Community.Contentment/Web/UI/backoffice-ui-shim.css @@ -22,7 +22,7 @@ [class].icon-umbraco { background-image: url(/umbraco/assets/img/application/logo_black.png); background-repeat: no-repeat; - background-size: cover; + background-size: contain; } .umb-action-link .icon-umbraco { From a5e9146cbfd1d119d5114912e785a673ff84e3d3 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Fri, 19 Mar 2021 16:20:08 +0000 Subject: [PATCH 12/30] Data List - "Buttons" list editor Reverts 25e54c660af5061f91847e7dc6a35de243bb3586 --- .../Buttons/ButtonsDataListEditor.cs | 89 ++++++++++++++++++ .../DataEditors/Buttons/buttons.css | 21 +++++ .../DataEditors/Buttons/buttons.html | 17 ++++ .../DataEditors/Buttons/buttons.js | 93 +++++++++++++++++++ .../Umbraco.Community.Contentment.csproj | 4 + 5 files changed, 224 insertions(+) create mode 100644 src/Umbraco.Community.Contentment/DataEditors/Buttons/ButtonsDataListEditor.cs create mode 100644 src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.css create mode 100644 src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.html create mode 100644 src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.js diff --git a/src/Umbraco.Community.Contentment/DataEditors/Buttons/ButtonsDataListEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/Buttons/ButtonsDataListEditor.cs new file mode 100644 index 00000000..a0ef661b --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/Buttons/ButtonsDataListEditor.cs @@ -0,0 +1,89 @@ +/* Copyright © 2020 Lee Kelleher. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +using System.Collections.Generic; +using Umbraco.Core; +using Umbraco.Core.IO; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Community.Contentment.DataEditors +{ + public sealed class ButtonsDataListEditor : IDataListEditor + { + internal const string DataEditorViewPath = Constants.Internals.EditorsPathRoot + "buttons.html"; + + public string Name => "Buttons"; + + public string Description => "Select multiple values from a group of buttons."; + + public string Icon => "icon-tab"; + + public IEnumerable Fields => new ConfigurationField[] + { + new ConfigurationField + { + Key = "defaultIcon", + Name = "Default icon", + Description = "Select an icon to be displayed as the default icon, (for when no icon is available).", + View = IOHelper.ResolveUrl("~/umbraco/views/propertyeditors/listview/icon.prevalues.html"), + }, + new ConfigurationField + { + Key = "size", + Name = "Size", + Description = "Select the button size. By default this is set to 'medium'.", + View = IOHelper.ResolveUrl(RadioButtonListDataListEditor.DataEditorViewPath), + Config = new Dictionary + { + { Constants.Conventions.ConfigurationFieldAliases.Items, new[] + { + new DataListItem { Name = "Small", Value = "s" }, + new DataListItem { Name = "Medium", Value = "m" }, + new DataListItem { Name = "Large", Value = "l" }, + } + }, + { Constants.Conventions.ConfigurationFieldAliases.DefaultValue, "m" } + } + }, + new ConfigurationField + { + Key = "hideIcon", + Name = "Hide icon?", + Description = "Select to hide the item's icon and only display the name.", + View = "boolean", + }, + new ConfigurationField + { + Key = "hideName", + Name = "Hide name?", + Description = "Select to hide the item's name and only display the icon.
(Of course, don't hide both the name and icon) 😉", + View = "boolean", + }, + new ConfigurationField + { + Key = "enableMultiple", + Name = "Multiple selection?", + Description = "Select to enable picking multiple items.", + View = "boolean", + }, + }; + + public Dictionary DefaultValues => new Dictionary + { + { "defaultIcon", Core.Constants.Icons.DefaultIcon }, + }; + + public Dictionary DefaultConfig => default; + + public bool HasMultipleValues(Dictionary config) + { + return config.TryGetValue("enableMultiple", out var tmp) && tmp.TryConvertTo().Result; + } + + public OverlaySize OverlaySize => OverlaySize.Small; + + public string View => DataEditorViewPath; + } +} diff --git a/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.css b/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.css new file mode 100644 index 00000000..550d4892 --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.css @@ -0,0 +1,21 @@ +/* Copyright © 2020 Lee Kelleher. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +.contentment.lk-buttons .umb-button { + margin-bottom: 5px; +} + +.contentment.lk-buttons .umb-button--selected .umb-button__button { + background-color: #f5c1bc; +} + +.contentment.lk-buttons .umb-button__button { + padding-left: 20px; + padding-right: 20px; +} + + .contentment.lk-buttons .umb-button__button[disabled] { + opacity: 0.5; + } diff --git a/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.html b/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.html new file mode 100644 index 00000000..122b583d --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.html @@ -0,0 +1,17 @@ + + +
+ + +
diff --git a/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.js b/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.js new file mode 100644 index 00000000..1212e879 --- /dev/null +++ b/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.js @@ -0,0 +1,93 @@ +/* Copyright © 2020 Lee Kelleher. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.Buttons.Controller", [ + "$scope", + function ($scope) { + + // console.log("buttons.model", $scope.model); + + var defaultConfig = { + defaultIcon: "icon-science", + defaultValue: [], + items: [], + enableMultiple: 0, + hideIcon: 0, + hideName: 0, + size: "m", + }; + var config = Object.assign({}, defaultConfig, $scope.model.config); + + var vm = this; + + function init() { + $scope.model.value = $scope.model.value || config.defaultValue; + + if (Array.isArray($scope.model.value) === false) { + $scope.model.value = [$scope.model.value]; + } + + vm.multiple = Object.toBoolean(config.enableMultiple); + + if (vm.multiple === false && $scope.model.value.length > 0) { + $scope.model.value.splice(1); + } + + vm.items = config.items.slice(); + + vm.hideIcon = Object.toBoolean(config.hideIcon); + vm.hideName = Object.toBoolean(config.hideName); + + vm.uniqueId = $scope.model.hasOwnProperty("dataTypeKey") + ? [$scope.model.alias, $scope.model.dataTypeKey.substring(0, 8)].join("-") + : $scope.model.alias; + + var sizes = { + "s": "small", + "m": "medium", + "l": "large", + }; + + vm.size = config.size; + + vm.defaultIcon = config.defaultIcon; + vm.iconExtras = sizes[config.size] + (vm.hideName === false ? " mr2 " : " mr0 "); + + vm.items.forEach(function (item) { + item.selected = $scope.model.value.indexOf(item.value) > -1; + }); + + vm.select = select; + }; + + function select(item) { + + item.selected = item.selected === false; + $scope.model.value = []; + + vm.items.forEach(function (x) { + + if (vm.multiple === false) { + x.selected = x.value === item.value; + } + + if (x.selected) { + $scope.model.value.push(x.value); + } + + }); + + setDirty(); + }; + + function setDirty() { + if ($scope.propertyForm) { + $scope.propertyForm.$setDirty(); + } + }; + + init(); + } +]); diff --git a/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj b/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj index f9927038..28589501 100644 --- a/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj +++ b/src/Umbraco.Community.Contentment/Umbraco.Community.Contentment.csproj @@ -296,6 +296,7 @@ + @@ -418,6 +419,9 @@ + + + From f9a0f345e40c3345e7a9fd5380a8455039fc2177 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 22 Mar 2021 15:44:40 +0000 Subject: [PATCH 13/30] Buttons - replaced "hide icon/name" options with "label style" field --- .../Buttons/ButtonsDataListEditor.cs | 28 +++++++++++-------- .../DataEditors/Buttons/buttons.js | 7 ++--- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/Buttons/ButtonsDataListEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/Buttons/ButtonsDataListEditor.cs index a0ef661b..4fe0c840 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/Buttons/ButtonsDataListEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/Buttons/ButtonsDataListEditor.cs @@ -49,17 +49,22 @@ public sealed class ButtonsDataListEditor : IDataListEditor }, new ConfigurationField { - Key = "hideIcon", - Name = "Hide icon?", - Description = "Select to hide the item's icon and only display the name.", - View = "boolean", - }, - new ConfigurationField - { - Key = "hideName", - Name = "Hide name?", - Description = "Select to hide the item's name and only display the icon.
(Of course, don't hide both the name and icon) 😉", - View = "boolean", + Key = "labelStyle", + Name = "Label style", + Description = "Select the style of the button's label.", + View = IOHelper.ResolveUrl(RadioButtonListDataListEditor.DataEditorViewPath), + Config = new Dictionary + { + { Constants.Conventions.ConfigurationFieldAliases.Items, new[] + { + new DataListItem { Name = "Icon and Text", Value = "both", Description = "Displays both the item's icon and name." }, + new DataListItem { Name = "Icon only", Value = "icon", Description = "Hides the item's name and only displays the icon." }, + new DataListItem { Name = "Text only", Value = "text", Description = "Hides the item's icon and only displays the name." }, + } + }, + { Constants.Conventions.ConfigurationFieldAliases.DefaultValue, "both" }, + { ShowDescriptionsConfigurationField.ShowDescriptions, Constants.Values.True }, + } }, new ConfigurationField { @@ -73,6 +78,7 @@ public sealed class ButtonsDataListEditor : IDataListEditor public Dictionary DefaultValues => new Dictionary { { "defaultIcon", Core.Constants.Icons.DefaultIcon }, + { "labelStyle", "both" }, }; public Dictionary DefaultConfig => default; diff --git a/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.js b/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.js index 1212e879..7c49d787 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.js +++ b/src/Umbraco.Community.Contentment/DataEditors/Buttons/buttons.js @@ -14,8 +14,7 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. defaultValue: [], items: [], enableMultiple: 0, - hideIcon: 0, - hideName: 0, + labelStyle: "both", size: "m", }; var config = Object.assign({}, defaultConfig, $scope.model.config); @@ -37,8 +36,8 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. vm.items = config.items.slice(); - vm.hideIcon = Object.toBoolean(config.hideIcon); - vm.hideName = Object.toBoolean(config.hideName); + vm.hideIcon = config.labelStyle === 'text'; + vm.hideName = config.labelStyle === 'icon'; vm.uniqueId = $scope.model.hasOwnProperty("dataTypeKey") ? [$scope.model.alias, $scope.model.dataTypeKey.substring(0, 8)].join("-") From dc3730cc023a519c878630bd514a04cd543221c4 Mon Sep 17 00:00:00 2001 From: Dave Woestenborghs Date: Tue, 23 Mar 2021 15:24:47 +0100 Subject: [PATCH 14/30] Fix for #81 This sets the selected value to the first item in the list when creating new content and no empty items are allowed. --- .../DataEditors/DropdownList/dropdown-list.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.js b/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.js index 25f96990..037124c8 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.js +++ b/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.js @@ -29,7 +29,12 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. vm.items = config.items.slice(); vm.allowEmpty = Object.toBoolean(config.allowEmpty) && vm.items.some(x => x.value === $scope.model.value); - + + if(vm.allowEmpty === false && $scope.model.value === '' && vm.items.length > 0) { + // set to first item in list when no empty values are allowed. + $scope.model.value = vm.items[0].value; + } + vm.htmlAttributes = config.htmlAttributes; vm.uniqueId = $scope.model.hasOwnProperty("dataTypeKey") From f1c96080493702a2525a91f1c3df609f7b3c4f7f Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 24 Mar 2021 17:16:01 +0000 Subject: [PATCH 15/30] DropdownList - hides extra empty option AngularJS automatically adds an empty option to the top of the options, until the `model.value` is selected. If the "allowEmpty" field is enabled, this update will automatically set the `model.value` to be the first item value. --- .../DropdownListDataListEditor.cs | 7 +++++-- .../DropdownList/dropdown-list.html | 2 +- .../DataEditors/DropdownList/dropdown-list.js | 19 ++++++++++--------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/DropdownList/DropdownListDataListEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/DropdownList/DropdownListDataListEditor.cs index 0bea99d7..38545921 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DropdownList/DropdownListDataListEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DropdownList/DropdownListDataListEditor.cs @@ -25,7 +25,7 @@ public sealed class DropdownListDataListEditor : IDataListEditor { Key = AllowEmpty, Name = "Allow empty?", - Description = "Enable to allow an empty option at the top of the dropdown list.", + Description = "Enable to allow an empty option at the top of the dropdown list.
When disabled, the default value will be set to the first option.", View = "views/propertyeditors/boolean/boolean.html", Config = new Dictionary { @@ -35,7 +35,10 @@ public sealed class DropdownListDataListEditor : IDataListEditor new HtmlAttributesConfigurationField(), }; - public Dictionary DefaultValues => default; + public Dictionary DefaultValues => new Dictionary + { + { AllowEmpty, Constants.Values.True } + }; public Dictionary DefaultConfig => default; diff --git a/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.html b/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.html index 2e32e0a9..49fe1c15 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.html +++ b/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.html @@ -10,6 +10,6 @@ ng-model="model.value" ng-change="vm.change()" ng-options="item.value as item.name disable when item.disabled for item in vm.items"> - +
diff --git a/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.js b/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.js index 037124c8..d0c423cd 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.js +++ b/src/Umbraco.Community.Contentment/DataEditors/DropdownList/dropdown-list.js @@ -20,21 +20,22 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. var vm = this; function init() { + + config.showEmpty = Object.toBoolean(config.allowEmpty); + + vm.items = config.items.slice(); + $scope.model.value = $scope.model.value || config.defaultValue; if (Array.isArray($scope.model.value)) { $scope.model.value = $scope.model.value[0]; } - - vm.items = config.items.slice(); - - vm.allowEmpty = Object.toBoolean(config.allowEmpty) && vm.items.some(x => x.value === $scope.model.value); - - if(vm.allowEmpty === false && $scope.model.value === '' && vm.items.length > 0) { - // set to first item in list when no empty values are allowed. + else if (config.showEmpty === false && $scope.model.value === '' && vm.items.length > 0) { $scope.model.value = vm.items[0].value; } - + + vm.showEmpty = config.showEmpty === true && vm.items.some(x => x.value === $scope.model.value); + vm.htmlAttributes = config.htmlAttributes; vm.uniqueId = $scope.model.hasOwnProperty("dataTypeKey") @@ -45,7 +46,7 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. }; function change() { - vm.allowEmpty = Object.toBoolean(config.allowEmpty) && vm.items.some(x => x.value === $scope.model.value); + vm.showEmpty = config.showEmpty === true && vm.items.some(x => x.value === $scope.model.value); }; init(); From 268dfa544b550101031752955e389d2719c631ae Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 31 Mar 2021 06:48:51 +0100 Subject: [PATCH 16/30] DataList - Preview, added label for no items --- .../DataEditors/DataList/data-list.preview.html | 4 +++- .../DataEditors/DataList/data-list.preview.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html index f8c1ea50..537b7c60 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html @@ -17,6 +17,9 @@
+
+ The data source returned no items to preview. +
-
diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js index 8d0a488e..c6ddee27 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js @@ -67,7 +67,7 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. .then(function (result) { vm.property = result; - vm.state = "loaded"; + vm.state = result.config.items.length > 0 ? "loaded" : "noItems"; }); } From dd67bd456c1dd9e9e2ca13c83178acdbd1bf49db Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 31 Mar 2021 06:49:40 +0100 Subject: [PATCH 17/30] DataList - Enabled filter to overlay if there are over 10 items --- .../DataList/DataListConfigurationEditor.cs | 10 ++++++---- .../TextInput/TextInputConfigurationEditor.cs | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs index 7ccfba3c..5143443f 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs @@ -36,8 +36,8 @@ public DataListConfigurationEditor(ConfigurationEditorUtility utility) { EnableDevModeConfigurationField.EnableDevMode, Constants.Values.True }, }; - var dataSources = utility.GetConfigurationEditorModels(); - var listEditors = utility.GetConfigurationEditorModels(); + var dataSources = utility.GetConfigurationEditorModels().ToList(); + var listEditors = utility.GetConfigurationEditorModels().ToList(); Fields.Add( DataSource, @@ -47,7 +47,8 @@ public DataListConfigurationEditor(ConfigurationEditorUtility utility) new Dictionary(defaultConfigEditorConfig) { { Constants.Conventions.ConfigurationFieldAliases.AddButtonLabelKey, "contentment_configureDataSource" }, - { Constants.Conventions.ConfigurationFieldAliases.Items, dataSources } + { EnableFilterConfigurationField.EnableFilter, dataSources.Count > 10 ? Constants.Values.True : Constants.Values.False }, + { Constants.Conventions.ConfigurationFieldAliases.Items, dataSources }, }); Fields.Add( @@ -58,7 +59,8 @@ public DataListConfigurationEditor(ConfigurationEditorUtility utility) new Dictionary(defaultConfigEditorConfig) { { Constants.Conventions.ConfigurationFieldAliases.AddButtonLabelKey, "contentment_configureListEditor" }, - { Constants.Conventions.ConfigurationFieldAliases.Items, listEditors } + { EnableFilterConfigurationField.EnableFilter, dataSources.Count > 10 ? Constants.Values.True : Constants.Values.False }, + { Constants.Conventions.ConfigurationFieldAliases.Items, listEditors }, }); Fields.Add( diff --git a/src/Umbraco.Community.Contentment/DataEditors/TextInput/TextInputConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/TextInput/TextInputConfigurationEditor.cs index e013651b..ea7ed286 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/TextInput/TextInputConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/TextInput/TextInputConfigurationEditor.cs @@ -21,7 +21,7 @@ public TextInputConfigurationEditor(ConfigurationEditorUtility utility) { _utility = utility; - var dataSources = _utility.GetConfigurationEditorModels(); + var dataSources = _utility.GetConfigurationEditorModels().ToList(); Fields.Add(new ConfigurationField { @@ -43,6 +43,7 @@ public TextInputConfigurationEditor(ConfigurationEditorUtility utility) { DisableSortingConfigurationField.DisableSorting, Constants.Values.True }, { Constants.Conventions.ConfigurationFieldAliases.OverlayView, IOHelper.ResolveUrl(ConfigurationEditorDataEditor.DataEditorOverlayViewPath) }, { EnableDevModeConfigurationField.EnableDevMode, Constants.Values.True }, + { EnableFilterConfigurationField.EnableFilter, dataSources.Count > 10 ? Constants.Values.True : Constants.Values.False }, { Constants.Conventions.ConfigurationFieldAliases.Items, dataSources }, }); From 6aecfaab0c18f32e8f194b58f337e1a538e1a9da Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 31 Mar 2021 06:50:57 +0100 Subject: [PATCH 18/30] Tags - fixed bug with the unique ID This caused an error in the DataList preview feature, as the model didn't contain the "dataTypeKey" property. --- src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js index ed31ddd1..98f3ccf3 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js +++ b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js @@ -39,7 +39,9 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. vm.showIcons = Object.toBoolean(config.showIcons); - vm.uniqueId = [$scope.model.alias, $scope.model.dataTypeKey.substring(0, 8)].join("-"); + vm.uniqueId = $scope.model.hasOwnProperty("dataTypeKey") + ? [$scope.model.alias, $scope.model.dataTypeKey.substring(0, 8)].join("-") + : $scope.model.alias; vm.add = add; vm.keyDown = keyDown; From 2b2dae0e1b8664fb8f73bf7d8face0056b399619 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 31 Mar 2021 06:51:29 +0100 Subject: [PATCH 19/30] Tags - marked class as `public` (Forgot to do this previously) --- .../DataEditors/Tags/TagsDataListEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/Tags/TagsDataListEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/Tags/TagsDataListEditor.cs index cd71543a..cdd0fa49 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/Tags/TagsDataListEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/Tags/TagsDataListEditor.cs @@ -8,7 +8,7 @@ namespace Umbraco.Community.Contentment.DataEditors { - internal sealed class TagsDataListEditor : IDataListEditor + public sealed class TagsDataListEditor : IDataListEditor { internal const string DataEditorViewPath = Constants.Internals.EditorsPathRoot + "tags.html"; From f11ff1f5eed4191237c1e81c06e252594243c8e9 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 31 Mar 2021 06:53:05 +0100 Subject: [PATCH 20/30] Contentment dashboard amends Replaced the Easter Egg audio + reduced the animation GIF + relocated to my own URL. --- .../backoffice/contentment/index.html | 6 ++++-- .../Web/UI/backoffice.js | 21 ++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/backoffice/contentment/index.html b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/backoffice/contentment/index.html index cda59ab8..219716a5 100644 --- a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/backoffice/contentment/index.html +++ b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/backoffice/contentment/index.html @@ -39,7 +39,7 @@ - + @@ -104,6 +104,8 @@
Tree dashboard
+
+
Telemetry

By default, the package sends telemetry data about which property-editors are being used (from Contentment only). For more details about the data being captured and transparency on the analysis, please visit leekelleher.com/umbraco/contentment/telemetry.

diff --git a/src/Umbraco.Community.Contentment/Web/UI/backoffice.js b/src/Umbraco.Community.Contentment/Web/UI/backoffice.js index 84fb3d3d..41c5eb03 100644 --- a/src/Umbraco.Community.Contentment/Web/UI/backoffice.js +++ b/src/Umbraco.Community.Contentment/Web/UI/backoffice.js @@ -63,7 +63,26 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.Tree.Control }; vm.vote = function (x) { - vm.nggyu = x == false; + if (x === false && !vm.nggyu) { + + vm.nggyu = true; + + // Kudos to Mathieu 'p01' Henri for this snippet: + // Music SoftSynth https://gist.github.com/p01/1285255 + var softSynth = function (f) { return eval("for(var t=0,S='RIFF_oO_WAVEfmt " + atob("EAAAAAEAAQBAHwAAQB8AAAEACAA") + "data';++t<3e5;)S+=String.fromCharCode(" + f + ")"); }; + var formula = "(t<<3)*[8/9,1,9/8,6/5,4/3,3/2,0][[0xd2d2c8,0xce4088,0xca32c8,0x8e4009][t>>14&3]>>(0x3dbe4688>>((t>>10&15)>9?18:t>>10&15)*3&7)*3&7]&255"; + vm.audio = new Audio("data:audio/wav;base64," + btoa(softSynth(formula))); + vm.audio.play(); + + } else { + + vm.nggyu = false; + + if (vm.audio) { + vm.audio.pause(); + } + + } }; vm.csharp = "csharp"; From 601616dbff8af242e2b7040f83f9663dd81084b9 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 31 Mar 2021 06:54:54 +0100 Subject: [PATCH 21/30] Notes - style amend for blockquote content --- .../DataEditors/Notes/notes.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Umbraco.Community.Contentment/DataEditors/Notes/notes.css b/src/Umbraco.Community.Contentment/DataEditors/Notes/notes.css index 0e5012ab..c546d6db 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/Notes/notes.css +++ b/src/Umbraco.Community.Contentment/DataEditors/Notes/notes.css @@ -11,6 +11,11 @@ margin-bottom: 10px; } + .umb-readonlyvalue .well blockquote p { + font-size: 16px; + margin-bottom: 10px; + } + .umb-readonlyvalue .well hr { border-bottom: 1px solid #e0e0e5; margin: 15px 0; From 5552b41a1b1d435a70d3b294663467fdcc8a1697 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 31 Mar 2021 13:20:45 +0100 Subject: [PATCH 22/30] Refactored `PublishedContentContractResolver` Separated fields for Content, Elements, and Properties. Omits internally used fields, e.g. IDs like TemplateId, WriterId, etc. If you are using this for external consumption, then those internal IDs are less relevant. Extension points are public properties for adding custom exclusions for property names, and whether to prefix the system fields with an underscore, "`_`". These amends shouldn't be considered a breaking-change, as the class signatures are unchanged. --- .../PublishedContentContractResolver.cs | 104 +++++++++++++++--- 1 file changed, 89 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Community.Contentment/Web/Serialization/PublishedContentContractResolver.cs b/src/Umbraco.Community.Contentment/Web/Serialization/PublishedContentContractResolver.cs index 33175758..056fd740 100644 --- a/src/Umbraco.Community.Contentment/Web/Serialization/PublishedContentContractResolver.cs +++ b/src/Umbraco.Community.Contentment/Web/Serialization/PublishedContentContractResolver.cs @@ -2,16 +2,17 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -/* This code has been derived from Rasmus Fjord's code, supplied on an - * Our Umbraco forum post: +/* This code was originally based on code by Rasmus Fjord, + * supplied on an Our Umbraco forum post: * https://our.umbraco.com/forum/umbraco-8/98381-serializing-an-publishedcontentmodel-modelsbuilder-model-in-v8#comment-310148 * From searching GitHub, I also found René Pjengaard's code: * https://github.com/rpjengaard/merchelloshop/blob/master/dev/code/Json/Resolvers/PublishedContentContractResolver.cs * It is unknown (to me) who the original author is, and how the code - * has been licensed. I'll assume it's available under MIT license. */ + * has been licensed. My assumption is under the MIT license. */ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -20,26 +21,43 @@ namespace Umbraco.Community.Contentment.Web.Serialization { - public sealed class PublishedContentContractResolver : CamelCasePropertyNamesContractResolver + public sealed class PublishedContentContractResolver : DefaultContractResolver { public static readonly PublishedContentContractResolver Instance = new PublishedContentContractResolver(); - private readonly Dictionary _converterLookup; + private readonly Dictionary _converterLookup; + private readonly HashSet _ignoreFromCustom; + private readonly HashSet _ignoreFromElement; private readonly HashSet _ignoreFromContent; private readonly HashSet _ignoreFromProperty; + private readonly HashSet _systemProperties; public PublishedContentContractResolver() + : base() { - _converterLookup = new Dictionary(StringComparer.OrdinalIgnoreCase) + NamingStrategy = new CamelCaseNamingStrategy { - { nameof(IPublishedContent.ItemType), new StringEnumConverter() }, + OverrideSpecifiedNames = true, + ProcessDictionaryKeys = true, }; - _ignoreFromContent = new HashSet(StringComparer.OrdinalIgnoreCase) + _converterLookup = new Dictionary() + { + { typeof(PublishedItemType), new StringEnumConverter() } + }; + + _ignoreFromCustom = new HashSet(StringComparer.OrdinalIgnoreCase); + + _ignoreFromElement = new HashSet(StringComparer.OrdinalIgnoreCase) + { + nameof(IPublishedElement.ContentType), + nameof(IPublishedElement.Properties), + }; + + _ignoreFromContent = new HashSet(_ignoreFromElement, StringComparer.OrdinalIgnoreCase) { nameof(IPublishedContent.Children), nameof(IPublishedContent.ChildrenForAllCultures), - nameof(IPublishedContent.ContentType), nameof(IPublishedContent.CreatorId), nameof(IPublishedContent.Cultures), nameof(IPublishedContent.Parent), @@ -51,24 +69,80 @@ public PublishedContentContractResolver() { nameof(IPublishedProperty.PropertyType), }; + + _systemProperties = new HashSet(StringComparer.OrdinalIgnoreCase) + { + nameof(IPublishedContent.CreateDate), + nameof(IPublishedContent.CreatorName), + nameof(IPublishedContent.Id), + nameof(IPublishedContent.ItemType), + nameof(IPublishedElement.Key), + nameof(IPublishedContent.Level), + nameof(IPublishedContent.Name), + nameof(IPublishedContent.Path), + nameof(IPublishedContent.SortOrder), + nameof(IPublishedContent.UpdateDate), + nameof(IPublishedContent.Url), + nameof(IPublishedContent.UrlSegment), + nameof(IPublishedContent.WriterName), + }; + } + + public string[] PropertiesToIgnore + { + set => _ignoreFromCustom.UnionWith(value); + } + + public Dictionary PropertyTypeConverters + { + set + { + foreach (var item in value) + { + if (_converterLookup.ContainsKey(item.Key) == false) + { + _converterLookup.Add(item.Key, item.Value); + } + } + } + } + + public bool PrefixSystemPropertyNamesWithUnderscore { private get; set; } + + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + return base.CreateProperties(type, memberSerialization).OrderBy(p => p.PropertyName).ToList(); } protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); - if (typeof(IPublishedContent).IsAssignableFrom(member.DeclaringType)) + if (_ignoreFromCustom.Contains(member.Name) == true) { - property.ShouldSerialize = _ => _ignoreFromContent.Contains(property.PropertyName) == false; + property.ShouldSerialize = _ => false; } - else if (typeof(IPublishedProperty).IsAssignableFrom(member.DeclaringType)) + else if (typeof(IPublishedContent).IsAssignableFrom(member.DeclaringType) == true) + { + property.ShouldSerialize = _ => _ignoreFromContent.Contains(member.Name) == false; + } + else if (typeof(IPublishedElement).IsAssignableFrom(member.DeclaringType) == true) + { + property.ShouldSerialize = _ => _ignoreFromElement.Contains(member.Name) == false; + } + else if (typeof(IPublishedProperty).IsAssignableFrom(member.DeclaringType) == true) + { + property.ShouldSerialize = _ => _ignoreFromProperty.Contains(member.Name) == false; + } + + if (_converterLookup.ContainsKey(property.PropertyType)) { - property.ShouldSerialize = _ => _ignoreFromProperty.Contains(property.PropertyName) == false; + property.Converter = _converterLookup[property.PropertyType]; } - if (_converterLookup.ContainsKey(property.PropertyName)) + if (PrefixSystemPropertyNamesWithUnderscore == true && _systemProperties.Contains(member.Name) == true) { - property.Converter = _converterLookup[property.PropertyName]; + property.PropertyName = "_" + property.PropertyName; } return property; From e7a6b600b742315dae3aeae901470d6071e59bff Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 7 Apr 2021 08:38:52 +0100 Subject: [PATCH 23/30] C# coding style, explicit ` == true` I can appreciate that this coding style could drive some developers up the wall, (and may consider it redundant code), these are typically the same developers who never adopted the use of `var`. For me, it improves readability (especially when reading code outside of Visual Studio, e.g. on GitHub directly). In terms of readability, it's about cognitive load, e.g. use of `TryGetValue` makes the presumption that you already understand the method's return value, (implicit coercion), whereas with the `== true` condition, you can see it's a boolean check. In terms of performance, I don't buy into the "redundant code" reason, as the C# compiler will optimize for this explicitly. After all that, who are we writing this open-source code for? A compiler or a human? --- .../Core/DictionaryExtensions.cs | 8 ++++---- .../DataEditors/Bytes/BytesConfigurationEditor.cs | 2 +- .../CodeEditor/CodeEditorConfigurationEditor.cs | 6 +++--- .../ContentBlocks/ContentBlockPreviewView.cs | 2 +- .../ContentBlocks/ContentBlocksConfigurationEditor.cs | 4 ++-- .../ContentBlocks/ContentBlocksDataValueEditor.cs | 4 ++-- .../ContentBlocks/ContentBlocksValueConverter.cs | 2 +- .../ContentBlocks/ContentTypeCacheHelper.cs | 6 +++--- .../DataList/DataListConfigurationEditor.cs | 8 ++++---- .../DataEditors/DataList/DataListDataEditor.cs | 4 ++-- .../DataEditors/DataList/DataListValueConverter.cs | 8 ++++---- .../DataList/DataSources/EnumDataListSource.cs | 6 +++--- .../DataList/DataSources/JsonDataListSource.cs | 10 +++++----- .../DataList/DataSources/SqlDataListSource.cs | 4 ++-- .../DataSources/TextDelimitedDataListSource.cs | 8 ++++---- .../DataSources/UmbracoContentDataListSource.cs | 4 ++-- .../DataList/DataSources/XmlDataListSource.cs | 4 ++-- .../DataEditors/Notes/NotesDataEditor.cs | 2 +- .../NumberInput/NumberInputValueConverter.cs | 2 +- .../DataEditors/RenderMacro/RenderMacroDataEditor.cs | 2 +- .../TextInput/TextInputConfigurationEditor.cs | 4 ++-- .../Web/Controllers/EnumDataListSourceApiController.cs | 6 +++--- .../Serialization/PublishedContentContractResolver.cs | 2 +- 23 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/Umbraco.Community.Contentment/Core/DictionaryExtensions.cs b/src/Umbraco.Community.Contentment/Core/DictionaryExtensions.cs index ca9589fa..e9ffae3f 100644 --- a/src/Umbraco.Community.Contentment/Core/DictionaryExtensions.cs +++ b/src/Umbraco.Community.Contentment/Core/DictionaryExtensions.cs @@ -11,7 +11,7 @@ internal static class DictionaryExtensions { public static TValueOut GetValueAs(this IDictionary config, TKey key, TValueOut defaultValue = default) { - if (config.TryGetValue(key, out var tmp)) + if (config.TryGetValue(key, out var tmp) == true) { if (tmp is TValueOut value) { @@ -19,7 +19,7 @@ public static TValueOut GetValueAs(this IDictionary(); - if (attempt.Success) + if (attempt.Success == true) { return attempt.Result; } @@ -30,7 +30,7 @@ public static TValueOut GetValueAs(this IDictionary(this IDictionary config, TKey key, out TValueOut value) { - if (config.TryGetValue(key, out var tmp1)) + if (config.TryGetValue(key, out var tmp1) == true) { if (tmp1 is TValueOut tmp2) { @@ -39,7 +39,7 @@ public static bool TryGetValueAs(this IDictionary(); - if (attempt.Success) + if (attempt.Success == true) { value = attempt.Result; return attempt.Success; diff --git a/src/Umbraco.Community.Contentment/DataEditors/Bytes/BytesConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/Bytes/BytesConfigurationEditor.cs index b561766c..8af6f7fa 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/Bytes/BytesConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/Bytes/BytesConfigurationEditor.cs @@ -57,7 +57,7 @@ public override IDictionary ToValueEditor(object configuration) { config.Add(Filter, "formatBytes"); - if (config.ContainsKey(Format) == false && config.ContainsKey(Kilo) && config.ContainsKey(Decimals)) + if (config.ContainsKey(Format) == false && config.ContainsKey(Kilo) == true && config.ContainsKey(Decimals) == true) { config.Add(Format, new { diff --git a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs index e019ea07..3885be21 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/CodeEditor/CodeEditorConfigurationEditor.cs @@ -24,7 +24,7 @@ public CodeEditorConfigurationEditor() var targetPath = "~/umbraco/lib/ace-builds/src-min-noconflict/"; var aceEditorPath = IOHelper.MapPath(targetPath); - if (Directory.Exists(aceEditorPath)) + if (Directory.Exists(aceEditorPath) == true) { var aceEditorFiles = Directory.GetFiles(aceEditorPath, "*.js"); if (aceEditorFiles != null && aceEditorFiles.Length > 0) @@ -35,13 +35,13 @@ public CodeEditorConfigurationEditor() foreach (var file in aceEditorFiles) { var filename = Path.GetFileNameWithoutExtension(file); - if (filename.StartsWith("mode-")) + if (filename.StartsWith("mode-") == true) { var mode = filename.Replace("mode-", string.Empty).ToLower(); modes.Add(new DataListItem { Name = mode.ToFirstUpperInvariant(), Value = mode }); } - if (filename.StartsWith("theme-")) + if (filename.StartsWith("theme-") == true) { var theme = filename.Replace("theme-", string.Empty).ToLower(); themes.Add(new DataListItem { Name = theme.ToFirstUpperInvariant(), Value = theme }); diff --git a/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlockPreviewView.cs b/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlockPreviewView.cs index 459afab7..516564d2 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlockPreviewView.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlockPreviewView.cs @@ -24,7 +24,7 @@ protected override void SetViewData(ViewDataDictionary viewData) { void setProperty(string key, Action action) { - if (viewData.TryGetValueAs(key, out T tmp)) + if (viewData.TryGetValueAs(key, out T tmp) == true) { action(tmp); diff --git a/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksConfigurationEditor.cs index 52d7b46a..b6da9cd4 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksConfigurationEditor.cs @@ -127,13 +127,13 @@ public override IDictionary ToValueEditor(object configuration) var item = (JObject)array2[i]; // NOTE: Patches a breaking-change. I'd renamed `type` to become `key`. [LK:2020-04-03] - if (item.ContainsKey("key") == false && item.ContainsKey("type")) + if (item.ContainsKey("key") == false && item.ContainsKey("type") == true) { item.Add("key", item["type"]); item.Remove("type"); } - if (Guid.TryParse(item.Value("key"), out var guid) && _elementTypes.ContainsKey(guid)) + if (Guid.TryParse(item.Value("key"), out var guid) && _elementTypes.ContainsKey(guid) == true) { var elementType = _elementTypes[guid]; diff --git a/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksDataValueEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksDataValueEditor.cs index a297f55b..643969b4 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksDataValueEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksDataValueEditor.cs @@ -43,7 +43,7 @@ public ContentBlocksDataValueEditor( public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var value = property.GetValue(culture, segment)?.ToString(); - if (string.IsNullOrWhiteSpace(value)) + if (string.IsNullOrWhiteSpace(value) == true) { return base.ToEditor(property, dataTypeService, culture, segment); } @@ -105,7 +105,7 @@ public override object ToEditor(Property property, IDataTypeService dataTypeServ public override object FromEditor(ContentPropertyData editorValue, object currentValue) { var value = editorValue?.Value?.ToString(); - if (string.IsNullOrWhiteSpace(value)) + if (string.IsNullOrWhiteSpace(value) == true) { return base.FromEditor(editorValue, currentValue); } diff --git a/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksValueConverter.cs b/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksValueConverter.cs index faba7bc0..bb093bb3 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksValueConverter.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentBlocksValueConverter.cs @@ -54,7 +54,7 @@ public override object ConvertIntermediateToObject(IPublishedElement owner, IPub foreach (var item in items) { - if (item == null || item.ElementType.Equals(Guid.Empty)) + if (item == null || item.ElementType == Guid.Empty) continue; // NOTE: [LK:2019-09-03] Why `IPublishedCache` doesn't support Guids or UDIs, I do not know!? diff --git a/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentTypeCacheHelper.cs b/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentTypeCacheHelper.cs index 557c413d..baddc58f 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentTypeCacheHelper.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/ContentBlocks/ContentTypeCacheHelper.cs @@ -42,7 +42,7 @@ public static void TryAdd(Guid guid, string alias, string icon = null) public static bool TryGetAlias(Guid key, out string alias, IContentTypeService contentTypeService = null) { - if (_forward.TryGetValue(key, out alias)) + if (_forward.TryGetValue(key, out alias) == true) return true; // The alias isn't cached, we can attempt to get it via the content-type service, using the GUID. @@ -62,7 +62,7 @@ public static bool TryGetAlias(Guid key, out string alias, IContentTypeService c public static bool TryGetIcon(string alias, out string icon, IContentTypeService contentTypeService = null) { - if (_icons.TryGetValue(alias, out icon)) + if (_icons.TryGetValue(alias, out icon) == true) return true; // The icon isn't cached, we can attempt to get it via the content-type service, using the alias. @@ -82,7 +82,7 @@ public static bool TryGetIcon(string alias, out string icon, IContentTypeService public static bool TryGetGuid(string alias, out Guid key, IContentTypeService contentTypeService = null) { - if (_reverse.TryGetValue(alias, out key)) + if (_reverse.TryGetValue(alias, out key) == true) return true; // The GUID isn't cached, we can attempt to get it via the content-type service, using the alias. diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs index 5143443f..809ac1c2 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListConfigurationEditor.cs @@ -76,10 +76,10 @@ public override IDictionary ToValueEditor(object configuration) var toValueEditor = new Dictionary(); - if (config.TryGetValueAs(DataSource, out JArray array1) && array1.Count > 0 && array1[0] is JObject item1) + if (config.TryGetValueAs(DataSource, out JArray array1) == true && array1.Count > 0 && array1[0] is JObject item1) { // NOTE: Patches a breaking-change. I'd renamed `type` to become `key`. [LK:2020-04-03] - if (item1.ContainsKey("key") == false && item1.ContainsKey("type")) + if (item1.ContainsKey("key") == false && item1.ContainsKey("type") == true) { item1.Add("key", item1["type"]); item1.Remove("type"); @@ -95,10 +95,10 @@ public override IDictionary ToValueEditor(object configuration) } } - if (config.TryGetValueAs(ListEditor, out JArray array2) && array2.Count > 0 && array2[0] is JObject item2) + if (config.TryGetValueAs(ListEditor, out JArray array2) == true && array2.Count > 0 && array2[0] is JObject item2) { // NOTE: Patches a breaking-change. I'd renamed `type` to become `key`. [LK:2020-04-03] - if (item2.ContainsKey("key") == false && item2.ContainsKey("type")) + if (item2.ContainsKey("key") == false && item2.ContainsKey("type") == true) { item2.Add("key", item2["type"]); item2.Remove("type"); diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListDataEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListDataEditor.cs index 6105a94c..3de04412 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListDataEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListDataEditor.cs @@ -54,12 +54,12 @@ public IDataValueEditor GetValueEditor(object configuration) var view = default(string); if (configuration is Dictionary config && - config.TryGetValueAs(DataListConfigurationEditor.ListEditor, out JArray array) && + config.TryGetValueAs(DataListConfigurationEditor.ListEditor, out JArray array) == true && array.Count > 0 && array[0] is JObject item) { // NOTE: Patches a breaking-change. I'd renamed `type` to become `key`. [LK:2020-04-03] - if (item.ContainsKey("key") == false && item.ContainsKey("type")) + if (item.ContainsKey("key") == false && item.ContainsKey("type") == true) { item.Add("key", item["type"]); item.Remove("type"); diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListValueConverter.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListValueConverter.cs index 119d12b5..03956a4d 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListValueConverter.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListValueConverter.cs @@ -125,13 +125,13 @@ private void TryGetPropertyTypeConfiguration(IPublishedPropertyType propertyType converter = default; if (propertyType.DataType.Configuration is Dictionary configuration && - configuration.TryGetValue(DataListConfigurationEditor.DataSource, out var tmp1) && + configuration.TryGetValue(DataListConfigurationEditor.DataSource, out var tmp1) == true && tmp1 is JArray array1 && array1.Count > 0 && array1[0] is JObject obj1 && - configuration.TryGetValue(DataListConfigurationEditor.ListEditor, out var tmp2) && + configuration.TryGetValue(DataListConfigurationEditor.ListEditor, out var tmp2) == true && tmp2 is JArray array2 && array2.Count > 0 && array2[0] is JObject obj2) { // NOTE: Patches a breaking-change. I'd renamed `type` to become `key`. [LK:2020-04-03] - if (obj1.ContainsKey("key") == false && obj1.ContainsKey("type")) + if (obj1.ContainsKey("key") == false && obj1.ContainsKey("type") == true) { obj1.Add("key", obj1["type"]); obj1.Remove("type"); @@ -146,7 +146,7 @@ tmp1 is JArray array1 && array1.Count > 0 && array1[0] is JObject obj1 && } // NOTE: Patches a breaking-change. I'd renamed `type` to become `key`. [LK:2020-04-03] - if (obj2.ContainsKey("key") == false && obj2.ContainsKey("type")) + if (obj2.ContainsKey("key") == false && obj2.ContainsKey("type") == true) { obj2.Add("key", obj2["type"]); obj2.Remove("type"); diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/EnumDataListSource.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/EnumDataListSource.cs index 58e50bd8..614d2f3f 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/EnumDataListSource.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/EnumDataListSource.cs @@ -93,7 +93,7 @@ public IEnumerable GetItems(Dictionary config) }); } - if (config.TryGetValueAs("sortAlphabetically", out string boolean) && boolean.Equals("1")) + if (config.TryGetValueAs("sortAlphabetically", out string boolean) == true && boolean == "1") { return items.OrderBy(x => x.Name, StringComparer.InvariantCultureIgnoreCase); } @@ -103,7 +103,7 @@ public IEnumerable GetItems(Dictionary config) public Type GetValueType(Dictionary config) { - if (config.TryGetValueAs("enumType", out JArray array)) + if (config.TryGetValueAs("enumType", out JArray array) == true) { var enumType = array.ToObject(); if (enumType?.Length > 1) @@ -114,7 +114,7 @@ public Type GetValueType(Dictionary config) { var type = default(Type); try { type = assembly.GetType(enumType[1]); } catch (Exception ex) { _logger.Error(ex); } - if (type != null && type.IsEnum) + if (type != null && type.IsEnum == true) { return type; } diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/JsonDataListSource.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/JsonDataListSource.cs index ffedc9d7..4d38a1ae 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/JsonDataListSource.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/JsonDataListSource.cs @@ -104,7 +104,7 @@ public IEnumerable GetItems(Dictionary config) var url = config.GetValueAs("url", string.Empty); - if (string.IsNullOrWhiteSpace(url)) + if (string.IsNullOrWhiteSpace(url) == true) { return items; } @@ -118,7 +118,7 @@ public IEnumerable GetItems(Dictionary config) var itemsJsonPath = config.GetValueAs("itemsJsonPath", string.Empty); - if (string.IsNullOrWhiteSpace(itemsJsonPath)) + if (string.IsNullOrWhiteSpace(itemsJsonPath) == true) { return items; } @@ -189,7 +189,7 @@ private JToken GetJson(string url) { var content = string.Empty; - if (url.StartsWith("http", StringComparison.InvariantCultureIgnoreCase)) + if (url.StartsWith("http", StringComparison.InvariantCultureIgnoreCase) == true) { try { @@ -207,7 +207,7 @@ private JToken GetJson(string url) { // assume local file var path = IOHelper.MapPath(url); - if (File.Exists(path)) + if (File.Exists(path) == true) { content = File.ReadAllText(path); } @@ -218,7 +218,7 @@ private JToken GetJson(string url) } } - if (string.IsNullOrWhiteSpace(content)) + if (string.IsNullOrWhiteSpace(content) == true) { _logger.Warn($"The contents of '{url}' was empty. Unable to process JSON data."); diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/SqlDataListSource.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/SqlDataListSource.cs index 958899e5..6368ad8a 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/SqlDataListSource.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/SqlDataListSource.cs @@ -99,7 +99,7 @@ public IEnumerable GetItems(Dictionary config) var query = config.GetValueAs("query", string.Empty); var connectionString = config.GetValueAs("connectionString", string.Empty); - if (string.IsNullOrWhiteSpace(query) || string.IsNullOrWhiteSpace(connectionString)) + if (string.IsNullOrWhiteSpace(query) == true || string.IsNullOrWhiteSpace(connectionString) == true) return items; var settings = ConfigurationManager.ConnectionStrings[connectionString]; @@ -107,7 +107,7 @@ public IEnumerable GetItems(Dictionary config) return items; // NOTE: SQLCE uses a different connection/command. I'm trying to keep this as generic as possible, without resorting to using NPoco. [LK] - if (settings.ProviderName.InvariantEquals(Core.Constants.DatabaseProviders.SqlCe)) + if (settings.ProviderName.InvariantEquals(Core.Constants.DatabaseProviders.SqlCe) == true) { items.AddRange(GetSqlItems(query, settings.ConnectionString)); } diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/TextDelimitedDataListSource.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/TextDelimitedDataListSource.cs index 20db7ad4..17d6d40d 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/TextDelimitedDataListSource.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/TextDelimitedDataListSource.cs @@ -112,7 +112,7 @@ public IEnumerable GetItems(Dictionary config) var iconIndex = config.GetValueAs("iconIndex", -1); var descriptionIndex = config.GetValueAs("descriptionIndex", -1); - if (string.IsNullOrWhiteSpace(url)) + if (string.IsNullOrWhiteSpace(url) == true) { return items; } @@ -129,7 +129,7 @@ public IEnumerable GetItems(Dictionary config) for (var i = 0; i < lines.Length; i++) { - if (i == 0 && ignoreFirstLine) + if (i == 0 && ignoreFirstLine == true) { continue; } @@ -174,7 +174,7 @@ public IEnumerable GetItems(Dictionary config) private string[] GetTextLines(string url) { - if (url.InvariantStartsWith("http")) + if (url.InvariantStartsWith("http") == true) { try { @@ -192,7 +192,7 @@ private string[] GetTextLines(string url) { // assume local file var path = IOHelper.MapPath(url); - if (File.Exists(path)) + if (File.Exists(path) == true) { return File.ReadAllLines(path); } diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/UmbracoContentDataListSource.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/UmbracoContentDataListSource.cs index 46b14b21..03520903 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/UmbracoContentDataListSource.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/UmbracoContentDataListSource.cs @@ -81,7 +81,7 @@ public IEnumerable GetItems(Dictionary config) startNode = umbracoContext.Content.GetSingleByXPath(preview, parsed); } } - else if (GuidUdi.TryParse(parentNode, out var udi) && udi.Guid.Equals(Guid.Empty) == false) + else if (GuidUdi.TryParse(parentNode, out var udi) == true && udi.Guid != Guid.Empty) { startNode = _umbracoContextAccessor.UmbracoContext.Content.GetById(preview, udi.Guid); } @@ -106,7 +106,7 @@ public Type GetValueType(Dictionary config) public object ConvertValue(Type type, string value) { - if (type == typeof(IPublishedContent) && Udi.TryParse(value, out var udi)) + if (type == typeof(IPublishedContent) && Udi.TryParse(value, out var udi) == true) { return _umbracoContextAccessor.UmbracoContext.Content.GetById(udi); } diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/XmlDataListSource.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/XmlDataListSource.cs index e5e9cfcc..10250209 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/XmlDataListSource.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataSources/XmlDataListSource.cs @@ -103,7 +103,7 @@ public IEnumerable GetItems(Dictionary config) var url = config.GetValueAs("url", string.Empty); - if (string.IsNullOrWhiteSpace(url)) + if (string.IsNullOrWhiteSpace(url) == true) return items; var path = url.InvariantStartsWith("http") == false @@ -133,7 +133,7 @@ public IEnumerable GetItems(Dictionary config) var itemsXPath = config.GetValueAs("itemsXPath", string.Empty); - if (string.IsNullOrWhiteSpace(itemsXPath)) + if (string.IsNullOrWhiteSpace(itemsXPath) == true) { return items; } diff --git a/src/Umbraco.Community.Contentment/DataEditors/Notes/NotesDataEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/Notes/NotesDataEditor.cs index 2bf191ed..463d4a0e 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/Notes/NotesDataEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/Notes/NotesDataEditor.cs @@ -47,7 +47,7 @@ public IDataValueEditor GetValueEditor(object configuration) { var hideLabel = false; - if (configuration is Dictionary config && config.ContainsKey(HideLabelConfigurationField.HideLabelAlias)) + if (configuration is Dictionary config && config.ContainsKey(HideLabelConfigurationField.HideLabelAlias) == true) { hideLabel = config[HideLabelConfigurationField.HideLabelAlias].TryConvertTo().Result; } diff --git a/src/Umbraco.Community.Contentment/DataEditors/NumberInput/NumberInputValueConverter.cs b/src/Umbraco.Community.Contentment/DataEditors/NumberInput/NumberInputValueConverter.cs index d41c0fdd..66425714 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/NumberInput/NumberInputValueConverter.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/NumberInput/NumberInputValueConverter.cs @@ -19,7 +19,7 @@ internal sealed class NumberInputValueConverter : PropertyValueConverterBase // TODO: [LK:2020-12-11] Commented out the value-type feature for the time being. Adds additional complexity that I don't currently need. //public override Type GetPropertyValueType(IPublishedPropertyType propertyType) //{ - // if (propertyType.DataType.Configuration is Dictionary config && config.TryGetValue(UmbConfigurationKeys.DataValueType, out var tmp) && tmp is string valueType) + // if (propertyType.DataType.Configuration is Dictionary config && config.TryGetValueAs(UmbConfigurationKeys.DataValueType, out string valueType) == true) // { // switch (valueType) // { diff --git a/src/Umbraco.Community.Contentment/DataEditors/RenderMacro/RenderMacroDataEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/RenderMacro/RenderMacroDataEditor.cs index 0e0f3e0b..5858f4a1 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/RenderMacro/RenderMacroDataEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/RenderMacro/RenderMacroDataEditor.cs @@ -47,7 +47,7 @@ public IDataValueEditor GetValueEditor(object configuration) { var hideLabel = false; - if (configuration is Dictionary config && config.ContainsKey(HideLabelConfigurationField.HideLabelAlias)) + if (configuration is Dictionary config && config.ContainsKey(HideLabelConfigurationField.HideLabelAlias) == true) { hideLabel = config[HideLabelConfigurationField.HideLabelAlias].TryConvertTo().Result; } diff --git a/src/Umbraco.Community.Contentment/DataEditors/TextInput/TextInputConfigurationEditor.cs b/src/Umbraco.Community.Contentment/DataEditors/TextInput/TextInputConfigurationEditor.cs index ea7ed286..8ffb59b0 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/TextInput/TextInputConfigurationEditor.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/TextInput/TextInputConfigurationEditor.cs @@ -76,10 +76,10 @@ public override IDictionary ToValueEditor(object configuration) { var config = base.ToValueEditor(configuration); - if (config.TryGetValueAs(Constants.Conventions.ConfigurationFieldAliases.Items, out JArray array) && array.Count > 0 && array[0] is JObject item) + if (config.TryGetValueAs(Constants.Conventions.ConfigurationFieldAliases.Items, out JArray array) == true && array.Count > 0 && array[0] is JObject item) { // NOTE: Patches a breaking-change. I'd renamed `type` to become `key`. - if (item.ContainsKey("key") == false && item.ContainsKey("type")) + if (item.ContainsKey("key") == false && item.ContainsKey("type") == true) { item.Add("key", item["type"]); item.Remove("type"); diff --git a/src/Umbraco.Community.Contentment/Web/Controllers/EnumDataListSourceApiController.cs b/src/Umbraco.Community.Contentment/Web/Controllers/EnumDataListSourceApiController.cs index b3b6dfb2..fe8c3872 100644 --- a/src/Umbraco.Community.Contentment/Web/Controllers/EnumDataListSourceApiController.cs +++ b/src/Umbraco.Community.Contentment/Web/Controllers/EnumDataListSourceApiController.cs @@ -33,7 +33,7 @@ public IEnumerable GetAssemblies() { foreach (var assembly in assemblies) { - if (options.ContainsKey(assembly.FullName) || assembly.IsDynamic) + if (options.ContainsKey(assembly.FullName) == true || assembly.IsDynamic == true) continue; var hasEnums = false; @@ -41,7 +41,7 @@ public IEnumerable GetAssemblies() { foreach (var exportedType in assembly.ExportedTypes) { - if (exportedType.IsEnum) + if (exportedType.IsEnum == true) { hasEnums = true; break; @@ -52,7 +52,7 @@ public IEnumerable GetAssemblies() if (hasEnums == false) continue; - if (assembly.FullName.StartsWith(App_Code) && options.ContainsKey(App_Code) == false) + if (assembly.FullName.StartsWith(App_Code) == true && options.ContainsKey(App_Code) == false) { options.Add(App_Code, new DataListItem { Name = App_Code, Value = App_Code }); } diff --git a/src/Umbraco.Community.Contentment/Web/Serialization/PublishedContentContractResolver.cs b/src/Umbraco.Community.Contentment/Web/Serialization/PublishedContentContractResolver.cs index 056fd740..67776567 100644 --- a/src/Umbraco.Community.Contentment/Web/Serialization/PublishedContentContractResolver.cs +++ b/src/Umbraco.Community.Contentment/Web/Serialization/PublishedContentContractResolver.cs @@ -135,7 +135,7 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ property.ShouldSerialize = _ => _ignoreFromProperty.Contains(member.Name) == false; } - if (_converterLookup.ContainsKey(property.PropertyType)) + if (_converterLookup.ContainsKey(property.PropertyType) == true) { property.Converter = _converterLookup[property.PropertyType]; } From 297f4c6a86f10b06328ad47d04f6a980c2bd1941 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 7 Apr 2021 08:42:56 +0100 Subject: [PATCH 24/30] Telemetry - captures additional configuration Since introducing the telemetry feature in v1.2.0, DataList appears to be the most popular, but I had no idea which types of data-source or list-editors were being used. This amendment attempts to capture the minimum amount of data that I need to analyze the usage of DataList (and ContentBlocks, TextInput) configurations. --- .../ContentmentTelemetryComponent.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/Umbraco.Community.Contentment/Telemetry/ContentmentTelemetryComponent.cs b/src/Umbraco.Community.Contentment/Telemetry/ContentmentTelemetryComponent.cs index 3d4e26c4..0fe9aeca 100644 --- a/src/Umbraco.Community.Contentment/Telemetry/ContentmentTelemetryComponent.cs +++ b/src/Umbraco.Community.Contentment/Telemetry/ContentmentTelemetryComponent.cs @@ -4,13 +4,16 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ using System; +using System.Collections.Generic; using System.Net; using System.Net.Mime; using System.Text; using System.Threading.Tasks; using ClientDependency.Core; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Umbraco.Community.Contentment.Configuration; +using Umbraco.Community.Contentment.DataEditors; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; @@ -56,6 +59,51 @@ private void DataTypeService_Saved(IDataTypeService sender, SaveEventArgs(); + + if (entity.Configuration is Dictionary config) + { + void AddConfigurationEditorKey(string alias) + { + if (config.ContainsKey(alias) == true && + config.TryGetValueAs(alias, out JArray array) == true && + array.Count > 0 && + array[0] is JObject item && + item.ContainsKey("key") == true) + { + var key = item.Value("key"); + + if (key.InvariantStartsWith(Constants.Internals.ProjectNamespace) == true && key.Length > 73) + { + // Strips off the namespace and assembly. + // e.g. "Umbraco.Community.Contentment.DataEditors.[DataSourceName], Umbraco.Community.Contentment" + key = key.Substring(42, key.Length - 73); + } + + dataTypeConfig.Add(alias, key); + } + }; + + switch (entity.EditorAlias) + { + case DataListDataEditor.DataEditorAlias: + AddConfigurationEditorKey(DataListConfigurationEditor.DataSource); + AddConfigurationEditorKey(DataListConfigurationEditor.ListEditor); + break; + + case ContentBlocksDataEditor.DataEditorAlias: + AddConfigurationEditorKey(ContentBlocksConfigurationEditor.DisplayMode); + break; + + case TextInputDataEditor.DataEditorAlias: + AddConfigurationEditorKey(Constants.Conventions.ConfigurationFieldAliases.Items); + break; + + default: + break; + } + } + // TODO: [LK] After v8.10.0 bump, switch this to use `IUmbracoSettingsSection.BackOffice.Id`. var umbracoId = _umbracoContextAccessor.UmbracoContext?.HttpContext?.Server != null ? new Guid(_umbracoContextAccessor.UmbracoContext.HttpContext.Server.MachineName.GenerateMd5()) @@ -69,6 +117,7 @@ private void DataTypeService_Saved(IDataTypeService sender, SaveEventArgs Date: Wed, 7 Apr 2021 09:52:29 +0100 Subject: [PATCH 25/30] DataList Preview - passes property alias to list-editor --- .../DataEditors/DataList/DataListApiController.cs | 4 +++- .../DataEditors/DataList/data-list.preview.js | 2 +- src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListApiController.cs b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListApiController.cs index 26b23625..36d4b406 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListApiController.cs +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/DataListApiController.cs @@ -8,6 +8,7 @@ using System.Net.Http; using System.Web.Http; using Newtonsoft.Json.Linq; +using Umbraco.Core; using Umbraco.Core.PropertyEditors; using Umbraco.Web.Editors; using Umbraco.Web.Mvc; @@ -32,11 +33,12 @@ public HttpResponseMessage GetPreview([FromBody] JObject data) if (_propertyEditors.TryGet(DataListDataEditor.DataEditorAlias, out var propertyEditor) == true) { + var alias = config.GetValueAs("alias", "preview"); var configurationEditor = propertyEditor.GetConfigurationEditor(); var valueEditorConfig = configurationEditor.ToValueEditor(config); var valueEditor = propertyEditor.GetValueEditor(config); - return Request.CreateResponse(HttpStatusCode.OK, new { config = valueEditorConfig, view = valueEditor.View }); + return Request.CreateResponse(HttpStatusCode.OK, new { config = valueEditorConfig, view = valueEditor.View, alias }); } return Request.CreateResponse(HttpStatusCode.NotFound); diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js index c6ddee27..772dceab 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.js @@ -12,7 +12,7 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. //console.log("data-list.preview.model", $scope.model); - var config = Object.assign({}, $scope.model.config); + var config = Object.assign({ alias: $scope.model.alias }, $scope.model.config); var vm = this; function init() { diff --git a/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js index 98f3ccf3..3a563ae7 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js +++ b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js @@ -40,8 +40,8 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. vm.showIcons = Object.toBoolean(config.showIcons); vm.uniqueId = $scope.model.hasOwnProperty("dataTypeKey") - ? [$scope.model.alias, $scope.model.dataTypeKey.substring(0, 8)].join("-") - : $scope.model.alias; + ? ["tags", $scope.model.alias, $scope.model.dataTypeKey.substring(0, 8)].join("-") + : ["tags", $scope.model.alias].join("-"); vm.add = add; vm.keyDown = keyDown; From 2141194a0f1278b8e2d42a349415007628ee7e55 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 7 Apr 2021 09:53:23 +0100 Subject: [PATCH 26/30] Tags - add support for querying an item's name no longer only the value. --- src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js index 3a563ae7..bd176a19 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js +++ b/src/Umbraco.Community.Contentment/DataEditors/Tags/tags.js @@ -62,10 +62,10 @@ angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors. vm.loading = false; var engine = new Bloodhound({ - datumTokenizer: Bloodhound.tokenizers.obj.whitespace("value"), + datumTokenizer: Bloodhound.tokenizers.obj.whitespace("name", "value"), queryTokenizer: Bloodhound.tokenizers.whitespace, initialize: false, - local: config.items.filter(x => !x.disabled), // TODO: Review the `filter`, is there a better way? + local: config.items.filter(x => !x.disabled), identify: d => d.value, }); From 69524ecc9fa969026b2fc8bcef072696e3d9a29f Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 7 Apr 2021 10:12:10 +0100 Subject: [PATCH 27/30] CodeEditor - documentation --- .github/README.md | 1 + docs/README.md | 1 + .../code-editor--configuration-editor.png | Bin 0 -> 2658 bytes .../code-editor--property-editor-01.png | Bin 0 -> 2658 bytes docs/editors/code-editor.md | 53 ++++++++++++++++++ docs/telemetry.md | 8 ++- 6 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 docs/editors/code-editor--configuration-editor.png create mode 100644 docs/editors/code-editor--property-editor-01.png diff --git a/.github/README.md b/.github/README.md index 3e6ec3c7..227c46db 100644 --- a/.github/README.md +++ b/.github/README.md @@ -24,6 +24,7 @@ Let's take a look inside... ##### Property Editors - [Bytes](../docs/editors/bytes.md) - a read-only label to display file sizes in relative bytes. +- [Code Editor](../docs/editors/code-editor.md) - a code snippet editor, _(using the ACE library that is bundled with Umbraco)._ - [Content Blocks](../docs/editors/content-blocks.md) - a block editor, configurable using element types. - [Data List](../docs/editors/data-list.md) - an editor that combines a custom data source with a custom list editor. - [Icon Picker](../docs/editors/icon-picker.md) - an editor to select an icon (from the Umbraco icon library). diff --git a/docs/README.md b/docs/README.md index 259cb34e..8c44072d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,6 +13,7 @@ Here is the documentation for the Contentment property-editors... - [Bytes](../docs/editors/bytes.md) - a read-only label to display file sizes in relative bytes. +- [Code Editor](../docs/editors/code-editor.md) - a code snippet editor, _(using the ACE library that is bundled with Umbraco)._ - [Content Blocks](../docs/editors/content-blocks.md) - a block editor, configurable using element types. - [Data List](../docs/editors/data-list.md) - an editor that combines a custom data source with a custom list editor. - [Icon Picker](../docs/editors/icon-picker.md) - an editor to select an icon (from the Umbraco icon library). diff --git a/docs/editors/code-editor--configuration-editor.png b/docs/editors/code-editor--configuration-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..57d3c35144f3959ddeb348c9bd1a3ad04ea53789 GIT binary patch literal 2658 zcmZ`*c{CJU8y{;m%-Gi^vYQx_HB(u#_hK3hF(E>-6=DiuL@~r<8%skXMpI-o_90Z( zi87W@WM8LVUMX9?(I4MA?|07k`{Ul{-em@)?gJ%m_wvzmj{kz#=4zperz&vfR~yi0mc!iA z`fer9Om7kwUZJQ%?4)vr(a?JIpUYJU2_({du`wMji!jabNi8KlM|Dss-GymP? z6|w8iR)V{wASIDX@qPm*H6$nW4`hW?Y#m3-HC~`Sri(~%JwGw2BcL>Ff z;`7b;@%r~*dl|%UiLl)wsFLClsLc2>k<`ik}X-IFVki}Rj?HFa?D)dZ6{qU z=LbPi{yy;|*~em!Ts(utEDE14ZG55E58RHz+*!saNwhAGCe2WZPTn_!!m0}h0MfPg z`S&>6YEXjw$VrVr^2Fg!pLqgI39!qZ*7@NfTNQt2R;?C~x2^Q3xfe;~yPFw&F5Ix$ zct6o_1_9#oJo~m=N$K%TY~@+m{(-ZEfq6G~T%4X1P*tQbh?76|ROV2!!1;I(7vt@@ z%OSU(2Vx7>;2G&oS1gA*2X6@4W+$#_?ZpDB_)2|TA2cYpcfrV3$uKe(&ajn35M}pC zucIGEzRRN5RV!vPdCs_B1sn3sR=;!M4Srg6aaPnc2&naHa=|C%)k7I)kEi8d22sI9yvEq? z^Zd?y0*UQ?04pOE0Wlb6SP52CKayNDM-xX%SWRXV#LEux;(X`4q7x~+g$&yhqKPVJkxwpE=boN5C5h;tJhI|YXseu zc07j2l&^@qg~LB~(baE!r@~m?SBruTetoT*6$ym%O81#_oHoZe42Ci$3zh0wkI1J|Q zh@(2}E0L;O06?#7FZr4DDZ=QShhF0x4S#15=Q z^{@iBPH=vdQ>!2RYZecxh+xShsHlWvk+$=;p0=Ha;nv*LLdRf3UBAW2FIJdc#qW*g zb-aU~nkT0-4F&`w)X07w=?>sZ88ZG?i@Pu!yb`t_A2Qi*1M(h#rOd>P@cdmUzt{Z_ zbflR}ZB_^JQvkQ&B4zldEOuo}hhbBo0YIlS(^3+;V8c8%CX4TLm_WqbtN_AM+}=-_ zOu}lN$e%AALx8j$?0dt9b>LzM7A{7S`&UbD-ksfFk4T|~M!7j-Upb@o`vp2&u8l8s z`snvh_C3oPb+GrC(CL?D+lxoO2_w}!teS{_XD*MCBfF+SE+Nm$tqnYI-Imu=gN%ot zsC-m=Q~IjYvh~sM9k0Ic30~&NGsj11{UO69T4omd9md`7(P?ubm~m;5Ug%?3ealO! zt)z2-SM~W;P-BQ6TH4D4^Fb6-JPB)DGf*4|7Hv0NN%v8&Idx~+MTUHrNcTp}!7IOC za8@X#XilZ8^AJ~gWAP4f?UKqGmUD|E1PWodnZwPr&xmZ2>^b`(&Z{pO)fuWkH@4p~ zgFbcVgu7ILtz$GKq$KIG$`^Khd9v58zZL?852Q0Stgwgi!cdXXuPDi>7=%u3G8^3mt>~ysghekj!=6prd8=T6D3HE z)bd5+Id;a4vV@%ybrorIM6>FR3kA>Xj}LlJ85+`VF8hdwzW5TBY`Pwa%2lun#AD$KqGBz;w#LWq#A2}-1cJ9J`F zna5vIa35()Bz%{jN|q>UG|eK+M*mY%&nr%(h*BXb1HVxlHflVXiv-m)CQTKLGyD8< zN1In8-ZU7nX|||`mUs&hl7GW>RP%>A!QmUwHPbyP=+qZ=`?@aAt_91qNR-I;a1Q9NC-`{U)s(1-oGEgy1G04oh@ssd-&aSP( zzkm0)S^v_UT`O%GPu_2G<{K(D=z$CwP{k?cQCSE|)D;*yWmEMg`W8CA29-Ki!m#_o zL{y1WTy`?q+S7o5C;2r-c_ocxp{m)q7SMsgF*LPe_qHodmO-~X(1 z9}AYv& Woie9@ws@F$;Bnp@X;x|CarZxzf$&ZM literal 0 HcmV?d00001 diff --git a/docs/editors/code-editor--property-editor-01.png b/docs/editors/code-editor--property-editor-01.png new file mode 100644 index 0000000000000000000000000000000000000000..57d3c35144f3959ddeb348c9bd1a3ad04ea53789 GIT binary patch literal 2658 zcmZ`*c{CJU8y{;m%-Gi^vYQx_HB(u#_hK3hF(E>-6=DiuL@~r<8%skXMpI-o_90Z( zi87W@WM8LVUMX9?(I4MA?|07k`{Ul{-em@)?gJ%m_wvzmj{kz#=4zperz&vfR~yi0mc!iA z`fer9Om7kwUZJQ%?4)vr(a?JIpUYJU2_({du`wMji!jabNi8KlM|Dss-GymP? z6|w8iR)V{wASIDX@qPm*H6$nW4`hW?Y#m3-HC~`Sri(~%JwGw2BcL>Ff z;`7b;@%r~*dl|%UiLl)wsFLClsLc2>k<`ik}X-IFVki}Rj?HFa?D)dZ6{qU z=LbPi{yy;|*~em!Ts(utEDE14ZG55E58RHz+*!saNwhAGCe2WZPTn_!!m0}h0MfPg z`S&>6YEXjw$VrVr^2Fg!pLqgI39!qZ*7@NfTNQt2R;?C~x2^Q3xfe;~yPFw&F5Ix$ zct6o_1_9#oJo~m=N$K%TY~@+m{(-ZEfq6G~T%4X1P*tQbh?76|ROV2!!1;I(7vt@@ z%OSU(2Vx7>;2G&oS1gA*2X6@4W+$#_?ZpDB_)2|TA2cYpcfrV3$uKe(&ajn35M}pC zucIGEzRRN5RV!vPdCs_B1sn3sR=;!M4Srg6aaPnc2&naHa=|C%)k7I)kEi8d22sI9yvEq? z^Zd?y0*UQ?04pOE0Wlb6SP52CKayNDM-xX%SWRXV#LEux;(X`4q7x~+g$&yhqKPVJkxwpE=boN5C5h;tJhI|YXseu zc07j2l&^@qg~LB~(baE!r@~m?SBruTetoT*6$ym%O81#_oHoZe42Ci$3zh0wkI1J|Q zh@(2}E0L;O06?#7FZr4DDZ=QShhF0x4S#15=Q z^{@iBPH=vdQ>!2RYZecxh+xShsHlWvk+$=;p0=Ha;nv*LLdRf3UBAW2FIJdc#qW*g zb-aU~nkT0-4F&`w)X07w=?>sZ88ZG?i@Pu!yb`t_A2Qi*1M(h#rOd>P@cdmUzt{Z_ zbflR}ZB_^JQvkQ&B4zldEOuo}hhbBo0YIlS(^3+;V8c8%CX4TLm_WqbtN_AM+}=-_ zOu}lN$e%AALx8j$?0dt9b>LzM7A{7S`&UbD-ksfFk4T|~M!7j-Upb@o`vp2&u8l8s z`snvh_C3oPb+GrC(CL?D+lxoO2_w}!teS{_XD*MCBfF+SE+Nm$tqnYI-Imu=gN%ot zsC-m=Q~IjYvh~sM9k0Ic30~&NGsj11{UO69T4omd9md`7(P?ubm~m;5Ug%?3ealO! zt)z2-SM~W;P-BQ6TH4D4^Fb6-JPB)DGf*4|7Hv0NN%v8&Idx~+MTUHrNcTp}!7IOC za8@X#XilZ8^AJ~gWAP4f?UKqGmUD|E1PWodnZwPr&xmZ2>^b`(&Z{pO)fuWkH@4p~ zgFbcVgu7ILtz$GKq$KIG$`^Khd9v58zZL?852Q0Stgwgi!cdXXuPDi>7=%u3G8^3mt>~ysghekj!=6prd8=T6D3HE z)bd5+Id;a4vV@%ybrorIM6>FR3kA>Xj}LlJ85+`VF8hdwzW5TBY`Pwa%2lun#AD$KqGBz;w#LWq#A2}-1cJ9J`F zna5vIa35()Bz%{jN|q>UG|eK+M*mY%&nr%(h*BXb1HVxlHflVXiv-m)CQTKLGyD8< zN1In8-ZU7nX|||`mUs&hl7GW>RP%>A!QmUwHPbyP=+qZ=`?@aAt_91qNR-I;a1Q9NC-`{U)s(1-oGEgy1G04oh@ssd-&aSP( zzkm0)S^v_UT`O%GPu_2G<{K(D=z$CwP{k?cQCSE|)D;*yWmEMg`W8CA29-Ki!m#_o zL{y1WTy`?q+S7o5C;2r-c_ocxp{m)q7SMsgF*LPe_qHodmO-~X(1 z9}AYv& Woie9@ws@F$;Bnp@X;x|CarZxzf$&ZM literal 0 HcmV?d00001 diff --git a/docs/editors/code-editor.md b/docs/editors/code-editor.md index db15ca0e..8f8a6f9c 100644 --- a/docs/editors/code-editor.md +++ b/docs/editors/code-editor.md @@ -4,16 +4,69 @@ ### Code Editor +Code Editor is a property-editor that is used to enter code snippets (as content), makes use of [AWS Cloud 9's Ace editor](https://ace.c9.io/) library that is distributed with Umbraco. ### How to configure the editor? +In your new Data Type, selected the "[Contentment] Code Editor" option. You will see the following configuration fields. + +![Configuration Editor for Code Editor](code-editor--configuration-editor.png) + +The first field is **Language mode**, this is used to select the programming language mode, for code syntax highlighting. The default mode is "Razor", meaning that you can use a combination of HTML, CSS, JavaScript and Razor syntax. + +The next field is **Theme**, which is used to set the visual appearance of the code editor. The default _(and only)_ theme is "Chrome". + +> **Please note,** by default, Umbraco ships a streamlined set of programming language modes and themes. +> +> If you would like to add more modes and themes, you can do this by [downloading the latest pre-packaged version of the Ace editor](https://github.com/ajaxorg/ace-builds/releases) and copy any of the `mode-*` or `theme-*` files from the `src-min-noconflict` folder over to the `~/umbraco/lib/ace-builds/src-min-noconflict/` folder in you Umbraco installation. +> +> Once you've done this, you can reload the Data Type screen, and the new programming language modes and themes will appear in the dropdown options for the fields above. + + +The **Font size** field is used to set the font size, the value must be a [valid CSS font-size value](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size), e.g. `14px`, `80%`, `0.8em`, etc. The default size is "`small`". + +The **Word wrapping** option can enable the code editor to wrap the text around to the following line. + +The next two fields, **Minimum lines** and **Maximum lines**, are used to set the default height size of the code editor. If you would like the height to auto-scale forever, then set the maximum number to something ridiculously high. If left empty, the height of the code editor will remain at a fixed height and not auto-scale. ### How to use the editor? +Once you have added the configured Data Type to your Document Type, the Code Editor editor will be displayed on the content page's property panel. + +![Code Editor property-editor](code-editor--property-editor-01.png) ### How to get the value? +The value for the Code Editor is a `string`. + +Programmatically, you would access the value exactly the same as Umbraco's Textarea editor, [see Umbraco's documentation for code snippet examples](https://our.umbraco.com/Documentation/Getting-Started/Backoffice/Property-Editors/Built-in-Property-Editors/Textarea/#mvc-view-example). + +If you are wanting to display the code content as a pre-formatted code snippet, I would recommend using the `
` and `` tags.
+
+Using Umbraco's Models Builder...
+
+```cshtml
+
@Html.Raw(Model.CodeEditor)
+``` + +Without ModelsBuilder... + +Weakly-typed... + +```cshtml +
@Html.Raw(Model.Value("codeEditor"))
+``` + +Strongly-typed... + +```cshtml +
@Html.Raw(Model.Value("codeEditor"))
+``` + +For code syntax highlighting, the following JavaScript libraries are quite popular: +- [Prism.js](https://prismjs.com/) +- [highlight.js](https://highlightjs.org/) diff --git a/docs/telemetry.md b/docs/telemetry.md index 26f996e3..220cfdd4 100644 --- a/docs/telemetry.md +++ b/docs/telemetry.md @@ -15,8 +15,12 @@ Here is an example of the JSON data that is sent. "dataType": "4E7D6B3A-F959-42E4-921E-081BC0E9E7EE", "editorAlias": "DataList", "umbracoId": "0403E47E-EFE7-4CF2-8E97-148681DAFC10", - "umbracoVersion": "8.6.6", - "contentmentVersion": "1.2.0", + "umbracoVersion": "8.6.8", + "contentmentVersion": "1.3.0", + "dataTypeConfig": { + "dataSource": "EnumDataListSource", + "listEditor": "CheckboxListDataListEditor", + } } ``` From 3c38a9c44c62e4147c905076204bfa121677ddff Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 7 Apr 2021 12:53:40 +0100 Subject: [PATCH 28/30] DataList Preview - added missing localizations --- .../DataEditors/DataList/data-list.preview.html | 2 +- .../Web/UI/App_Plugins/Contentment/lang/da.xml | 2 ++ .../Web/UI/App_Plugins/Contentment/lang/en.xml | 1 + .../Web/UI/App_Plugins/Contentment/lang/pt-br.xml | 2 ++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html index 537b7c60..483eefbf 100644 --- a/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html +++ b/src/Umbraco.Community.Contentment/DataEditors/DataList/data-list.preview.html @@ -18,7 +18,7 @@
- The data source returned no items to preview. + The data source returned no items to preview.
diff --git a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/da.xml b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/da.xml index 54dc95b8..4702eb89 100644 --- a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/da.xml +++ b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/da.xml @@ -27,6 +27,8 @@ Vælg og konfigurer en datakilde og en listeeditor, tak. Vælg og konfigurer en datakilde, tak. Vælg og konfigurer en liste, tak. + Datakilden returnerede ingen elementer til forhåndsvisning. + Indtast nøgleord (tryk på Enter efter hvert nøgleord)... diff --git a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml index eb6558d7..08152da5 100644 --- a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml +++ b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/en.xml @@ -27,6 +27,7 @@ Please select and configure a data source and list editor. Please select and configure a data source. Please select and configure a list editor. + The data source returned no items to preview. Type to select an item... diff --git a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/pt-br.xml b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/pt-br.xml index 7587ccbf..8aa8a340 100644 --- a/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/pt-br.xml +++ b/src/Umbraco.Community.Contentment/Web/UI/App_Plugins/Contentment/lang/pt-br.xml @@ -27,6 +27,8 @@ Selecionar e configurar a origem dos dados e o editor de lista, por favor. Selecionar e configurar a origem dos dados, por favor. Selecionar e configurar o editor de lista, por favor. + A fonte de dados não retornou nenhum item para visualização. + Digite para selecionar um item... From 283b301945dc1051072112848c86f076311b73b9 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 7 Apr 2021 12:57:27 +0100 Subject: [PATCH 29/30] :roller_coaster: Updated ROADMAP --- .github/ROADMAP.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/ROADMAP.md b/.github/ROADMAP.md index 4c83f1c0..7ae3b38e 100644 --- a/.github/ROADMAP.md +++ b/.github/ROADMAP.md @@ -37,8 +37,13 @@ Property Editors are: - [Code Editor](../docs/editors/code-editor.md) _(using ACE bundled with Umbraco)_ - Data List: Preview _(a real time preview of the configured Data Source and List Editor)_ +- Data List: Buttons _(list editor, similar to what folk see used in Umbraco Uno)_ - Data List: Tags _(list editor, visually similar to Umbraco Tags editor)_ +### v1.4 + +- 🤫 + ## v2 From bd9b79a7241679b5489ff7ec8f5dec17ba3a49a4 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 7 Apr 2021 13:17:17 +0100 Subject: [PATCH 30/30] Incremented version number, v1.3.0 --- VERSION | 2 +- src/Umbraco.Community.Contentment/Properties/VersionInfo.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 89cddd5e..589268e6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.0-develop \ No newline at end of file +1.3.0 \ No newline at end of file diff --git a/src/Umbraco.Community.Contentment/Properties/VersionInfo.cs b/src/Umbraco.Community.Contentment/Properties/VersionInfo.cs index 8716556b..0ebad52c 100644 --- a/src/Umbraco.Community.Contentment/Properties/VersionInfo.cs +++ b/src/Umbraco.Community.Contentment/Properties/VersionInfo.cs @@ -2,4 +2,4 @@ [assembly: AssemblyVersion("1.3")] [assembly: AssemblyFileVersion("1.3.0")] -[assembly: AssemblyInformationalVersion("1.3.0-develop")] +[assembly: AssemblyInformationalVersion("1.3.0")]