promethee 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +164 -19
  3. data/Rakefile +33 -2
  4. data/app/assets/images/icon-promethee.png +0 -0
  5. data/app/assets/images/logo-promethee-horizontal.svg +14 -0
  6. data/app/assets/images/logo-promethee-vertical.svg +14 -0
  7. data/app/assets/javascripts/promethee.js +59 -0
  8. data/app/assets/javascripts/promethee/controller.js +22 -0
  9. data/app/assets/stylesheets/promethee-editor.sass +105 -0
  10. data/app/assets/stylesheets/promethee-editor/_mixins.sass +19 -0
  11. data/app/assets/stylesheets/promethee-editor/_variables.sass +4 -0
  12. data/app/assets/stylesheets/promethee.sass +4 -0
  13. data/app/views/promethee/_edit.html.erb +172 -0
  14. data/app/views/promethee/_show.html.erb +6 -0
  15. data/app/views/promethee/components/_column.html.erb +8 -0
  16. data/app/views/promethee/components/_column_edit.html.erb +40 -0
  17. data/app/views/promethee/components/_image.html.erb +7 -0
  18. data/app/views/promethee/components/_image_edit.html.erb +60 -0
  19. data/app/views/promethee/components/_index.html.erb +3 -0
  20. data/app/views/promethee/components/_index_edit.html.erb +7 -0
  21. data/app/views/promethee/components/_row.html.erb +6 -0
  22. data/app/views/promethee/components/_row_edit.html.erb +53 -0
  23. data/app/views/promethee/components/_show.html.erb +4 -0
  24. data/app/views/promethee/components/_show_edit.html.erb +3 -0
  25. data/app/views/promethee/components/_text.html.erb +6 -0
  26. data/app/views/promethee/components/_text_edit.html.erb +59 -0
  27. data/app/views/promethee/components/_video.html.erb +16 -0
  28. data/app/views/promethee/components/_video_edit.html.erb +63 -0
  29. data/app/views/promethee/partials/_toolbar_buttons.html.erb +4 -0
  30. data/lib/promethee.rb +37 -2
  31. data/lib/promethee/component.rb +28 -0
  32. data/lib/promethee/component/attribute.rb +42 -0
  33. data/lib/promethee/component/attribute/boolean.rb +4 -0
  34. data/lib/promethee/component/attribute/float.rb +3 -0
  35. data/lib/promethee/component/attribute/integer.rb +3 -0
  36. data/lib/promethee/component/attribute/string.rb +3 -0
  37. data/lib/promethee/component/attributes.rb +50 -0
  38. data/lib/promethee/component/attributes/definer.rb +13 -0
  39. data/lib/promethee/component/base.rb +68 -0
  40. data/lib/promethee/component/collection.rb +17 -0
  41. data/lib/promethee/component/column.rb +8 -0
  42. data/lib/promethee/component/image.rb +6 -0
  43. data/lib/promethee/component/row.rb +3 -0
  44. data/lib/promethee/component/text.rb +5 -0
  45. data/lib/promethee/component/video.rb +5 -0
  46. data/lib/promethee/core_ext/form_builder.rb +6 -0
  47. data/lib/promethee/core_ext/form_helper.rb +6 -0
  48. data/lib/promethee/core_ext/tags.rb +18 -0
  49. data/lib/promethee/grid.rb +52 -0
  50. data/lib/promethee/rails/engine.rb +7 -0
  51. data/lib/promethee/rails/helper.rb +26 -0
  52. data/lib/promethee/rails/version.rb +5 -0
  53. data/lib/tasks/promethee/promethee.rake +4 -0
  54. metadata +202 -20
  55. data/.gitignore +0 -9
  56. data/CODE_OF_CONDUCT.md +0 -74
  57. data/Gemfile +0 -6
  58. data/LICENSE +0 -21
  59. data/bin/console +0 -14
  60. data/bin/setup +0 -8
  61. data/lib/promethee/version.rb +0 -3
  62. data/promethee.gemspec +0 -24
