From 04fcd8c01e34c41dfb30facef152d462b752497d Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 11 Aug 2021 00:53:30 +0200 Subject: [PATCH 1/6] Add infinite editor for file picker and static file picker --- .../src/common/services/editor.service.js | 45 ++++++++++++ ...t.blockconfiguration.overlay.controller.js | 69 ++++++++----------- 2 files changed, 72 insertions(+), 42 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js index b0a2465f42..c68e005d7b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js @@ -905,6 +905,50 @@ When building a custom infinite editor view you can use the same components as a open(editor); } + /** + * @ngdoc method + * @name umbraco.services.editorService#filePicker + * @methodOf umbraco.services.editorService + * + * @description + * Opens a file picker in infinite editing, the submit callback returns an array of selected items. + * + * @param {object} editor rendering options. + * @param {function} editor.submit Callback function when the submit button is clicked. Returns the editor model object. + * @param {function} editor.close Callback function when the close button is clicked. + * @returns {object} editor object. + */ + function filePicker(editor) { + editor.view = "views/common/infiniteeditors/treepicker/treepicker.html"; + if (!editor.size) editor.size = "small"; + editor.section = "settings"; + editor.treeAlias = "files"; + editor.entityType = "file"; + open(editor); + } + + /** + * @ngdoc method + * @name umbraco.services.editorService#staticFilePicker + * @methodOf umbraco.services.editorService + * + * @description + * Opens a static file picker in infinite editing, the submit callback returns an array of selected items. + * + * @param {object} editor rendering options. + * @param {function} editor.submit Callback function when the submit button is clicked. Returns the editor model object. + * @param {function} editor.close Callback function when the close button is clicked. + * @returns {object} editor object. + */ + function staticFilePicker(editor) { + editor.view = "views/common/infiniteeditors/treepicker/treepicker.html"; + if (!editor.size) editor.size = "small"; + editor.section = "settings"; + editor.treeAlias = "staticFiles"; + editor.entityType = "file"; + open(editor); + } + /** * @ngdoc method * @name umbraco.services.editorService#itemPicker @@ -1069,6 +1113,7 @@ When building a custom infinite editor view you can use the same components as a move: move, embed: embed, rollback: rollback, + filePicker: filePicker, linkPicker: linkPicker, mediaPicker: mediaPicker, iconPicker: iconPicker, diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js index c655ad3606..cb9b31909c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js @@ -76,33 +76,28 @@ vm.addSettingsForBlock = function($event, block) { - localizationService.localize("blockEditor_headlineAddSettingsElementType").then(function(localizedTitle) { + localizationService.localize("blockEditor_headlineAddSettingsElementType").then(localizedTitle => { const settingsTypePicker = { title: localizedTitle, - section: "settings", - treeAlias: "documentTypes", entityType: "documentType", - isDialog: true, - filter: function (node) { + filter: node => { if (node.metaData.isElement === true) { return false; } return true; }, filterCssClass: "not-allowed", - select: function (node) { + select: node => { vm.applySettingsToBlock(block, udiService.getKey(node.udi)); editorService.close(); }, - close: function () { - editorService.close(); - }, + close: () => editorService.close(), extraActions: [ { style: "primary", labelKey: "blockEditor_labelcreateNewElementType", - action: function () { + action: () => { vm.createElementTypeAndCallback((key) => { vm.applySettingsToBlock(block, key); @@ -113,7 +108,8 @@ } ] }; - editorService.treePicker(settingsTypePicker); + + editorService.contentTypePicker(settingsTypePicker); }); }; @@ -170,24 +166,19 @@ const filePicker = { title: localizedTitle, - section: "settings", - treeAlias: "files", - entityType: "file", - isDialog: true, - filter: function (i) { + filter: i => { return !(i.name.indexOf(".html") !== -1); }, filterCssClass: "not-allowed", - select: function (node) { + select: node => { const filepath = decodeURIComponent(node.id.replace(/\+/g, " ")); block.view = "~/" + filepath; editorService.close(); }, - close: function () { - editorService.close(); - } + close: () => editorService.close() }; - editorService.treePicker(filePicker); + + editorService.filePicker(filePicker); }); }; @@ -217,24 +208,20 @@ const filePicker = { title: localizedTitle, - section: "settings", - treeAlias: "files", - entityType: "file", isDialog: true, - filter: function (i) { + filter: i => { return !(i.name.indexOf(".css") !== -1); }, filterCssClass: "not-allowed", - select: function (node) { + select: node => { const filepath = decodeURIComponent(node.id.replace(/\+/g, " ")); block.stylesheet = "~/" + filepath; editorService.close(); }, - close: function () { - editorService.close(); - } + close: () => editorService.close() }; - editorService.treePicker(filePicker); + + editorService.filePicker(filePicker); }); }; @@ -261,28 +248,26 @@ vm.addThumbnailForBlock = function(block) { - localizationService.localize("blockEditor_headlineAddThumbnail").then(function (localizedTitle) { + localizationService.localize("blockEditor_headlineAddThumbnail").then(function (localizedTitle) { + + let allowedFileExtensions = ['jpg', 'jpeg', 'png', 'svg', 'webp', 'gif']; const thumbnailPicker = { title: localizedTitle, - section: "settings", - treeAlias: "staticFiles", - entityType: "file", - isDialog: true, - filter: function (i) { - return !(i.name.indexOf(".jpg") !== -1 || i.name.indexOf(".jpeg") !== -1 || i.name.indexOf(".png") !== -1 || i.name.indexOf(".svg") !== -1 || i.name.indexOf(".webp") !== -1 || i.name.indexOf(".gif") !== -1); + filter: i => { + let ext = i.name.substr((i.name.lastIndexOf('.') + 1)); + return allowedFileExtensions.includes(ext) === false; }, filterCssClass: "not-allowed", - select: function (file) { + select: file => { const id = decodeURIComponent(file.id.replace(/\+/g, " ")); block.thumbnail = "~/" + id.replace("wwwroot/", ""); editorService.close(); }, - close: function () { - editorService.close(); - } + close: () => editorService.close() }; - editorService.treePicker(thumbnailPicker); + + editorService.staticFilePicker(thumbnailPicker); }); }; From c33294ae7feb3199ac68b1c9379712034a309ecc Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 11 Aug 2021 00:55:01 +0200 Subject: [PATCH 2/6] Include static file picker --- src/Umbraco.Web.UI.Client/src/common/services/editor.service.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js index c68e005d7b..55c68dd1d0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js @@ -1114,6 +1114,7 @@ When building a custom infinite editor view you can use the same components as a embed: embed, rollback: rollback, filePicker: filePicker, + staticFilePicker: staticFilePicker, linkPicker: linkPicker, mediaPicker: mediaPicker, iconPicker: iconPicker, From 1fac53e1201d7592bf7909b0b6e32d48d0c2a44a Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 11 Aug 2021 01:12:13 +0200 Subject: [PATCH 3/6] Simplify code --- .../blocklist.blockconfiguration.overlay.controller.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js index cb9b31909c..63310b62d2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js @@ -162,7 +162,7 @@ unsubscribe.push(eventsService.on("editors.documentType.saved", updateUsedElementTypes)); vm.addViewForBlock = function(block) { - localizationService.localize("blockEditor_headlineAddCustomView").then(function (localizedTitle) { + localizationService.localize("blockEditor_headlineAddCustomView").then(localizedTitle => { const filePicker = { title: localizedTitle, @@ -204,11 +204,10 @@ }; vm.addStylesheetForBlock = function(block) { - localizationService.localize("blockEditor_headlineAddCustomStylesheet").then(function (localizedTitle) { + localizationService.localize("blockEditor_headlineAddCustomStylesheet").then(localizedTitle => { const filePicker = { title: localizedTitle, - isDialog: true, filter: i => { return !(i.name.indexOf(".css") !== -1); }, @@ -248,7 +247,7 @@ vm.addThumbnailForBlock = function(block) { - localizationService.localize("blockEditor_headlineAddThumbnail").then(function (localizedTitle) { + localizationService.localize("blockEditor_headlineAddThumbnail").then(localizedTitle => { let allowedFileExtensions = ['jpg', 'jpeg', 'png', 'svg', 'webp', 'gif']; From 94f7a55698642cdf78b8ba32f00e33a7c84f0bbf Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 11 Aug 2021 01:22:22 +0200 Subject: [PATCH 4/6] Add back isDialog --- .../blocklist.blockconfiguration.overlay.controller.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js index 63310b62d2..60a4b9245a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.controller.js @@ -81,6 +81,7 @@ const settingsTypePicker = { title: localizedTitle, entityType: "documentType", + isDialog: true, filter: node => { if (node.metaData.isElement === true) { return false; @@ -166,6 +167,7 @@ const filePicker = { title: localizedTitle, + isDialog: true, filter: i => { return !(i.name.indexOf(".html") !== -1); }, @@ -208,6 +210,7 @@ const filePicker = { title: localizedTitle, + isDialog: true, filter: i => { return !(i.name.indexOf(".css") !== -1); }, @@ -253,6 +256,7 @@ const thumbnailPicker = { title: localizedTitle, + isDialog: true, filter: i => { let ext = i.name.substr((i.name.lastIndexOf('.') + 1)); return allowedFileExtensions.includes(ext) === false; From 520a7e519c6fe0bdbdb4f177f65f744beb433e86 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 11 Aug 2021 01:26:15 +0200 Subject: [PATCH 5/6] Use file picker for packages --- .../src/views/packages/edit.controller.js | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js index f5db75ebe1..808d71daa2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js @@ -277,29 +277,25 @@ } function openViewPicker() { - const controlPicker = { - title: "Select view", - section: "settings", - treeAlias: "files", - entityType: "file", - onlyInitialized: false, - filter: function (i) { - if (i.name.indexOf(".html") === -1 && - i.name.indexOf(".htm") === -1) { - return true; - } - }, - filterCssClass: "not-allowed", - select: function (node) { - const id = decodeURIComponent(node.id.replace(/\+/g, " ")); - vm.package.packageView = id; - editorService.close(); - }, - close: function () { - editorService.close(); - } - }; - editorService.treePicker(controlPicker); + + const controlPicker = { + title: "Select view", + onlyInitialized: false, + filter: i => { + if (i.name.indexOf(".html") === -1 && i.name.indexOf(".htm") === -1) { + return true; + } + }, + filterCssClass: "not-allowed", + select: node => { + const id = decodeURIComponent(node.id.replace(/\+/g, " ")); + vm.package.packageView = id; + editorService.close(); + }, + close: () => editorService.close() + }; + + editorService.filePicker(controlPicker); } function removePackageView() { From b8b8fb667b3c515861659d726d37053d60079eb2 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 11 Aug 2021 08:31:37 +0200 Subject: [PATCH 6/6] Use constants --- src/Umbraco.Web.BackOffice/Trees/StaticFilesTreeController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.BackOffice/Trees/StaticFilesTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/StaticFilesTreeController.cs index 474becaf17..58fc53e28c 100644 --- a/src/Umbraco.Web.BackOffice/Trees/StaticFilesTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/StaticFilesTreeController.cs @@ -47,7 +47,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees var hasChildren = _fileSystem.GetFiles(directory).Any() || _fileSystem.GetDirectories(directory).Any(); var name = Path.GetFileName(directory); - var node = CreateTreeNode(WebUtility.UrlEncode(directory), path, queryStrings, name, "icon-folder", hasChildren); + var node = CreateTreeNode(WebUtility.UrlEncode(directory), path, queryStrings, name, Constants.Icons.Folder, hasChildren); if (node != null) { @@ -61,7 +61,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees foreach (var file in files) { var name = Path.GetFileName(file); - var node = CreateTreeNode(WebUtility.UrlEncode(file), path, queryStrings, name, "icon-document", false); + var node = CreateTreeNode(WebUtility.UrlEncode(file), path, queryStrings, name, Constants.Icons.DefaultIcon, false); if (node != null) {