promethee 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -39
  3. data/app/assets/javascripts/promethee-edit.js +209 -0
  4. data/app/assets/stylesheets/{promethee-editor.sass → promethee-edit.sass} +6 -6
  5. data/app/assets/stylesheets/{promethee-editor → promethee-edit}/_move.sass +7 -7
  6. data/app/assets/stylesheets/{promethee-editor → promethee-edit}/_preview.sass +1 -1
  7. data/app/assets/stylesheets/{promethee-editor → promethee-edit}/_write.sass +8 -8
  8. data/app/views/promethee/_edit.html.erb +33 -115
  9. data/app/views/promethee/_localize.html.erb +11 -7
  10. data/app/{assets/javascripts/promethee-editor.js → views/promethee/components/column/_edit.define.html.erb} +0 -0
  11. data/app/views/promethee/{edit/inspector/component/_column.html.erb → components/column/_edit.inspect.html.erb} +1 -1
  12. data/app/views/promethee/{edit/move/component/_column.html.erb → components/column/_edit.move.html.erb} +4 -4
  13. data/app/views/promethee/components/column/_edit.write.html.erb +17 -0
  14. data/app/views/promethee/components/column/_localize.html.erb +3 -0
  15. data/app/views/promethee/{show/component/_column.html.erb → components/column/_show.html.erb} +0 -0
  16. data/app/views/promethee/components/cover/_edit.define.html.erb +13 -0
  17. data/app/views/promethee/{edit/inspector/component/_cover.html.erb → components/cover/_edit.inspect.html.erb} +1 -1
  18. data/app/views/promethee/components/cover/_edit.move.html.erb +7 -0
  19. data/app/views/promethee/components/cover/_edit.write.html.erb +39 -0
  20. data/app/views/promethee/{localize/component/_cover.html.erb → components/cover/_localize.html.erb} +4 -2
  21. data/app/views/promethee/{show/component/_cover.html.erb → components/cover/_show.html.erb} +0 -0
  22. data/app/views/promethee/components/details/_edit.define.html.erb +13 -0
  23. data/app/views/promethee/{edit/inspector/component/_details.html.erb → components/details/_edit.inspect.html.erb} +1 -1
  24. data/app/views/promethee/{edit/move/component/_details.html.erb → components/details/_edit.move.html.erb} +1 -1
  25. data/app/views/promethee/components/details/_edit.write.html.erb +35 -0
  26. data/app/views/promethee/{localize/component/_details.html.erb → components/details/_localize.html.erb} +3 -1
  27. data/app/views/promethee/{show/component/_details.html.erb → components/details/_show.html.erb} +0 -0
  28. data/app/views/promethee/components/image/_edit.define.html.erb +14 -0
  29. data/app/views/promethee/{edit/inspector/component/_image.html.erb → components/image/_edit.inspect.html.erb} +1 -1
  30. data/app/views/promethee/{edit/move/component/_image.html.erb → components/image/_edit.move.html.erb} +1 -1
  31. data/app/views/promethee/{edit/write/component/_image.html.erb → components/image/_edit.write.html.erb} +7 -23
  32. data/app/views/promethee/{localize/component/_image.html.erb → components/image/_localize.html.erb} +5 -2
  33. data/app/views/promethee/{show/component/_image.html.erb → components/image/_show.html.erb} +0 -0
  34. data/app/views/promethee/components/row/_edit.define.html.erb +11 -0
  35. data/app/views/promethee/components/row/_edit.inspect.html.erb +3 -0
  36. data/app/views/promethee/{edit/move/component/_row.html.erb → components/row/_edit.move.html.erb} +1 -1
  37. data/app/views/promethee/components/row/_edit.write.html.erb +33 -0
  38. data/app/views/promethee/components/row/_localize.html.erb +3 -0
  39. data/app/views/promethee/{show/component/_row.html.erb → components/row/_show.html.erb} +0 -0
  40. data/app/views/promethee/components/slider/_edit.define.html.erb +11 -0
  41. data/app/views/promethee/components/slider/_edit.inspect.html.erb +3 -0
  42. data/app/views/promethee/{edit/move/component/_slider.html.erb → components/slider/_edit.move.html.erb} +2 -3
  43. data/app/views/promethee/{edit/write/component/_slider.html.erb → components/slider/_edit.write.html.erb} +25 -32
  44. data/app/views/promethee/components/slider/_localize.html.erb +3 -0
  45. data/app/views/promethee/{show/component/_slider.html.erb → components/slider/_show.html.erb} +0 -0
  46. data/app/views/promethee/components/text/_edit.define.html.erb +12 -0
  47. data/app/views/promethee/{edit/inspector/component/_text.html.erb → components/text/_edit.inspect.html.erb} +1 -1
  48. data/app/views/promethee/{edit/move/component/_text.html.erb → components/text/_edit.move.html.erb} +1 -1
  49. data/app/views/promethee/components/text/_edit.write.html.erb +32 -0
  50. data/app/views/promethee/{localize/component/_text.html.erb → components/text/_localize.html.erb} +4 -2
  51. data/app/views/promethee/{show/component/_text.html.erb → components/text/_show.html.erb} +0 -0
  52. data/app/views/promethee/components/video/_edit.define.html.erb +12 -0
  53. data/app/views/promethee/{edit/inspector/component/_video.html.erb → components/video/_edit.inspect.html.erb} +1 -1
  54. data/app/views/promethee/{edit/move/component/_video.html.erb → components/video/_edit.move.html.erb} +1 -1
  55. data/app/views/promethee/{edit/write/component/_video.html.erb → components/video/_edit.write.html.erb} +7 -39
  56. data/app/views/promethee/components/video/_localize.html.erb +3 -0
  57. data/app/views/promethee/{show/component/_video.html.erb → components/video/_show.html.erb} +0 -0
  58. data/app/views/promethee/edit/_move.html.erb +35 -74
  59. data/app/views/promethee/edit/_preview.html.erb +3 -3
  60. data/app/views/promethee/edit/_write.html.erb +67 -17
  61. data/app/views/promethee/show/_component.html.erb +1 -1
  62. data/lib/promethee/rails/version.rb +1 -1
  63. metadata +55 -57
  64. data/app/views/promethee/edit/inspector/_inspector.html.erb +0 -11
  65. data/app/views/promethee/edit/inspector/component/_row.html.erb +0 -3
  66. data/app/views/promethee/edit/inspector/component/_slider.html.erb +0 -3
  67. data/app/views/promethee/edit/move/_component.html.erb +0 -5
  68. data/app/views/promethee/edit/move/_components.html.erb +0 -26
  69. data/app/views/promethee/edit/move/component/_cover.html.erb +0 -8
  70. data/app/views/promethee/edit/shared/_data.html.erb +0 -1
  71. data/app/views/promethee/edit/shared/_navbar.html.erb +0 -25
  72. data/app/views/promethee/edit/write/_add_button.html.erb +0 -66
  73. data/app/views/promethee/edit/write/_component.html.erb +0 -3
  74. data/app/views/promethee/edit/write/_components.html.erb +0 -7
  75. data/app/views/promethee/edit/write/_toolbar.html.erb +0 -5
  76. data/app/views/promethee/edit/write/component/_column.html.erb +0 -21
  77. data/app/views/promethee/edit/write/component/_cover.html.erb +0 -55
  78. data/app/views/promethee/edit/write/component/_details.html.erb +0 -52
  79. data/app/views/promethee/edit/write/component/_row.html.erb +0 -42
  80. data/app/views/promethee/edit/write/component/_text.html.erb +0 -44
  81. data/app/views/promethee/localize/_component.html.erb +0 -3
  82. data/app/views/promethee/localize/component/_column.html.erb +0 -3
  83. data/app/views/promethee/localize/component/_row.html.erb +0 -3
  84. data/app/views/promethee/localize/component/_slider.html.erb +0 -3
  85. data/app/views/promethee/localize/component/_video.html.erb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fedae453568a7c76951d9a5f5afac39107887fa1
