diff --git a/src/Umbraco.Web.UI.Client/bower.json b/src/Umbraco.Web.UI.Client/bower.json index 0f3eea3291..4cef3058dd 100644 --- a/src/Umbraco.Web.UI.Client/bower.json +++ b/src/Umbraco.Web.UI.Client/bower.json @@ -28,6 +28,7 @@ "tinymce": "~4.1.10", "codemirror": "~5.3.0", "angular-local-storage": "~0.2.3", - "moment": "~2.10.3" + "moment": "~2.10.3", + "ace-builds": "^1.2.3" } } diff --git a/src/Umbraco.Web.UI.Client/gruntFile.js b/src/Umbraco.Web.UI.Client/gruntFile.js index 0a28d9efaf..9ce6c14731 100644 --- a/src/Umbraco.Web.UI.Client/gruntFile.js +++ b/src/Umbraco.Web.UI.Client/gruntFile.js @@ -394,7 +394,7 @@ module.exports = function (grunt) { tutorials: { src: [], title: '' - } + } }, eslint:{ @@ -524,7 +524,10 @@ module.exports = function (grunt) { 'addon/selection/*', 'addon/dialog/*' ] - } + }, + 'ace-builds': { + files: ['src-min-noconflict/**'] + } } } }, diff --git a/src/Umbraco.Web.UI.Client/lib/ace-razor-mode/theme/razor_chrome.css b/src/Umbraco.Web.UI.Client/lib/ace-razor-mode/theme/razor_chrome.css new file mode 100644 index 0000000000..7f401520d5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/lib/ace-razor-mode/theme/razor_chrome.css @@ -0,0 +1,161 @@ +.ace-chrome .ace_gutter { + background: white !important; + color: #ccc !important; + overflow : hidden; +} + +.ace-chrome .ace_print-margin { + +} + +.ace-chrome { + background-color: #FFFFFF; + color: black; +} + +.ace-chrome .ace_cursor { + color: black; +} + +.ace-chrome .ace_invisible { + color: rgb(191, 191, 191); +} + +.ace-chrome .ace_constant.ace_buildin { + color: rgb(88, 72, 246); +} + +.ace-chrome .ace_constant.ace_language { + color: rgb(88, 92, 246); +} + +.ace-chrome .ace_constant.ace_library { + color: rgb(6, 150, 14); +} + +.ace-chrome .ace_invalid { + background-color: rgb(153, 0, 0); + color: white; +} + +.ace_punctuation.ace_short.ace_razor{ + background: yellow; +} + +.ace-chrome .ace_fold { +} + +.ace-chrome .ace_support.ace_function { + color: rgb(60, 76, 114); +} + +.ace-chrome .ace_support.ace_constant { + color: rgb(6, 150, 14); +} + +.ace-chrome .ace_support.ace_type, +.ace-chrome .ace_support.ace_class +.ace-chrome .ace_support.ace_other { + color: rgb(109, 121, 222); +} + +.ace-chrome .ace_variable.ace_parameter { + font-style:italic; + color:#FD971F; +} +.ace-chrome .ace_keyword.ace_operator { + color: rgb(104, 118, 135); +} + +.ace-chrome .ace_comment { + color: #236e24; +} + +.ace-chrome .ace_comment.ace_doc { + color: #236e24; +} + +.ace-chrome .ace_comment.ace_doc.ace_tag { + color: #236e24; +} + +.ace-chrome .ace_constant.ace_numeric { + color: rgb(0, 0, 205); +} + +.ace-chrome .ace_variable { + color: rgb(49, 132, 149); +} + +.ace-chrome .ace_xml-pe { + color: rgb(104, 104, 91); +} + +.ace-chrome .ace_entity.ace_name.ace_function { + color: #0000A2; +} + + +.ace-chrome .ace_heading { + color: rgb(12, 7, 255); +} + +.ace-chrome .ace_list { + color:rgb(185, 6, 144); +} + +.ace-chrome .ace_marker-layer .ace_selection { + background: rgb(181, 213, 255); +} + +.ace-chrome .ace_marker-layer .ace_step { + background: rgb(252, 255, 0); +} + +.ace-chrome .ace_marker-layer .ace_stack { + background: rgb(164, 229, 101); +} + +.ace-chrome .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgb(192, 192, 192); +} + +.ace-chrome .ace_marker-layer .ace_active-line { + background: rgba(0, 0, 0, 0.07) !important; +} + +.ace-chrome .ace_gutter-active-line { + background: rgba(0, 0, 0, 0.07) !important; +} + +.ace-chrome .ace_marker-layer .ace_selected-word { + background: rgb(250, 250, 255); + border: 1px solid rgb(200, 200, 250); +} + +.ace-chrome .ace_storage, +.ace-chrome .ace_keyword, +.ace-chrome .ace_meta.ace_tag { + color: rgb(147, 15, 128); +} + +.ace-chrome .ace_string.ace_regex { + color: rgb(255, 0, 0) +} + +.ace-chrome .ace_string { + color: #1A1AA6; +} + +.ace-chrome .ace_entity.ace_other.ace_attribute-name { + color: #994409; +} + +.ace-chrome .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; +} + +.ace-chrome .ace_razor { + background: yellow; +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js index cc57eb6e74..4d9222fa45 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js @@ -254,6 +254,7 @@ Use this directive to construct a header inside the main editor window. hideAlias: "@", description: "=", hideDescription: "@", + descriptionLocked: "@", navigation: "=" }, link: link diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbaceeditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbaceeditor.directive.js new file mode 100644 index 0000000000..c97851bbb9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbaceeditor.directive.js @@ -0,0 +1,342 @@ +(function() { + 'use strict'; + + function AceEditorDirective(umbAceEditorConfig, assetsService, angularHelper) { + + /** + * Sets editor options such as the wrapping mode or the syntax checker. + * + * The supported options are: + * + *
++ ++ +++ + +
+ (function () {
+ "use strict";
+
+ function Controller() {
+
+ var vm = this;
+
+ vm.date = "";
+
+ vm.config = {
+ pickDate: true,
+ pickTime: true,
+ useSeconds: true,
+ format: "YYYY-MM-DD HH:mm:ss",
+ icons: {
+ time: "icon-time",
+ date: "icon-calendar",
+ up: "icon-chevron-up",
+ down: "icon-chevron-down"
+ }
+ };
+
+ vm.datePickerChange = datePickerChange;
+ vm.datePickerError = datePickerError;
+
+ function datePickerChange(event) {
+ // handle change
+ if(event.date && event.date.isValid()) {
+ var date = event.date.format(vm.datePickerConfig.format);
+ }
+ }
+
+ function datePickerError(event) {
+ // handle error
+ }
+
+ }
+
+ angular.module("umbraco").controller("My.Controller", Controller);
+
+ })();
+
+
+@param {object} options (binding): Config object for the date picker.
+@param {callback} onHide (callback): Hide callback.
+@param {callback} onShow (callback): Show callback.
+@param {callback} onChange (callback): Change callback.
+@param {callback} onError (callback): Error callback.
+@param {callback} onUpdate (callback): Update callback.
+**/
+
+(function () {
+ 'use strict';
+
+ function DateTimePickerDirective(assetsService) {
+
+ function link(scope, element, attrs, ctrl) {
+
+ function onInit() {
+ // load css file for the date picker
+ assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css');
+
+ // load the js file for the date picker
+ assetsService.loadJs('lib/datetimepicker/bootstrap-datetimepicker.js').then(function () {
+ // init date picker
+ initDatePicker();
+ });
+ }
+
+ function onHide(event) {
+ if (scope.onHide) {
+ scope.$apply(function(){
+ // callback
+ scope.onHide({event: event});
+ });
+ }
+ }
+
+ function onShow() {
+ if (scope.onShow) {
+ scope.$apply(function(){
+ // callback
+ scope.onShow();
+ });
+ }
+ }
+
+ function onChange(event) {
+ if (scope.onChange && event.date && event.date.isValid()) {
+ scope.$apply(function(){
+ // callback
+ scope.onChange({event: event});
+ });
+ }
+ }
+
+ function onError(event) {
+ if (scope.onError) {
+ scope.$apply(function(){
+ // callback
+ scope.onError({event:event});
+ });
+ }
+ }
+
+ function onUpdate(event) {
+ if (scope.onUpdate) {
+ scope.$apply(function(){
+ // callback
+ scope.onUpdate({event: event});
+ });
+ }
+ }
+
+ function initDatePicker() {
+ // Open the datepicker and add a changeDate eventlistener
+ element
+ .datetimepicker(scope.options)
+ .on("dp.hide", onHide)
+ .on("dp.show", onShow)
+ .on("dp.change", onChange)
+ .on("dp.error", onError)
+ .on("dp.update", onUpdate);
+ }
+
+ onInit();
+
+ }
+
+ var directive = {
+ restrict: 'E',
+ replace: true,
+ templateUrl: 'views/components/umb-date-time-picker.html',
+ scope: {
+ options: "=",
+ onHide: "&",
+ onShow: "&",
+ onChange: "&",
+ onError: "&",
+ onUpdate: "&"
+ },
+ link: link
+ };
+
+ return directive;
+
+ }
+
+ angular.module('umbraco.directives').directive('umbDateTimePicker', DateTimePickerDirective);
+
+})();
diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/template.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/template.resource.js
new file mode 100644
index 0000000000..f969864ba1
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/template.resource.js
@@ -0,0 +1,196 @@
+/**
+ * @ngdoc service
+ * @name umbraco.resources.templateResource
+ * @description Loads in data for templates
+ **/
+function templateResource($q, $http, umbDataFormatter, umbRequestHelper) {
+
+ return {
+
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.templateResource#getById
+ * @methodOf umbraco.resources.templateResource
+ *
+ * @description
+ * Gets a template item with a given id
+ *
+ * ##usage
+ *
+ * templateResource.getById(1234)
+ * .then(function(template) {
+ * alert('its here!');
+ * });
+ *
+ *
+ * @param {Int} id id of template to retrieve
+ * @returns {Promise} resourcePromise object.
+ *
+ */
+ getById: function (id) {
+
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "templateApiBaseUrl",
+ "GetById",
+ [{ id: id }])),
+ "Failed to retrieve data for template id " + id);
+ },
+
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.templateResource#getByAlias
+ * @methodOf umbraco.resources.templateResource
+ *
+ * @description
+ * Gets a template item with a given alias
+ *
+ * ##usage
+ *
+ * templateResource.getByAlias("upload")
+ * .then(function(template) {
+ * alert('its here!');
+ * });
+ *
+ *
+ * @param {String} alias Alias of template to retrieve
+ * @returns {Promise} resourcePromise object.
+ *
+ */
+ getByAlias: function (alias) {
+
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "templateApiBaseUrl",
+ "GetByAlias",
+ [{ alias: alias }])),
+ "Failed to retrieve data for template with alias: " + alias);
+ },
+
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.templateResource#getAll
+ * @methodOf umbraco.resources.templateResource
+ *
+ * @description
+ * Gets all templates
+ *
+ * ##usage
+ *
+ * templateResource.getAll()
+ * .then(function(templates) {
+ * alert('its here!');
+ * });
+ *
+ *
+ * @returns {Promise} resourcePromise object.
+ *
+ */
+ getAll: function () {
+
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "templateApiBaseUrl",
+ "GetAll")),
+ "Failed to retrieve data");
+ },
+
+
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.templateResource#getScaffold
+ * @methodOf umbraco.resources.templateResource
+ *
+ * @description
+ * Returns a scaffold of an empty template item
+ *
+ * The scaffold is used to build editors for templates that has not yet been populated with data.
+ *
+ * ##usage
+ *
+ * templateResource.getScaffold()
+ * .then(function(template) {
+ * alert('its here!');
+ * });
+ *
+ *
+ * @returns {Promise} resourcePromise object containing the template scaffold.
+ *
+ */
+ getScaffold: function (id) {
+
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "templateApiBaseUrl",
+ "GetScaffold",
+ [{ id: id }] )),
+ "Failed to retrieve data for empty template");
+ },
+
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.templateResource#deleteById
+ * @methodOf umbraco.resources.templateResource
+ *
+ * @description
+ * Deletes a template with a given id
+ *
+ * ##usage
+ *
+ * templateResource.deleteById(1234)
+ * .then(function() {
+ * alert('its gone!');
+ * });
+ *
+ *
+ * @param {Int} id id of template to delete
+ * @returns {Promise} resourcePromise object.
+ *
+ */
+ deleteById: function(id) {
+ return umbRequestHelper.resourcePromise(
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "templateApiBaseUrl",
+ "DeleteById",
+ [{ id: id }])),
+ "Failed to delete item " + id);
+ },
+
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.templateResource#save
+ * @methodOf umbraco.resources.templateResource
+ *
+ * @description
+ * Saves or update a template
+ *
+ * ##usage
+ *
+ * templateResource.save(template)
+ * .then(function(template) {
+ * alert('its saved!');
+ * });
+ *
+ *
+ * @param {Object} template object to save
+ * @returns {Promise} resourcePromise object.
+ *
+ */
+ save: function (template) {
+ return umbRequestHelper.resourcePromise(
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "templateApiBaseUrl",
+ "PostSave"),
+ template),
+ "Failed to save data for template id " + template.id);
+ }
+ };
+}
+
+angular.module("umbraco.resources").factory("templateResource", templateResource);
diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/templatequery.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/templatequery.resource.js
new file mode 100644
index 0000000000..04569fccff
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/templatequery.resource.js
@@ -0,0 +1,151 @@
+/**
+ * @ngdoc service
+ * @name umbraco.resources.templateQueryResource
+ * @function
+ *
+ * @description
+ * Used by the query builder
+ */
+(function () {
+ 'use strict';
+
+ function templateQueryResource($http, umbRequestHelper) {
+
+ /**
+ * @ngdoc function
+ * @name umbraco.resources.templateQueryResource#getAllowedProperties
+ * @methodOf umbraco.resources.templateQueryResource
+ * @function
+ *
+ * @description
+ * Called to get allowed properties
+ * ##usage
+ *
+ * templateQueryResource.getAllowedProperties()
+ * .then(function(response) {
+ *
+ * });
+ *
+ */
+ function getAllowedProperties() {
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "templateQueryApiBaseUrl",
+ "GetAllowedProperties")),
+ 'Failed to retrieve properties');
+ }
+
+ /**
+ * @ngdoc function
+ * @name umbraco.resources.templateQueryResource#getContentTypes
+ * @methodOf umbraco.resources.templateQueryResource
+ * @function
+ *
+ * @description
+ * Called to get content types
+ * ##usage
+ *
+ * templateQueryResource.getContentTypes()
+ * .then(function(response) {
+ *
+ * });
+ *
+ */
+ function getContentTypes() {
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "templateQueryApiBaseUrl",
+ "GetContentTypes")),
+ 'Failed to retrieve content types');
+ }
+
+ /**
+ * @ngdoc function
+ * @name umbraco.resources.templateQueryResource#getFilterConditions
+ * @methodOf umbraco.resources.templateQueryResource
+ * @function
+ *
+ * @description
+ * Called to the filter conditions
+ * ##usage
+ *
+ * templateQueryResource.getFilterConditions()
+ * .then(function(response) {
+ *
+ * });
+ *
+ */
+ function getFilterConditions() {
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "templateQueryApiBaseUrl",
+ "GetFilterConditions")),
+ 'Failed to retrieve filter conditions');
+ }
+
+ /**
+ * @ngdoc function
+ * @name umbraco.resources.templateQueryResource#postTemplateQuery
+ * @methodOf umbraco.resources.templateQueryResource
+ * @function
+ *
+ * @description
+ * Called to get content types
+ * ##usage
+ *
+ * var query = {
+ * contentType: {
+ * name: "Everything"
+ * },
+ * source: {
+ * name: "My website"
+ * },
+ * filters: [
+ * {
+ * property: undefined,
+ * operator: undefined
+ * }
+ * ],
+ * sort: {
+ * property: {
+ * alias: "",
+ * name: "",
+ * },
+ * direction: "ascending"
+ * }
+ * };
+ *
+ * templateQueryResource.postTemplateQuery(query)
+ * .then(function(response) {
+ *
+ * });
+ *
+ * @param {object} query Query to build result
+ */
+ function postTemplateQuery(query) {
+ return umbRequestHelper.resourcePromise(
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "templateQueryApiBaseUrl",
+ "PostTemplateQuery"),
+ query),
+ 'Failed to retrieve query');
+ }
+
+ var resource = {
+ getAllowedProperties: getAllowedProperties,
+ getContentTypes: getContentTypes,
+ getFilterConditions: getFilterConditions,
+ postTemplateQuery: postTemplateQuery
+ };
+
+ return resource;
+
+ }
+
+ angular.module('umbraco.resources').factory('templateQueryResource', templateQueryResource);
+
+})();
diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less
index 2b53fbddfc..c988f9edbb 100644
--- a/src/Umbraco.Web.UI.Client/src/less/belle.less
+++ b/src/Umbraco.Web.UI.Client/src/less/belle.less
@@ -111,14 +111,17 @@
@import "components/umb-empty-state.less";
@import "components/umb-property-editor.less";
@import "components/umb-iconpicker.less";
+@import "components/umb-insert-code-box.less";
@import "components/umb-packages.less";
@import "components/umb-package-local-install.less";
@import "components/umb-lightbox.less";
@import "components/umb-avatar.less";
@import "components/umb-progress-bar.less";
+@import "components/umb-querybuilder.less";
@import "components/buttons/umb-button.less";
@import "components/buttons/umb-button-group.less";
+@import "components/buttons/umb-era-button.less";
@import "components/notifications/umb-notifications.less";
@import "components/umb-file-dropzone.less";
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button-group.less b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button-group.less
index 0b063d094d..4d5fd90fad 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button-group.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button-group.less
@@ -8,3 +8,25 @@
right: 0;
left: auto;
}
+
+// hack for umb-era-button
+.umb-era-button-group {
+
+ display: flex;
+
+ .umb-era-button:first-child {
+ padding-right: 15px;
+ border-radius: 3px 0 0 3px;
+ }
+
+ .umb-era-button.umb-button-group__toggle {
+ padding-right: 10px;
+ padding-left: 10px;
+ border-radius: 0 3px 3px 0;
+ }
+
+ .umb-era-button.umb-button-group__toggle .caret {
+ margin: 0;
+ }
+
+}
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-era-button.less b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-era-button.less
new file mode 100644
index 0000000000..8087a601bb
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-era-button.less
@@ -0,0 +1,104 @@
+.umb-era-button {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 14px;
+ //font-weight: bold;
+ height: 38px;
+ line-height: 1;
+ max-width: 100%;
+ padding: 0 18px;
+ color: #202129;
+ background-color: #edeeee;
+ text-decoration: none !important;
+ user-select: none;
+ white-space: nowrap;
+ overflow: hidden;
+ border-radius: 3px;
+ border: 0 none;
+ box-sizing: border-box;
+ cursor: pointer;
+ transition: background-color 80ms ease, color 80ms ease;
+}
+
+
+.umb-era-button:hover,
+.umb-era-button:active {
+ color: #484848;
+ background-color: #e1e2e2;
+ outline: none;
+ text-decoration: none;
+}
+
+
+.umb-era-button:focus {
+ outline: none;
+}
+
+.umb-era-button.-blue {
+ background: @blue;
+ color: white;
+}
+
+.umb-era-button.-blue:hover {
+ background-color: @blueDark;
+}
+
+.umb-era-button.-red {
+ background: @btnDangerBackground;
+ color: white;
+}
+
+.umb-era-button.-red:hover {
+ background-color: darken(@btnDangerBackground, 5%);
+}
+
+.umb-era-button.-link {
+ padding: 0;
+ background: transparent;
+}
+
+.umb-era-button.-link:hover {
+ background-color: transparent;
+ opacity: .6;
+}
+
+.umb-era-button.-inactive {
+ cursor: not-allowed;
+ color: #BBB;
+ background: #EAE7E7;
+}
+
+.umb-era-button.-inactive:hover {
+ color: #BBB;
+ background: #EAE7E7;
+}
+
+
+.umb-era-button.-full-width {
+ display: block;
+ width: 100%;
+}
+
+.umb-era-button.umb-button--s {
+ height: 30px;
+ font-size: 13px;
+}
+
+.umb-era-button.-white {
+ background-color: @white;
+
+ &:hover {
+ opacity: .9;
+ }
+}
+
+.umb-era-button.-text-black {
+ color: @black;
+}
+
+/* icons */
+
+.umb-era-button i {
+ margin-right: 5px;
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-insert-code-box.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-insert-code-box.less
new file mode 100644
index 0000000000..9d722f82bf
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-insert-code-box.less
@@ -0,0 +1,47 @@
+.umb-insert-code-boxes {
+ display: flex;
+ flex-direction: column;
+}
+
+.umb-insert-code-box {
+ border: 2px solid @grayLighter;
+ padding: 15px 20px;
+ margin-bottom: 10px;
+ border-radius: 3px;
+}
+
+.umb-insert-code-box:hover,
+.umb-insert-code-box.-selected {
+ border-color: @blue;
+ cursor: pointer;
+}
+
+.umb-insert-code-box__title {
+ font-size: 15px;
+ margin-bottom: 5px;
+ font-weight: bold;
+ color: @black;
+}
+
+.umb-insert-code-box__description {
+ font-size: 11px;
+}
+
+.umb-insert-code-box__check {
+ width: 18px;
+ height: 18px;
+ background: @grayLighter;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 12px;
+ float: left;
+ margin-right: 5px;
+ margin-top: 1px;
+}
+
+.umb-insert-code-box__check--checked {
+ background: @green;
+ color: @white;
+}
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less
index f14df918c0..a043cd5571 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less
@@ -248,95 +248,6 @@
color: black;
}
-/* umb-buttons-era */
-.umb-era-button {
- display: flex;
- justify-content: center;
- align-items: center;
-
- font-size: 14px;
- font-weight: bold;
-
- height: 38px;
- line-height: 1;
-
- max-width: 100%;
- padding: 0 18px;
-
- color: #484848;
- background-color: #e0e0e0;
-
- text-decoration: none !important;
- user-select: none;
-
- white-space: nowrap;
- overflow: hidden;
-
- border-radius: 3px;
- border: 0 none;
- box-sizing: border-box;
-
- cursor: pointer;
-
- transition: background-color 80ms ease, color 80ms ease;
-}
-
-
-.umb-era-button:hover,
-.umb-era-button:active {
- color: #484848;
- background-color: #d3d3d3;
- outline: none;
- text-decoration: none;
-}
-
-
-.umb-era-button:focus {
- outline: none;
-}
-
-.umb-era-button.-blue {
- background: @blue;
- color: white;
-}
-
-.umb-era-button.-blue:hover {
- background-color: @blueDark;
-}
-
-.umb-era-button.-link {
- padding: 0;
- background: transparent;
-}
-
-.umb-era-button.-link:hover {
- background-color: transparent;
- opacity: .6;
-}
-
-.umb-era-button.-inactive {
- cursor: not-allowed;
- color: #BBB;
- background: #EAE7E7;
-}
-
-.umb-era-button.-inactive:hover {
- color: #BBB;
- background: #EAE7E7;
-}
-
-
-.umb-era-button.-full-width {
- display: block;
- width: 100%;
-}
-
-.umb-era-button.umb-button--s {
- height: 30px;
- font-size: 13px;
-}
-
-
/* CATEGORIES */
.umb-packages-categories {
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-querybuilder.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-querybuilder.less
new file mode 100644
index 0000000000..cf72c04b1b
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-querybuilder.less
@@ -0,0 +1,41 @@
+.umb-querybuilder .row {
+ font-size: 12px;
+ line-height: 12px
+}
+
+.umb-querybuilder .row a.btn {
+ padding: 5px 8px;
+ margin: 0 5px;
+ font-weight: bold;
+ background-color: #f3f9ff;
+ border: 1px solid #bfdff9;
+ border-radius: 3px;
+ text-align: center;
+ display: inline-block;
+
+}
+
+.umb-querybuilder .row a.btn:hover {
+ background: #e8f1fb;
+ text-decoration: none;
+}
+
+.umb-querybuilder .row > div {
+ padding: 20px 0;
+ border-bottom: 1px solid @grayLighter;
+}
+
+.umb-querybuilder .datepicker input {
+ width: 90px;
+}
+
+.umb-querybuilder .query-items {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+}
+
+.umb-querybuilder .query-items > * {
+ flex: 0 1 auto;
+ margin: 5px;
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/less/hacks.less b/src/Umbraco.Web.UI.Client/src/less/hacks.less
index 716cb40256..dc1212f33d 100644
--- a/src/Umbraco.Web.UI.Client/src/less/hacks.less
+++ b/src/Umbraco.Web.UI.Client/src/less/hacks.less
@@ -197,7 +197,7 @@ pre {
font-size: @baseFontSize - 1; // 14px to 13px
color: @grayDark;
line-height: @baseLineHeight;
- white-space: pre; // 1
+ white-space: pre-line; // 1
overflow-x: auto; // 1
background-color: #f5f5f5;
border: 1px solid #ccc; // fallback for IE7-8
diff --git a/src/Umbraco.Web.UI.Client/src/less/healthcheck.less b/src/Umbraco.Web.UI.Client/src/less/healthcheck.less
index 6e82d424bb..d0427d96f7 100644
--- a/src/Umbraco.Web.UI.Client/src/less/healthcheck.less
+++ b/src/Umbraco.Web.UI.Client/src/less/healthcheck.less
@@ -95,111 +95,6 @@
}
-/* umb-buttons-era */
-.umb-era-button {
- display: flex;
- justify-content: center;
- align-items: center;
-
- font-size: 14px;
- font-weight: bold;
-
- height: 40px;
- line-height: 1;
-
- max-width: 100%;
- padding: 0 15px;
-
- color: #484848;
- background-color: #e0e0e0;
-
- text-decoration: none !important;
- user-select: none;
-
- white-space: nowrap;
- overflow: hidden;
-
- border-radius: 3px;
- border: 0 none;
- box-sizing: border-box;
-
- cursor: pointer;
-
- transition: background-color 80ms ease, color 80ms ease, opacity 80ms ease;
-}
-
-
-.umb-era-button:hover,
-.umb-era-button:active {
- color: #484848;
- background-color: #d3d3d3;
- outline: none;
- text-decoration: none;
-}
-
-
-.umb-era-button:focus {
- outline: none;
-}
-
-.umb-era-button.-blue {
- background: @blue;
- color: white;
-}
-
-.umb-era-button.-blue:hover {
- background-color: @blueDark;
-}
-
-.umb-era-button.-red {
- background: @btnDangerBackground;
- color: white;
-}
-
-.umb-era-button.-red:hover {
- background-color: darken(@btnDangerBackground, 5%);
-}
-
-.umb-era-button.-link {
- padding: 0;
- background: transparent;
-}
-
-.umb-era-button.-link:hover {
- background-color: transparent;
- opacity: .6;
-}
-
-.umb-era-button.-inactive {
- cursor: not-allowed;
- color: #BBB;
- background: #EAE7E7;
-}
-
-.umb-era-button.-inactive:hover {
- color: #BBB;
- background: #EAE7E7;
-}
-
-
-.umb-era-button.-full-width {
- display: block;
- width: 100%;
-}
-
-.umb-era-button.-white {
- background-color: @white;
-
- &:hover {
- opacity: .9;
- }
-}
-
-.umb-era-button.-text-black {
- color: @black;
-}
-
-
/* Spacing for boxes */
.umb-air {
flex: 0 0 auto;
diff --git a/src/Umbraco.Web.UI.Client/src/less/panel.less b/src/Umbraco.Web.UI.Client/src/less/panel.less
index c80f72921c..ded8411dea 100644
--- a/src/Umbraco.Web.UI.Client/src/less/panel.less
+++ b/src/Umbraco.Web.UI.Client/src/less/panel.less
@@ -480,6 +480,14 @@ input.umb-panel-header-description {
}
}
+.umb-panel-header-locked-description {
+ font-size: 12px;
+ margin-left: 2px;
+ margin-top: 3px;
+ height: 25px;
+ line-height: 25px;
+}
+
.umb-editor-drawer-content {
display: flex;
align-items: center;
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/insert/insert.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/insert/insert.controller.js
new file mode 100644
index 0000000000..59a00a5797
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/insert/insert.controller.js
@@ -0,0 +1,136 @@
+(function () {
+ "use strict";
+
+ function InsertOverlayController($scope) {
+
+ var vm = this;
+
+ if(!$scope.model.title) {
+ $scope.model.title = "Insert";
+ }
+
+ if(!$scope.model.subtitle) {
+ $scope.model.subtitle = "Choose what to insert into your template";
+ }
+
+ vm.openMacroPicker = openMacroPicker;
+ vm.openPageFieldOverlay = openPageFieldOverlay;
+ vm.openDictionaryItemOverlay = openDictionaryItemOverlay;
+ vm.openPartialOverlay = openPartialOverlay;
+
+ function openMacroPicker() {
+
+ vm.macroPickerOverlay = {
+ view: "macropicker",
+ title: "Insert macro",
+ dialogData: {},
+ show: true,
+ submit: function(model) {
+
+ $scope.model.insert = {
+ "type": "macro",
+ "macroParams": model.macroParams,
+ "selectedMacro": model.selectedMacro
+ };
+
+ $scope.model.submit($scope.model);
+
+ vm.macroPickerOverlay.show = false;
+ vm.macroPickerOverlay = null;
+
+ }
+ };
+
+ }
+
+ function openPageFieldOverlay() {
+ vm.pageFieldOverlay = {
+ title: "Insert value",
+ description: "Select a value from the currentpage",
+ submitButtonLabel: "Insert",
+ closeButtonlabel: "Cancel",
+ view: "insertfield",
+ show: true,
+ submit: function(model) {
+
+ $scope.model.insert = {
+ "type": "umbracoField",
+ "umbracoField": model.umbracoField
+ };
+
+ $scope.model.submit($scope.model);
+
+ vm.pageFieldOverlay.show = false;
+ vm.pageFieldOverlay = null;
+ },
+ close: function (model) {
+ vm.pageFieldOverlay.show = false;
+ vm.pageFieldOverlay = null;
+ }
+ };
+ }
+
+ function openDictionaryItemOverlay() {
+
+ vm.dictionaryItemOverlay = {
+ view: "treepicker",
+ section: "settings",
+ treeAlias: "dictionary",
+ entityType: "dictionary",
+ multiPicker: false,
+ title: "Insert dictionary item",
+ show: true,
+ select: function(node){
+
+ $scope.model.insert = {
+ "type": "dictionary",
+ "node": node
+ };
+
+ $scope.model.submit($scope.model);
+
+ vm.dictionaryItemOverlay.show = false;
+ vm.dictionaryItemOverlay = null;
+ },
+
+ close: function(model) {
+ vm.dictionaryItemOverlay.show = false;
+ vm.dictionaryItemOverlay = null;
+ }
+ };
+ }
+
+ function openPartialOverlay() {
+ vm.partialItemOverlay = {
+ view: "treepicker",
+ section: "settings",
+ treeAlias: "partialViews",
+ entityType: "partialView",
+ multiPicker: false,
+ show: true,
+ title: "Insert partial view",
+
+ select: function(node){
+
+ $scope.model.insert = {
+ "type": "partial",
+ "node": node
+ };
+
+ $scope.model.submit($scope.model);
+
+ vm.partialItemOverlay.show = false;
+ vm.partialItemOverlay = null;
+ },
+
+ close: function (model) {
+ vm.partialItemOverlay.show = false;
+ vm.partialItemOverlay = null;
+ }
+ };
+ }
+
+ }
+
+ angular.module("umbraco").controller("Umbraco.Overlays.InsertOverlay", InsertOverlayController);
+})();
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/insert/insert.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/insert/insert.html
new file mode 100644
index 0000000000..4b92ea86ad
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/insert/insert.html
@@ -0,0 +1,61 @@
+{{ vm.generateOutputSample() }}
+
+{{model.result.queryExpression}}
+
+
+ @RenderBody() placeholder.
+ @RenderSection(name) placeholder.
+ This renders an area of a child template which is wrapped in a corresponding @section [name]{ ... } definition.
+ @section definition, otherwise an error is shown.
+ @section { ... }. This can be rendered in a
+ specific area of the master of this template, by using @RenderSection.
+