udongo 5.8.0 → 5.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/backend/general.js +1 -0
- data/app/assets/javascripts/backend/tree.js +2 -2
- data/app/controllers/backend/forms/base_controller.rb +9 -0
- data/app/controllers/backend/forms/fields_controller.rb +63 -0
- data/app/controllers/backend/forms/submissions_controller.rb +23 -0
- data/app/controllers/backend/forms_controller.rb +58 -0
- data/app/decorators/form_decorator.rb +7 -0
- data/app/decorators/form_submission_data_decorator.rb +9 -0
- data/app/forms/backend/form_field_translation_form.rb +8 -0
- data/app/forms/backend/form_translation_form.rb +7 -0
- data/app/helpers/link_helper.rb +21 -11
- data/app/models/form.rb +10 -0
- data/app/models/form_field.rb +13 -0
- data/app/models/form_submission.rb +19 -0
- data/app/models/form_submission_data.rb +17 -0
- data/app/views/backend/articles/index.html.erb +1 -1
- data/app/views/backend/email_templates/index.html.erb +1 -1
- data/app/views/backend/forms/_fields.html.erb +42 -0
- data/app/views/backend/forms/_form.html.erb +24 -0
- data/app/views/backend/forms/_tabs.html.erb +29 -0
- data/app/views/backend/forms/edit.html.erb +5 -0
- data/app/views/backend/forms/edit_translation.html.erb +20 -0
- data/app/views/backend/forms/fields/_form.html.erb +34 -0
- data/app/views/backend/forms/fields/_tabs.html.erb +21 -0
- data/app/views/backend/forms/fields/edit.html.erb +6 -0
- data/app/views/backend/forms/fields/edit_translation.html.erb +25 -0
- data/app/views/backend/forms/fields/index.html.erb +44 -0
- data/app/views/backend/forms/fields/new.html.erb +5 -0
- data/app/views/backend/forms/index.html.erb +51 -0
- data/app/views/backend/forms/new.html.erb +4 -0
- data/app/views/backend/forms/submissions/_form.html.erb +0 -0
- data/app/views/backend/forms/submissions/index.html.erb +40 -0
- data/app/views/backend/forms/submissions/show.html.erb +20 -0
- data/app/views/backend/navigations/index.html.erb +2 -2
- data/app/views/backend/snippets/index.html.erb +3 -3
- data/app/views/layouts/backend/_top_navigation.html.erb +1 -0
- data/changelog.md +11 -0
- data/config/locales/en_backend.yml +25 -0
- data/config/locales/en_forms.yml +3 -0
- data/config/locales/nl_backend.yml +25 -0
- data/config/locales/nl_forms.yml +4 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20170407115044_readd_forms.rb +39 -0
- data/db/migrate/20170410115600_rename_name_to_identifier_for_form_field.rb +5 -0
- data/db/migrate/20170410120608_remove_placeholder_from_form_fields.rb +5 -0
- data/db/migrate/20170410121055_remove_default_value_from_form_fields.rb +5 -0
- data/db/migrate/20170411161008_add_validation_fields_to_form_fields.rb +6 -0
- data/lib/udongo/configs/forms.rb +18 -0
- data/lib/udongo/pages/tree_node.rb +1 -1
- data/lib/udongo/version.rb +1 -1
- data/spec/factories/form_fields.rb +7 -0
- data/spec/factories/form_submission_data.rb +7 -0
- data/spec/factories/form_submissions.rb +5 -0
- data/spec/factories/forms.rb +5 -0
- metadata +40 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ce4d4a15bc9ca2173d65611f6cfe39d92c8a2aa
|
4
|
+
data.tar.gz: 5545139075d1cac88213402b77c12d6d43f12137
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0724a9d61b1b0418ca16b73843b7688d48babe0c8147b4c4c6472712f280bfbfb79e73572f8617cc9aeea95b5d0694ebe03720427d112c503ade039455e2286a
|
7
|
+
data.tar.gz: 4940bb72cb0f5e2644e03f125a0dcbd6245e334d8c77040577d59cf3bc737d95c9921c9e9838a8a49f1002cf3e1e12f2c7f7a6e47d4b449a9d863617dea037aa
|
@@ -63,7 +63,7 @@ var tree = tree || {
|
|
63
63
|
|
64
64
|
contextmenu_remove_listener: function(obj) {
|
65
65
|
var instance = tree.vars.container.jstree(true);
|
66
|
-
var node = instance.get_node(obj.reference
|
66
|
+
var node = instance.get_node(obj.reference);
|
67
67
|
|
68
68
|
$.ajax({
|
69
69
|
data: { id: node.data.id },
|
@@ -80,7 +80,7 @@ var tree = tree || {
|
|
80
80
|
|
81
81
|
contextmenu_toggle_visibility_listener: function(obj) {
|
82
82
|
var instance = tree.vars.container.jstree(true);
|
83
|
-
var node = instance.get_node(obj.reference
|
83
|
+
var node = instance.get_node(obj.reference);
|
84
84
|
|
85
85
|
$.ajax({
|
86
86
|
data: { id: node.data.id },
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class Backend::Forms::FieldsController < Backend::Forms::BaseController
|
2
|
+
include Concerns::Backend::TranslatableController
|
3
|
+
include Concerns::Backend::PositionableController
|
4
|
+
include Concerns::PaginationController
|
5
|
+
|
6
|
+
before_action :find_model, only: [:edit, :update, :destroy]
|
7
|
+
before_action -> do
|
8
|
+
breadcrumb.add t('b.forms'), backend_forms_path
|
9
|
+
breadcrumb.add @form.description, edit_backend_form_path(@form)
|
10
|
+
end
|
11
|
+
|
12
|
+
def new
|
13
|
+
@field = @form.fields.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
@field = @form.fields.new(allowed_params)
|
18
|
+
|
19
|
+
if @field.save
|
20
|
+
redirect_to edit_translation_backend_form_field_path(@form, @field, locale),
|
21
|
+
notice: translate_notice(:added, :form_field)
|
22
|
+
else
|
23
|
+
render :new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def update
|
28
|
+
if @field.update_attributes allowed_params
|
29
|
+
redirect_to backend_form_fields_path(@form),
|
30
|
+
notice: translate_notice(:edited, :form_field)
|
31
|
+
else
|
32
|
+
render :edit
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def destroy
|
37
|
+
@field.destroy
|
38
|
+
redirect_to backend_form_fields_path(@form),
|
39
|
+
notice: translate_notice(:deleted, :form_field)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def allowed_params
|
45
|
+
params[:form_field].permit(:identifier, :field_type, :presence, :email)
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_model
|
49
|
+
@field ||= @form.fields.find(params[:id])
|
50
|
+
end
|
51
|
+
|
52
|
+
def translation_form
|
53
|
+
Backend::FormFieldTranslationForm.new(
|
54
|
+
@field,
|
55
|
+
@field.translation(params[:translation_locale])
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def translatable_path
|
60
|
+
method = "edit_translation_backend_#{model_name}_path"
|
61
|
+
@translatable_path || send(method, @form, @model, params[:translation_locale])
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Backend::Forms::SubmissionsController < Backend::Forms::BaseController
|
2
|
+
include Concerns::PaginationController
|
3
|
+
|
4
|
+
before_action :find_model, except: [:index]
|
5
|
+
before_action -> do
|
6
|
+
breadcrumb.add t('b.forms'), backend_forms_path
|
7
|
+
breadcrumb.add @form.description, edit_backend_form_path(@form)
|
8
|
+
end
|
9
|
+
|
10
|
+
def index
|
11
|
+
@submissions = paginate(@form.submissions)
|
12
|
+
end
|
13
|
+
|
14
|
+
def destroy
|
15
|
+
@model.destroy
|
16
|
+
redirect_to backend_forms_path,
|
17
|
+
notice: translate_notice(:deleted, :form_submission)
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_model
|
21
|
+
@model = FormSubmission.find(params[:id])
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class Backend::FormsController < Backend::BaseController
|
2
|
+
include Concerns::Backend::TranslatableController
|
3
|
+
|
4
|
+
before_action :find_model, only: [:edit, :update, :destroy]
|
5
|
+
before_action -> { breadcrumb.add t('b.forms'), backend_forms_path}
|
6
|
+
|
7
|
+
def index
|
8
|
+
@forms = Form.all
|
9
|
+
end
|
10
|
+
|
11
|
+
def new
|
12
|
+
@model = Form.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
@model = Form.new(allowed_params)
|
17
|
+
|
18
|
+
if @model.save
|
19
|
+
redirect_to backend_forms_path, notice: translate_notice(:added, :form)
|
20
|
+
else
|
21
|
+
render :new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def edit
|
26
|
+
@model = Form.find(params[:id])
|
27
|
+
end
|
28
|
+
|
29
|
+
def update
|
30
|
+
if @model.update_attributes allowed_params
|
31
|
+
redirect_to backend_forms_path, notice: translate_notice(:edited, :form)
|
32
|
+
else
|
33
|
+
render :edit
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def destroy
|
38
|
+
@model.destroy
|
39
|
+
redirect_to backend_forms_path, notice: translate_notice(:deleted, :form)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def allowed_params
|
45
|
+
params[:form].permit(:identifier, :description)
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_model
|
49
|
+
@model = Form.find(params[:id].to_i)
|
50
|
+
end
|
51
|
+
|
52
|
+
def translation_form
|
53
|
+
Backend::FormTranslationForm.new(
|
54
|
+
@model,
|
55
|
+
@model.translation(params[:translation_locale])
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
data/app/helpers/link_helper.rb
CHANGED
@@ -1,33 +1,43 @@
|
|
1
1
|
module LinkHelper
|
2
|
-
def link_to_show(
|
3
|
-
str = Udongo::ObjectPath.find(object)
|
4
|
-
|
2
|
+
def link_to_show(value)
|
5
3
|
link_to(
|
6
4
|
icon(:search),
|
7
|
-
|
5
|
+
path_from_string_or_object(value),
|
8
6
|
title: t('b.view')
|
9
7
|
)
|
10
8
|
end
|
11
9
|
|
12
|
-
def link_to_edit(
|
13
|
-
str = "edit_#{Udongo::ObjectPath.find(object)}"
|
14
|
-
|
10
|
+
def link_to_edit(value)
|
15
11
|
link_to(
|
16
12
|
icon(:pencil_square_o),
|
17
|
-
|
13
|
+
path_from_string_or_object(value, 'edit_'),
|
18
14
|
title: t('b.edit')
|
19
15
|
)
|
20
16
|
end
|
21
17
|
|
22
|
-
def
|
23
|
-
str = Udongo::ObjectPath.find(object)
|
18
|
+
def link_to_edit_translation(object, locale = Udongo.config.i18n.app.default_locale)
|
19
|
+
str = "edit_translation_#{Udongo::ObjectPath.find(object)}"
|
20
|
+
url = send(str, *Udongo::ObjectPath.remove_symbols(object), locale)
|
21
|
+
|
22
|
+
link_to_edit(url)
|
23
|
+
end
|
24
24
|
|
25
|
+
def link_to_delete(value)
|
25
26
|
link_to(
|
26
27
|
icon(:trash),
|
27
|
-
|
28
|
+
path_from_string_or_object(value),
|
28
29
|
method: :delete,
|
29
30
|
data: { confirm: t('b.msg.confirm') },
|
30
31
|
title: t('b.delete')
|
31
32
|
)
|
32
33
|
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def path_from_string_or_object(value, prefix = nil)
|
38
|
+
return value if value.is_a?(String)
|
39
|
+
|
40
|
+
str = "#{prefix}#{Udongo::ObjectPath.find(value)}"
|
41
|
+
send(str, *Udongo::ObjectPath.remove_symbols(value))
|
42
|
+
end
|
33
43
|
end
|
data/app/models/form.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
class Form < ApplicationRecord
|
2
|
+
include Concerns::Translatable
|
3
|
+
translatable_fields :success_message
|
4
|
+
|
5
|
+
has_many :fields, class_name: 'FormField', dependent: :destroy
|
6
|
+
has_many :submissions, class_name: 'FormSubmission', dependent: :destroy
|
7
|
+
has_many :data, through: :submissions
|
8
|
+
|
9
|
+
validates :description, presence: true
|
10
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class FormField < ApplicationRecord
|
2
|
+
include Concerns::Sortable
|
3
|
+
sortable scope: [:form_id]
|
4
|
+
|
5
|
+
include Concerns::Translatable
|
6
|
+
translatable_fields :label, :default_value
|
7
|
+
|
8
|
+
belongs_to :form
|
9
|
+
|
10
|
+
validates :form, :identifier, :field_type, presence: true
|
11
|
+
|
12
|
+
validates_uniqueness_of :identifier, scope: :form_id
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class FormSubmission < ApplicationRecord
|
2
|
+
include Concerns::Emailable
|
3
|
+
include Concerns::Searchable
|
4
|
+
|
5
|
+
# TODO: Make this searchable by adding the key/value columns on data
|
6
|
+
# as accessible attributes on FormSubmission.
|
7
|
+
|
8
|
+
belongs_to :form
|
9
|
+
has_many :data, class_name: 'FormSubmissionData'
|
10
|
+
|
11
|
+
validates :form, presence: true
|
12
|
+
|
13
|
+
def data_object
|
14
|
+
data.inject(OpenStruct.new) do |stack, d|
|
15
|
+
stack.send("#{d.name}=", d.value)
|
16
|
+
stack
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class FormSubmissionData < ApplicationRecord
|
2
|
+
# By saving the form submission data as a search index, you work around
|
3
|
+
# possible slow searches for the form submissions.
|
4
|
+
after_save do
|
5
|
+
next if value.blank?
|
6
|
+
index = form_submission.search_indices.find_or_initialize_by(
|
7
|
+
locale: Udongo.config.i18n.app.default_locale,
|
8
|
+
name: name
|
9
|
+
)
|
10
|
+
index.value = value
|
11
|
+
index.save!
|
12
|
+
end
|
13
|
+
|
14
|
+
belongs_to :form_submission
|
15
|
+
|
16
|
+
validates :form_submission, presence: true
|
17
|
+
end
|
@@ -15,7 +15,7 @@
|
|
15
15
|
<tr data-update-position="<%= update_position_backend_email_template_path(s) %>">
|
16
16
|
<td><%= s.description %></td>
|
17
17
|
<td class="text-xs-right">
|
18
|
-
<%=
|
18
|
+
<%= link_to_edit_translation [:backend, s] %>
|
19
19
|
</td>
|
20
20
|
</tr>
|
21
21
|
<% end %>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<% javascript 'backend/sortable' %>
|
2
|
+
|
3
|
+
<div id="form-fields" class="card">
|
4
|
+
<div class="card-header">
|
5
|
+
<%= t 'b.msg.form_fields.index_header_html', form: form.description %>
|
6
|
+
<% if form.fields.any? %>
|
7
|
+
<div class="pull-right">
|
8
|
+
<%= link_to icon(:plus, t('b.msg.form_fields.add')), new_backend_form_field_path(form), class: 'btn btn-primary btn-sm' %>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div class="card-block">
|
14
|
+
<% if form.fields.any? %>
|
15
|
+
<table class="table table-hover">
|
16
|
+
<thead>
|
17
|
+
<tr>
|
18
|
+
<th><%= t('b.name') %></th>
|
19
|
+
<th> </th>
|
20
|
+
</tr>
|
21
|
+
</thead>
|
22
|
+
|
23
|
+
<tbody>
|
24
|
+
<% form.fields.each do |f| %>
|
25
|
+
<tr data-update-position="<%= update_position_backend_form_field_path(form, f) %>">
|
26
|
+
<td><%= f.identifier %></td>
|
27
|
+
<td class="text-xs-right">
|
28
|
+
<%= link_to icon(:pencil_square_o), edit_backend_form_field_path(form, f) %>
|
29
|
+
<%= link_to icon(:trash), backend_form_field_path(form, f), method: :delete, data: { confirm: t('b.msg.confirm') }, title: t('b.delete') %>
|
30
|
+
</td>
|
31
|
+
</tr>
|
32
|
+
<% end %>
|
33
|
+
</tbody>
|
34
|
+
</table>
|
35
|
+
<% else %>
|
36
|
+
<p>
|
37
|
+
<%= t('b.msg.form_fields.explanation') %>
|
38
|
+
<%= link_to t('b.msg.form_fields.add_first'), new_backend_form_field_path(form) %>.
|
39
|
+
</p>
|
40
|
+
<% end %>
|
41
|
+
</div>
|
42
|
+
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%= render 'backend/general_form_error', object: @model %>
|
2
|
+
|
3
|
+
<%= simple_form_for [:backend, @model] do |f| %>
|
4
|
+
<div class="row">
|
5
|
+
<div class="col-md-12">
|
6
|
+
<div class="card">
|
7
|
+
<div class="card-header">
|
8
|
+
<%= t 'b.general' %>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div class="card-block">
|
12
|
+
<%= f.input :description, as: :string %>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<% unless @model.new_record? %>
|
19
|
+
<%# TODO: rendered form preview instead of formfields datagrid %>
|
20
|
+
<%# render 'backend/forms/fields', form: @model %>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<%= render 'backend/form_actions', cancel_url: backend_forms_path %>
|
24
|
+
<% end %>
|