diff --git a/src/Umbraco.Web.UI.Client/src/less/gridview.less b/src/Umbraco.Web.UI.Client/src/less/gridview.less index b8864b529c..5a6b9e17ae 100644 --- a/src/Umbraco.Web.UI.Client/src/less/gridview.less +++ b/src/Umbraco.Web.UI.Client/src/less/gridview.less @@ -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/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/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index 76db356538..05dbb1d425 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 @@ -53,8 +53,8 @@ angular.module("umbraco") $scope.checkContent = function() { var isEmpty = true; if ($scope.model.value && - $scope.model.value.columns) { - angular.forEach($scope.model.value.columns, function (value, key) { + $scope.model.value.sections) { + angular.forEach($scope.model.value.sections, function (value, key) { if ( value.rows && value.rows.length > 0) { isEmpty = false; } @@ -65,21 +65,16 @@ angular.module("umbraco") { $scope.model.value = undefined; } - - } + }; $scope.addTemplate = function (template) { - $scope.model.value = { - gridWidth: "", - columns: [] - }; - - 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); + $scope.model.value = angular.copy(template); + + //default row data + _.forEach($scope.model.value.sections, function(section){ + section.rows = []; }); - } + }; // ********************************************* @@ -88,34 +83,29 @@ angular.module("umbraco") $scope.setCurrentRow = function (row) { $scope.currentRow = row; - } + }; $scope.disableCurrentRow = function () { $scope.currentRow = null; - } + }; - $scope.addRow = function (column, cellModel) { + $scope.getAllowedLayouts = function(column){ + var layouts = $scope.model.config.items.layouts; - column.rows.splice(column.rows.length + 1, 0, - { - uniqueId: $scope.setUniqueId(), - cells: [], - cssClass: '' - }); + if(column.allowed && column.allowed.length > 0){ + return _.filter(layouts, function(layout){ + return _.indexOf(column.allowed, layout.name) >= 0; + }); + }else{ + return layouts; + } + }; - 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.addRow = function (column, layout) { + //copy the selected layout into the rows collection + var row = angular.copy(layout); + column.rows.push(row); }; $scope.removeRow = function (column, $index) { @@ -124,7 +114,8 @@ angular.module("umbraco") $scope.openRTEToolbarId = null; $scope.checkContent(); } - } + }; + // ********************************************* // Cell management functions @@ -132,20 +123,23 @@ angular.module("umbraco") $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]); + if(cell && cell.$allowedEditors){ + var editor = cell.$allowedEditors[0]; return editor.icon; }else{ return "icon-layout"; } - } + }; + + + // ********************************************* // Control management functions @@ -196,14 +190,11 @@ angular.module("umbraco") 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, + $uniqueId: newId, value: null, editor: editor }; @@ -212,11 +203,14 @@ angular.module("umbraco") index = cell.controls.length; } + //populate control + $scope.initControl(newControl, index+1); + cell.controls.splice(index + 1, 0, newControl); }; $scope.addTinyMce = function(cell){ - var rte = _.find($scope.availableEditors, function(editor){return editor.alias === "rte";}); + var rte = $scope.getEditor("rte"); $scope.addControl(rte, cell); }; @@ -228,28 +222,99 @@ angular.module("umbraco") 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; - } + $scope.percentage = function(spans){ + return ((spans/12)*100).toFixed(1); }; + + // ********************************************* // 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(); + + + // ********************************************* + // 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.initSection = function(section){ + section.$percentage = $scope.percentage(section.grid); + + var layouts = $scope.model.config.items.layouts; + + if(section.allowed && sectionn.allowed.length > 0){ + return _.filter(layouts, function(layout){ + section.$allowedLayouts = _.indexOf(section.allowed, layout.name) >= 0; + }); + }else{ + section.$allowedLayouts = layouts; + } + }; + + + // ********************************************* + // Init layout / row + // ********************************************* + $scope.initRow = function(row){ + + if(!row.areas){ + row.areas = []; + } + + //set a disposable unique ID + row.$uniqueId = $scope.setUniqueId(); + + //populate with data + _.forEach(row.areas, function(area){ + if(!area.controls){ + area.controls = []; + } + + area.$percentage = $scope.percentage(area.grid); + + 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; + }); + + if(_.indexOf(area.allowed,"rte")>=0){ + area.$allowsRTE = true; + } + } + }); + }; + + + + // ********************************************* + // Init control + // ********************************************* + + $scope.initControl = function(control, index){ + control.$index = index; + + //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"; + } + }; }); // ********************************************* 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..3911fab34b 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 @@ -5,13 +5,15 @@
-
+
+ ng-repeat="section in template.sections" + ng-init="initSection(section)" + style="width:{{ section.$percentage }}%">
@@ -25,24 +27,26 @@ -
+
+ ng-class="{last:$last}" + ng-repeat="section in model.value.sections" + ng-init="initSection(section)" + style="width:{{section.$percentage}}%"> -
+
- +
@@ -58,7 +62,7 @@ Are you sure? - Yes + Yes @@ -85,43 +89,42 @@
+ ng-repeat="area in row.areas"> - +
+ ng-if="area.controls.length == 0">
- +
{{singleEditor.name}}
-

+

Start writing here...

-
+
-

+

Start writing here...

+ ng-repeat="editor in area.$allowedEditors track by editor.alias" + ng-click="addControl(editor,area)">
@@ -131,33 +134,31 @@
-
-
+ ng-repeat="editor in area.$allowedEditors" + ng-click="addControl(editor,area, control.$index)" + ng-show="(currentToolsControl == control)">
@@ -176,7 +177,7 @@ Are you sure? - Yes + Yes @@ -186,8 +187,8 @@
@@ -213,15 +214,20 @@
    -
  • -
    +
  • +
    -
    - +
    + + +
    - {{cellModel.name}} + {{layout.name}}
@@ -238,9 +244,6 @@
-
- -
\ 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..8ee402ab7c 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,252 @@ 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","subHeadline"] + } + ] + }, + { + name: "Article", + areas: [ + { + grid: 4 + }, + { + grid: 8 + } + ] + } + ], + + gridConfigPath: "views/propertyeditors/grid/config/grid.default.config.js" + }; + + + + + /**************** + 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..9976f81875 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,267 @@ -
+
-

Config file path:

- - - - -
- -
+
+ +
+ - - + - -

Others settings:

- - - - -
-

  Multiple controls in cell

- -
+
+ {{template.name}}
+ {{template.sections.length}} configurable sections
+ + Delete template +
+ +
+ + + + +
+ + +
+
Template
+ + + + + +
+
+
+ + + + + + +
+
+
+ +
+
Modify template Section
+ +
+ + + + {{currentSection.grid}} + + + +
+
+ + +
    +
  • + +
  • +
+ +
+
+
    +
  • + +
  • +
+
+
+ + + + Delete section +
+ +
+ + + + + + +
+ + +
+ + +
+ +
+ +
+ + + +
+
+
+ +
+
Layout
+ + + + + +
+
+
+ + + + + + +
+
+
+ +
+
Modify layout area
+ +
+ + + + + {{currentArea.grid}} + + + + +
+
+ + + +
    +
  • + +
  • +
+ +
+
+
    +
  • + +
  • +
+
+
+ + + + Delete area +
+
+ + + + + + +
+ + +
\ No newline at end of file