4
- data.tar.gz: d9999169433575cee9b82bb574241d4265d68c3e
3
+ metadata.gz: b6fd84303285742e3b357dde0c4fcf780d3de1b3
4
+ data.tar.gz: 1b5d5b514e70ee8ac836f0ad341e5287479d970a
5
5
  SHA512:
6
- metadata.gz: f9a7e5e765d5f8a2d770a2cba25e3c26b0dc2219e0e3936b9c25911934a0e6bb908b8b20d563f0cdd629e15d6299c77ebb200db1d2ebb098a217521a7309d1fb
7
- data.tar.gz: 66d57d9ef3e5c6699aa773db250d6a233ad2ed5dbed2286bc44cc483d27ba54f848b25e22ced61c9c51b20a52a8a17f2c30fac013aab1f6c6ce6fa5b26b37c79
6
+ metadata.gz: ac96f5b9991320ae569efcd8d63632f74b387477942aeb7009a2fb1647b0bd2f3cb575da37f097fc5445f8b76eb78f99c0ddd8cab8f9c54c88e05bb3fbda307e
7
+ data.tar.gz: c44d83d03795e3ae3cda160d47aa5d5b94004db1d164298ea62e3a7125679375ca06a97c5e0a3273ed30d27b36a85452d1db284a54ad8a2deb5ec2220e985a51
data/README.md CHANGED
@@ -1,43 +1,7 @@
1
- ![Prométhée](https://github.com/lespoupeesrusses/promethee/blob/master/app/assets/images/logo-promethee-vertical.svg)
2
-
3
- # Bring fire to your page
1
+ # Prométhée
4
2
 
5
3
  [![Maintainability](https://api.codeclimate.com/v1/badges/98a8649f411bc9f50786/maintainability)](https://codeclimate.com/github/lespoupeesrusses/promethee/maintainability)
6
4
 
7
- ## Where does it come from?
8
- As we build sites and digital solutions for some of the most prestigious brands (Givenchy, L’Oréal, Lancôme, Cartier, Hermès…) we often need to build spectacular pages, with a responsive layout, using a predefined design system or visual guidelines. Very often, our clients need to be able to do some creation or adaptation on their own. And in most situation, it has to be translated very easily, with no technical cost.
9
-
10
- Our first approach was to generate custom templates. For example, 10 years ago, before responsivity, we did a lot of multilingual content for Parfums Lolita Lempicka using a simple read/write system with something like 10 templates. We soon made a “Do what you feel” template, allowing the designer to put fields wherever he needed on the page, but it was completely unusable for people who lacked either design or development background.
11
-
12
- We then built a system for Cartier, where the content was made by a designer, then implemented by a front end developer with keys allowing the translation. This was good because creation was very free, but the client could make no content on its own.
13
-
14
- We built another tool for Diptyque, with content bricks that we assembled. Basically, it looked like vertical slides doing a nice one-page. It seemed like the perfect solution, but in the end it had so many options it became very hard to use, and still the different pages like quite similar.
15
-
16
- Then came the page builder. Inspired by Divi, the idea was to offer rows and columns, based on bootstrap. We built that for Hermès, as one of the different components available to build pages. Translation was fine, responsivity was fine, content was not super simple to do, but still quite simple, and the use of presets provided a good “easy to use” solution.
17
-
18
- We re-used the concept for Céline, and realized we had a mis-conception: the builder was the basic page editor, and we could add components in it.
19
-
20
- As we needed the solution for 2 projects, and a third one coming, we decided to make it a gem.
21
-
22
- Prométhée was born.
23
-
24
- ## What does it do?
25
- It builds responsive pages!
26
-
27
- There are 2 parts: the editor, which lets you build the pages, and the renderer. The pages are stored as json data, which can easily be added to a model in rails, and saved via a regular form.
28
-
29
- ## How does it relate to existing solutions?
30
-
31
- ### Regarding wysiwyg editors like tinymce, trix...
32
-
33
- It's not only rich text: it lets you build complete pages, with a grid system.
34
-
35
- ### Regarding page builders like Divi, Semplice, Shogun
36
-
37
- It's for Rails (unlike Divi or Semplice which are for Wordpress).
38
- It's open source.
39
- It does not provide as many options, as it's intended to be integrated in a website with specific brand guidelines through some custom css.
40
-
41
5
  ## Installation
42
6
  Add this line to your application's Gemfile:
43
7
 
@@ -169,7 +133,7 @@ With javascript set:
169
133
  //= require angular-ui-bootstrap
170
134
  //= require angular-summernote
171
135
  //= require promethee
172
- //= require promethee-editor
136
+ //= require promethee-edit
173
137
  ```
174
138
 
175
139
  With stylesheets set:
@@ -179,7 +143,7 @@ With stylesheets set:
179
143
  @import 'material_icons.css'
180
144
  @import 'summernote'
181
145
  @import 'promethee'
182
- @import 'promethee-editor'
146
+ @import 'promethee-edit'
183
147
  ```
184
148
 
185
149
  #### The editor has components
@@ -0,0 +1,209 @@
1
+ var promethee = angular
2
+ .module('Promethee', ['summernote', 'ngAnimate'])
3
+ .value('definitions', [])
4
+ // What does the next 3 lines do? Why?
5
+ .config(function($rootScopeProvider) {
6
+ $rootScopeProvider.digestTtl(20);
7
+ })
8
+ .filter('htmlSafe', ['$sce', function($sce) {
9
+ return function(val) {
10
+ return $sce.trustAsHtml(val);
11
+ };
12
+ }])
13
+ .filter('urlSafe', ['$sce', function($sce) {
14
+ return function(val) {
15
+ return $sce.trustAsResourceUrl(val);
16
+ };
17
+ }])
18
+ .filter('humanize', function() {
19
+ return function(val) {
20
+ val = (val + '').replace(/_/g, ' ').replace(/([A-Z])/g, ' $1').replace(/\s\s+/, ' ').trim();
21
+ return val[0].toUpperCase() + val.substring(1).toLowerCase();
22
+ };
23
+ })
24
+ .filter('textContentFromHTML', function() {
25
+ return function(val, distinctParagraphs) {
26
+ var element = document.createElement('div');
27
+ element.innerHTML = val;
28
+
29
+ if(distinctParagraphs === 'distinctParagraphs') {
30
+ var paragraphs = element.querySelectorAll('p');
31
+ for(var i = 0; i < paragraphs.length; i++) paragraphs[i].textContent += ' ';
32
+ }
33
+
34
+ return element.textContent;
35
+ }
36
+ })
37
+ .filter('numberOfCharacters', function() {
38
+ return function(val) {
39
+ return val.length;
40
+ };
41
+ })
42
+ .filter('numberOfWords', function() {
43
+ return function(val) {
44
+ var words = val
45
+ .replace(/\bhttps?:\/\/[a-z0-9\-\._]+(?:\/[^\s\n\r]+)?/gi, 'a') // A URL is one word
46
+ .replace(/\b[a-z0-9\-\._]+@[a-z0-9\-\._]+\.[a-z0-9\-\._]+\b/gi, 'a') // An email is one word
47
+ .replace(/[^a-z0-9\s\n\r]/gi, ' ')
48
+ .replace(/[\s\n\r]+/g, ' ')
49
+ .trim()
50
+ .split(' ');
51
+
52
+ return words[0] === '' ? 0 : words.length;
53
+ };
54
+ });
55
+
56
+ promethee.controller('PrometheeController', ['$scope', 'definitions', '$http', function($scope, definitions, $http) {
57
+
58
+ // Data (TODO use Adder and probably page definition to init)
59
+ if($scope.data === null || $scope.data === '') {
60
+ $scope.data = {
61
+ id: '',
62
+ type: 'page',
63
+ version: 1,
64
+ children: []
65
+ };
66
+ }
67
+
68
+ $scope.promethee = {
69
+ data: $scope.data,
70
+ inspected: null,
71
+ mode: 'write',
72
+ preview: 'desktop',
73
+ fullscreen: false
74
+ };
75
+
76
+ $scope.inspect = function(component, event) {
77
+ $scope.promethee.inspected = component;
78
+ event.stopPropagation();
79
+ }
80
+
81
+ $scope.enablePreview = function() {
82
+ if (this.promethee.mode === 'preview') return;
83
+ this.promethee.mode = 'preview';
84
+
85
+ var form = document.createElement('form');
86
+ document.body.appendChild(form);
87
+ form.method = 'POST';
88
+ form.action = '/promethee/preview';
89
+ form.target = 'preview';
90
+
91
+ var input = document.createElement('input');
92
+ input.type = 'text';
93
+ input.value = JSON.stringify($scope.promethee.data);
94
+ input.name = 'data';
95
+ form.appendChild(input);
96
+ form.submit();
97
+ document.body.removeChild(form);
98
+ }
99
+
100
+ $scope.remove = function(component, components) {
101
+ var index = components.indexOf(component);
102
+ components.splice(index, 1);
103
+ }
104
+
105
+ }]);
106
+
107
+
108
+ promethee.controller('AdderController', ['$scope', '$rootScope', 'definitions', function($scope, $rootScope, definitions) {
109
+
110
+ $scope.adding = false;
111
+ $scope.childrenToAddTo = null;
112
+ $scope.definitions = definitions;
113
+
114
+ $scope.close = function() {
115
+ $scope.adding = false;
116
+ $scope.addingToChildren = null;
117
+ };
118
+
119
+ $scope.pushComponent = function(definition) {
120
+ var definition = angular.copy(definition.data);
121
+ definition.id = $scope.createIdentifier();
122
+ $scope.childrenToAddTo.push(definition);
123
+ $scope.close();
124
+ };
125
+
126
+ $rootScope.addComponentTo = function(components) {
127
+ $scope.adding = true;
128
+ $scope.childrenToAddTo = components;
129
+ };
130
+
131
+ // https://gist.github.com/gordonbrander/2230317
132
+ $scope.createIdentifier = function () {
133
+ // Math.random should be unique because of its seeding algorithm.
134
+ // Convert it to base 36 (numbers + letters), and grab the first 9 characters
135
+ // after the decimal.
136
+ return '' + Math.random().toString(36).substr(2, 9);
137
+ };
138
+
139
+ }])
140
+
141
+
142
+
143
+ promethee
144
+ .directive('draggable', function() {
145
+ return {
146
+ restrict:'A',
147
+ link: function(scope, element, attrs) {
148
+ element.draggable({
149
+ revert: true,
150
+ revertDuration: 0,
151
+ scroll: true,
152
+ refreshPositions: true,
153
+ start: function() {
154
+ var $elementDragged = $(element[0]);
155
+ var type = $elementDragged.data('type');
156
+ $('.promethee-edit__move').addClass('promethee-edit__move--dragging promethee-edit__move--dragging--' + type);
157
+
158
+ // The droppable zone immediately before has no use, it would put the object at the same position
159
+ // FIXME the selector is not correct
160
+ /*
161
+ var $droppableBefore = $elementDragged.prev('.promethee-edit__move__draggable').find('.promethee-edit__move__droppable').last();
162
+ if ($droppableBefore.length === 0) {
163
+ // For the first child, we look for the previous droppable zone
164
+ $droppableBefore = $elementDragged.prev('.promethee-edit__move__droppable');
165
+ }
166
+ $droppableBefore.addClass('promethee-edit__move__droppable--hidden');
167
+ */
168
+ },
169
+ stop: function() {
170
+ var $elementDragged = $(element[0]);
171
+ var type = $elementDragged.data('type');
172
+ $('.promethee-edit__move').removeClass('promethee-edit__move--dragging promethee-edit__move--dragging--' + type);
173
+ // $('.promethee-edit__move__droppable').removeClass('promethee-edit__move__droppable--hidden');
174
+ }
175
+ });
176
+ }
177
+ }
178
+ })
179
+ .directive('droppable', function($compile) {
180
+ return {
181
+ restrict: 'A',
182
+ link: function(scope, element, attrs) {
183
+ element.droppable({
184
+ tolerance: 'pointer',
185
+ drop: function(event, ui) {
186
+ var draggedFromList = angular.element(ui.draggable).parent().scope().components;
187
+ var draggedFromIndex = parseInt(ui.draggable[0].getAttribute('data-index'));
188
+ // console.log('dragged', draggedFromList, draggedFromIndex);
189
+ draggedFromList.splice(draggedFromIndex, 1);
190
+
191
+ var component = angular.element(ui.draggable).scope().component;
192
+ var droppedToList = angular.element(this).scope().components;
193
+ var droppedToIndex = parseInt(this.getAttribute('data-index'));
194
+ if (draggedFromList == droppedToList) {
195
+ // The object we dragged was removed from the list
196
+ if (draggedFromIndex < droppedToIndex) {
197
+ // It was before the dropped index, so removing it changed the index
198
+ droppedToIndex -= 1;
199
+ }
200
+ }
201
+ // console.log('dropped', component, droppedToList, droppedToIndex);
202
+ droppedToList.splice(droppedToIndex, 0, component);
203
+
204
+ scope.$apply();
205
+ }
206
+ });
207
+ }
208
+ }
209
+ });
@@ -3,11 +3,11 @@ $promethee-transparent-grey: transparentize($promethee-grey, .8)
3
3
  $promethee-light-grey: #eee
4
4
  $promethee-color: #ff9900 !default
5
5
 
6
- @import 'promethee-editor/write'
7
- @import 'promethee-editor/move'
8
- @import 'promethee-editor/preview'
6
+ @import 'promethee-edit/write'
7
+ @import 'promethee-edit/move'
8
+ @import 'promethee-edit/preview'
9
9
 
10
- .promethee-editor
10
+ .promethee-edit
11
11
  background: white
12
12
  position: relative
13
13
  &--fullscreen
@@ -18,10 +18,10 @@ $promethee-color: #ff9900 !default
18
18
  top: 50px
19
19
  z-index: 10000
20
20
  overflow: auto
21
- .promethee-editor__write
21
+ .promethee-edit__write
22
22
  padding-right: 300px
23
23
  padding-top: 15px
24
- .promethee-editor__inspector
24
+ .promethee-edit__inspect
25
25
  top: 65px
26
26
 
27
27
  &__navbar
@@ -1,4 +1,4 @@
1
- .promethee-editor__move
1
+ .promethee-edit__move
2
2
  width: 432px
3
3
  margin: 0 auto
4
4
  padding-bottom: 200px
@@ -82,21 +82,21 @@
82
82
  z-index: 1000
83
83
  opacity: 0.5
84
84
  // Nothing is droppable inside components being dragged
85
- .promethee-editor__move__droppable
85
+ .promethee-edit__move__droppable
86
86
  visibility: hidden !important
87
87
 
88
88
  // By default, nothing is dropped in rows
89
89
  &--dragging
90
- .promethee-editor__move__droppable--row
90
+ .promethee-edit__move__droppable--row
91
91
  display: none
92
92
 
93
93
  // Except for columns, which can be dropped only on rows
94
- &--dragging.promethee-editor__move--dragging--column
95
- .promethee-editor__move__droppable
94
+ &--dragging.promethee-edit__move--dragging--column
95
+ .promethee-edit__move__droppable
96
96
  display: none
97
97
  // It's a little specific, columns can be dropped on rows "first droppable", or on columns "inside droppables"
98
- &.promethee-editor__move__droppable--row--inside-column,
99
- &.promethee-editor__move__droppable--row--first
98
+ &.promethee-edit__move__droppable--row--inside-column,
99
+ &.promethee-edit__move__droppable--row--first
100
100
  display: block
101
101
 
102
102
 
@@ -1,4 +1,4 @@
1
- .promethee-editor__preview
1
+ .promethee-edit__preview
2
2
  background: black
3
3
  position: relative
4
4
  height: 100%
@@ -1,6 +1,6 @@
1
- .promethee-editor__write
1
+ .promethee-edit__write
2
2
 
3
- .promethee-editor__toolbar
3
+ .promethee-edit__toolbar
4
4
  background: #253742
5
5
  padding: 10px
6
6
  font-size: 11px
@@ -10,7 +10,7 @@
10
10
  &, *
11
11
  user-select: none
12
12
 
13
- .promethee-editor__inspector
13
+ .promethee-edit__inspect
14
14
  background: #fff
15
15
  width: 300px
16
16
  top: 15px
@@ -31,22 +31,22 @@
31
31
  &-content
32
32
  padding: 15px
33
33
 
34
- .promethee-editor__adder__button
34
+ .promethee-edit__adder__button
35
35
  display: block
36
36
  text-align: center
37
37
  margin: 50px 0
38
38
 
39
- .promethee-editor__component
39
+ .promethee-edit__component
40
40
  margin-bottom: 5px
41
41
  &--cover
42
- .promethee-editor__cover-content
42
+ .promethee-edit__cover-content
43
43
  padding: 150px 30px
44
44
  background-repeat: no-repeat
45
45
  background-position: center center
46
46
  background-size: cover
47
- &--row > div > .promethee-editor__toolbar
47
+ &--row > div > .promethee-edit__toolbar
48
48
  margin-bottom: 5px
49
- &--column > div > .promethee-editor__toolbar
49
+ &--column > div > .promethee-edit__toolbar
50
50
  margin-bottom: 5px
51
51
  &--slider
52
52
  .fontawesome-carousel-control .fa
@@ -1,126 +1,44 @@
1
1
  <%
2
- master_data ||= nil
3
2
  promethee_data = Promethee::Data.new master_data
4
3
  %>
5
-
6
- <script>
7
-
8
- var promethee = angular
9
- .module('Promethee', ['summernote', 'ngAnimate'])
10
- .value('data', <%= promethee_data.to_json.html_safe %>)
11
- .value('definitions', [])
12
- .config(function($rootScopeProvider) {
13
- $rootScopeProvider.digestTtl(20);
14
- })
15
- .filter('htmlSafe', ['$sce', function($sce) {
16
- return function(val) {
17
- return $sce.trustAsHtml(val);
18
- };
19
- }])
20
- .filter('urlSafe', ['$sce', function($sce) {
21
- return function(val) {
22
- return $sce.trustAsResourceUrl(val);
23
- };
24
- }])
25
- .filter('humanize', function() {
26
- return function(val) {
27
- val = (val + '').replace(/_/g, ' ').replace(/([A-Z])/g, ' $1').replace(/\s\s+/, ' ').trim();
28
- return val[0].toUpperCase() + val.substring(1).toLowerCase();
29
- };
30
- })
31
- .filter('textContentFromHTML', function() {
32
- return function(val, distinctParagraphs) {
33
- var element = document.createElement('div');
34
- element.innerHTML = val;
35
-
36
- if(distinctParagraphs === 'distinctParagraphs') {
37
- var paragraphs = element.querySelectorAll('p');
38
- for(var i = 0; i < paragraphs.length; i++) paragraphs[i].textContent += ' ';
39
- }
40
-
41
- return element.textContent;
42
- }
43
- })
44
- .filter('numberOfCharacters', function() {
45
- return function(val) {
46
- return val.length;
47
- };
48
- })
49
- .filter('numberOfWords', function() {
50
- return function(val) {
51
- var words = val
52
- .replace(/\bhttps?:\/\/[a-z0-9\-\._]+(?:\/[^\s\n\r]+)?/gi, 'a') // A URL is one word
53
- .replace(/\b[a-z0-9\-\._]+@[a-z0-9\-\._]+\.[a-z0-9\-\._]+\b/gi, 'a') // An email is one word
54
- .replace(/[^a-z0-9\s\n\r]/gi, ' ')
55
- .replace(/[\s\n\r]+/g, ' ')
56
- .trim()
57
- .split(' ');
58
-
59
- return words[0] === '' ? 0 : words.length;
60
- };
61
- });
62
-
63
- promethee.controller('PrometheeController', ['data', '$scope', 'definitions', '$http',
64
- function(data, $scope, definitions, $http) {
65
-
66
- // Data (TODO use Adder and probably page definition to init)
67
- if(data === null || data === '') {
68
- data = {
69
- id: '',
70
- type: 'page',
71
- version: 1,
72
- children: []
73
- };
74
- }
75
-
76
- $scope.promethee = { inspected: null };
77
- $scope.data = $scope.component = data;
78
- $scope.mode = 'write';
79
- $scope.preview = 'desktop';
80
- $scope.fullscreen = false;
81
-
82
- $scope.inspect = function(component, event) {
83
- $scope.promethee.inspected = component;
84
- event.stopPropagation();
85
- }
86
-
87
- $scope.enablePreview = function() {
88
- if (this.mode === 'preview') return;
89
- this.mode = 'preview';
90
-
91
- var form = document.createElement('form');
92
- document.body.appendChild(form);
93
- form.method = 'POST';
94
- form.action = <%= promethee_preview_path.to_json.html_safe %>;
95
- form.target = 'preview';
96
-
97
- var input = document.createElement('input');
98
- input.type = 'text';
99
- input.value = JSON.stringify(data);
100
- input.name = 'data';
101
- form.appendChild(input);
102
- form.submit();
103
- document.body.removeChild(form);
104
- }
105
-
106
- $scope.remove = function(component, components) {
107
- var index = components.indexOf(component);
108
- components.splice(index, 1);
109
- }
110
-
111
- }]);
112
-
113
- </script>
114
-
115
4
  <div
116
5
  id="promethee"
117
- class="promethee-editor"
118
- ng-class="{ 'promethee-editor--fullscreen': fullscreen }"
6
+ class="promethee-edit"
119
7
  ng-app="Promethee"
8
+ ng-class="{ 'promethee-edit--fullscreen': promethee.fullscreen }"
120
9
  ng-controller="PrometheeController as prometheeController"
10
+ ng-init="promethee.data=<%= promethee_data.to_json %>"
121
11
  >
122
- <%= render 'promethee/edit/shared/data' %>
123
- <%= render 'promethee/edit/shared/navbar' %>
12
+ <input type="hidden" name="page[data]" id="page_data" value="{{promethee.data}}" />
13
+ <nav class="navbar navbar-default promethee-edit__navbar" ng-class="{'navbar-fixed-top': promethee.fullscreen }">
14
+ <div class="container-fluid">
15
+ <div class="navbar-header promethee-edit__icon">
16
+ <div class="navbar-brand"><%= File.read(__dir__ + '/../../assets/images/icon-promethee.svg').html_safe %></div>
17
+ </div>
18
+ <div id="navbar">
19
+ <ul class="nav navbar-nav navbar-right">
20
+ <li ng-click="promethee.mode = 'write'" ng-class="{active: promethee.mode == 'write'}"><a><%= fa_icon :pencil %></a></li>
21
+ <li ng-click="promethee.mode = 'move'" ng-class="{active: promethee.mode == 'move'}"><a><%= fa_icon :arrows %></a></li>
22
+ <li ng-click="enablePreview()" ng-class="{active: promethee.mode == 'preview'}">
23
+ <a data-toggle="dropdown"><%= fa_icon :eye %></a>
24
+ <ul class="dropdown-menu" ng-show="promethee.mode == 'preview'">
25
+ <li ng-click="promethee.preview = 'desktop'" ng-class="{active: promethee.preview == 'desktop'}"><a><i class="fa fa-desktop"></i></a></li>
26
+ <li ng-click="promethee.preview = 'tablet'" ng-class="{active: promethee.preview == 'tablet'}"><a><i class="fa fa-tablet"></i></a></li>
27
+ <li ng-click="promethee.preview = 'mobile'" ng-class="{active: promethee.preview == 'mobile'}"><a><i class="fa fa-mobile"></i></a></li>
28
+ </ul>
29
+ </li>
30
+ <li ng-click="promethee.fullscreen = !promethee.fullscreen">
31
+ <a ng-show="promethee.fullscreen"><%= fa_icon :expand %></a>
32
+ <a ng-hide="promethee.fullscreen"><%= fa_icon :compress %></a>
33
+ </li>
34
+ </ul>
35
+ </div>
36
+ </div>
37
+ </nav>
38
+ <% Dir["#{__dir__}/components/*/_edit.*.html.erb"].map do |file| %>
39
+ <% partial = file.split('app/views/').last.gsub('.html.erb', '').gsub('/_', '/') %>
40
+ <%= render partial %>
41
+ <% end %>
124
42
  <%= render 'promethee/edit/write' %>
125
43
  <%= render 'promethee/edit/move' %>
126
44
  <%= render 'promethee/edit/preview' %>