From ef9dd6d80383472a5012318d86ab0912a24053aa Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 18 Jan 2017 15:38:40 +0100 Subject: [PATCH 1/2] add scripts editor --- .../src/views/scripts/edit.controller.js | 132 ++++++++++++++++++ .../src/views/scripts/edit.html | 51 +++++++ 2 files changed, 183 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/views/scripts/edit.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/scripts/edit.html diff --git a/src/Umbraco.Web.UI.Client/src/views/scripts/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/scripts/edit.controller.js new file mode 100644 index 0000000000..fe8837e50d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/scripts/edit.controller.js @@ -0,0 +1,132 @@ +(function () { + "use strict"; + + function ScriptsEditController($scope, $routeParams, $timeout, appState, editorState, navigationService, assetsService, codefileResource, contentEditingHelper, notificationsService, localizationService) { + + var vm = this; + var currentPosition = null; + var localizeSaving = localizationService.localize("general_saving"); + + vm.page = {}; + vm.page.loading = true; + vm.page.menu = {}; + vm.page.menu.currentSection = appState.getSectionState("currentSection"); + vm.page.menu.currentNode = null; + vm.page.saveButtonState = "init"; + + vm.script = {}; + + // bind functions to view model + vm.save = save; + + /* Function bound to view model */ + + function save() { + + vm.page.saveButtonState = "busy"; + + vm.script.content = vm.editor.getValue(); + + contentEditingHelper.contentEditorPerformSave({ + statusMessage: localizeSaving, + saveMethod: codefileResource.save, + scope: $scope, + content: vm.script, + // We do not redirect on failure for scripts - this is because it is not possible to actually save the script + // when server side validation fails - as opposed to content where we are capable of saving the content + // item if server side validation fails + redirectOnFailure: false, + rebindCallback: function (orignal, saved) {} + }).then(function (saved) { + + notificationsService.success("Script saved"); + vm.page.saveButtonState = "success"; + vm.script = saved; + + //sync state + editorState.set(vm.script); + + // sync tree + navigationService.syncTree({ tree: "scripts", path: vm.script.virtualPath, forceReload: true }).then(function (syncArgs) { + vm.page.menu.currentNode = syncArgs.node; + }); + + }, function (err) { + + vm.page.saveButtonState = "error"; + + localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) { + localizationService.localize("speechBubbles_validationFailedMessage").then(function(msgValue) { + notificationsService.error(headerValue, msgValue); + }); + }); + + }); + + + } + + /* Local functions */ + + function init() { + + //we need to load this somewhere, for now its here. + assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css"); + + if ($routeParams.create) { + codefileResource.getScaffold().then(function (script) { + ready(script); + }); + } else { + codefileResource.getByPath('scripts', $routeParams.id).then(function (script) { + ready(script); + }); + } + + } + + function ready(script) { + + vm.page.loading = false; + + vm.script = script; + + //sync state + editorState.set(vm.script); + + navigationService.syncTree({ tree: "scripts", path: vm.script.virtualPath, forceReload: true }).then(function (syncArgs) { + vm.page.menu.currentNode = syncArgs.node; + }); + + vm.aceOption = { + mode: "javascript", + theme: "chrome", + showPrintMargin: false, + advanced: { + fontSize: '14px' + }, + onLoad: function(_editor) { + + vm.editor = _editor; + + // initial cursor placement + // Keep cursor in name field if we are create a new script + // else set the cursor at the bottom of the code editor + if(!$routeParams.create) { + $timeout(function(){ + vm.editor.navigateFileEnd(); + vm.editor.focus(); + }); + } + + } + } + + } + + init(); + + } + + angular.module("umbraco").controller("Umbraco.Editors.Scripts.EditController", ScriptsEditController); +})(); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html b/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html new file mode 100644 index 0000000000..18e5e8525c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html @@ -0,0 +1,51 @@ +
+ + + +
+ + + + + + + + +
+
+ +
+ + + + + + + + + + + + +
+
+ +
\ No newline at end of file From 49d24dada774b9faa4cefb376c175213211c1e34 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 18 Jan 2017 15:39:08 +0100 Subject: [PATCH 2/2] add partial views macros editor --- .../partialviewmacros/edit.controller.js | 309 ++++++++++++++++++ .../src/views/partialviewmacros/edit.html | 123 +++++++ 2 files changed, 432 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.controller.js new file mode 100644 index 0000000000..d0a47aaa77 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.controller.js @@ -0,0 +1,309 @@ +(function () { + "use strict"; + + function partialViewMacrosEditController($scope, $routeParams, codefileResource, assetsService, notificationsService, editorState, navigationService, appState, macroService, angularHelper, $timeout, contentEditingHelper, localizationService, templateHelper) { + + var vm = this; + var localizeSaving = localizationService.localize("general_saving"); + + vm.page = {}; + vm.page.loading = true; + vm.partialViewMacroFile = {}; + + //menu + vm.page.menu = {}; + vm.page.menu.currentSection = appState.getSectionState("currentSection"); + vm.page.menu.currentNode = null; + + // bind functions to view model + vm.save = save; + vm.openPageFieldOverlay = openPageFieldOverlay; + vm.openDictionaryItemOverlay = openDictionaryItemOverlay; + vm.openQueryBuilderOverlay = openQueryBuilderOverlay; + vm.openMacroOverlay = openMacroOverlay; + vm.openInsertOverlay = openInsertOverlay; + + /* Functions bound to view model */ + + function save() { + + vm.page.saveButtonState = "busy"; + vm.partialViewMacro.content = vm.editor.getValue(); + + contentEditingHelper.contentEditorPerformSave({ + statusMessage: localizeSaving, + saveMethod: codefileResource.save, + scope: $scope, + content: vm.partialViewMacro, + // We do not redirect on failure for partial view macros - this is because it is not possible to actually save the partial view + // when server side validation fails - as opposed to content where we are capable of saving the content + // item if server side validation fails + redirectOnFailure: false, + rebindCallback: function (orignal, saved) {} + }).then(function (saved) { + + notificationsService.success("Partial View Macro File saved"); + vm.page.saveButtonState = "success"; + vm.partialViewMacro = saved; + + //sync state + editorState.set(vm.partialViewMacro); + + // normal tree sync + navigationService.syncTree({ tree: "partialViewMacros", path: vm.partialViewMacro.path, forceReload: true }).then(function (syncArgs) { + vm.page.menu.currentNode = syncArgs.node; + }); + + // clear $dirty state on form + setFormState("pristine"); + + }, function (err) { + + vm.page.saveButtonState = "error"; + + localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) { + localizationService.localize("speechBubbles_validationFailedMessage").then(function(msgValue) { + notificationsService.error(headerValue, msgValue); + }); + }); + + }); + + } + + function openInsertOverlay() { + + vm.insertOverlay = { + view: "insert", + allowedTypes: { + macro: true, + dictionary: true, + umbracoField: true + }, + hideSubmitButton: true, + show: true, + submit: function(model) { + + switch(model.insert.type) { + case "macro": + var macroObject = macroService.collectValueData(model.insert.selectedMacro, model.insert.macroParams, "Mvc"); + insert(macroObject.syntax); + break; + + case "dictionary": + var code = templateHelper.getInsertDictionarySnippet(model.insert.node.name); + insert(code); + break; + + case "umbracoField": + insert(model.insert.umbracoField); + break; + } + + vm.insertOverlay.show = false; + vm.insertOverlay = null; + + }, + close: function(oldModel) { + // close the dialog + vm.insertOverlay.show = false; + vm.insertOverlay = null; + // focus editor + vm.editor.focus(); + } + }; + + } + + + function openMacroOverlay() { + + vm.macroPickerOverlay = { + view: "macropicker", + dialogData: {}, + show: true, + title: "Insert macro", + submit: function (model) { + + var macroObject = macroService.collectValueData(model.selectedMacro, model.macroParams, "Mvc"); + insert(macroObject.syntax); + + vm.macroPickerOverlay.show = false; + vm.macroPickerOverlay = null; + + }, + close: function(oldModel) { + // close the dialog + vm.macroPickerOverlay.show = false; + vm.macroPickerOverlay = null; + // focus editor + vm.editor.focus(); + } + }; + } + + + function openPageFieldOverlay() { + vm.pageFieldOverlay = { + submitButtonLabel: "Insert", + closeButtonlabel: "Cancel", + view: "insertfield", + show: true, + submit: function (model) { + insert(model.umbracoField); + vm.pageFieldOverlay.show = false; + vm.pageFieldOverlay = null; + }, + close: function (model) { + // close the dialog + vm.pageFieldOverlay.show = false; + vm.pageFieldOverlay = null; + // focus editor + vm.editor.focus(); + } + }; + } + + + function openDictionaryItemOverlay() { + vm.dictionaryItemOverlay = { + view: "treepicker", + section: "settings", + treeAlias: "dictionary", + entityType: "dictionary", + multiPicker: false, + show: true, + title: "Insert dictionary item", + select: function(node){ + + var code = templateHelper.getInsertDictionarySnippet(node.name); + insert(code); + + vm.dictionaryItemOverlay.show = false; + vm.dictionaryItemOverlay = null; + }, + close: function (model) { + // close dialog + vm.dictionaryItemOverlay.show = false; + vm.dictionaryItemOverlay = null; + // focus editor + vm.editor.focus(); + } + }; + } + + function openQueryBuilderOverlay() { + vm.queryBuilderOverlay = { + view: "querybuilder", + show: true, + title: "Query for content", + + submit: function (model) { + + var code = templateHelper.getQuerySnippet(model.result.queryExpression); + insert(code); + + vm.queryBuilderOverlay.show = false; + vm.queryBuilderOverlay = null; + }, + + close: function (model) { + // close dialog + vm.queryBuilderOverlay.show = false; + vm.queryBuilderOverlay = null; + // focus editor + vm.editor.focus(); + } + }; + } + + /* Local functions */ + + function init() { + //we need to load this somewhere, for now its here. + assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css"); + if ($routeParams.create) { + codefileResource.getScaffold().then(function (partialViewMacro) { + ready(partialViewMacro); + }); + } else { + codefileResource.getByPath('partialViewMacros', $routeParams.id).then(function (partialViewMacro) { + ready(partialViewMacro); + }); + } + } + + function ready(partialViewMacro) { + + vm.page.loading = false; + vm.partialViewMacro = partialViewMacro; + + //sync state + editorState.set(vm.partialViewMacro); + navigationService.syncTree({ tree: "partialViewMacros", path: vm.partialViewMacro.virtualPath, forceReload: true }).then(function (syncArgs) { + vm.page.menu.currentNode = syncArgs.node; + }); + + // ace configuration + vm.aceOption = { + mode: "razor", + theme: "chrome", + showPrintMargin: false, + advanced: { + fontSize: '14px' + }, + onLoad: function(_editor) { + vm.editor = _editor; + + // initial cursor placement + // Keep cursor in name field if we are create a new template + // else set the cursor at the bottom of the code editor + if(!$routeParams.create) { + $timeout(function(){ + vm.editor.navigateFileEnd(); + vm.editor.focus(); + persistCurrentLocation(); + }); + } + + //change on blur, focus + vm.editor.on("blur", persistCurrentLocation); + vm.editor.on("focus", persistCurrentLocation); + } + } + + } + + function insert(str) { + vm.editor.moveCursorToPosition(vm.currentPosition); + vm.editor.insert(str); + vm.editor.focus(); + + // set form state to $dirty + setFormState("dirty"); + } + + function persistCurrentLocation() { + vm.currentPosition = vm.editor.getCursorPosition(); + } + + function setFormState(state) { + + // get the current form + var currentForm = angularHelper.getCurrentForm($scope); + + // set state + if(state === "dirty") { + currentForm.$setDirty(); + } else if(state === "pristine") { + currentForm.$setPristine(); + } + } + + + init(); + + } + + angular.module("umbraco").controller("Umbraco.Editors.PartialViewMacros.EditController", partialViewMacrosEditController); +})(); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html new file mode 100644 index 0000000000..28e720c736 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html @@ -0,0 +1,123 @@ +
+ + + +
+ + + + + + + + +
+ +
+ + + + +
+ +
+ +
+
+ + +
+ + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + +
\ No newline at end of file