para 0.7.1 → 0.7.2
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/app/assets/javascripts/para/admin/tabs.coffee +20 -1
- data/app/assets/javascripts/para/admin.coffee +1 -0
- data/app/assets/javascripts/para/inputs/multi-select-input.coffee +5 -3
- data/app/assets/javascripts/para/inputs/nested_many.coffee +35 -1
- data/app/assets/javascripts/para/lib/remote-file-forms.coffee +6 -7
- data/app/assets/javascripts/para/lib/turbolinks-loading.coffee +1 -1
- data/app/assets/stylesheets/para/admin/main.sass +1 -0
- data/app/assets/stylesheets/para/admin/src/_affix.sass +4 -0
- data/app/assets/stylesheets/para/admin/src/_base.sass +4 -1
- data/app/assets/stylesheets/para/admin/src/_breadcrumb.sass +12 -2
- data/app/assets/stylesheets/para/admin/src/_form.sass +22 -3
- data/app/assets/stylesheets/para/admin/src/_navtabs.sass +23 -6
- data/app/assets/stylesheets/para/admin/src/_nested-many.sass +5 -0
- data/app/assets/stylesheets/para/admin/src/_nested_one.sass +6 -5
- data/app/controllers/para/admin/base_controller.rb +5 -0
- data/app/controllers/para/admin/crud_resources_controller.rb +1 -1
- data/app/controllers/para/admin/exports_controller.rb +2 -1
- data/app/controllers/para/admin/nested_forms_controller.rb +13 -0
- data/app/controllers/para/admin/resources_controller.rb +14 -3
- data/app/controllers/para/admin/search_controller.rb +7 -5
- data/app/decorators/para/component/base_decorator.rb +7 -2
- data/app/decorators/para/component/crud_decorator.rb +4 -0
- data/app/decorators/para/component/form_decorator.rb +6 -0
- data/app/exporters/call_for_projects_votes_exporter.rb +79 -0
- data/app/helpers/para/admin/base_helper.rb +2 -3
- data/app/helpers/para/admin/history_helper.rb +16 -0
- data/app/helpers/para/form_helper.rb +9 -1
- data/app/helpers/para/model_helper.rb +0 -2
- data/app/models/para/cache/item.rb +4 -0
- data/app/models/para/component/base.rb +4 -0
- data/app/models/para/component/crud.rb +1 -0
- data/app/models/para/component/form.rb +2 -0
- data/app/models/para/library/file.rb +40 -12
- data/app/models/para/page/section.rb +13 -1
- data/app/views/admin/para/exporter/bases/_completed.html.haml +1 -1
- data/app/views/layouts/para/admin.html.haml +5 -5
- data/app/views/para/admin/form_resources/show.html.haml +6 -2
- data/app/views/para/admin/nested_forms/show.html.haml +9 -0
- data/app/views/para/admin/resources/_exports_menu.html.haml +2 -2
- data/app/views/para/admin/resources/_list.html.haml +26 -21
- data/app/views/para/admin/resources/_remote_nested_form.html.haml +1 -0
- data/app/views/para/admin/resources/edit.html.haml +7 -2
- data/app/views/para/admin/resources/history/_index.html.haml +3 -0
- data/app/views/para/admin/shared/_header.html.haml +3 -3
- data/app/views/para/admin/shared/_navigation.html.haml +1 -1
- data/app/views/para/form/_tabs.html.haml +12 -9
- data/app/views/para/inputs/_multi_select.html.haml +6 -2
- data/app/views/para/inputs/_nested_many.html.haml +4 -4
- data/app/views/para/inputs/_nested_one.html.haml +12 -1
- data/app/views/para/inputs/multi_select/_no_items.html.haml +8 -4
- data/app/views/para/inputs/nested_many/_add.html.haml +2 -2
- data/app/views/para/inputs/nested_many/_add_with_subclasses.html.haml +3 -3
- data/app/views/para/inputs/nested_many/_container.html.haml +10 -7
- data/lib/generators/para/exporter/templates/csv_exporter.rb +24 -0
- data/lib/generators/para/exporter/templates/xls_exporter.rb +24 -0
- data/lib/para/attribute_field/belongs_to.rb +4 -1
- data/lib/para/attribute_field/nested_field.rb +4 -2
- data/lib/para/attribute_field/nested_many.rb +1 -1
- data/lib/para/attribute_field/nested_one.rb +1 -1
- data/lib/para/cache/database_store.rb +14 -1
- data/lib/para/cloneable.rb +44 -2
- data/lib/para/component/history.rb +15 -0
- data/lib/para/component.rb +1 -0
- data/lib/para/components_configuration.rb +8 -3
- data/lib/para/engine.rb +8 -0
- data/lib/para/exporter/base.rb +49 -1
- data/lib/para/ext/request_iframe_xhr.rb +17 -0
- data/lib/para/ext.rb +1 -0
- data/lib/para/form_builder/attributes_mappings_tracker.rb +15 -3
- data/lib/para/form_builder/containers.rb +6 -1
- data/lib/para/form_builder/nested_form.rb +7 -4
- data/lib/para/form_builder/tabs.rb +49 -8
- data/lib/para/iframe_transport/middleware.rb +58 -0
- data/lib/para/iframe_transport.rb +7 -0
- data/lib/para/importer/base.rb +1 -0
- data/lib/para/inputs/multi_select_input.rb +27 -8
- data/lib/para/inputs/nested_base_input.rb +26 -0
- data/lib/para/inputs/nested_many_input.rb +43 -18
- data/lib/para/inputs/nested_one_input.rb +18 -4
- data/lib/para/inputs.rb +1 -0
- data/lib/para/log_config.rb +14 -0
- data/lib/para/markup/resources_table.rb +2 -2
- data/lib/para/model_field_parsers/relations.rb +12 -1
- data/lib/para/page/model.rb +2 -1
- data/lib/para/postgres_extensions_checker.rb +15 -11
- data/lib/para/routes.rb +3 -3
- data/lib/para/search/distinct.rb +1 -1
- data/lib/para/version.rb +1 -1
- data/lib/para.rb +2 -0
- data/lib/rails/routing_mapper.rb +19 -27
- data/vendor/assets/javascripts/jquery.iframe-transport.js +260 -0
- data/vendor/assets/javascripts/jquery.remote-modal-form.coffee +80 -2
- metadata +23 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f2e4cc7267a3d024fb9690cf426b0064bdb5da8
|
|
4
|
+
data.tar.gz: eea345a2e6a7b354420b6fb27d8bcef5bda8d5b9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 75f8375384ace99363c1d518f82df23c7261cc96d86b925d743dcf6052b8d9d79a767eb2c2d21ebbe549798cf22caa429ca7cd88d1bb32acd96f497bf9afc9b0
|
|
7
|
+
data.tar.gz: ea104d47ae45e079a54d0af2c2af8212dc2d5148722ee432f54764594d09cfff86988ec4ff2b4bdb15f96938c668fbb817e6c19f6774519c3ddcf5f99c96f0a5
|
|
@@ -10,13 +10,17 @@ class Para.Tabs extends Vertebra.View
|
|
|
10
10
|
@$anchorInput = options.$anchorInput
|
|
11
11
|
@showActiveTab()
|
|
12
12
|
@refreshTabsErrors()
|
|
13
|
+
@initializeAffix()
|
|
13
14
|
|
|
14
15
|
showActiveTab: ->
|
|
15
16
|
if (hash = (location.hash or @$anchorInput?.val()))
|
|
16
17
|
@findTab(hash).tab('show')
|
|
17
18
|
|
|
18
19
|
onTabShown: (e) =>
|
|
19
|
-
|
|
20
|
+
$tab = $(e.target)
|
|
21
|
+
return unless $tab.closest('[data-form-tabs]').is('[data-top-level-tabs]')
|
|
22
|
+
|
|
23
|
+
tabHash = $tab.attr('href')
|
|
20
24
|
history.pushState(null, null, tabHash)
|
|
21
25
|
@updateAnchorInput()
|
|
22
26
|
|
|
@@ -31,6 +35,21 @@ class Para.Tabs extends Vertebra.View
|
|
|
31
35
|
$panel = @$($tab.attr('href'))
|
|
32
36
|
$tab.addClass('has-error') if $panel.find('.has-error').length
|
|
33
37
|
|
|
38
|
+
#
|
|
39
|
+
initializeAffix: ->
|
|
40
|
+
return unless (@$nav = @$('[data-tabs-nav-affix]')).length
|
|
41
|
+
|
|
42
|
+
headerHeight = $('[data-header]').outerHeight()
|
|
43
|
+
offsetTop = @$nav.offset().top - headerHeight
|
|
44
|
+
sidebarWidth = $('[data-admin-left-sidebar]').outerWidth()
|
|
45
|
+
|
|
46
|
+
@$nav.affix(offset: { top: offsetTop })
|
|
47
|
+
.css(top: headerHeight, left: sidebarWidth)
|
|
48
|
+
|
|
49
|
+
# Fix parent wrapper height to maintain the same scroll position when the
|
|
50
|
+
# nav tabs are fixed to top
|
|
51
|
+
@$nav.closest('[data-nav-tabs-wrapper]').height(@$nav.outerHeight())
|
|
52
|
+
|
|
34
53
|
onFormInputUpdate: (e) ->
|
|
35
54
|
$tab = @findTab($(e.currentTarget).attr('id'))
|
|
36
55
|
@refreshTabErrors($tab)
|
|
@@ -12,6 +12,7 @@ class Para.MultiSelectInput extends Vertebra.View
|
|
|
12
12
|
|
|
13
13
|
@searchURL = @$el.data('search-url')
|
|
14
14
|
@orderable = @$el.is('[data-orderable]')
|
|
15
|
+
@searchParam = @$searchField.attr('name')
|
|
15
16
|
|
|
16
17
|
@noSelectedItemsTemplate = @$('[data-no-selected-items]').data('no-selected-items')
|
|
17
18
|
@noAvailableItemsTemplate = @$('[data-no-available-items]').data('no-available-items')
|
|
@@ -31,13 +32,14 @@ class Para.MultiSelectInput extends Vertebra.View
|
|
|
31
32
|
|
|
32
33
|
searchFor: (terms) ->
|
|
33
34
|
terms = trim(terms)
|
|
34
|
-
return if terms is @terms
|
|
35
|
+
return if terms is @terms or (!terms and !@terms)
|
|
35
36
|
@terms = terms
|
|
36
37
|
@setLoading(true)
|
|
37
38
|
@_currentSearchXHR?.abort()
|
|
38
|
-
|
|
39
|
+
data = @$('[data-search-field-input]').serialize()
|
|
40
|
+
@_currentSearchXHR = $.get(@searchURL, data).done(@onSearchReturn)
|
|
39
41
|
|
|
40
|
-
onSearchReturn: (results
|
|
42
|
+
onSearchReturn: (results) =>
|
|
41
43
|
@_currentSearchXHR = null
|
|
42
44
|
@setLoading(false)
|
|
43
45
|
@$('[data-available-items] tbody').html(results)
|
|
@@ -48,11 +48,45 @@ class Para.NestedManyField
|
|
|
48
48
|
|
|
49
49
|
collapseShown: (e) ->
|
|
50
50
|
$target = $(e.target)
|
|
51
|
+
|
|
52
|
+
if $target.is("[data-rendered]") or $target.data("rendered")
|
|
53
|
+
@initializeCollapseContent($target)
|
|
54
|
+
else
|
|
55
|
+
@loadCollapseContent($target)
|
|
56
|
+
@scrollToTarget($target)
|
|
57
|
+
|
|
58
|
+
initializeCollapseContent: ($target) ->
|
|
59
|
+
@scrollToTarget($target)
|
|
60
|
+
@focusFirstField($target)
|
|
61
|
+
|
|
62
|
+
scrollToTarget: ($target) ->
|
|
51
63
|
$field = @$field.find("[data-toggle='collapse'][href='##{ $target.attr('id') }']")
|
|
52
|
-
scrollOffset = -($('[data-header]').outerHeight() +
|
|
64
|
+
scrollOffset = -($('[data-header]').outerHeight() + 30)
|
|
65
|
+
|
|
66
|
+
if ($affixNavTabs = $("[data-tabs-nav-affix]:eq(0)")).length
|
|
67
|
+
scrollOffset -= $affixNavTabs.outerHeight()
|
|
68
|
+
|
|
53
69
|
$.scrollTo($field, 200, offset: scrollOffset)
|
|
70
|
+
|
|
71
|
+
focusFirstField: ($target) ->
|
|
54
72
|
$target.find('input, textarea, select').eq('0').focus()
|
|
55
73
|
|
|
74
|
+
loadCollapseContent: ($target) ->
|
|
75
|
+
targetUrl = $target.data("render-path")
|
|
76
|
+
return unless targetUrl
|
|
77
|
+
|
|
78
|
+
data = {
|
|
79
|
+
"id": $target.data("id")
|
|
80
|
+
"object_name": $target.data("object-name")
|
|
81
|
+
"model_name": $target.data("model-name")
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
$.get(targetUrl, data).then (resp) =>
|
|
85
|
+
$content = $(resp)
|
|
86
|
+
$target.find("[data-nested-form-container]:eq(0)").html($content)
|
|
87
|
+
$content.simpleForm()
|
|
88
|
+
@focusFirstField($target)
|
|
89
|
+
$target.data("rendered", true)
|
|
56
90
|
|
|
57
91
|
$.simpleForm.onDomReady ($document) ->
|
|
58
92
|
$document.find('.nested-many-field').each (i, el) -> new Para.NestedManyField($(el))
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
# of original rails' remote form requests, to allow existing handling code
|
|
7
7
|
# to run without any modification.
|
|
8
8
|
#
|
|
9
|
-
class RemoteFileForm
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
class @RemoteFileForm extends Vertebra.View
|
|
10
|
+
@supported = FormData isnt undefined
|
|
11
|
+
|
|
12
|
+
initialize: (options = {}) ->
|
|
12
13
|
@submitForm() if $.rails.fire(@$el, 'ajax:before')
|
|
13
14
|
|
|
14
15
|
submitForm: ->
|
|
@@ -28,7 +29,7 @@ class RemoteFileForm
|
|
|
28
29
|
success: @success
|
|
29
30
|
complete: @complete
|
|
30
31
|
error: @error
|
|
31
|
-
crossDomain: $.rails.isCrossDomain(url)
|
|
32
|
+
crossDomain: $.rails.isCrossDomain?(url)
|
|
32
33
|
|
|
33
34
|
buildXHR: =>
|
|
34
35
|
xhr = $.ajaxSettings.xhr()
|
|
@@ -50,10 +51,8 @@ class RemoteFileForm
|
|
|
50
51
|
error: (xhr, status, error) =>
|
|
51
52
|
@$el.trigger('ajax:error', [xhr, status, error])
|
|
52
53
|
|
|
53
|
-
# TODO : Implement an upload progress bar for heavy files
|
|
54
|
-
#
|
|
55
54
|
progress: (e) =>
|
|
56
|
-
|
|
55
|
+
@trigger('progress', e)
|
|
57
56
|
|
|
58
57
|
$(document).on 'ajax:aborted:file', (e) ->
|
|
59
58
|
new RemoteFileForm(el: e.target)
|
|
@@ -22,4 +22,4 @@ $(document).on('page:fetch', Para.loadingManager.start)
|
|
|
22
22
|
|
|
23
23
|
$(document).on 'page:change turbolinks:load', ->
|
|
24
24
|
Para.loadingManager.stop()
|
|
25
|
-
$('body').on('submit', '[data-para-form]', Para.loadingManager.start)
|
|
25
|
+
$('body').on('submit', '[data-para-form]:not([data-remote])', Para.loadingManager.start)
|
|
@@ -40,9 +40,12 @@ body
|
|
|
40
40
|
float: left
|
|
41
41
|
line-height: 34px
|
|
42
42
|
|
|
43
|
+
.admin-main-page-content
|
|
44
|
+
position: relative
|
|
45
|
+
|
|
43
46
|
.page-content-wrap
|
|
44
|
-
background-color: #fff
|
|
45
47
|
margin: 25px 10px 25px 10px
|
|
48
|
+
background-color: #fff
|
|
46
49
|
+border-radius($border-radius-small)
|
|
47
50
|
+material-box-shadow-soft
|
|
48
51
|
padding: 25px
|
|
@@ -7,11 +7,21 @@
|
|
|
7
7
|
//## Just a override of bootstrap
|
|
8
8
|
|
|
9
9
|
.breadcrumb
|
|
10
|
+
float: left
|
|
11
|
+
width: calc(100% - 90px)
|
|
12
|
+
max-height: 60px
|
|
13
|
+
margin: 0
|
|
14
|
+
|
|
10
15
|
border: none
|
|
11
16
|
+border-radius(0)
|
|
12
|
-
|
|
13
|
-
float: left
|
|
17
|
+
|
|
14
18
|
li
|
|
19
|
+
max-width: 30%
|
|
20
|
+
height: 60px
|
|
21
|
+
overflow: hidden
|
|
22
|
+
text-overflow: ellipsis
|
|
23
|
+
white-space: nowrap
|
|
24
|
+
|
|
15
25
|
a
|
|
16
26
|
color: $breadcrumb-color
|
|
17
27
|
font-size: 1em
|
|
@@ -57,20 +57,24 @@ legend
|
|
|
57
57
|
//
|
|
58
58
|
//##
|
|
59
59
|
|
|
60
|
+
.form-control
|
|
61
|
+
font-size: 14px
|
|
62
|
+
|
|
60
63
|
.form-inputs,
|
|
61
64
|
.nested-one-field,
|
|
62
65
|
.tab-pane
|
|
63
66
|
+clearfix
|
|
64
67
|
.form-group:last-of-type,
|
|
65
68
|
.form-group:only-child,
|
|
66
|
-
.nested-one-field:last-of-type
|
|
69
|
+
.nested-one-field:last-of-type
|
|
67
70
|
margin-bottom: 0
|
|
68
71
|
|
|
69
72
|
.nested-one-field
|
|
70
73
|
margin-bottom: $form-group-margin-bottom
|
|
71
74
|
|
|
72
|
-
.
|
|
73
|
-
|
|
75
|
+
.nested-input-title
|
|
76
|
+
&.has-error
|
|
77
|
+
color: $brand-danger
|
|
74
78
|
|
|
75
79
|
|
|
76
80
|
//== Inputs outline
|
|
@@ -165,6 +169,21 @@ legend
|
|
|
165
169
|
&:active:focus
|
|
166
170
|
+box-shadow(none)
|
|
167
171
|
|
|
172
|
+
//== Color picker
|
|
173
|
+
//
|
|
174
|
+
//##
|
|
175
|
+
|
|
176
|
+
.input-group
|
|
177
|
+
&.color
|
|
178
|
+
max-width: 300px
|
|
179
|
+
.input-group-addon
|
|
180
|
+
padding: 0
|
|
181
|
+
padding-left: 5px
|
|
182
|
+
i
|
|
183
|
+
border: 1px solid #ccc
|
|
184
|
+
width: 25px
|
|
185
|
+
height: 25px
|
|
186
|
+
|
|
168
187
|
//== Search form filter
|
|
169
188
|
//
|
|
170
189
|
//##
|
|
@@ -7,22 +7,39 @@
|
|
|
7
7
|
//##
|
|
8
8
|
|
|
9
9
|
//** Add negative margin top if the nav tab is the frst content of the page
|
|
10
|
-
.page-content-wrap
|
|
11
|
-
.nav-tabs
|
|
10
|
+
.page-content-wrap
|
|
11
|
+
.nav-tabs-wrapper
|
|
12
12
|
margin-top: -25px
|
|
13
|
+
|
|
14
|
+
.nav-tabs
|
|
13
15
|
+border-radius($border-radius-small)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
|
|
17
|
+
&.affix
|
|
18
|
+
margin-top: 0
|
|
19
|
+
width: 100%
|
|
20
|
+
z-index: $zindex-navbar-fixed - 1
|
|
21
|
+
+material-box-shadow-soft(3)
|
|
22
|
+
|
|
23
|
+
.form-inputs
|
|
24
|
+
.nav-tabs-wrapper
|
|
16
25
|
margin-top: 0
|
|
26
|
+
|
|
27
|
+
.nav-tabs
|
|
17
28
|
+border-radius(0)
|
|
18
29
|
|
|
30
|
+
.panel-body
|
|
31
|
+
.nav-tabs-wrapper
|
|
32
|
+
margin-top: -25px
|
|
33
|
+
|
|
19
34
|
//** Override bootstrap nav tabs
|
|
20
|
-
.nav-tabs
|
|
21
|
-
background-color: $gray-lighter
|
|
35
|
+
.nav-tabs-wrapper
|
|
22
36
|
margin-right: -25px
|
|
23
37
|
margin-left: -25px
|
|
24
38
|
margin-bottom: 25px
|
|
25
39
|
|
|
40
|
+
.nav-tabs
|
|
41
|
+
background-color: $gray-lighter
|
|
42
|
+
|
|
26
43
|
> li > a
|
|
27
44
|
color: $text-color
|
|
28
45
|
border: none
|
|
@@ -8,14 +8,15 @@
|
|
|
8
8
|
|
|
9
9
|
.form-group.nested_one
|
|
10
10
|
label.control-label.nested_one
|
|
11
|
-
|
|
12
|
-
font-size: 21px
|
|
13
|
-
color: $blue-darker
|
|
14
|
-
text-transform: inherit
|
|
11
|
+
width: 100%
|
|
15
12
|
margin-top: 15px
|
|
16
13
|
margin-bottom: 15px
|
|
14
|
+
padding-bottom: 10px
|
|
15
|
+
border-bottom: 1px solid $gray-light
|
|
16
|
+
font-weight: 600
|
|
17
|
+
font-size: 18px
|
|
17
18
|
|
|
18
19
|
.tab-pane
|
|
19
20
|
> .form-group.nested_one
|
|
20
21
|
label.control-label.nested_one
|
|
21
|
-
margin-top: 0
|
|
22
|
+
margin-top: 0
|
|
@@ -12,6 +12,7 @@ module Para
|
|
|
12
12
|
layout 'para/admin'
|
|
13
13
|
|
|
14
14
|
helper_method :current_admin
|
|
15
|
+
helper_method :admin_body_class
|
|
15
16
|
|
|
16
17
|
def current_admin
|
|
17
18
|
@current_admin ||= if Para.config.current_admin_method
|
|
@@ -27,6 +28,10 @@ module Para
|
|
|
27
28
|
|
|
28
29
|
private
|
|
29
30
|
|
|
31
|
+
def admin_body_class
|
|
32
|
+
'admin'
|
|
33
|
+
end
|
|
34
|
+
|
|
30
35
|
# Override cancan controlelr resource class to avoid attributes
|
|
31
36
|
# assignation issues with resources
|
|
32
37
|
#
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module Admin
|
|
3
|
+
class NestedFormsController < ComponentController
|
|
4
|
+
def show
|
|
5
|
+
@model = params[:model_name].constantize
|
|
6
|
+
@object = params[:id] ? @model.find(params[:id]) : @model.new
|
|
7
|
+
@object_name = params[:object_name]
|
|
8
|
+
|
|
9
|
+
render layout: false
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -49,7 +49,7 @@ module Para
|
|
|
49
49
|
def destroy
|
|
50
50
|
resource.destroy
|
|
51
51
|
flash_message(:success, resource)
|
|
52
|
-
redirect_to
|
|
52
|
+
redirect_to after_form_submit_path
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def order
|
|
@@ -83,14 +83,25 @@ module Para
|
|
|
83
83
|
|
|
84
84
|
def after_form_submit_path
|
|
85
85
|
if params[:_save_and_edit]
|
|
86
|
-
|
|
86
|
+
host_redirect_params.merge(
|
|
87
|
+
action: 'edit',
|
|
88
|
+
id: resource.id,
|
|
89
|
+
anchor: current_anchor
|
|
90
|
+
)
|
|
87
91
|
elsif params[:_save_and_add_another]
|
|
88
|
-
|
|
92
|
+
host_redirect_params.merge(
|
|
93
|
+
action: 'new',
|
|
94
|
+
type: resource.try(:type)
|
|
95
|
+
)
|
|
89
96
|
else
|
|
90
97
|
params.delete(:return_to).presence || @component.path
|
|
91
98
|
end
|
|
92
99
|
end
|
|
93
100
|
|
|
101
|
+
def host_redirect_params
|
|
102
|
+
{ subdomain: request.subdomain, domain: request.domain }
|
|
103
|
+
end
|
|
104
|
+
|
|
94
105
|
def resource_model
|
|
95
106
|
@resource_model ||= self.class.resource_model
|
|
96
107
|
end
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
module Para
|
|
2
2
|
module Admin
|
|
3
3
|
class SearchController < ApplicationController
|
|
4
|
-
include Para::ModelHelper
|
|
5
|
-
include Para::SearchHelper
|
|
6
|
-
|
|
7
4
|
def index
|
|
5
|
+
# Parse ids that are provided as string into array
|
|
6
|
+
if params[:q] && params[:q][:id_in].is_a?(String)
|
|
7
|
+
params[:q][:id_in] = params[:q][:id_in].split(',')
|
|
8
|
+
end
|
|
9
|
+
|
|
8
10
|
model = params[:model_name].constantize
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
@results = model.ransack(params[:q]).result
|
|
12
|
+
|
|
11
13
|
render layout: false
|
|
12
14
|
end
|
|
13
15
|
end
|
|
@@ -9,15 +9,20 @@ module Para
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def relation_path(controller_or_resource, options = {})
|
|
12
|
-
if Hash
|
|
12
|
+
if controller_or_resource.is_a?(Hash)
|
|
13
13
|
options = controller_or_resource
|
|
14
14
|
controller_or_resource = nil
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
components = [:admin, self, controller_or_resource].compact
|
|
18
|
+
|
|
18
19
|
find_path(components, options)
|
|
19
20
|
end
|
|
20
21
|
|
|
22
|
+
def page_container_class
|
|
23
|
+
'col-xs-12'
|
|
24
|
+
end
|
|
25
|
+
|
|
21
26
|
private
|
|
22
27
|
|
|
23
28
|
# Try to find a polymorphic path for the given arguments
|
|
@@ -28,7 +33,7 @@ module Para
|
|
|
28
33
|
#
|
|
29
34
|
def find_path(path, options)
|
|
30
35
|
safe_polymorphic_path(path, options).tap do |result|
|
|
31
|
-
raise result
|
|
36
|
+
raise result if result.is_a?(Exception)
|
|
32
37
|
end
|
|
33
38
|
end
|
|
34
39
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
class CallForProjectsVotesExporter < Para::Exporter::Xls
|
|
2
|
+
attr_reader :call_for_projects
|
|
3
|
+
|
|
4
|
+
def name
|
|
5
|
+
'votes-appel-projets'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
protected
|
|
9
|
+
|
|
10
|
+
def self.params_whitelist
|
|
11
|
+
[:call_for_projects_id]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def resources
|
|
15
|
+
resources = ActsAsVotable::Vote.joins(
|
|
16
|
+
"LEFT JOIN call_for_projects_applications " +
|
|
17
|
+
"ON call_for_projects_applications.id = votes.votable_id " +
|
|
18
|
+
"AND votes.votable_type = 'CallForProjectsApplication'"
|
|
19
|
+
).includes(:voter, votable: :call_for_projects)
|
|
20
|
+
|
|
21
|
+
# Filter if available
|
|
22
|
+
resources = resources.where(
|
|
23
|
+
call_for_projects_applications: {
|
|
24
|
+
call_for_projects_id: params[:call_for_projects_id]
|
|
25
|
+
}
|
|
26
|
+
) if params[:call_for_projects_id]
|
|
27
|
+
|
|
28
|
+
resources
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Defining the fields that you want to export will export all those fields
|
|
32
|
+
# directly to the XLS file
|
|
33
|
+
#
|
|
34
|
+
def headers
|
|
35
|
+
['Appel à projets', 'Projet', 'E-mail', 'Nom', 'Prénom', 'Date du vote']
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# If you need special behavior in the row generation (rendering associated
|
|
39
|
+
# models or other specific logic), you can return an array here that will
|
|
40
|
+
# be written to the XLS
|
|
41
|
+
#
|
|
42
|
+
# For safe XLS writing, use the #encode method on every string in the
|
|
43
|
+
# returned array.
|
|
44
|
+
#
|
|
45
|
+
# Example :
|
|
46
|
+
#
|
|
47
|
+
# fields = [...]
|
|
48
|
+
# fields.map!(&:encode)
|
|
49
|
+
#
|
|
50
|
+
def row_for(resource)
|
|
51
|
+
[
|
|
52
|
+
resource.votable.call_for_projects.title,
|
|
53
|
+
resource.votable.name,
|
|
54
|
+
resource.voter.email,
|
|
55
|
+
resource.voter.last_name,
|
|
56
|
+
resource.voter.first_name,
|
|
57
|
+
I18n.l(resource.created_at)
|
|
58
|
+
]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# If you need complete control over you XLS generation, use the following
|
|
62
|
+
# method instead of the #fields or #row_for methods, and return a valid XLS
|
|
63
|
+
# StringIO object.
|
|
64
|
+
#
|
|
65
|
+
# A `#generate_workbook` method is provided, which will yield the workbook to
|
|
66
|
+
# you so you can just fill it, and then returns a StringIO that can be
|
|
67
|
+
# directly written to the Excel file.
|
|
68
|
+
#
|
|
69
|
+
# Please check the [Spreadsheet](https://github.com/zdavatz/spreadsheet) gem
|
|
70
|
+
# documentation for more informations about how to build your Excel document.
|
|
71
|
+
#
|
|
72
|
+
# def generate
|
|
73
|
+
# generate_workbook do |workbook|
|
|
74
|
+
# sheet = workbook.create_worksheet
|
|
75
|
+
# sheet.row(0).concat ['data', 'row']
|
|
76
|
+
# sheet.row(1).concat ['other', 'row']
|
|
77
|
+
# end
|
|
78
|
+
# end
|
|
79
|
+
end
|
|
@@ -39,9 +39,8 @@ module Para
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def template_path_lookup(*paths)
|
|
42
|
-
paths.find
|
|
43
|
-
|
|
44
|
-
end
|
|
42
|
+
path = paths.find { |path| lookup_context.find_all(path).any? }
|
|
43
|
+
path&.gsub(/\/_([^\/]+)\z/, '/\1')
|
|
45
44
|
end
|
|
46
45
|
|
|
47
46
|
def resource_title_for(resource)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module Admin
|
|
3
|
+
module HistoryHelper
|
|
4
|
+
def history_for(component, action:, **options)
|
|
5
|
+
return unless component.history?
|
|
6
|
+
|
|
7
|
+
partial_path = find_partial_for(
|
|
8
|
+
(options[:resource] || options[:relation]),
|
|
9
|
+
"history/#{ action }"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
render partial: partial_path, locals: options
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -6,7 +6,15 @@ module Para
|
|
|
6
6
|
wrapper: :vertical_form,
|
|
7
7
|
wrapper_mappings: Para::SimpleFormConfig.wrapper_mappings,
|
|
8
8
|
track_attribute_mappings: true,
|
|
9
|
-
html: {
|
|
9
|
+
html: {
|
|
10
|
+
class: '',
|
|
11
|
+
data: { :'para-form' => true },
|
|
12
|
+
# Force multipart forms to allow forms with no file input on creation
|
|
13
|
+
# to fetch nested fields with image inputs through the remote nested
|
|
14
|
+
# form loading system. Without this option, rails does not create a
|
|
15
|
+
# multipart form when there is no file input during the form creation.
|
|
16
|
+
multipart: true
|
|
17
|
+
}
|
|
10
18
|
}
|
|
11
19
|
|
|
12
20
|
options = default_options.deep_merge(options)
|