promethee 1.11.29 → 2.0.0
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.
- 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
|