diff --git a/src/Umbraco.Web.UI.Client/gruntFile.js b/src/Umbraco.Web.UI.Client/gruntFile.js
index 6823de125b..3f3c5ba391 100644
--- a/src/Umbraco.Web.UI.Client/gruntFile.js
+++ b/src/Umbraco.Web.UI.Client/gruntFile.js
@@ -6,7 +6,7 @@ module.exports = function (grunt) {
grunt.registerTask('dev', ['jshint:dev', 'build', 'webserver', 'open:dev', 'watch']);
//run by the watch task
- grunt.registerTask('watch-js', ['jshint:dev','concat','copy:app','copy:mocks','copy:packages','copy:tuning','copy:vs','karma:unit']);
+ grunt.registerTask('watch-js', ['jshint:dev','concat','copy:app','copy:mocks','copy:packages','copy:tuning','copy:vs']);
grunt.registerTask('watch-less', ['recess:build', 'recess:installer', 'recess:tuning','copy:tuning', 'copy:assets', 'copy:vs']);
grunt.registerTask('watch-html', ['copy:views', 'copy:vs']);
grunt.registerTask('watch-packages', ['copy:packages']);
@@ -125,12 +125,6 @@ module.exports = function (grunt) {
{
dest: '<%= distdir %>/lib/lazyload/lazyload.min.js',
src: 'bower_components/rgrove-lazyload/lazyload.js'
- },
- {
- dest: '<%= distdir %>/lib/ace/',
- src: '**',
- expand: true,
- cwd: 'bower_components/ace-builds/src-min-noconflict/'
}
]
},
@@ -171,12 +165,15 @@ module.exports = function (grunt) {
//then we need to figure out how to not copy all the test stuff either!?
{ dest: '<%= vsdir %>/assets', src: '**', expand: true, cwd: '<%= distdir %>/assets' },
{ dest: '<%= vsdir %>/js', src: '**', expand: true, cwd: '<%= distdir %>/js' },
- { dest: '<%= vsdir %>/lib', src: '**', expand: true, cwd: '<%= distdir %>/lib' },
{ dest: '<%= vsdir %>/views', src: '**', expand: true, cwd: '<%= distdir %>/views' },
{ dest: '<%= vsdir %>/preview', src: '**', expand: true, cwd: '<%= distdir %>/preview' }
]
},
-
+ vsLibs: {
+ files: [
+ { dest: '<%= vsdir %>/lib', src: '**', expand: true, cwd: '<%= distdir %>/lib' }
+ ]
+ },
packages: {
files: [{ dest: '<%= vsdir %>/../App_Plugins', src : '**', expand: true, cwd: 'src/packages/' }]
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/utill/checklistmodel.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/utill/checklistmodel.directive.js
index 87e56edcaf..181d8a1881 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/utill/checklistmodel.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/utill/checklistmodel.directive.js
@@ -1,3 +1,10 @@
+/*
+
+ http://vitalets.github.io/checklist-model/
+
+ {{role.text}}
+
+*/
angular.module('umbraco.directives')
.directive('checklistModel', ['$parse', '$compile', function($parse, $compile) {
// contains
diff --git a/src/Umbraco.Web.UI.Client/src/less/gridview.less b/src/Umbraco.Web.UI.Client/src/less/gridview.less
index b8864b529c..1a727cbc2a 100644
--- a/src/Umbraco.Web.UI.Client/src/less/gridview.less
+++ b/src/Umbraco.Web.UI.Client/src/less/gridview.less
@@ -7,7 +7,7 @@
// Sortabel
// -------------------------
.usky-grid .ui-sortable-helper {
- border: dashed 1px #000;
+ border: dashed 1px #$000;
background: #ccc;
opacity: 0.4;
height: 50px !important;
@@ -241,7 +241,7 @@
// CONTROL PLACEHOLDER
// -------------------------
.usky-grid .usky-control-placeholder {
- min-height: 100px;
+ min-height: 50px;
position: relative;
text-align: center;
text-align: -moz-center;
@@ -493,7 +493,7 @@
}
.usky-grid .usky-control{
- margin: 30px;
+ margin: 15px 30px 0px 10px;
padding: 5px;
}
@@ -519,7 +519,7 @@
margin: 20px;
}
- .usky-grid .uSky-templates-template .tb:hover {
+ .usky-grid .uSky-templates-template a.tb:hover {
border:5px solid @blue;
}
@@ -532,7 +532,7 @@
cursor:pointer;
position: relative;
}
-
+
.usky-grid .uSky-templates-template .tr {
height: 100%;
position: relative;
@@ -548,6 +548,10 @@
border-right: 1px dashed @grayLight !important;
}
+ .usky-grid a.uSky-templates-column:hover, .usky-grid a.uSky-templates-column.selected{
+ background-color: @blue;
+ }
+
/**************************************************************************************************/
/* template column */
@@ -576,10 +580,82 @@
border: 2px solid @grayLight;
margin:0px;
background-color: @grayLighter;
- }
+ }
.usky-grid .mainTdpt {
height: 35px;
border: 1px dashed @grayLight;
margin:0px;
background-color: rgba(228, 228, 228, 0.41);
- }
\ No newline at end of file
+ }
+
+
+
+ /**************************************************************************************************/
+ /* Configuration specific styles */
+ /**************************************************************************************************/
+.usky-grid-configuration .uSky-templates{
+ text-align: left;
+}
+
+.usky-grid-configuration ul{
+ display: block;
+}
+
+.usky-grid-configuration ul li{
+ display: block;
+ width: auto;
+ text-align: left;
+}
+
+.usky-grid-configuration .uSky-templates .uSky-templates-template{
+ margin: 0px 20px 20px 0px;
+ width: 60px;
+}
+
+.usky-grid-configuration .uSky-templates .uSky-templates-template .tb{
+ height: 50px;
+ border-width: 2px !important;
+ padding: 0px;
+ border-spacing:2px;
+}
+
+.usky-grid-configuration .uSky-templates .uSky-templates-template .tb:hover{
+ border-width: 2px !important;
+}
+
+.usky-grid-configuration .uSky-templates-column{
+ display: block;
+ float: left;
+ margin-left: -1px;
+}
+
+.usky-grid-configuration .uSky-templates-column.last{
+ margin-right: -1px;
+}
+
+.usky-grid-configuration .uSky-templates-column.add{
+ text-align: center;
+ font-size: 20px;
+ line-height: 70px;
+ color: #ccc;
+ text-decoration: none
+}
+
+
+.usky-grid-configuration .uSky-templates-rows .uSky-templates-row{
+ margin: 0px 50px 20px 0px;
+ width: 60px;
+}
+
+.usky-grid-configuration .uSky-templates-rows .uSky-templates-row .tb{
+ border-width: 2px !important;
+ padding: 0px;
+ border-spacing:2px;
+}
+
+.usky-grid-configuration .uSky-templates-rows .mainTdpt{
+ height: 10px !important;
+}
+
+.usky-grid-configuration a.uSky-templates-column{height: 70px !important;}
+
diff --git a/src/Umbraco.Web.UI.Client/src/less/modals.less b/src/Umbraco.Web.UI.Client/src/less/modals.less
index cef94524b0..2d76403c2e 100644
--- a/src/Umbraco.Web.UI.Client/src/less/modals.less
+++ b/src/Umbraco.Web.UI.Client/src/less/modals.less
@@ -185,33 +185,3 @@
.umb-modal .breadcrumb input {
height: 12px
}
-
-/* YSOD */
-/* These styles are an exact replica of a real .Net YSOD */
-.umb-modal .ysod {
- font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;padding:5px;
-}
-.umb-modal .ysod > div {
- font-family: Arial, Helvetica, Geneva, SunSans-Regular, sans-serif;
- line-height: 13px;
- font-size: 11px;
-}
-.umb-modal .ysod hr {
- margin: 0px;
- color: silver;
- background-color: silver;
- height: 1px;
-}
-.umb-modal .ysod p {font-family:"Verdana";font-weight:normal;color:black;}
-.umb-modal .ysod b {font-family:"Verdana";font-weight:bold;color:black;}
-.umb-modal .ysod h1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red;padding: 0px;text-transform: none !important;margin: 0px; }
-.umb-modal .ysod h2 { font-style:italic; font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon; }
-.umb-modal .ysod pre {border:none;font-family:"Consolas","Lucida Console",Monospace;font-size:13px;margin:0;padding:0.5em;line-height:17px;}
-.umb-modal .ysod .marker {font-weight: bold; color: black;text-decoration: none;}
-.umb-modal .ysod .version {color: gray;}
-.umb-modal .ysod .error {margin-bottom: 10px;}
-.umb-modal .ysod .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:pointer; }
-.umb-modal .ysod table {background-color:#ffffcc;width:100%;}
-.umb-modal .ysod table pre {background-color: inherit;}
-.umb-modal .ysod table code {background-color: inherit;}
-.umb-modal .ysod a.btn { margin-top:10px;margin-right:10px;float:right;}
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/ysod.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/ysod.html
index a096546090..d6b980fa3c 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/ysod.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/ysod.html
@@ -1,28 +1,28 @@
-
+
-
Close
+
-
{{error.errorMsg}}
-
-
{{error.data.ExceptionMessage || error.data.Message}}
-
-
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
-
-
-
Exception Details: {{error.data.ExceptionType}}: {{error.data.ExceptionMessage}}
-
-
-
Stack Trace:
-
-
-
-
-
-
- {{error.data.StackTrace}}
-
-
-
+
Received an error from the server
+
+ {{error.errorMsg}}
+ {{error.data.ExceptionMessage || error.data.Message}}
+
+
+
+ Exception Details:
+ {{error.data.ExceptionType}}: {{error.data.ExceptionMessage}}
+
+
+
+ Stacktrace:
+ {{error.data.StackTrace}}
+
-
+
+
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-control-group.html b/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-control-group.html
index 7284e96cc4..9d144d79d3 100644
--- a/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-control-group.html
+++ b/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-control-group.html
@@ -1,7 +1,7 @@
-
+
-
+
{{labelstring}}
{{description}}
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/config/grid.default.config.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/config/grid.default.config.js
index 7c18b2d8e6..c52c529041 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/config/grid.default.config.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/config/grid.default.config.js
@@ -1,29 +1,33 @@
var uSkyGridConfig = [
{
- columns: [
+ layouts: [
{
grid: 12,
percentage: 100,
-
- cellModels: [
+
+
+ rows: [
{
name: "Single column",
- models: [{
- grid: 12,
- percentage: 100
- }]
- }, {
+ columns: [{
+ grid: 12,
+ percentage: 100
+ }]
+ },
+
+ {
name: "Article",
- models: [{
- grid: 4,
- percentage: 33.3,
- allowed: ["media","quote"]
- }, {
- grid: 8,
- percentage: 66.6,
- allowed: ["rte"]
- }]
+ models: [{
+ grid: 4,
+ percentage: 33.3,
+ allowed: ["media","quote"]
+ }, {
+ grid: 8,
+ percentage: 66.6,
+ allowed: ["rte"]
+ }]
},
+
{
name: "Article, reverse",
models: [
@@ -92,6 +96,7 @@ var uSkyGridConfig = [
{
grid: 9,
percentage: 70,
+
cellModels: [
{
models: [{
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/rte.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/rte.html
index 199bdbeacb..708cd9071d 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/rte.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/rte.html
@@ -1,4 +1,4 @@
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js
index 76db356538..0a2b310f5b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js
@@ -2,261 +2,332 @@ angular.module("umbraco")
.controller("Umbraco.PropertyEditors.GridController",
function ($scope, $http, assetsService, $rootScope, dialogService, gridService, mediaResource, imageHelper, $timeout) {
- var gridConfigPath = $scope.model.config.items.gridConfigPath;
+ // Grid status variables
+ $scope.currentRow = null;
+ $scope.currentCell = null;
+ $scope.currentToolsControl = null;
+ $scope.currentControl = null;
+ $scope.openRTEToolbarId = null;
- if(!gridConfigPath){
- gridConfigPath = "views/propertyeditors/grid/grid.default.config.js";
- }
+
+ // *********************************************
+ // Sortable options
+ // *********************************************
- assetsService.loadJs(gridConfigPath).then(function(){
+ $scope.sortableOptions = {
+ distance: 10,
+ cursor: "move",
+ placeholder: 'ui-sortable-placeholder',
+ handle: '.cell-tools-move',
+ start: function (e, ui) {
+ ui.item.find('.mceNoEditor').each(function () {
+ tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id'));
- // Grid config
- $scope.uSkyGridConfig = uSkyGridConfig;
+ });
+ },
+ stop: function (e, ui) {
+ ui.item.find('.mceNoEditor').each(function () {
+ tinyMCE.execCommand('mceAddEditor', false, $(this).attr('id'));
+ });
+ }
+ };
- // Grid status variables
- $scope.currentRow = null;
- $scope.currentCell = null;
- $scope.currentToolsControl = null;
- $scope.currentControl = null;
+ // *********************************************
+ // Template management functions
+ // *********************************************
+
+ $scope.addTemplate = function (template) {
+ $scope.model.value = angular.copy(template);
+
+ //default row data
+ _.forEach($scope.model.value.sections, function(section){
+ $scope.initSection(section);
+ });
+ };
+
+
+ // *********************************************
+ // Row management function
+ // *********************************************
+
+ $scope.setCurrentRow = function (row) {
+ $scope.currentRow = row;
+ };
+
+ $scope.disableCurrentRow = function () {
+ $scope.currentRow = null;
+ };
+
+
+ $scope.getAllowedLayouts = function(column){
+ var layouts = $scope.model.config.items.layouts;
+
+ if(column.allowed && column.allowed.length > 0){
+ return _.filter(layouts, function(layout){
+ return _.indexOf(column.allowed, layout.name) >= 0;
+ });
+ }else{
+ return layouts;
+ }
+ };
+
+ $scope.addRow = function (column, layout) {
+ //copy the selected layout into the rows collection
+ var row = angular.copy(layout);
+ $scope.initRow(row);
+
+ column.rows.push(row);
+ };
+
+ $scope.removeRow = function (section, $index) {
+ if (section.rows.length > 0) {
+ section.rows.splice($index, 1);
$scope.openRTEToolbarId = null;
- gridService.getGridEditors().then(function(response){
- $scope.availableEditors = response.data;
+ $scope.initContent();
+ }
+ };
+
+
+ // *********************************************
+ // Cell management functions
+ // *********************************************
+
+ $scope.setCurrentCell = function (cell) {
+ $scope.currentCell = cell;
+ };
+
+ $scope.disableCurrentCell = function (cell) {
+ $scope.currentCell = null;
+ };
+
+ $scope.cellPreview = function(cell){
+ if(cell && cell.$allowedEditors){
+ var editor = cell.$allowedEditors[0];
+ return editor.icon;
+ }else{
+ return "icon-layout";
+ }
+ };
+
+
+
+
+ // *********************************************
+ // Control management functions
+ // *********************************************
+ $scope.setCurrentControl = function (Control) {
+ $scope.currentControl = Control;
+ };
+
+ $scope.disableCurrentControl = function (Control) {
+ $scope.currentControl = null;
+ };
+
+ $scope.setCurrentToolsControl = function (Control) {
+ $scope.currentToolsControl = Control;
+ };
+
+ $scope.disableCurrentToolsControl = function (Control) {
+ $scope.currentToolsControl = null;
+ };
+
+ $scope.setCurrentRemoveControl = function (Control) {
+ $scope.currentRemoveControl = Control;
+ };
+
+ $scope.disableCurrentRemoveControl = function (Control) {
+ $scope.currentRemoveControl = null;
+ };
+
+ $scope.setCurrentMoveControl = function (Control) {
+ $scope.currentMoveControl = Control;
+ };
+
+ $scope.disableCurrentMoveControl = function (Control) {
+ $scope.currentMoveControl = null;
+ };
+
+ $scope.setUniqueId = function (cell, index) {
+ var date = new Date();
+ var components = [
+ date.getYear(),
+ date.getMonth(),
+ date.getDate(),
+ date.getHours(),
+ date.getMinutes(),
+ date.getSeconds(),
+ date.getMilliseconds()
+ ];
+ return components.join("");
+ };
+
+
+ $scope.addControl = function (editor, cell, index){
+ var newControl = {
+ value: null,
+ editor: editor
+ };
+
+ if (index === undefined) {
+ index = cell.controls.length;
+ }
+
+ //populate control
+ $scope.initControl(newControl, index+1);
+
+ cell.controls.splice(index + 1, 0, newControl);
+ };
+
+ $scope.addTinyMce = function(cell){
+ var rte = $scope.getEditor("rte");
+ $scope.addControl(rte, cell);
+ };
+
+ $scope.getEditor = function(alias){
+ return _.find($scope.availableEditors, function(editor){return editor.alias === alias});
+ };
+
+ $scope.removeControl = function (cell, $index) {
+ cell.controls.splice($index, 1);
+ };
+
+ $scope.percentage = function(spans){
+ return ((spans/12)*100).toFixed(1);
+ };
+
+
+
+
+
+
+
+
+ // *********************************************
+ // INITIALISATION
+ // these methods are called from ng-init on the template
+ // so we can controll their first load data
+ //
+ // intialisation sets non-saved data like percentage sizing, allowed editors and
+ // other data that should all be pre-fixed with $ to strip it out on save
+ // *********************************************
+
+ // *********************************************
+ // Init template + sections
+ // *********************************************
+ $scope.initContent = function() {
+ var clear = true;
+
+ if ($scope.model.value && $scope.model.value.sections && $scope.model.value.sections.length > 0) {
+ _.forEach($scope.model.value.sections, function(section){
+
+ $scope.initSection(section);
+
+ //we do this to ensure that the grid can be reset by deleting the last row
+ if(section.rows.length > 0){
+ clear = false;
+ }
});
-
- // *********************************************
- // Sortable options
- // *********************************************
+ }
- $scope.sortableOptions = {
- distance: 10,
- cursor: "move",
- placeholder: 'ui-sortable-placeholder',
- handle: '.cell-tools-move',
- start: function (e, ui) {
- ui.item.find('.mceNoEditor').each(function () {
- tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id'));
+ if(clear){
+ $scope.model.value = undefined;
+ }
+ };
- });
- },
- stop: function (e, ui) {
- ui.item.find('.mceNoEditor').each(function () {
- tinyMCE.execCommand('mceAddEditor', false, $(this).attr('id'));
- });
- }
- };
+ $scope.initSection = function(section){
+ section.$percentage = $scope.percentage(section.grid);
- // *********************************************
- // Template management functions
- // *********************************************
+ var layouts = $scope.model.config.items.layouts;
- $scope.checkContent = function() {
- var isEmpty = true;
- if ($scope.model.value &&
- $scope.model.value.columns) {
- angular.forEach($scope.model.value.columns, function (value, key) {
- if ( value.rows && value.rows.length > 0) {
- isEmpty = false;
- }
- });
- }
+ if(section.allowed && section.allowed.length > 0){
+ section.$allowedLayouts = _.filter(layouts, function(layout){
+ return _.indexOf(section.allowed, layout.name) >= 0;
+ });
+ }else{
+ section.$allowedLayouts = layouts;
+ }
- if (isEmpty)
- {
- $scope.model.value = undefined;
- }
+ if(!section.rows){
+ section.rows = [];
+ }else{
+ _.forEach(section.rows, function(row){
+ $scope.initRow(row);
+ });
+ }
+ };
- }
- $scope.addTemplate = function (template) {
- $scope.model.value = {
- gridWidth: "",
- columns: []
- };
+ // *********************************************
+ // Init layout / row
+ // *********************************************
+ $scope.initRow = function(row){
+
+ if(!row.areas){
+ row.areas = [];
+ }
- angular.forEach(template.columns, function (value, key) {
- var newCol = angular.copy(value);
- newCol.rows = [];
- $scope.model.value.columns.splice($scope.model.value.columns.length + 1, 0, newCol);
+ //set a disposable unique ID
+ row.$uniqueId = $scope.setUniqueId();
+
+ //populate with data
+ _.forEach(row.areas, function(area){
+ if(!area.controls){
+ area.controls = [];
+ }else{
+ _.forEach(area.controls, function(control, index){
+ $scope.initControl(control, index);
});
}
-
-
- // *********************************************
- // Row management function
- // *********************************************
-
- $scope.setCurrentRow = function (row) {
- $scope.currentRow = row;
- }
-
- $scope.disableCurrentRow = function () {
- $scope.currentRow = null;
- }
-
- $scope.addRow = function (column, cellModel) {
+ area.$percentage = $scope.percentage(area.grid);
- column.rows.splice(column.rows.length + 1, 0,
- {
- uniqueId: $scope.setUniqueId(),
- cells: [],
- cssClass: ''
+ if(!area.allowed){
+ area.$allowedEditors = $scope.availableEditors;
+ area.$allowsRTE = true;
+ }else{
+ area.$allowedEditors = _.filter($scope.availableEditors, function(editor){
+ return _.indexOf(area.allowed, editor.alias) >= 0;
});
- for (var i = 0; i < cellModel.models.length; i++) {
-
- var cells = column.rows[column.rows.length - 1].cells;
- var model = angular.copy(cellModel.models[i]);
-
- cells.splice(
- cells.length + 1, 0,
- {
- model: model,
- controls: []
- });
- }
- };
-
- $scope.removeRow = function (column, $index) {
- if (column.rows.length > 0) {
- column.rows.splice($index, 1);
- $scope.openRTEToolbarId = null;
- $scope.checkContent();
+ if(_.indexOf(area.allowed,"rte")>=0){
+ area.$allowsRTE = true;
}
}
-
- // *********************************************
- // Cell management functions
- // *********************************************
-
- $scope.setCurrentCell = function (cell) {
- $scope.currentCell = cell;
- }
-
- $scope.disableCurrentCell = function (cell) {
- $scope.currentCell = null;
- }
-
- $scope.cellPreview = function(cell){
- if($scope.availableEditors && cell && cell.allowed && angular.isArray(cell.allowed)){
- var editor = $scope.getEditor(cell.allowed[0]);
- return editor.icon;
- }else{
- return "icon-layout";
- }
- }
-
- // *********************************************
- // Control management functions
- // *********************************************
- $scope.setCurrentControl = function (Control) {
- $scope.currentControl = Control;
- };
-
- $scope.disableCurrentControl = function (Control) {
- $scope.currentControl = null;
- };
-
- $scope.setCurrentToolsControl = function (Control) {
- $scope.currentToolsControl = Control;
- };
-
- $scope.disableCurrentToolsControl = function (Control) {
- $scope.currentToolsControl = null;
- };
-
- $scope.setCurrentRemoveControl = function (Control) {
- $scope.currentRemoveControl = Control;
- };
-
- $scope.disableCurrentRemoveControl = function (Control) {
- $scope.currentRemoveControl = null;
- };
-
- $scope.setCurrentMoveControl = function (Control) {
- $scope.currentMoveControl = Control;
- };
-
- $scope.disableCurrentMoveControl = function (Control) {
- $scope.currentMoveControl = null;
- };
-
- $scope.setUniqueId = function (cell, index) {
- var date = new Date();
- var components = [
- date.getYear(),
- date.getMonth(),
- date.getDate(),
- date.getHours(),
- date.getMinutes(),
- date.getSeconds(),
- date.getMilliseconds()
- ];
- return components.join("");
- };
-
- $scope.setEditorPath = function(control){
- control.editorPath = "views/propertyeditors/grid/editors/" + control.editor.view + ".html";
- };
-
- $scope.addControl = function (editor, cell, index){
- var newId = $scope.setUniqueId();
- var newControl = {
- uniqueId: newId,
- value: null,
- editor: editor
- };
-
- if (index === undefined) {
- index = cell.controls.length;
- }
-
- cell.controls.splice(index + 1, 0, newControl);
- };
-
- $scope.addTinyMce = function(cell){
- var rte = _.find($scope.availableEditors, function(editor){return editor.alias === "rte";});
- $scope.addControl(rte, cell);
- };
-
- $scope.getEditor = function(alias){
- return _.find($scope.availableEditors, function(editor){return editor.alias === alias});
- };
-
- $scope.removeControl = function (cell, $index) {
- cell.controls.splice($index, 1);
- };
-
- $scope.allowedControl = function (editor, cell){
- if(cell.model.allowed && angular.isArray(cell.model.allowed)){
- return _.contains(cell.model.allowed, editor.alias);
- }else{
- return true;
- }
- };
-
-
- // *********************************************
- // Init grid
- // *********************************************
-
- /* init grid data */
- if ($scope.model.value && $scope.model.value != "") {
- if (!$scope.model.config.items.enableGridWidth) {
- $scope.model.value.gridWidth = $scope.model.config.items.defaultGridWith;
- }
- }
-
- $scope.checkContent();
-
});
+ };
+
+
// *********************************************
- // asset styles
- // *********************************************
+ // Init control
+ // *********************************************
- //assetsService.loadCss("/App_Plugins/Lecoati.uSky.Grid/lib/jquery-ui-1.10.4.custom/css/ui-lightness/jquery-ui-1.10.4.custom.min.css");
- //assetsService.loadCss($scope.model.config.items.approvedBackgroundCss);
+ $scope.initControl = function(control, index){
+ control.$index = index;
+ control.$uniqueId = $scope.setUniqueId();
+ if(!control.$editorPath){
+ //if its a path
+ if(_.indexOf(control.editor.view, "/") >= 0){
+ control.$editorPath = control.editor.view;
+ }else{
+ //use convention
+ control.$editorPath = "views/propertyeditors/grid/editors/" + control.editor.view + ".html";
+ }
+ }
+ };
+
+
+ gridService.getGridEditors().then(function(response){
+ $scope.availableEditors = response.data;
+
+ $scope.contentReady = true;
+
+ // *********************************************
+ // Init grid
+ // *********************************************
+ $scope.initContent();
+
+ });
});
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html
index 7071e7374d..d823806f93 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html
@@ -1,17 +1,18 @@
-
+
-
+
+ ng-repeat="section in template.sections"
+ style="width:{{ section.$percentage }}%">
@@ -25,21 +26,22 @@
-
+
+ ng-class="{last:$last}"
+ ng-repeat="section in model.value.sections"
+ ng-init="initSection(section)"
+ style="width:{{section.$percentage}}%">
-
+
-
+
Are you sure?
-
Yes
+
Yes
@@ -85,43 +87,43 @@
+ ng-repeat="area in row.areas">
-
+
+
+ ng-if="area.controls.length == 0">
-
+
-
+
Start writing here...
@@ -131,33 +133,30 @@
-
+
-
-
+
+
-
{{cellModel.name}}
+
{{layout.name}}
@@ -238,9 +242,8 @@
-
-
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js
index 49b6c74556..095b0bb04c 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js
@@ -2,39 +2,248 @@ angular.module("umbraco")
.controller("Umbraco.PropertyEditors.GridPrevalueEditorController",
function ($scope, $http, assetsService, $rootScope, dialogService, mediaResource, gridService, imageHelper, $timeout) {
- var emptyModel = {
- enableGridWidth: true,
- defaultGridWith: "",
- enableBackground: true,
- enableSkipTopMargin: true,
- defaultSkipTopMargin: false,
- enableSkipBottomMargin: true,
- defaultSkipBottomMargin: false,
- enableSkipLeftMargin: true,
- defaultSkipLeftMargin: false,
- enableSkipRightMargin: true,
- defaultSkipRightMargin: false,
- enableSkipControlMargin: true,
- defaultSkipControlMargin: false,
- enableFullScreen: true,
- defaultFullScreen: false,
- enableBoxed: true,
- defaultBoxed: false,
- enableRte: true,
- enableMedia: true,
- enableMacro: true,
- enabledEditors: [ "rte", "media", "macro" ],
- enableMultiCells: true,
- approvedBackgroundCss: "",
- gridConfigPath: "views/propertyeditors/grid/config/grid.default.config.js"
- }
+ var emptyModel = {
+ templates:[
+ {
+ name: "1 column",
+ sections: [
+ {
+ grid: 12,
+ }
+ ]
+ },
+ {
+ name: "2 column",
+ sections: [
+ {
+ grid: 4,
+ },
+ {
+ grid: 8
+ }
+ ]
+ },
+ {
+ name: "2 column reversed",
+ sections: [
+ {
+ grid: 8,
+ },
+ {
+ grid: 4
+ }
+ ]
+ }
+ ],
+
+ layouts:[
+ {
+ name: "Headline",
+ areas: [
+ {
+ grid: 12,
+ editors: ["headline"]
+ }
+ ]
+ },
+ {
+ name: "Article",
+ areas: [
+ {
+ grid: 4
+ },
+ {
+ grid: 8
+ }
+ ]
+ }
+ ]
+ };
+
+
+
+
+ /****************
+ template
+ *****************/
+
+ $scope.configureTemplate = function(template){
+ if($scope.currentTemplate && $scope.currentTemplate === template){
+ delete $scope.currentTemplate;
+ }else{
+ //if no template is passed in, we can assume we are adding a new one
+ if(template === undefined){
+ template = {
+ name: "",
+ sections:[
+
+ ]
+ };
+ $scope.model.value.templates.push(template);
+ }
+ $scope.currentTemplate = template;
+ }
+ };
+ $scope.deleteTemplate = function(index){
+ $scope.model.value.templates.splice(index, 1);
+ };
+ $scope.closeTemplate = function(){
+
+ //clean-up
+ _.forEach($scope.currentTemplate.sections, function(section, index){
+ if(section.grid <= 0){
+ $scope.currentTemplate.sections.splice(index, 1);
+ }
+ });
+
+ $scope.currentTemplate = undefined;
+
+ };
+
+ /****************
+ Section
+ *****************/
+ $scope.configureSection = function(section, template){
+ if($scope.currentSection && $scope.currentSection === section){
+ delete $scope.currentSection;
+ }else{
+ if(section === undefined){
+ var space = ($scope.availableTemplateSpace > 4) ? 4 : $scope.availableTemplateSpace;
+ section = {
+ grid: space
+ };
+ template.sections.push(section);
+ }
+ $scope.currentSection = section;
+ }
+ };
+ $scope.deleteSection = function(index){
+ $scope.currentTemplate.sections.splice(index, 1);
+ };
+ $scope.closeSection = function(){
+ $scope.currentSection = undefined;
+ };
+
+
+
+
+ /****************
+ layout
+ *****************/
+
+ $scope.configureLayout = function(layout){
+ if($scope.currentLayout && $scope.currentLayout === layout){
+ delete $scope.currentLayout;
+ }else{
+ //if no template is passed in, we can assume we are adding a new one
+ if(layout === undefined){
+ layout = {
+ name: "",
+ areas:[
+
+ ]
+ };
+ $scope.model.value.layouts.push(layout);
+ }
+ $scope.currentLayout = layout;
+ }
+ };
+ $scope.deleteLayout = function(index){
+ $scope.model.value.layouts.splice(index, 1);
+ };
+ $scope.closeLayout = function(){
+
+ //clean-up
+ _.forEach($scope.currentLayout.areas, function(area, index){
+ if(area.grid <= 0){
+ $scope.currentLayout.areas.splice(index, 1);
+ }
+ });
+
+ $scope.currentLayout = undefined;
+ };
+
+ /****************
+ area
+ *****************/
+ $scope.configureArea = function(area, layout){
+ if($scope.currentArea && $scope.currentArea === area){
+ delete $scope.currentArea;
+ }else{
+ if(area === undefined){
+ var space = ($scope.availableLayoutSpace > 4) ? 4 : $scope.availableLayoutSpace;
+ area = {
+ grid: space
+ };
+ layout.areas.push(area);
+ }
+ $scope.currentArea = area;
+ }
+ };
+ $scope.deleteArea = function(index){
+ $scope.currentLayout.areas.splice(index, 1);
+ };
+ $scope.closeArea = function(){
+ $scope.currentArea = undefined;
+ };
+
+
+ /****************
+ utillities
+ *****************/
+ $scope.scaleUp = function(section, max){
+ var add = (max > 2) ? 2 : max;
+ section.grid = section.grid+add;
+ };
+ $scope.scaleDown = function(section){
+ var remove = (section.grid > 2) ? 2 : section.grid;
+ section.grid = section.grid-remove;
+ };
+ $scope.toggleCollection = function(collection){
+ if(collection === undefined){
+ collection = [];
+ }else{
+ delete collection;
+ }
+ }
+ $scope.percentage = function(spans){
+ return ((spans/12)*100).toFixed(1);
+ };
+
+ /****************
+ watchers
+ *****************/
+ $scope.$watch("currentTemplate", function(template){
+ if(template){
+ var total = 0;
+ _.forEach(template.sections, function(section){
+ total = (total + section.grid);
+ });
+ $scope.availableTemplateSpace = 12 - total;
+ }
+ }, true);
+
+ $scope.$watch("currentLayout", function(layout){
+ if(layout){
+ var total = 0;
+ _.forEach(layout.areas, function(area){
+ total = (total + area.grid);
+ });
+ $scope.availableLayoutSpace = 12 - total;
+ }
+ }, true);
+
+
+ /****************
+ editors
+ *****************/
gridService.getGridEditors().then(function(response){
$scope.editors = response.data;
});
/* init grid data */
- if (!$scope.model.value || $scope.model.value == "") {
+ if (!$scope.model.value || $scope.model.value === "" || !$scope.model.value.templates) {
$scope.model.value = emptyModel;
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html
index f3e656d89e..77b1957753 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html
@@ -1,109 +1,290 @@
-
+
-
Config file path:
-
+
+
+
+
-
-
+
-
- Others settings:
-
+
+
+
+
+
+
+ Add template
+
+
+
+
+
Template
+
+
+
+
+
+
+
+
+
Modify template Section
+
+
+
+
+
+ {{currentSection.grid}}
+
+
+
+
+
+
+
+
+
+
+
+
+
Finish editing section
+
+
Delete section
+
+
+
+
+
+
+
+
+ Finish editing template
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Layout
+
+
+
+
+
+
+
+
+
Modify layout area
+
+
+
+
+
+
+ {{currentArea.grid}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Finish editing area
+
+
Delete area
+
+
+
+
+
+
+ Finish editing layout
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/bootstrap3.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/bootstrap3.cshtml
index 284a8423c3..91dd2c02e2 100644
--- a/src/Umbraco.Web.UI/Views/Partials/Grid/bootstrap3.cshtml
+++ b/src/Umbraco.Web.UI/Views/Partials/Grid/bootstrap3.cshtml
@@ -4,24 +4,24 @@
@if (Model != null && !string.IsNullOrEmpty(Model.ToString()))
{
- var onlyOneColumn = Model.columns != null ? ((System.Collections.ICollection)Model.columns).Count : 0;
+ var onlyOneColumn = Model.sections != null ? ((System.Collections.ICollection)Model.sections).Count : 0;
- @foreach (var column in Model.columns)
+ @foreach (var s in Model.sections)
{
-
- @foreach (var row in column.rows)
+
+ @foreach (var row in s.rows)
{
- @foreach (var cell in row.cells)
+ @foreach (var area in row.areas)
{
-
+
- @foreach (var control in cell.controls)
+ @foreach (var control in area.controls)
{
if (control != null && control.editor != null && control.editor.view != null)
{
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/TemplateQueryController.cs b/src/Umbraco.Web/Editors/TemplateQueryController.cs
similarity index 99%
rename from src/Umbraco.Web/Editors/TemplateQuery/TemplateQueryController.cs
rename to src/Umbraco.Web/Editors/TemplateQueryController.cs
index 0bcc60cfbd..da4b90607d 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/TemplateQueryController.cs
+++ b/src/Umbraco.Web/Editors/TemplateQueryController.cs
@@ -18,7 +18,7 @@ namespace Umbraco.Web.Editors
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Web.Dynamics;
- using Umbraco.Web.Editors.TemplateQuery;
+ using Umbraco.Web.Models.TemplateQuery;
using System.Linq.Expressions;
using Umbraco.Web.Models;
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/ContentTypeModel.cs b/src/Umbraco.Web/Models/TemplateQuery/ContentTypeModel.cs
similarity index 85%
rename from src/Umbraco.Web/Editors/TemplateQuery/ContentTypeModel.cs
rename to src/Umbraco.Web/Models/TemplateQuery/ContentTypeModel.cs
index 5ea110f7bb..4974932476 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/ContentTypeModel.cs
+++ b/src/Umbraco.Web/Models/TemplateQuery/ContentTypeModel.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Umbraco.Web.Editors.TemplateQuery
+namespace Umbraco.Web.Models.TemplateQuery
{
public class ContentTypeModel
{
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/Operathor.cs b/src/Umbraco.Web/Models/TemplateQuery/Operathor.cs
similarity index 83%
rename from src/Umbraco.Web/Editors/TemplateQuery/Operathor.cs
rename to src/Umbraco.Web/Models/TemplateQuery/Operathor.cs
index d04ebc13b1..0bfb990b84 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/Operathor.cs
+++ b/src/Umbraco.Web/Models/TemplateQuery/Operathor.cs
@@ -1,4 +1,4 @@
-namespace Umbraco.Web.Editors
+namespace Umbraco.Web.Models.TemplateQuery
{
public enum Operathor
{
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/OperathorTerm.cs b/src/Umbraco.Web/Models/TemplateQuery/OperathorTerm.cs
similarity index 93%
rename from src/Umbraco.Web/Editors/TemplateQuery/OperathorTerm.cs
rename to src/Umbraco.Web/Models/TemplateQuery/OperathorTerm.cs
index c85d700950..8f9b4ec4b3 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/OperathorTerm.cs
+++ b/src/Umbraco.Web/Models/TemplateQuery/OperathorTerm.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
-namespace Umbraco.Web.Editors
+namespace Umbraco.Web.Models.TemplateQuery
{
public class OperathorTerm
{
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/PropertyModel.cs b/src/Umbraco.Web/Models/TemplateQuery/PropertyModel.cs
similarity index 86%
rename from src/Umbraco.Web/Editors/TemplateQuery/PropertyModel.cs
rename to src/Umbraco.Web/Models/TemplateQuery/PropertyModel.cs
index 577eb61b2d..6c3bdcf037 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/PropertyModel.cs
+++ b/src/Umbraco.Web/Models/TemplateQuery/PropertyModel.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Umbraco.Web.Editors.TemplateQuery
+namespace Umbraco.Web.Models.TemplateQuery
{
public class PropertyModel
{
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/QueryCondition.cs b/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs
similarity index 96%
rename from src/Umbraco.Web/Editors/TemplateQuery/QueryCondition.cs
rename to src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs
index 8fe8c7e83e..284518bf1e 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/QueryCondition.cs
+++ b/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs
@@ -1,7 +1,5 @@
-namespace Umbraco.Web.Editors
+namespace Umbraco.Web.Models.TemplateQuery
{
- using Umbraco.Web.Editors.TemplateQuery;
-
public class QueryCondition
{
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/QueryModel.cs b/src/Umbraco.Web/Models/TemplateQuery/QueryModel.cs
similarity index 81%
rename from src/Umbraco.Web/Editors/TemplateQuery/QueryModel.cs
rename to src/Umbraco.Web/Models/TemplateQuery/QueryModel.cs
index 999406f1a3..0b7e27f991 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/QueryModel.cs
+++ b/src/Umbraco.Web/Models/TemplateQuery/QueryModel.cs
@@ -1,9 +1,7 @@
using System.Collections.Generic;
-namespace Umbraco.Web.Editors
+namespace Umbraco.Web.Models.TemplateQuery
{
- using Umbraco.Web.Editors.TemplateQuery;
-
public class QueryModel
{
public ContentTypeModel ContentType { get; set; }
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/QueryResultModel.cs b/src/Umbraco.Web/Models/TemplateQuery/QueryResultModel.cs
similarity index 89%
rename from src/Umbraco.Web/Editors/TemplateQuery/QueryResultModel.cs
rename to src/Umbraco.Web/Models/TemplateQuery/QueryResultModel.cs
index d4922f6f62..13421e1199 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/QueryResultModel.cs
+++ b/src/Umbraco.Web/Models/TemplateQuery/QueryResultModel.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
-namespace Umbraco.Web.Editors
+namespace Umbraco.Web.Models.TemplateQuery
{
public class QueryResultModel
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/SortExpression.cs b/src/Umbraco.Web/Models/TemplateQuery/SortExpression.cs
similarity index 64%
rename from src/Umbraco.Web/Editors/TemplateQuery/SortExpression.cs
rename to src/Umbraco.Web/Models/TemplateQuery/SortExpression.cs
index d891ece0d8..76f42b8a69 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/SortExpression.cs
+++ b/src/Umbraco.Web/Models/TemplateQuery/SortExpression.cs
@@ -1,7 +1,5 @@
-namespace Umbraco.Web.Editors
+namespace Umbraco.Web.Models.TemplateQuery
{
- using Umbraco.Web.Editors.TemplateQuery;
-
public class SortExpression
{
public PropertyModel Property { get; set; }
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/SourceModel.cs b/src/Umbraco.Web/Models/TemplateQuery/SourceModel.cs
similarity index 72%
rename from src/Umbraco.Web/Editors/TemplateQuery/SourceModel.cs
rename to src/Umbraco.Web/Models/TemplateQuery/SourceModel.cs
index bba62e3a78..828de22759 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/SourceModel.cs
+++ b/src/Umbraco.Web/Models/TemplateQuery/SourceModel.cs
@@ -1,4 +1,4 @@
-namespace Umbraco.Web.Editors
+namespace Umbraco.Web.Models.TemplateQuery
{
public class SourceModel
{
diff --git a/src/Umbraco.Web/Editors/TemplateQuery/TemplateQueryResult.cs b/src/Umbraco.Web/Models/TemplateQuery/TemplateQueryResult.cs
similarity index 74%
rename from src/Umbraco.Web/Editors/TemplateQuery/TemplateQueryResult.cs
rename to src/Umbraco.Web/Models/TemplateQuery/TemplateQueryResult.cs
index f277d91cee..376caca7df 100644
--- a/src/Umbraco.Web/Editors/TemplateQuery/TemplateQueryResult.cs
+++ b/src/Umbraco.Web/Models/TemplateQuery/TemplateQueryResult.cs
@@ -1,4 +1,4 @@
-namespace Umbraco.Web.Editors
+namespace Umbraco.Web.Models.TemplateQuery
{
public class TemplateQueryResult
{
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 6cebf2e214..5e4a683519 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -312,18 +312,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -379,7 +379,7 @@
-
+