@@ -0,0 +1,19 @@
1
+ =grid-builder-set-gutter-width($width)
2
+ $was: $grid-gutter-width
3
+ $grid-gutter-width: $width !global
4
+
5
+ .row
6
+ +make-row
7
+
8
+ +make-grid-columns
9
+ +make-grid(xs)
10
+ @media(min-width: 768px)
11
+ +make-grid(sm)
12
+
13
+ @media (min-width: 992px)
14
+ +make-grid(md)
15
+
16
+ @media (min-width: 1200px)
17
+ +make-grid(lg)
18
+
19
+ $grid-gutter-width: $was !global
@@ -0,0 +1,4 @@
1
+ $promethee-grey: #bbb
2
+ $promethee-transparent-grey: transparentize($promethee-grey, .8)
3
+
4
+ $promethee-light-grey: #eee
@@ -0,0 +1,4 @@
1
+ // @import 'promethee/colors'
2
+ @import 'bootstrap'
3
+
4
+ .promethee
@@ -0,0 +1,172 @@
1
+ <%
2
+ promethee_id = "promethee-#{SecureRandom.hex 10}"
3
+ promethee_data = promethee.data
4
+ promethee_data = promethee_data.to_json unless promethee_data.is_a? String
5
+ %>
6
+
7
+ <script>
8
+ var promethee = angular
9
+ .module('<%= promethee_id %>', ['ui.tinymce', 'dndLists'])
10
+ .constant('data', <%= promethee_data.html_safe %>)
11
+ .value('state', {
12
+ editing: false
13
+ })
14
+ .value('definitions', [])
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
+ </script>
32
+
33
+ <div id="<%= promethee_id %>"
34
+ class="promethee-editor"
35
+ ng-app="<%= promethee_id %>"
36
+ ng-controller="PrometheeController as prometheeController"
37
+ ng-class="{
38
+ 'fullscreen': fullscreen,
39
+ 'promethee-editor--preview': preview,
40
+ 'promethee-editor--preview--mobile': preview && previewMode == 'mobile',
41
+ 'promethee-editor--preview--tablet': preview && previewMode == 'tablet',
42
+ 'promethee-editor--preview--desktop': preview && previewMode == 'desktop'
43
+ }">
44
+
45
+ <% # TODO custom views %>
46
+ <% Dir['app/views/promethee/components/*'].each do |file| %>
47
+ <% end %>
48
+ <% # TODO iterate over files in gem %>
49
+ <% ['index', 'show', 'row', 'column', 'text', 'image', 'video'].each do |type| %>
50
+ <%= render partial: "promethee/components/#{type}_edit", locals: { promethee_id: promethee_id } %>
51
+ <% end %>
52
+
53
+ <input type="hidden" name="page[data]" id="page_data" value="{{data}}" />
54
+
55
+ <nav class="navbar navbar-default">
56
+ <div class="container-fluid">
57
+ <div class="navbar-header">
58
+ <%= image_tag 'icon-promethee.png', class: 'navbar-brand' %>
59
+ </div>
60
+ <div id="navbar">
61
+ <ul class="nav navbar-nav navbar-right">
62
+ <li ng-click="enablePreview()" ng-hide="preview"><a><%= fa_icon :eye %></a></li>
63
+ <li ng-click="previewMode = 'mobile'" ng-class="{ active: previewMode == 'mobile' }" ng-show="preview">
64
+ <a><%= fa_icon :mobile %></a>
65
+ </li>
66
+ <li ng-click="previewMode = 'tablet'" ng-class="{ active: previewMode == 'tablet' }" ng-show="preview"><a>
67
+ <%= fa_icon :tablet %></a>
68
+ </li>
69
+ <li ng-click="previewMode = 'desktop'" ng-class="{ active: previewMode == 'desktop' }" ng-show="preview"><a>
70
+ <%= fa_icon :desktop %></a>
71
+ </li>
72
+ <li ng-click="disablePreview()" ng-show="preview"><a><%= fa_icon 'eye-slash' %></a>
73
+ </li>
74
+ <li ng-click="enableFullscreen()" ng-hide="fullscreen"><a><%= fa_icon :expand %></a></li>
75
+ <li ng-click="disableFullscreen()" ng-show="fullscreen"><a><%= fa_icon :compress %></a></li>
76
+ </ul>
77
+ </div>
78
+ </div>
79
+ </nav>
80
+ <div class="promethee-editor__page" ng-class="{ 'container-fluid': fullscreen }">
81
+ <ng-include src="'promethee/components/index'"></ng-include>
82
+ </div>
83
+
84
+ <span type="button" class="btn btn-default btn-block" ng-click="addComponentTo(data)" style="margin-bottom: 6px">Add component</span>
85
+
86
+ <div class="promethee-editor__adder" ng-controller="AdderController">
87
+ <div class="modal fade in" tabindex="-1" role="dialog" style="display: {{adding ? 'block' : 'none'}}">
88
+ <div class="modal-dialog modal-lg" role="document">
89
+ <div class="modal-content">
90
+ <div class="modal-header">
91
+ <button type="button" class="close" ng-click="close()"><span aria-hidden="true">&times;</span></button>
92
+ <h4 class="modal-title">Select component</h4>
93
+ </div>
94
+ <div class="modal-body">
95
+ <div class="row">
96
+ <div ng-repeat="definition in definitions"
97
+ ng-click="pushComponent(definition)"
98
+ class="col-md-3">
99
+ <div class="thumbnail">
100
+ <img ng-src="{{definition.thumb}}" class="img-responsive">
101
+ <h4>{{definition.name}}</h4>
102
+ </div>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </div>
110
+
111
+ <!-- Work in progress -->
112
+ <!-- <iframe id="iframe"></iframe> !-->
113
+ </div>
114
+
115
+ <script>
116
+ promethee.controller('PrometheeController', ['data', '$scope', 'definitions', function(data, $scope, definitions) {
117
+ if (data === null || data === '') {
118
+ data = [];
119
+ }
120
+ $scope.data = data;
121
+ $scope.fullscreen = false;
122
+ $scope.preview = false;
123
+ $scope.previewMode = 'desktop';
124
+ $scope.component = {
125
+ children: data
126
+ };
127
+
128
+ $scope.allowedTypes = definitions.map(function(definition) {
129
+ return definition.data.type;
130
+ });
131
+
132
+ $scope.enablePreview = function() {
133
+ this.preview = true;
134
+ // Work in progress
135
+ // document.getElementById('iframe').contentWindow.document.documentElement.innerHTML = document.documentElement.innerHTML;
136
+ }
137
+
138
+ $scope.disablePreview = function() {
139
+ this.preview = false;
140
+ }
141
+
142
+ $scope.enableFullscreen = function() {
143
+ this.fullscreen = true;
144
+ }
145
+
146
+ $scope.disableFullscreen = function() {
147
+ this.fullscreen = false;
148
+ }
149
+
150
+ }]);
151
+
152
+ promethee.controller('AdderController', ['$scope', '$rootScope', 'definitions', function($scope, $rootScope, definitions) {
153
+
154
+ $scope.adding = null;
155
+ $scope.definitions = definitions;
156
+
157
+ $scope.close = function() {
158
+ $scope.adding = null;
159
+ };
160
+
161
+ $scope.pushComponent = function(definition) {
162
+ var definition = angular.copy(definition.data);
163
+ $scope.adding.push(definition);
164
+ $scope.close();
165
+ };
166
+
167
+ $rootScope.addComponentTo = function(components) {
168
+ $scope.adding = components;
169
+ };
170
+
171
+ }]);
172
+ </script>
@@ -0,0 +1,6 @@
1
+ <%
2
+ data = JSON.parse data, symbolize_names: true if data.is_a? String
3
+ %>
4
+ <div class="promethee">
5
+ <%= render partial: 'promethee/components/index', locals: { components: data } %>
6
+ </div>
@@ -0,0 +1,8 @@
1
+ <%
2
+ size = component[:attributes][:size]
3
+ offset = component[:attributes][:offset]
4
+ children = component[:children]
5
+ %>
6
+ <div class="col col-md-<%= size %><%= " col-md-offset-#{offset}" if offset > 0 %> <%= promethee_class_for component %>">
7
+ <%= render partial: 'promethee/components/index', locals: { components: children } %>
8
+ </div>
@@ -0,0 +1,40 @@
1
+ <script type="text/ng-template" id="promethee/components/column">
2
+ <div ng-controller="ColumnController">
3
+ <div class="col col-md-{{component.attributes.size}} col-md-offset-{{component.attributes.offset}}">
4
+ <div dnd-draggable="component" dnd-moved="remove()" dnd-type="component.type" class="promethee-editor__component promethee-editor__component--column">
5
+ <div class="promethee-editor__toolbar">
6
+ Column
7
+ <%= render 'promethee/partials/toolbar_buttons' %>
8
+ </div>
9
+ <div ng-show="editing" class="promethee-editor__wrapper">
10
+ <div class="form-group">
11
+ <label class="label-control">Size</label>
12
+ <input ng-model="component.attributes.size" class="form-control" type="number"/>
13
+ </div>
14
+ <div class="form-group">
15
+ <label class="label-control">Offset</label>
16
+ <input ng-model="component.attributes.offset" class="form-control" type="number"/>
17
+ </div>
18
+ </div>
19
+
20
+ <ng-include src="'promethee/components/index'"></ng-include>
21
+
22
+ <span type="button" class="btn btn-default btn-block" ng-click="addComponentTo(component.children)" style="margin: 0 6px 6px 6px;width: auto">Add component</span>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </script>
27
+
28
+ <script>
29
+ promethee.controller('ColumnController', ['$scope', 'definitions', function($scope, definitions) {
30
+
31
+ $scope.allowedTypes = definitions.map(function(definition) {
32
+ return definition.data.type;
33
+ });
34
+
35
+ $scope.remove = function() {
36
+ this.components.splice(this.components.indexOf(this.component), 1);
37
+ };
38
+
39
+ }]);
40
+ </script>
@@ -0,0 +1,7 @@
1
+ <%
2
+ src = component[:attributes][:src]
3
+ alt = component[:attributes][:alt]
4
+ %>
5
+ <div class="<%= promethee_class_for component %>">
6
+ <img class="img-responsive" src="<%= src %>" alt="<%= alt %>">
7
+ </div>
@@ -0,0 +1,60 @@
1
+ <script type="text/ng-template" id="promethee/components/image">
2
+ <div ng-controller="ImageController" style="position: relative">
3
+ <div dnd-draggable="component"
4
+ dnd-moved="remove()"
5
+ dnd-type="component.type"
6
+ class="promethee-editor__component promethee-editor__component--image promethee-editor__component--final">
7
+ <div class="promethee-editor__toolbar">
8
+ Image
9
+ <%= render 'promethee/partials/toolbar_buttons' %>
10
+ </div>
11
+ <div ng-show="editing" class="promethee-editor__wrapper">
12
+ <div class="form-group">
13
+ <label class="label-control">Url</label>
14
+ <input ng-model="component.attributes.src" class="form-control" type="text"/>
15
+ </div>
16
+ <div class="form-group">
17
+ <label class="label-control">Alt</label>
18
+ <input ng-model="component.attributes.alt" class="form-control" type="text"/>
19
+ </div>
20
+ </div>
21
+ <div ng-show="component.attributes.src">
22
+ <img ng-click="edit()" ng-src="{{component.attributes.src}}" class="img-responsive">
23
+ </div>
24
+ <div ng-hide="component.attributes.src">
25
+ <p ng-hide="editing" ng-click="edit()" class="text-center">Click to set the image</p>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </script>
30
+
31
+ <script>
32
+ angular.injector(['ng', '<%= promethee_id %>']).get('definitions').push({
33
+ name: 'Image',
34
+ thumb: 'http://via.placeholder.com/300x200',
35
+ data: {
36
+ type: 'image',
37
+ attributes: {
38
+ src: 'https://source.unsplash.com/random/1920x1080'
39
+ }
40
+ }
41
+ });
42
+
43
+ promethee.controller('ImageController', ['$scope', function($scope) {
44
+
45
+ $scope.editing = false;
46
+
47
+ $scope.edit = function() {
48
+ this.editing = true;
49
+ };
50
+
51
+ $scope.complete = function() {
52
+ this.editing = false;
53
+ };
54
+
55
+ $scope.remove = function() {
56
+ this.components.splice(this.components.indexOf(this.component), 1);
57
+ };
58
+
59
+ }]);
60
+ </script>
@@ -0,0 +1,3 @@
1
+ <% components.each do |component| %>
2
+ <%= render partial: 'promethee/components/show', locals: { component: component } %>
3
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <script type="text/ng-template" id="promethee/components/index">
2
+ <div class="promethee-editor__components" ng-init="components = component.children" dnd-list="components" dnd-allowed-types="allowedTypes">
3
+ <div ng-repeat="component in components">
4
+ <ng-include src="'promethee/components/show'"></ng-include>
5
+ </div>
6
+ </div>
7
+ </script>
@@ -0,0 +1,6 @@
1
+ <%
2
+ children = component[:children]
3
+ %>
4
+ <div class="row <%= promethee_class_for component %>">
5
+ <%= render partial: 'promethee/components/index', locals: { components: children } %>
6
+ </div>
@@ -0,0 +1,53 @@
1
+ <script type="text/ng-template" id="promethee/components/row">
2
+ <div ng-controller="RowController">
3
+ <div class="row">
4
+ <div dnd-draggable="component" dnd-moved="remove()" dnd-type="component.type" class="promethee-editor__component promethee-editor__component--row">
5
+ <div class="promethee-editor__toolbar">
6
+ Row
7
+ <%= render 'promethee/partials/toolbar_buttons' %>
8
+ </div>
9
+ <div ng-show="editing" class="promethee-editor__wrapper">
10
+ Nothing to edit (yet...)
11
+ </div>
12
+
13
+ <ng-include src="'promethee/components/index'"></ng-include>
14
+
15
+ <div class="clearfix"></div>
16
+ <span class="btn btn-default btn-block" ng-click="addColumn()" style="margin: 0 6px 6px 6px;width: auto">Add column</span>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </script>
21
+
22
+ <script>
23
+ angular.injector(['ng', '<%= promethee_id %>']).get('definitions').push({
24
+ name: 'Row',
25
+ thumb: 'http://via.placeholder.com/300x200',
26
+ data: {
27
+ type: 'row',
28
+ attributes: {},
29
+ children: []
30
+ }
31
+ });
32
+
33
+ promethee.controller('RowController', ['$scope', function($scope) {
34
+
35
+ $scope.allowedTypes = ['column'];
36
+
37
+ $scope.addColumn = function() {
38
+ this.component.children.push({
39
+ type: 'column',
40
+ attributes: {
41
+ size: 3,
42
+ offset: 0
43
+ },
44
+ children: []
45
+ })
46
+ }
47
+
48
+ $scope.remove = function() {
49
+ this.components.splice(this.components.indexOf(this.component), 1);
50
+ };
51
+
52
+ }]);
53
+ </script>
@@ -0,0 +1,4 @@
1
+ <%
2
+ type = component[:type]
3
+ %>
4
+ <%= render partial: "promethee/components/#{type}", locals: { component: component } %>
@@ -0,0 +1,3 @@
1
+ <script type="text/ng-template" id="promethee/components/show">
2
+ <ng-include src="'promethee/components/' + component.type"></ng-include>
3
+ </script>
@@ -0,0 +1,6 @@
1
+ <%
2
+ body = component[:attributes][:body].to_s
3
+ %>
4
+ <div class="<%= promethee_class_for component %>">
5
+ <%= body.html_safe %>
6
+ </div>
@@ -0,0 +1,59 @@
1
+ <script type="text/ng-template" id="promethee/components/text">
2
+ <div ng-controller="TextController">
3
+ <div dnd-draggable="component"
4
+ dnd-moved="remove()"
5
+ dnd-type="component.type"
6
+ class="promethee-editor__component promethee-editor__component--text promethee-editor__component--final">
7
+ <div class="promethee-editor__toolbar">
8
+ Text
9
+ <%= render 'promethee/partials/toolbar_buttons' %>
10
+ </div>
11
+ <div ng-show="editing">
12
+ <textarea ui-tinymce="tinymceOptions" ng-model="component.attributes.body"></textarea>
13
+ </div>
14
+ <div ng-hide="editing">
15
+ <div class="promethee-editor__wrapper" ng-bind-html="component.attributes.body | htmlSafe" ng-click="edit()"></div>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ </script>
20
+
21
+ <script>
22
+ angular.injector(['ng', '<%= promethee_id %>']).get('definitions').push({
23
+ name: 'Text',
24
+ thumb: 'http://via.placeholder.com/300x200',
25
+ data: {
26
+ type: 'text',
27
+ attributes: {
28
+ body: 'Edit me'
29
+ }
30
+ }
31
+ });
32
+
33
+ promethee.controller('TextController', ['$scope', function($scope) {
34
+
35
+ $scope.editing = false;
36
+
37
+ $scope.edit = function() {
38
+ this.editing = true;
39
+ };
40
+
41
+ $scope.complete = function() {
42
+ this.editing = false;
43
+ };
44
+
45
+ $scope.remove = function() {
46
+ this.components.splice(this.components.indexOf(this.component), 1);
47
+ };
48
+
49
+ $scope.tinymceOptions = {
50
+ plugins: 'autoresize',
51
+ toolbar: 'styleselect | bold italic',
52
+ menubar: false,
53
+ statusbar: false,
54
+ branding: false,
55
+ autoresize_bottom_margin: 0
56
+ };
57
+
58
+ }]);
59
+ </script>