promethee 1.11.29 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/UPGRADING +10 -0
- data/app/assets/stylesheets/promethee.sass +130 -122
- data/app/models/concerns/promethee_data.rb +2 -0
- data/app/services/promethee/localize_clean_service.rb +77 -0
- data/app/services/promethee/table_upgrade_service.rb +69 -0
- data/app/views/promethee/_edit.html.erb +23 -11
- data/app/views/promethee/components/collection_item/_localize.html.erb +14 -2
- data/app/views/promethee/components/cover/_localize.html.erb +1 -1
- data/app/views/promethee/components/slider_item/_localize.html.erb +14 -2
- data/app/views/promethee/components/table/_edit.define.html.erb +4 -24
- data/app/views/promethee/components/table/_edit.inspect.html.erb +92 -32
- data/app/views/promethee/components/table/_edit.move.html.erb +7 -3
- data/app/views/promethee/components/table/_localize.html.erb +16 -8
- data/app/views/promethee/components/table/_show.html.erb +25 -12
- data/app/views/promethee/edit/_move.html.erb +2 -3
- data/app/views/promethee/presets/_image-with-text.html.erb +1 -1
- data/lib/promethee/data/localization.rb +2 -1
- data/lib/promethee/data/master_localized.rb +3 -1
- data/lib/promethee/rails/version.rb +1 -1
- data/lib/promethee.rb +1 -0
- data/lib/tasks/promethee/promethee.rake +15 -4
- metadata +30 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b24d3197b6a9f29120ec8849dffae52cb78cf47b309200bd6b1d228dbd930170
|
4
|
+
data.tar.gz: 4c47e50f8ea5ec4c239d9adeba78c17e41fa02801631e1896032f64016e57104
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60837d5bb49e78e27cd9816bc78794ec2ebc74a8a25d2ed3074926ba884e80fa140e463daad482eabeb9fc9cab278e80dd569bbc21cdef16b116ccddd09086de
|
7
|
+
data.tar.gz: a36840b631435a45a53e26c40148a2e4baf2cab78d28d3938fef818391072988540dfac3cddb2523f1d7f79a0b8f1a98e02288025ce96ca791531d1e898e01cf
|
data/UPGRADING
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
##########################################
|
2
|
+
# NOTE FOR UPGRADING TO 2.0.0 OR LATER #
|
3
|
+
##########################################
|
4
|
+
|
5
|
+
Prométhée 2.0 brings:
|
6
|
+
- [BREAKING CHANGE] New structure for table component. A rake task is available to update them in your master models. Localization has to be manual.
|
7
|
+
- [TOOL TO FIX ISSUE] A rake task to clean your localization models.
|
8
|
+
|
9
|
+
For more details, check the documentation:
|
10
|
+
https://github.com/lespoupeesrusses/promethee/tree/dev-2.0/doc
|
@@ -1,127 +1,135 @@
|
|
1
1
|
@import "@fancyapps/fancybox/dist/jquery.fancybox.min"
|
2
2
|
|
3
|
+
// aside
|
4
|
+
// blockquote
|
5
|
+
// collection
|
6
|
+
// cover
|
7
|
+
// faq
|
8
|
+
// image
|
9
|
+
// slider
|
10
|
+
|
3
11
|
.promethee
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
12
|
+
&__component
|
13
|
+
&__page > div:not(&__cover):not(&__slider),
|
14
|
+
&__page > aside
|
15
|
+
@extend .container
|
16
|
+
margin-bottom: 50px
|
17
|
+
padding-left: $grid-gutter-width/2
|
18
|
+
padding-right: $grid-gutter-width/2
|
19
|
+
|
20
|
+
&__page > &__collection,
|
21
|
+
&__page > &__row
|
22
|
+
padding-left: 0
|
23
|
+
padding-right: 0
|
24
|
+
|
25
|
+
&__aside
|
26
|
+
.aside__button
|
27
|
+
padding-top: $grid-gutter-width
|
28
|
+
a
|
29
|
+
display: inline-block
|
30
|
+
&--center
|
31
|
+
text-align: center
|
32
|
+
&--left
|
33
|
+
text-align: left
|
34
|
+
&--right
|
35
|
+
text-align: right
|
36
|
+
|
37
|
+
&__blockquote
|
38
|
+
.blockquote
|
39
|
+
border: none
|
40
|
+
font-size: 30px
|
41
|
+
|
42
|
+
p
|
43
|
+
display: inline
|
44
|
+
|
45
|
+
&::before, &::after
|
46
|
+
display: inline-block
|
47
|
+
|
48
|
+
&::before
|
49
|
+
content: '« '
|
50
|
+
|
51
|
+
&::after
|
52
|
+
content: ' »'
|
53
|
+
|
54
|
+
.author
|
55
|
+
font-size: 14px
|
56
|
+
font-style: italic
|
57
|
+
|
58
|
+
&__collection
|
59
|
+
margin-bottom: 20px
|
60
|
+
margin-top: 20px
|
61
|
+
.clearfix
|
62
|
+
margin: 40px 0
|
63
|
+
.collection-item__content
|
64
|
+
margin-bottom: $grid-gutter-width
|
65
|
+
a + p
|
66
|
+
margin-top: 10px
|
67
|
+
|
68
|
+
&__cover
|
69
|
+
background-position: center center
|
70
|
+
background-repeat: no-repeat
|
71
|
+
background-size: cover
|
72
|
+
display: flex
|
73
|
+
flex-direction: column
|
74
|
+
justify-content: center
|
75
|
+
margin-bottom: 50px
|
76
|
+
min-height: 300px
|
77
|
+
padding: 150px 30px
|
78
|
+
text-align: center
|
79
|
+
|
80
|
+
p:last-of-type
|
81
|
+
margin-bottom: 0
|
82
|
+
|
83
|
+
&__image
|
84
|
+
margin-bottom: $grid-gutter-width
|
85
|
+
figcaption
|
86
|
+
margin-top: 10px
|
87
|
+
|
88
|
+
&__faq
|
89
|
+
&_item:not(:last-of-type)
|
90
|
+
padding-bottom: 10px
|
91
|
+
h4
|
92
|
+
cursor: pointer
|
93
|
+
position: relative
|
94
|
+
&::after
|
95
|
+
border-right: 2px solid #000
|
96
|
+
border-top: 2px solid #000
|
97
|
+
content: ''
|
98
|
+
display: block
|
99
|
+
height: 8px
|
100
|
+
position: absolute
|
101
|
+
right: 10px
|
102
|
+
top: 5px
|
103
|
+
transform: rotate(135deg)
|
104
|
+
transition: transform .4s ease
|
105
|
+
width: 8px
|
106
|
+
&[aria-expanded="true"]
|
107
|
+
&::after
|
108
|
+
transform: rotate(315deg)
|
109
|
+
img
|
110
|
+
margin-bottom: $grid-gutter-width
|
111
|
+
|
112
|
+
&__slider
|
113
|
+
.promethee__component
|
114
|
+
margin-bottom: 0
|
115
|
+
.fontawesome-carousel-control .fa
|
116
|
+
font-size: 30px
|
117
|
+
position: absolute
|
118
|
+
top: 50%
|
119
|
+
transform: translateY(-50%)
|
120
|
+
.carousel-item
|
121
|
+
&__content
|
122
|
+
text-align: center
|
123
|
+
p:last-of-type
|
124
|
+
margin-bottom: 0
|
125
|
+
margin-top: 10px
|
112
126
|
|
113
127
|
@media print
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
&__page > &__video,
|
123
|
-
&__page > &__collection,
|
124
|
-
&__page > &__row
|
125
|
-
max-width: 90% !important
|
126
|
-
.container
|
127
|
-
max-width: 90% !important
|
128
|
+
body
|
129
|
+
font-size: 125%
|
130
|
+
.promethee
|
131
|
+
&__component
|
132
|
+
&__page > div:not(&__cover):not(&__slider)
|
133
|
+
max-width: 90%
|
134
|
+
.container
|
135
|
+
max-width: 90%
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Promethee
|
2
|
+
class LocalizeCleanService
|
3
|
+
DEFAULT_WHITELIST = {
|
4
|
+
"aside" => ["searchable_visible_content", "searchable_collapsed_content", "searchable_open_label"],
|
5
|
+
"blockquote" => ["searchable_body", "searchable_author"],
|
6
|
+
"collection" => [],
|
7
|
+
"collection_item" => ["searchable_caption", "video"],
|
8
|
+
"column" => [],
|
9
|
+
"cover" => ["searchable_surtitle", "searchable_title", "searchable_subtitle"],
|
10
|
+
"faq" => [],
|
11
|
+
"faq_item" => ["searchable_title", "searchable_body"],
|
12
|
+
"image" => ["searchable_alt", "searchable_caption"],
|
13
|
+
"page" => ["searchable_title", "searchable_description"],
|
14
|
+
"row" => [],
|
15
|
+
"slider" => [],
|
16
|
+
"slider_item" => ["searchable_caption", "video"],
|
17
|
+
"table" => ["cols", "cols_data", "rows", "rows_data"],
|
18
|
+
"text" => ["searchable_body"],
|
19
|
+
"video" => ["url"]
|
20
|
+
}
|
21
|
+
|
22
|
+
attr_accessor :objects
|
23
|
+
|
24
|
+
def initialize(model_name, whitelist = {})
|
25
|
+
begin
|
26
|
+
model_class = model_name.constantize
|
27
|
+
objects = model_class.all
|
28
|
+
rescue
|
29
|
+
puts 'Please provide a valid model name (e.g. `rake promethee:clean_localizations[Page]`)'
|
30
|
+
exit
|
31
|
+
end
|
32
|
+
@objects = objects
|
33
|
+
@whitelist = DEFAULT_WHITELIST.merge(whitelist)
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_rule(type, attributes = [])
|
37
|
+
@whitelist[type] = attributes
|
38
|
+
end
|
39
|
+
|
40
|
+
def start
|
41
|
+
puts '= START LOCALIZE CLEAN ='
|
42
|
+
puts "Number of objects: #{objects.count}"
|
43
|
+
i = 0
|
44
|
+
objects.each do |object|
|
45
|
+
next unless can_process?(object.data)
|
46
|
+
|
47
|
+
i += 1
|
48
|
+
puts "Processing object ##{object.id}"
|
49
|
+
|
50
|
+
object.data = clean(object.data)
|
51
|
+
object.save
|
52
|
+
puts "End processing object ##{object.id}"
|
53
|
+
end
|
54
|
+
puts "Number of processed objects: #{i}"
|
55
|
+
puts '====== END CLEANER ========'
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def clean(data)
|
61
|
+
i = 0
|
62
|
+
data["components"].each do |component|
|
63
|
+
component_whitelist = @whitelist[component["type"]]
|
64
|
+
next if component_whitelist.nil? # Process only types in whitelist
|
65
|
+
|
66
|
+
i += 1
|
67
|
+
component["attributes"]&.slice!(*component_whitelist)
|
68
|
+
end
|
69
|
+
puts "- #{i} components were processed"
|
70
|
+
data
|
71
|
+
end
|
72
|
+
|
73
|
+
def can_process?(data)
|
74
|
+
data.is_a?(Hash) && data.has_key?("components")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Promethee
|
2
|
+
class TableUpgradeService
|
3
|
+
attr_accessor :objects
|
4
|
+
|
5
|
+
def initialize(model_name)
|
6
|
+
begin
|
7
|
+
model_class = model_name.constantize
|
8
|
+
objects = model_class.all.select { |page| page.data&.to_json&.include? '"type":"table"' }
|
9
|
+
rescue
|
10
|
+
puts 'Please provide a valid model name (e.g. `rake promethee:clean_localizations[Page]`)'
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
@objects = objects
|
14
|
+
end
|
15
|
+
|
16
|
+
def start
|
17
|
+
puts '= START TABLE UPGRADE ='
|
18
|
+
puts "Number of objects: #{objects.count}"
|
19
|
+
objects.each do |object|
|
20
|
+
puts "Processing object ##{object.id}"
|
21
|
+
|
22
|
+
object.data = process_component(object.data)
|
23
|
+
object.save
|
24
|
+
puts "End processing object ##{object.id}"
|
25
|
+
end
|
26
|
+
puts '====== END CLEANER ========'
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def process_component(component)
|
32
|
+
component = upgrade(component) if component["type"] == "table"
|
33
|
+
component["children"].map do |child|
|
34
|
+
process_component(child)
|
35
|
+
end if component["children"]&.any?
|
36
|
+
component
|
37
|
+
end
|
38
|
+
|
39
|
+
def upgrade(component)
|
40
|
+
return component unless component.has_key? "attributes"
|
41
|
+
|
42
|
+
head = component["attributes"]["head"]
|
43
|
+
body = component["attributes"]["body"]
|
44
|
+
return component if head.nil? || body.nil?
|
45
|
+
|
46
|
+
cols = create_uids(head)
|
47
|
+
rows = create_uids(body)
|
48
|
+
|
49
|
+
cols_data = head.map.with_index { |col_data, i| [cols[i], col_data] }.to_h
|
50
|
+
rows_data = body.map.with_index { |row_data, i|
|
51
|
+
new_row_data = row_data.map.with_index { |cell_data, j| [cols[j], cell_data] }.to_h
|
52
|
+
[rows[i], new_row_data]
|
53
|
+
}.to_h
|
54
|
+
|
55
|
+
component["attributes"].except!("head", "body")
|
56
|
+
|
57
|
+
component["attributes"]["cols"] = cols
|
58
|
+
component["attributes"]["cols_data"] = cols_data
|
59
|
+
component["attributes"]["rows"] = rows
|
60
|
+
component["attributes"]["rows_data"] = rows_data
|
61
|
+
|
62
|
+
component
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_uids(array)
|
66
|
+
(0...array.size).map { |_| SecureRandom.hex(5) }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -8,9 +8,31 @@ back_url ||= nil
|
|
8
8
|
logo = File.read "#{__dir__}/../../assets/images/icon-promethee.svg"
|
9
9
|
%>
|
10
10
|
|
11
|
+
<script type="text/javascript">
|
12
|
+
angular
|
13
|
+
.module('uid', [])
|
14
|
+
.factory('uidService', function () {
|
15
|
+
// Option 3 : https://stackoverflow.com/a/27747377
|
16
|
+
return {
|
17
|
+
generate: function () {
|
18
|
+
var arr = new Uint8Array(10 / 2),
|
19
|
+
hexArr = [],
|
20
|
+
i;
|
21
|
+
|
22
|
+
(window.crypto || window.msCrypto).getRandomValues(arr);
|
23
|
+
for (i = 0; i < arr.length; i += 1) {
|
24
|
+
hexArr[i] = ('0' + arr[i].toString(16)).substr(-2);
|
25
|
+
}
|
26
|
+
|
27
|
+
return hexArr.join('');
|
28
|
+
}
|
29
|
+
};
|
30
|
+
});
|
31
|
+
</script>
|
32
|
+
|
11
33
|
<script type="text/javascript">
|
12
34
|
var promethee = angular
|
13
|
-
.module('Promethee', ['summernote', 'ngAnimate', 'ngFileUpload', 'ui.sortable', 'colorpicker.module'], ['$rootScopeProvider', function($rootScopeProvider) {
|
35
|
+
.module('Promethee', ['summernote', 'ngAnimate', 'ngFileUpload', 'ui.sortable', 'colorpicker.module', 'uid'], ['$rootScopeProvider', function($rootScopeProvider) {
|
14
36
|
$rootScopeProvider.digestTtl(30);
|
15
37
|
}])
|
16
38
|
.value('definitions', [])
|
@@ -92,16 +114,6 @@ promethee.controller('PrometheeController', ['$scope', 'summernoteConfig', 'pres
|
|
92
114
|
$scope.inspect = function(component, event) {
|
93
115
|
if(event.target.closest('.promethee-edit__component') === event.currentTarget) {
|
94
116
|
$scope.promethee.inspected = component;
|
95
|
-
$scope.refreshInspect(component.type);
|
96
|
-
}
|
97
|
-
}
|
98
|
-
|
99
|
-
$scope.refreshInspect = function (componentType) {
|
100
|
-
var inspectContainer = document.querySelector(".promethee-edit__inspect-content--"+componentType);
|
101
|
-
var summernoteToolbars = inspectContainer.querySelectorAll('.note-toolbar-wrapper');
|
102
|
-
var i;
|
103
|
-
for (i = 0 ; i < summernoteToolbars.length ; i += 1) {
|
104
|
-
summernoteToolbars[i].removeAttribute('style');
|
105
117
|
}
|
106
118
|
}
|
107
119
|
|
@@ -1,7 +1,8 @@
|
|
1
1
|
<script type="text/ng-template" id="promethee/components/collection_item/localize">
|
2
|
-
<div ng-show="master.attributes.searchable_caption !== ''">
|
2
|
+
<div ng-show="master.attributes.searchable_caption !== '' || master.attributes.media_type == 'video'">
|
3
3
|
<hr>
|
4
|
-
|
4
|
+
|
5
|
+
<div class="row" ng-show="master.attributes.searchable_caption !== ''">
|
5
6
|
<div class="col-md-6">
|
6
7
|
<b>Collection Item Caption</b>
|
7
8
|
<div class="promethee-edit__wrapper" ng-bind-html="master.attributes.searchable_caption | htmlSafe"></div>
|
@@ -11,5 +12,16 @@
|
|
11
12
|
<summernote config="summernoteConfig" ng-model="component.attributes.searchable_caption"></summernote>
|
12
13
|
</div>
|
13
14
|
</div>
|
15
|
+
|
16
|
+
<div class="row" ng-show="master.attributes.media_type == 'video'">
|
17
|
+
<div class="col-md-6">
|
18
|
+
<b>Video URL</b>
|
19
|
+
<div ng-bind-html="master.attributes.video.url | htmlSafe"></div>
|
20
|
+
</div>
|
21
|
+
<div class="col-md-6">
|
22
|
+
<label class="label-control">Video URL</label>
|
23
|
+
<input class="form-control" ng-model="component.attributes.video.url" type="text">
|
24
|
+
</div>
|
25
|
+
</div>
|
14
26
|
</div>
|
15
27
|
</script>
|
@@ -1,7 +1,8 @@
|
|
1
1
|
<script type="text/ng-template" id="promethee/components/slider_item/localize">
|
2
|
-
<div ng-show="master.attributes.
|
2
|
+
<div ng-show="master.attributes.searchable_caption !== '' || master.attributes.media_type == 'video'">
|
3
3
|
<hr>
|
4
|
-
|
4
|
+
|
5
|
+
<div class="row" ng-show="master.attributes.searchable_caption !== ''">
|
5
6
|
<div class="col-md-6">
|
6
7
|
<b>Slider Item Caption</b>
|
7
8
|
<div class="promethee-edit__wrapper" ng-bind-html="master.attributes.searchable_caption | htmlSafe"></div>
|
@@ -11,5 +12,16 @@
|
|
11
12
|
<summernote config="summernoteConfig" ng-model="component.attributes.searchable_caption"></summernote>
|
12
13
|
</div>
|
13
14
|
</div>
|
15
|
+
|
16
|
+
<div class="row" ng-show="master.attributes.media_type == 'video'">
|
17
|
+
<div class="col-md-6">
|
18
|
+
<b>Video URL</b>
|
19
|
+
<div ng-bind-html="master.attributes.video.url | htmlSafe"></div>
|
20
|
+
</div>
|
21
|
+
<div class="col-md-6">
|
22
|
+
<label class="label-control">Video URL</label>
|
23
|
+
<input class="form-control" ng-model="component.attributes.video.url" type="text">
|
24
|
+
</div>
|
25
|
+
</div>
|
14
26
|
</div>
|
15
27
|
</script>
|
@@ -8,30 +8,10 @@
|
|
8
8
|
data: {
|
9
9
|
type: 'table',
|
10
10
|
attributes: {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
{
|
16
|
-
searchable_text: 'Column 2'
|
17
|
-
},
|
18
|
-
{
|
19
|
-
searchable_text: 'Column 3'
|
20
|
-
}
|
21
|
-
],
|
22
|
-
body: [
|
23
|
-
[
|
24
|
-
{
|
25
|
-
searchable_text: 'Text 1'
|
26
|
-
},
|
27
|
-
{
|
28
|
-
searchable_text: 'Text 2'
|
29
|
-
},
|
30
|
-
{
|
31
|
-
searchable_text: 'Text 3'
|
32
|
-
}
|
33
|
-
]
|
34
|
-
]
|
11
|
+
cols: [],
|
12
|
+
cols_data: {},
|
13
|
+
rows: [],
|
14
|
+
rows_data: {}
|
35
15
|
}
|
36
16
|
}
|
37
17
|
})
|
@@ -1,42 +1,102 @@
|
|
1
1
|
<script type="text/ng-template" id="promethee/components/table/edit/inspect">
|
2
|
-
<div
|
3
|
-
<
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
<div
|
10
|
-
<div
|
11
|
-
<
|
2
|
+
<div ng-controller="TableInspectController" ng-init="component = promethee.inspected">
|
3
|
+
<div class="form-group">
|
4
|
+
<label class="label-control">Columns</label><br/>
|
5
|
+
<div class="btn btn-default btn-light btn-sm"
|
6
|
+
ng-click="addColumn()">
|
7
|
+
Add column
|
8
|
+
</div><br/><br/>
|
9
|
+
<div ui-sortable ng-model="component.attributes.cols">
|
10
|
+
<div ng-repeat="colUid in component.attributes.cols">
|
11
|
+
<div class="form-group row align-items-center">
|
12
|
+
<div class="col-1" style="line-height: 38px">
|
13
|
+
<i class="fas fa-bars"></i>
|
14
|
+
</div>
|
15
|
+
<div class="col-9">
|
16
|
+
<input type="text"
|
17
|
+
ng-model="component.attributes.cols_data[colUid].searchable_text"
|
18
|
+
class="form-control" />
|
19
|
+
</div>
|
20
|
+
<div class="col-2">
|
21
|
+
<a class="btn btn-default btn-light btn-sm"
|
22
|
+
ng-click="removeColumn(colUid)">
|
23
|
+
<%= icon('fa', 'close') %>
|
24
|
+
</a>
|
25
|
+
</div>
|
26
|
+
</div>
|
12
27
|
</div>
|
13
|
-
|
14
|
-
|
15
|
-
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
<hr>
|
31
|
+
<div class="form-group">
|
32
|
+
<label class="label-control">Rows</label><br/>
|
33
|
+
<div class="btn btn-default btn-light btn-sm"
|
34
|
+
ng-click="addRow()">
|
35
|
+
Add row
|
36
|
+
</div><br/><br/>
|
37
|
+
<div ng-repeat="rowUid in component.attributes.rows track by $index">
|
38
|
+
<span class="small">
|
39
|
+
<b>Row {{$index+1}}</b>
|
40
|
+
<a class="btn btn-default btn-light btn-sm float-right"
|
41
|
+
ng-click="removeRow(rowUid)">
|
16
42
|
<%= icon('fa', 'close') %>
|
17
43
|
</a>
|
44
|
+
</span><br/>
|
45
|
+
<div ng-repeat="colUid in component.attributes.cols">
|
46
|
+
<span class="small">
|
47
|
+
{{component.attributes.cols_data[colUid].searchable_text}}
|
48
|
+
</span>
|
49
|
+
<br/>
|
50
|
+
<input type="text"
|
51
|
+
ng-model="component.attributes.rows_data[rowUid][colUid].searchable_text"
|
52
|
+
class="form-control" />
|
18
53
|
</div>
|
54
|
+
<hr/>
|
19
55
|
</div>
|
20
56
|
</div>
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
<a class="btn btn-default btn-light btn-sm float-right"
|
31
|
-
ng-click="promethee.inspected.attributes.body.splice($index, 1)">
|
32
|
-
<%= icon('fa', 'close') %>
|
33
|
-
</a>
|
34
|
-
</span><br/>
|
35
|
-
<div ng-repeat="th in promethee.inspected.attributes.head track by $index">
|
36
|
-
<span class="small">{{th.searchable_text}}</span><br/>
|
37
|
-
<input type="text" ng-model="tr[$index].searchable_text" class="form-control" />
|
38
|
-
</div>
|
39
|
-
<hr/>
|
57
|
+
<div class="form-group" ng-show="component.attributes.rows.length > 1">
|
58
|
+
<label class="label-control">Drag the rows below to reorder them:</label>
|
59
|
+
<ul ui-sortable
|
60
|
+
ng-model="component.attributes.rows"
|
61
|
+
class="list-unstyled">
|
62
|
+
<li ng-repeat="_ in component.attributes.rows track by $index">
|
63
|
+
<%= icon('fa', 'bars') %> Row {{$index + 1}}
|
64
|
+
</li>
|
65
|
+
</ul>
|
40
66
|
</div>
|
41
67
|
</div>
|
42
68
|
</script>
|
69
|
+
|
70
|
+
<script>
|
71
|
+
promethee.controller('TableInspectController', ['$scope', 'uidService', function($scope, uidService) {
|
72
|
+
$scope.addColumn = function () {
|
73
|
+
var uid = uidService.generate();
|
74
|
+
$scope.component.attributes.cols.push(uid);
|
75
|
+
$scope.component.attributes.cols_data[uid] = { searchable_text: 'New column' };
|
76
|
+
}
|
77
|
+
|
78
|
+
$scope.addRow = function () {
|
79
|
+
var uid = uidService.generate();
|
80
|
+
$scope.component.attributes.rows.push(uid);
|
81
|
+
|
82
|
+
console.log($scope.component.attributes);
|
83
|
+
}
|
84
|
+
|
85
|
+
$scope.removeItem = function (uid, arrayKey) {
|
86
|
+
var dataKey = arrayKey + '_data';
|
87
|
+
var index = $scope.component.attributes[arrayKey].indexOf(uid);
|
88
|
+
if (index !== -1) {
|
89
|
+
$scope.component.attributes[arrayKey].splice(index, 1);
|
90
|
+
delete $scope.component.attributes[dataKey][uid];
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
$scope.removeColumn = function (uid) {
|
95
|
+
$scope.removeItem(uid, 'cols');
|
96
|
+
}
|
97
|
+
|
98
|
+
$scope.removeRow = function (uid) {
|
99
|
+
$scope.removeItem(uid, 'rows');
|
100
|
+
}
|
101
|
+
}]);
|
102
|
+
</script>
|
@@ -4,12 +4,16 @@
|
|
4
4
|
<table class="table">
|
5
5
|
<thead>
|
6
6
|
<tr>
|
7
|
-
<th ng-repeat="
|
7
|
+
<th ng-repeat="colUid in component.attributes.cols">
|
8
|
+
{{component.attributes.cols_data[colUid].searchable_text}}
|
9
|
+
</th>
|
8
10
|
</tr>
|
9
11
|
</thead>
|
10
12
|
<tbody>
|
11
|
-
<tr ng-repeat="
|
12
|
-
<td ng-repeat="
|
13
|
+
<tr ng-repeat="rowUid in component.attributes.rows">
|
14
|
+
<td ng-repeat="colUid in component.attributes.cols">
|
15
|
+
{{component.attributes.rows_data[rowUid][colUid].searchable_text}}
|
16
|
+
</td>
|
13
17
|
</tr>
|
14
18
|
</tbody>
|
15
19
|
</table>
|
@@ -6,12 +6,16 @@
|
|
6
6
|
<table class="table">
|
7
7
|
<thead>
|
8
8
|
<tr>
|
9
|
-
<th ng-repeat="
|
9
|
+
<th ng-repeat="colUid in master.attributes.cols track by $index">
|
10
|
+
{{ master.attributes.cols_data[colUid].searchable_text }}
|
11
|
+
</th>
|
10
12
|
</tr>
|
11
13
|
</thead>
|
12
14
|
<tbody>
|
13
|
-
<tr ng-repeat="
|
14
|
-
<td ng-repeat="
|
15
|
+
<tr ng-repeat="rowUid in master.attributes.rows">
|
16
|
+
<td ng-repeat="colUid in master.attributes.cols">
|
17
|
+
{{ master.attributes.rows_data[rowUid][colUid].searchable_text }}
|
18
|
+
</td>
|
15
19
|
</tr>
|
16
20
|
</tbody>
|
17
21
|
</table>
|
@@ -20,15 +24,19 @@
|
|
20
24
|
<table class="table">
|
21
25
|
<thead>
|
22
26
|
<tr>
|
23
|
-
<th ng-repeat="
|
24
|
-
<input
|
27
|
+
<th ng-repeat="colUid in master.attributes.cols track by $index">
|
28
|
+
<input type="text"
|
29
|
+
ng-model="component.attributes.cols_data[colUid].searchable_text"
|
30
|
+
class="form-control">
|
25
31
|
</th>
|
26
32
|
</tr>
|
27
33
|
</thead>
|
28
34
|
<tbody>
|
29
|
-
<tr ng-repeat="
|
30
|
-
<td ng-repeat="
|
31
|
-
<input
|
35
|
+
<tr ng-repeat="rowUid in master.attributes.rows">
|
36
|
+
<td ng-repeat="colUid in master.attributes.cols">
|
37
|
+
<input class="form-control"
|
38
|
+
ng-model="component.attributes.rows_data[rowUid][colUid].searchable_text"
|
39
|
+
type="text">
|
32
40
|
</td>
|
33
41
|
</tr>
|
34
42
|
</tbody>
|
@@ -1,24 +1,37 @@
|
|
1
|
+
<%
|
2
|
+
return unless ([:cols, :cols_data, :rows, :rows_data] - component[:attributes].keys).empty?
|
3
|
+
columns = component[:attributes][:cols].map { |colUid|
|
4
|
+
colData = component[:attributes][:cols_data][colUid.to_sym] || {}
|
5
|
+
{ uid: colUid, searchable_text: colData[:searchable_text] }
|
6
|
+
}
|
7
|
+
|
8
|
+
rows = component[:attributes][:rows].map { |rowUid|
|
9
|
+
rowData = component[:attributes][:rows_data][rowUid.to_sym] || {}
|
10
|
+
{ uid: rowUid, data: rowData }
|
11
|
+
}
|
12
|
+
%>
|
13
|
+
|
1
14
|
<div id="component-<%= component[:id] %>" class="<%= promethee_class_for(component) %>">
|
2
15
|
<div class="table-responsive">
|
3
16
|
<table class="table">
|
4
17
|
<thead>
|
5
18
|
<tr>
|
6
|
-
<%
|
7
|
-
<th><%=
|
19
|
+
<% columns.each do |col| %>
|
20
|
+
<th><%= col[:searchable_text] %></th>
|
8
21
|
<% end %>
|
9
22
|
</tr>
|
10
23
|
</thead>
|
11
24
|
<tbody>
|
12
|
-
<%
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
25
|
+
<% rows.each do |row| %>
|
26
|
+
<tr>
|
27
|
+
<% columns.each do |col| %>
|
28
|
+
<%
|
29
|
+
cell = row[:data][col[:uid].to_sym]
|
30
|
+
next if cell.nil?
|
31
|
+
%>
|
32
|
+
<td><%= cell[:searchable_text] %></td>
|
33
|
+
<% end %>
|
34
|
+
</tr>
|
22
35
|
<% end %>
|
23
36
|
</tbody>
|
24
37
|
</table>
|
@@ -108,8 +108,7 @@ promethee
|
|
108
108
|
// console.log('dropped', component, droppedToList, droppedToIndex);
|
109
109
|
droppedToList.splice(droppedToIndex, 0, component);
|
110
110
|
|
111
|
-
scope.promethee.inspected = component
|
112
|
-
scope.refreshInspect(component.type);
|
111
|
+
scope.promethee.inspected = component;
|
113
112
|
|
114
113
|
scope.$apply();
|
115
114
|
}
|
@@ -155,7 +154,7 @@ promethee
|
|
155
154
|
<div class="promethee-edit__inspect-content">
|
156
155
|
<div ng-repeat="definition in promethee.definitions | orderBy:'position'">
|
157
156
|
<ng-include src="'promethee/components/' + definition.data.type + '/edit/inspect'"
|
158
|
-
ng-
|
157
|
+
ng-if="promethee.inspected.type == definition.data.type"
|
159
158
|
class="promethee-edit__inspect-content--{{ definition.data.type }}"></ng-include>
|
160
159
|
</div>
|
161
160
|
</div>
|
@@ -27,7 +27,7 @@
|
|
27
27
|
"children": [
|
28
28
|
{
|
29
29
|
"type": "text",
|
30
|
-
"attributes": {"
|
30
|
+
"attributes": {"searchable_body": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. A dicta, est quos distinctio culpa! Quasi cupiditate, totam nulla reprehenderit animi iusto qui cumque culpa repellat eum sit? Debitis, laboriosam reiciendis!</p>"}
|
31
31
|
}
|
32
32
|
]
|
33
33
|
}
|
@@ -25,7 +25,8 @@ class Promethee::Data::Localization < Promethee::Data
|
|
25
25
|
@master_data.flat.each do |master_component|
|
26
26
|
localized_component = find_localized_component master_component[:id]
|
27
27
|
# We take the localized component if it exists, the master component otherwise
|
28
|
-
component = localized_component || master_component
|
28
|
+
component = localized_component || master_component.except(:attributes)
|
29
|
+
component[:attributes] ||= {}
|
29
30
|
# We add it to the list of localized components
|
30
31
|
@data[:components] << component
|
31
32
|
end
|
@@ -18,9 +18,11 @@ class Promethee::Data::MasterLocalized < Promethee::Data
|
|
18
18
|
def localize_component_attributes(component)
|
19
19
|
localized_component = find_localized_component component[:id]
|
20
20
|
return if (localized_component.nil? || !localized_component.include?(:attributes))
|
21
|
-
component[:attributes].
|
21
|
+
component[:attributes].deep_merge_existing_keys! localized_component[:attributes]
|
22
22
|
end
|
23
23
|
|
24
|
+
|
25
|
+
|
24
26
|
def localize_component_children(component)
|
25
27
|
component[:children].each { |child| localize_component child }
|
26
28
|
end
|
data/lib/promethee.rb
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
namespace :promethee do
|
2
|
+
|
3
|
+
desc "Remove useless attributes from localizations' data"
|
4
|
+
task :clean_localizations, [:model_name] => :environment do |task, args|
|
5
|
+
service = Promethee::LocalizeCleanService.new(args[:model_name])
|
6
|
+
service.start
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Upgrade your table components' to 2.x structure"
|
10
|
+
task :upgrade_table, [:model_name] => :environment do |task, args|
|
11
|
+
service = Promethee::TableUpgradeService.new(args[:model_name])
|
12
|
+
service.start
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: promethee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sébastien Gaya
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2019-
|
17
|
+
date: 2019-05-15 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: rails
|
@@ -128,6 +128,20 @@ dependencies:
|
|
128
128
|
- - "~>"
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: 0.8.10.0
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: deep_merge_existing_keys
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :runtime
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
131
145
|
- !ruby/object:Gem::Dependency
|
132
146
|
name: byebug
|
133
147
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,6 +171,7 @@ extra_rdoc_files: []
|
|
157
171
|
files:
|
158
172
|
- README.md
|
159
173
|
- Rakefile
|
174
|
+
- UPGRADING
|
160
175
|
- app/assets/images/icon-promethee.png
|
161
176
|
- app/assets/images/icon-promethee.svg
|
162
177
|
- app/assets/images/loader.gif
|
@@ -176,6 +191,8 @@ files:
|
|
176
191
|
- app/assets/stylesheets/promethee.sass
|
177
192
|
- app/controllers/promethee_controller.rb
|
178
193
|
- app/models/concerns/promethee_data.rb
|
194
|
+
- app/services/promethee/localize_clean_service.rb
|
195
|
+
- app/services/promethee/table_upgrade_service.rb
|
179
196
|
- app/views/promethee/_edit.html.erb
|
180
197
|
- app/views/promethee/_localize.html.erb
|
181
198
|
- app/views/promethee/_show.html.erb
|
@@ -430,7 +447,17 @@ homepage: https://github.com/lespoupeesrusses/promethee
|
|
430
447
|
licenses:
|
431
448
|
- MIT
|
432
449
|
metadata: {}
|
433
|
-
post_install_message:
|
450
|
+
post_install_message: |-
|
451
|
+
##########################################
|
452
|
+
# NOTE FOR UPGRADING TO 2.0.0 OR LATER #
|
453
|
+
##########################################
|
454
|
+
|
455
|
+
Prométhée 2.0 brings:
|
456
|
+
- [BREAKING CHANGE] New structure for table component. A rake task is available to update them in your master models. Localization has to be manual.
|
457
|
+
- [TOOL TO FIX ISSUE] A rake task to clean your localization models.
|
458
|
+
|
459
|
+
For more details, check the documentation:
|
460
|
+
https://github.com/lespoupeesrusses/promethee/tree/dev-2.0/doc
|
434
461
|
rdoc_options: []
|
435
462
|
require_paths:
|
436
463
|
- lib
|