Merge pull request #10829 from bjarnef/v9/feature/infinite-editor-file-picker
V9: Infinite editor file picker
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,8 @@ When building a custom infinite editor view you can use the same components as a
|
||||
move: move,
|
||||
embed: embed,
|
||||
rollback: rollback,
|
||||
filePicker: filePicker,
|
||||
staticFilePicker: staticFilePicker,
|
||||
linkPicker: linkPicker,
|
||||
mediaPicker: mediaPicker,
|
||||
iconPicker: iconPicker,
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -76,33 +76,29 @@
|
||||
|
||||
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 +109,8 @@
|
||||
}
|
||||
]
|
||||
};
|
||||
editorService.treePicker(settingsTypePicker);
|
||||
|
||||
editorService.contentTypePicker(settingsTypePicker);
|
||||
|
||||
});
|
||||
};
|
||||
@@ -166,28 +163,24 @@
|
||||
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,
|
||||
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);
|
||||
|
||||
});
|
||||
};
|
||||
@@ -213,28 +206,24 @@
|
||||
};
|
||||
|
||||
vm.addStylesheetForBlock = function(block) {
|
||||
localizationService.localize("blockEditor_headlineAddCustomStylesheet").then(function (localizedTitle) {
|
||||
localizationService.localize("blockEditor_headlineAddCustomStylesheet").then(localizedTitle => {
|
||||
|
||||
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 +250,27 @@
|
||||
|
||||
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'];
|
||||
|
||||
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);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user