symphonia 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +674 -0
  3. data/README.md +16 -0
  4. data/Rakefile +44 -0
  5. data/app/assets/images/bg-checker.png +0 -0
  6. data/app/assets/images/bullet.gif +0 -0
  7. data/app/assets/images/close.png +0 -0
  8. data/app/assets/images/loading.gif +0 -0
  9. data/app/assets/images/next.png +0 -0
  10. data/app/assets/images/prev.png +0 -0
  11. data/app/assets/javascripts/ckeditor/plugins/autogrow/plugin.js +232 -0
  12. data/app/assets/javascripts/ckeditor/plugins/autogrow/samples/autogrow.html +102 -0
  13. data/app/assets/javascripts/ckeditor/plugins/image_chooser/icons/addimage.png +0 -0
  14. data/app/assets/javascripts/ckeditor/plugins/image_chooser/plugin.js +15 -0
  15. data/app/assets/javascripts/symphonia/Sortable.js +1249 -0
  16. data/app/assets/javascripts/symphonia/_core.js +45 -0
  17. data/app/assets/javascripts/symphonia/application.js.erb +147 -0
  18. data/app/assets/javascripts/symphonia/filters.js +44 -0
  19. data/app/assets/javascripts/symphonia/symphonia_bootstrap_dialog.js +136 -0
  20. data/app/assets/javascripts/symphonia/symphonia_ckeditor.js +55 -0
  21. data/app/assets/stylesheets/symphonia/application.css +4 -0
  22. data/app/assets/stylesheets/symphonia/basic.scss +218 -0
  23. data/app/assets/stylesheets/symphonia/filters.scss +19 -0
  24. data/app/assets/stylesheets/symphonia/symphonia_bootstrap.scss +56 -0
  25. data/app/channels/application_cable/channel.rb +5 -0
  26. data/app/controllers/symphonia/accounts_controller.rb +169 -0
  27. data/app/controllers/symphonia/admin_controller.rb +22 -0
  28. data/app/controllers/symphonia/api_controller.rb +64 -0
  29. data/app/controllers/symphonia/application_controller.rb +8 -0
  30. data/app/controllers/symphonia/attachments_controller.rb +37 -0
  31. data/app/controllers/symphonia/filters_controller.rb +23 -0
  32. data/app/controllers/symphonia/images_controller.rb +16 -0
  33. data/app/controllers/symphonia/login_controller.rb +80 -0
  34. data/app/controllers/symphonia/roles_controller.rb +100 -0
  35. data/app/controllers/symphonia/user_sessions_controller.rb +16 -0
  36. data/app/controllers/symphonia/users_controller.rb +168 -0
  37. data/app/helpers/symphonia/application_helper.rb +422 -0
  38. data/app/helpers/symphonia/bootstrap_modal_helper.rb +59 -0
  39. data/app/helpers/symphonia/form_helper.rb +50 -0
  40. data/app/helpers/symphonia/renderer_helper.rb +85 -0
  41. data/app/mailers/symphonia/application_mailer.rb +6 -0
  42. data/app/mailers/symphonia/notifier.rb +42 -0
  43. data/app/models/symphonia/admin_module.rb +18 -0
  44. data/app/models/symphonia/application_record.rb +14 -0
  45. data/app/models/symphonia/attachment.rb +16 -0
  46. data/app/models/symphonia/common_file.rb +9 -0
  47. data/app/models/symphonia/email_preference.rb +5 -0
  48. data/app/models/symphonia/image.rb +46 -0
  49. data/app/models/symphonia/preference.rb +12 -0
  50. data/app/models/symphonia/role.rb +55 -0
  51. data/app/models/symphonia/swagger/error_model.rb +19 -0
  52. data/app/models/symphonia/swagger/responses.rb +27 -0
  53. data/app/models/symphonia/user.rb +141 -0
  54. data/app/models/symphonia/user_session.rb +19 -0
  55. data/app/views/common/403.html.erb +5 -0
  56. data/app/views/common/404.html.erb +2 -0
  57. data/app/views/layouts/symphonia/_modal.html.erb +19 -0
  58. data/app/views/layouts/symphonia/_query.html.erb +51 -0
  59. data/app/views/layouts/symphonia/application.html.erb +45 -0
  60. data/app/views/layouts/symphonia/application.pdf.erb +15 -0
  61. data/app/views/layouts/symphonia/mailer.html.erb +13 -0
  62. data/app/views/symphonia/accounts/_detail.html.erb +65 -0
  63. data/app/views/symphonia/accounts/_form.html.erb +14 -0
  64. data/app/views/symphonia/accounts/edit.html.erb +9 -0
  65. data/app/views/symphonia/accounts/edit.js.erb +5 -0
  66. data/app/views/symphonia/accounts/lost_password.html.erb +6 -0
  67. data/app/views/symphonia/accounts/lost_password.js.erb +3 -0
  68. data/app/views/symphonia/accounts/new_activation.html.erb +11 -0
  69. data/app/views/symphonia/accounts/new_activation.js.erb +6 -0
  70. data/app/views/symphonia/accounts/register.html.erb +20 -0
  71. data/app/views/symphonia/accounts/reset_password.html.erb +18 -0
  72. data/app/views/symphonia/accounts/update.js.erb +1 -0
  73. data/app/views/symphonia/admin/index.html.erb +15 -0
  74. data/app/views/symphonia/attachments/destroy.js.erb +1 -0
  75. data/app/views/symphonia/common/_editable_images_grid.html.erb +12 -0
  76. data/app/views/symphonia/common/_filters.html.erb +23 -0
  77. data/app/views/symphonia/common/_locale_chooser.html.erb +16 -0
  78. data/app/views/symphonia/common/_share_links.html.erb +5 -0
  79. data/app/views/symphonia/filters/options.html.erb +36 -0
  80. data/app/views/symphonia/filters/options.js.erb +9 -0
  81. data/app/views/symphonia/filters/table.html.erb +21 -0
  82. data/app/views/symphonia/login/_form.html.erb +19 -0
  83. data/app/views/symphonia/login/new.html.erb +11 -0
  84. data/app/views/symphonia/login_sessions/new.html.erb +1 -0
  85. data/app/views/symphonia/notifier/activation_user.html.erb +7 -0
  86. data/app/views/symphonia/notifier/activation_user.text.erb +3 -0
  87. data/app/views/symphonia/notifier/reset_password_user.html.erb +7 -0
  88. data/app/views/symphonia/notifier/reset_password_user.text.erb +3 -0
  89. data/app/views/symphonia/notifier/test_mail.html.erb +2 -0
  90. data/app/views/symphonia/notifier/test_mail.text.erb +3 -0
  91. data/app/views/symphonia/notifier/user_change_to_active.html.erb +3 -0
  92. data/app/views/symphonia/notifier/user_change_to_active.text.erb +1 -0
  93. data/app/views/symphonia/notifier/user_registered.html.erb +13 -0
  94. data/app/views/symphonia/notifier/user_registered.text.erb +8 -0
  95. data/app/views/symphonia/roles/_form.html.erb +30 -0
  96. data/app/views/symphonia/roles/edit.html.erb +5 -0
  97. data/app/views/symphonia/roles/index.html.erb +6 -0
  98. data/app/views/symphonia/roles/new.html.erb +4 -0
  99. data/app/views/symphonia/roles/show.html.erb +5 -0
  100. data/app/views/symphonia/users/_form.html.erb +13 -0
  101. data/app/views/symphonia/users/edit.html.erb +26 -0
  102. data/app/views/symphonia/users/edit.js.erb +3 -0
  103. data/app/views/symphonia/users/edit_current.html.erb +7 -0
  104. data/app/views/symphonia/users/index.html.erb +5 -0
  105. data/app/views/symphonia/users/new.html.erb +8 -0
  106. data/app/views/symphonia/users/show.html.erb +63 -0
  107. data/config/locales/cs.yml +233 -0
  108. data/config/locales/en.yml +47 -0
  109. data/config/routes.rb +52 -0
  110. data/db/migrate/20130714140500_create_users.rb +49 -0
  111. data/db/migrate/20130714140501_create_roles.rb +16 -0
  112. data/db/migrate/20130714140502_create_preferences.rb +26 -0
  113. data/db/migrate/20130828175114_create_attachments.rb +20 -0
  114. data/db/migrate/20141213204351_create_admin_modules.rb +20 -0
  115. data/db/seeds.rb +12 -0
  116. data/lib/generators/symphonia/entity_controller/entity_controller_generator.rb +48 -0
  117. data/lib/generators/symphonia/entity_controller/templates/controller.rb +100 -0
  118. data/lib/generators/symphonia/query/query_generator.rb +37 -0
  119. data/lib/generators/symphonia/setup/setup_generator.rb +52 -0
  120. data/lib/generators/symphonia/setup/templates/404.html +26 -0
  121. data/lib/generators/symphonia/setup/templates/500.html +37 -0
  122. data/lib/generators/symphonia/setup/templates/Gemfile +18 -0
  123. data/lib/generators/symphonia/setup/templates/base_layout.html.erb +46 -0
  124. data/lib/generators/symphonia/setup/templates/design.scss +4 -0
  125. data/lib/generators/symphonia/setup/templates/settings.rb +65 -0
  126. data/lib/generators/symphonia/setup/templates/spec_helper.rb +18 -0
  127. data/lib/symphonia/action_cable/connection.rb +31 -0
  128. data/lib/symphonia/admin_constraint.rb +9 -0
  129. data/lib/symphonia/attachable.rb +35 -0
  130. data/lib/symphonia/base_controller.rb +96 -0
  131. data/lib/symphonia/bootstrap_link_render.rb +69 -0
  132. data/lib/symphonia/controller_extensions.rb +200 -0
  133. data/lib/symphonia/engine.rb +137 -0
  134. data/lib/symphonia/form_builder.rb +137 -0
  135. data/lib/symphonia/menu_manager.rb +23 -0
  136. data/lib/symphonia/model_attributes/attribute.rb +137 -0
  137. data/lib/symphonia/model_attributes.rb +102 -0
  138. data/lib/symphonia/model_filters/base.rb +82 -0
  139. data/lib/symphonia/model_filters/boolean_filter.rb +26 -0
  140. data/lib/symphonia/model_filters/date_filter.rb +81 -0
  141. data/lib/symphonia/model_filters/integer_filter.rb +18 -0
  142. data/lib/symphonia/model_filters/select_filter.rb +48 -0
  143. data/lib/symphonia/model_filters/string_filter.rb +18 -0
  144. data/lib/symphonia/model_filters.rb +10 -0
  145. data/lib/symphonia/object.rb +31 -0
  146. data/lib/symphonia/permissions.rb +93 -0
  147. data/lib/symphonia/query.rb +275 -0
  148. data/lib/symphonia/query_columns/attribute_column.rb +43 -0
  149. data/lib/symphonia/query_columns/generic_column.rb +165 -0
  150. data/lib/symphonia/query_columns.rb +8 -0
  151. data/lib/symphonia/spec_helper.rb +4 -0
  152. data/lib/symphonia/user_management.rb +58 -0
  153. data/lib/symphonia/version.rb +4 -0
  154. data/lib/symphonia.rb +20 -0
  155. data/spec/controllers/account_controller_spec.rb +90 -0
  156. data/spec/controllers/admin_controller_spec.rb +35 -0
  157. data/spec/controllers/api_controller_spec.rb +9 -0
  158. data/spec/controllers/filters_controller_spec.rb +35 -0
  159. data/spec/controllers/images_controller_spec.rb +5 -0
  160. data/spec/controllers/login_controller_spec.rb +20 -0
  161. data/spec/controllers/roles_controller_spec.rb +12 -0
  162. data/spec/controllers/users_controller_spec.rb +47 -0
  163. data/spec/factories/factories.rb +52 -0
  164. data/spec/helpers/symphonia/application_helper_spec.rb +62 -0
  165. data/spec/mailers/previews/symphonia/notifier_preview.rb +27 -0
  166. data/spec/mailers/symphonia/notifier_spec.rb +76 -0
  167. data/spec/models/attachment_spec.rb +22 -0
  168. data/spec/models/query/attribute_spec.rb +8 -0
  169. data/spec/models/query/symphonia_query_spec.rb +70 -0
  170. data/spec/models/role_spec.rb +13 -0
  171. data/spec/models/user_spec.rb +10 -0
  172. data/spec/rails_helper.rb +13 -0
  173. data/spec/requests/accounts_spec.rb +118 -0
  174. data/spec/requests/attachments_controller_spec.rb +23 -0
  175. data/spec/requests/login_spec.rb +26 -0
  176. data/spec/requests/roles_spec.rb +10 -0
  177. data/spec/requests/users_spec.rb +50 -0
  178. data/spec/spec_helper.rb +101 -0
  179. data/spec/support/common_file.txt +2 -0
  180. data/spec/support/query.rb +36 -0
  181. data/spec/support/shared.rb +62 -0
  182. data/spec/support/shared_controllers.rb +31 -0
  183. data/spec/support/stub_users.rb +32 -0
  184. data/spec/support/symphonia.jpg +0 -0
  185. data/spec/support/wait_for_ajax.rb +15 -0
  186. data/spec/version_spec.rb +5 -0
  187. data/spec/views/filters/options.html.erb_spec.rb +14 -0
  188. metadata +697 -0
@@ -0,0 +1,100 @@
1
+ <% if namespaced? -%>
2
+ require_dependency "<%= namespaced_path %>/application_controller"
3
+
4
+ <% end -%>
5
+ <% module_namespacing do -%>
6
+ class <%= controller_class_name %>Controller < ApplicationController
7
+
8
+ before_action :authorize
9
+ before_action :set_<%= singular_table_name %>, only: [:show, :edit, :update, :destroy]
10
+
11
+ def index
12
+ @query = <%= class_name %>.query.new(self)
13
+ @entities = @query.entities
14
+ respond_to do |format|
15
+ format.html do
16
+ @entities = @entities.page(params[:page])
17
+ render layout: !request.xhr?
18
+ end
19
+ format.json { render json: @entities.all, only: %i(id)+<%= class_name %>.registered_attributes.keys }
20
+ format.xml { render xml: @entities.all, only: %i(id)+<%= class_name %>.registered_attributes.keys }
21
+ end
22
+ end
23
+
24
+ def show
25
+ respond_to do |format|
26
+ format.html
27
+ format.json { render json: @<%= singular_table_name %> }
28
+ format.xml { render xml: @<%= singular_table_name %> }
29
+ end
30
+ end
31
+
32
+ def new
33
+ @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
34
+ respond_to do |format|
35
+ format.html
36
+ format.js
37
+ end
38
+ end
39
+
40
+ def edit
41
+ respond_to do |format|
42
+ format.html
43
+ format.js
44
+ end
45
+ end
46
+
47
+ def create
48
+ @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
49
+ respond_to do |format|
50
+ if @<%= orm_instance.save %>
51
+ format.html { redirect_to @<%= singular_table_name %>, notice: t(:text_created) }
52
+ format.json { render json: @<%= singular_table_name %>, status: :created, location: @<%= singular_table_name %> }
53
+ format.xml { render xml: @<%= singular_table_name %>, status: :created, location: @<%= singular_table_name %> }
54
+ else
55
+ format.html { render :new }
56
+ format.json { render json: @<%= singular_table_name %>.errors, status: :unprocessable_entity }
57
+ format.xml { render xml: @<%= singular_table_name %>.errors, status: :unprocessable_entity }
58
+ end
59
+ end
60
+ end
61
+
62
+ def update
63
+ respond_to do |format|
64
+ if @<%= orm_instance.update("#{singular_table_name}_params") %>
65
+ format.html { render(:edit, notice: t(:text_updated)) }
66
+ format.any(:json, :xml) { head(:no_content) }
67
+ else
68
+ format.html { render(:edit) }
69
+ format.json { render(json: @<%= singular_table_name %>.errors, status: :unprocessable_entity) }
70
+ end
71
+ end
72
+ end
73
+
74
+ def destroy
75
+ @<%= orm_instance.destroy %>
76
+
77
+ respond_to do |format|
78
+ format.html { redirect_back_or_default <%= index_helper %>_path, notice: t(:text_destroyed) }
79
+ format.js { render js: "Symphonia.filters.removeRow('#{view_context.dom_id(@<%= singular_table_name %>)}')"}
80
+ format.any(:json, :xml) { head :no_content }
81
+ end
82
+ end
83
+
84
+ private
85
+ # Use callbacks to share common setup or constraints between actions.
86
+ def set_<%= singular_table_name %>
87
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
88
+ end
89
+
90
+ # Only allow a trusted parameter "white list" through.
91
+ def <%= "#{singular_table_name}_params" %>
92
+ <%- if attributes_names.empty? -%>
93
+ params.fetch(:<%= singular_table_name %>, {})
94
+ <%- else -%>
95
+ allowed = [<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>]
96
+ params.require(:<%= singular_table_name %>).permit(allowed)
97
+ <%- end -%>
98
+ end
99
+ end
100
+ <% end -%>
@@ -0,0 +1,37 @@
1
+ #encoding: utf-8
2
+ require 'rails/generators'
3
+ module Symphonia
4
+ class QueryGenerator < Rails::Generators::Base
5
+ # include Rails::Generators::Migration
6
+ #
7
+ # USAGE: rails g symphonia:query name_of_query
8
+ #
9
+
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ argument :name, :type => :string
13
+ desc 'Create symphonia query for model [NAME]'
14
+ def create_symphonia_query_file
15
+ create_file "app/models/symphonia_queries/#{name.pluralize}_query.rb", <<-FILE
16
+ module SymphoniaQueries
17
+ class #{name.classify.pluralize}Query < SymphoniaQuery
18
+
19
+ def register_filters
20
+ # register_filter('string', :attribute)
21
+ # register_filter('select', :attribute) do |f|
22
+ # f.available_values = Proc.new{[1, 'a']}
23
+ # end
24
+
25
+ end
26
+
27
+ def model
28
+ #{name.classify}
29
+ end
30
+
31
+ end
32
+ end
33
+ FILE
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,52 @@
1
+ #encoding: utf-8
2
+ require 'rails/generators'
3
+ module Symphonia
4
+ class SetupGenerator < Rails::Generators::Base
5
+ # include Rails::Generators::Migration
6
+
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def create_settings
10
+ copy_file 'settings.rb', 'config/initializers/settings.rb'
11
+ end
12
+
13
+ def copy_static
14
+ copy_file '404.html', 'public/404.html'
15
+ copy_file '500.html', 'public/500.html'
16
+ end
17
+
18
+ def copy_assets
19
+ append_to_file 'app/assets/javascripts/application.js', '//= require symphonia/application'
20
+ copy_file 'design.scss', 'app/assets/stylesheets/general.scss'
21
+ end
22
+
23
+ def copy_rspec
24
+ copy_file 'spec_helper.rb', 'spec/spec_helper.rb'
25
+
26
+ create_file '.rspec' do
27
+ '--require spec_helper'
28
+ '--format documentation'
29
+ end
30
+ end
31
+
32
+ def copy_setup_file
33
+
34
+ copy_file 'base_layout.html.erb', 'app/views/layouts/application.html.erb'
35
+
36
+ append_to_file 'db/seeds.rb', 'Symphonia::Engine.load_seed'
37
+ append_to_file '.gitignore', 'public/system'
38
+
39
+ inject_into_file 'config/routes.rb', after: "Rails.application.routes.draw do\n" do
40
+ " mount Symphonia::Engine => '/'"
41
+ end
42
+
43
+ end
44
+
45
+ def setup_gemfile
46
+ append_to_file 'Gemfile' do
47
+ File.read(File.join(File.dirname(__FILE__), 'templates/Gemfile'))
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>404 STránka nenalezena</title>
7
+ <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
8
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />
9
+ </head>
10
+
11
+ <body>
12
+ <!-- This file lives in public/500.html -->
13
+ <br />
14
+ <div class="rows">
15
+ <p class="col-sm-6 col-md-3">
16
+ <i class="fa fa-times-circle-o" id="internal_static_page_sign" style="font-size: 20em"></i>
17
+ </p>
18
+ <div class="col-sm-6 col-md-9">
19
+ <h1>404 Stránka nenalezena</h1>
20
+ <p>
21
+ Požadovaná stránka nebyla nalezena. Možná je smazaná nebo přesunutá.
22
+ </p>
23
+ </div>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,37 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>500 INTERNAL SERVER ERROR</title>
7
+ <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
8
+ <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />
9
+ </head>
10
+
11
+ <body>
12
+ <!-- This file lives in public/500.html -->
13
+ <br />
14
+ <div class="rows">
15
+ <p class="col-sm-6 col-md-3">
16
+ <i class="fa fa-exclamation-triangle fa-5x" id="internal_static_page_sign" style="font-size: 20em"></i>
17
+ </p>
18
+ <div class="col-sm-6 col-md-9">
19
+ <h1>500 Internal server error</h1>
20
+ <p>
21
+ Při zpracování požadavku došlo k vnitřní chybě serveru. Kontaktujte prosím administrátora.
22
+ </p>
23
+ <ul class="fa-ul">
24
+ <li>
25
+ <h3>Lukáš Pokorný</h3>
26
+ </li>
27
+ <li>
28
+ <i class="fa fa-li fa fa-envelope"></i>e-mail: <a href="mailto:admin@lagrace.cz">admin@lagrace.cz</a>
29
+ </li>
30
+ <li>
31
+ <i class="fa fa-li fa fa-mobile-phone"></i>tel: 604484983
32
+ </li>
33
+ </ul>
34
+ </div>
35
+ </div>
36
+ </body>
37
+ </html>
@@ -0,0 +1,18 @@
1
+ group :development, :test do
2
+ # Adds support for Capybara system testing and selenium driver
3
+
4
+ # gem 'capybara', '~> 2.13'
5
+ # gem 'selenium-webdriver'
6
+ gem 'rspec-rails', '~>3.6'
7
+ gem 'factory_bot_rails', '~> 4.8.2'
8
+ gem 'database_cleaner'
9
+ gem 'faker', '~> 1.8.4'
10
+ gem 'sqlite3'
11
+
12
+ gem 'pry-rails'
13
+ end
14
+
15
+ # gem 'bootswatch-rails'
16
+ # gem 'jquery-colorbox-rails'
17
+ # gem 'recaptacha'
18
+ # gem 'ckeditor-rails'
@@ -0,0 +1,46 @@
1
+ <!DOCTYPE html>
2
+ <html lang="<%= I18n.locale %>">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title><%= html_title %></title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <%= yield :meta_tags %>
8
+ <%= stylesheet_link_tag 'application', :media => 'all', 'data-turbolinks-track' => true %>
9
+ <%= yield :stylesheet_tags %>
10
+ <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
11
+ <%= yield :javascript_tags %>
12
+ <%= csrf_meta_tags %>
13
+ </head>
14
+ <body class="controller-<%= controller_name %> action-<%= action_name %>" data-menu-item="<%= @menu_item.to_sym %>">
15
+ <header data-turbolinks-permanent>
16
+ <nav class="navbar navbar-expand-lg navbar-light bg-light">
17
+ <!--<a class="navbar-brand" href="#">Navbar</a>-->
18
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
19
+ <%= fa_icon('bars') %>
20
+ </button>
21
+
22
+ <div class="collapse navbar-collapse" id="navbarSupportedContent">
23
+
24
+ <%= render_menu(:top_menu, { container_class: 'navbar-left' }) %>
25
+ <%= render_menu(:top_menu_account, { container_class: 'navbar-right' }) %>
26
+ </div>
27
+ </nav>
28
+ </header>
29
+
30
+ <section id="wrapper">
31
+
32
+ <div id="flash_messages"><%= render_flash_messages.html_safe -%></div>
33
+ <section id="main" class="container">
34
+ <%= yield %>
35
+ </section>
36
+ </section>
37
+ <footer>
38
+ <div class="container">
39
+ &copy; Lukáš Pokorný
40
+ <%= yield :footer %>
41
+ </div>
42
+ </footer>
43
+
44
+ <div id="ajax-indicator" style="display:none"><i class="fa fa-spinner fa-spin fa-large"></i></div>
45
+ </body>
46
+ </html>
@@ -0,0 +1,4 @@
1
+ //@import 'bootswatch/slate/variables'; // only when gem 'bootswatch' is used
2
+ @import 'symphonia/application';
3
+ @import 'symphonia/basic';
4
+ @import 'symphonia/symphonia_bootstrap';
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ # Recaptcha.configure do |config|
4
+ # config.site_key = '6LejxOESAAAAALC3ohQCddKilokhYnTNXfYVItZe'
5
+ # config.secret_key = '6LejxOESAAAAANf-9T4nyHCDGW6Ok78Zo7GaG2GK'
6
+ # end
7
+
8
+ WillPaginate.per_page = 20
9
+ # Rails.application.config.i18n.available_locales = %i[en cs ru pl]
10
+
11
+ Symphonia.configure do |config|
12
+ config.after_login_path = ->(h) { h.symphonia.user_current_path }
13
+ config.allow_registrations = false
14
+ config.default_locale = :cs
15
+ end
16
+
17
+
18
+ Symphonia::MenuManager.map :top_menu do |m|
19
+ m[:home] = {
20
+ label: :label_home,
21
+ icon: 'fa fa-home',
22
+ url: '/',
23
+ data: { turbolinks: false }
24
+ }
25
+ m[:users] = {
26
+ label: :label_users,
27
+ icon: 'fa fa-user',
28
+ url: ->(h) { h.symphonia.users_path },
29
+ if: proc { Symphonia::User.current.admin? }
30
+ }
31
+ m[:roles] = {
32
+ label: :label_roles,
33
+ icon: 'fa fa-key',
34
+ url: ->(h) { h.symphonia.roles_path },
35
+ if: proc { Symphonia::User.current.admin? }
36
+ }
37
+
38
+ end
39
+ Symphonia::MenuManager.map :top_menu_account do |m|
40
+ # -----
41
+ m[:my_account] = {
42
+ label: :label_my_account,
43
+ icon: 'fa fa-wrench',
44
+ url: ->(h) { h.symphonia.account_path },
45
+ if: proc { Symphonia::User.current.logged_in? }
46
+ }
47
+ m[:logout] = {
48
+ label: :button_logout,
49
+ icon: 'fa fa-sign-out',
50
+ url: ->(h) { h.symphonia.logout_path },
51
+ method: 'delete',
52
+ if: proc { Symphonia::User.current.logged_in? }
53
+ }
54
+ m[:login] = {
55
+ label: :button_login,
56
+ icon: 'fa fa-signin',
57
+ url: ->(h) { h.symphonia.login_path },
58
+ if: proc { !Symphonia::User.current.logged_in? }
59
+ }
60
+ end
61
+
62
+ Symphonia::Permissions.map do |m|
63
+ # m.register(:name).add(:controller, [:actions])
64
+ # m.update(:name).add(:controller, [:more_actions])
65
+ end
@@ -0,0 +1,18 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+ require File.expand_path('../../config/environment', __FILE__)
3
+ # Prevent database truncation if the environment is production
4
+ abort('The Rails environment is running in production mode!') if Rails.env.production?
5
+
6
+ # require 'symphonia'
7
+ RSpec.configure do |config|
8
+ Dir.glob(File.join(__dir__, 'support', '*.rb')).each { |f| require f }
9
+
10
+ require 'symphonia/spec_helper'
11
+
12
+ # Load AuthLogic
13
+ require 'authlogic/test_case'
14
+ config.include Authlogic::TestCase
15
+
16
+ config.infer_spec_type_from_file_location!
17
+ config.filter_rails_from_backtrace!
18
+ end
@@ -0,0 +1,31 @@
1
+ module Symphonia
2
+ module ActionCable
3
+ module Connection
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ identified_by :current_user
9
+
10
+ def connect
11
+ self.current_user = find_verified_user_or_guest
12
+ logger.add_tags 'ActionCable', self.current_user.login unless self.current_user.nil?
13
+ end
14
+
15
+ protected
16
+
17
+ def find_verified_user_or_guest
18
+ if (credentials = request.cookie_jar['symphonia/user_credentials']).present?
19
+ ::Symphonia::User.find_by_persistence_token(credentials.split(':')[0])
20
+ else
21
+ nil
22
+ end
23
+ end
24
+ end
25
+
26
+ module ClassMethods
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+ module Symphonia
2
+ class AdminConstraint
3
+ def matches?(request)
4
+ return false unless (credentials = request.cookie_jar['symphonia/user_credentials']).present?
5
+ user = User.find_by_persistence_token(credentials.split(':')[0])
6
+ user&.admin?
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,35 @@
1
+ module Symphonia
2
+ module Attachable
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ has_many :images, -> { order(:position) }, as: :attachable, dependent: :destroy, validate: false, class_name: 'Symphonia::Image'
8
+ has_many :common_files, -> { order(:position) }, as: :attachable, dependent: :destroy, class_name: 'Symphonia::CommonFile'
9
+
10
+ # validate do |container|
11
+ # container.images.each do |img|
12
+ # next if img.valid?
13
+ # img.errors.full_messages.each do |msg|
14
+ # errors.add(:base, "#{img.name}: #{msg}")
15
+ # end
16
+ # end
17
+ # end
18
+
19
+ def image_attachments=(form_images=[])
20
+ form_images.each do |attribute|
21
+ self.images.build(attachment: attribute)
22
+ end
23
+ end
24
+
25
+ def file_attachments=(form_files=[])
26
+ form_files.each do |attribute|
27
+ self.common_files.build(attachment: attribute)
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,96 @@
1
+ module Symphonia
2
+ module BaseController
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ # before_action :authorize
7
+ before_action :find_entity, only: [:show, :edit, :update, :destroy]
8
+
9
+ include Rails::Pagination
10
+ helper Symphonia::RendererHelper
11
+
12
+ end
13
+
14
+ def index
15
+ @query ||= model.query.new
16
+ @query.from_params params
17
+ @entities = @query.entities
18
+ respond_to do |format|
19
+ format.html do
20
+ @entities = paginate(@entities)
21
+ render layout: !request.xhr?
22
+ end
23
+ format.json do
24
+ paginate(json: @entities)
25
+ end
26
+ end
27
+ end
28
+
29
+ def show
30
+ respond_to do |format|
31
+ format.html
32
+ format.json { render json: @entity }
33
+ end
34
+ end
35
+
36
+ def new
37
+ @entity ||= instance_variable_set(:"@#{model_name}", model.new)
38
+ end
39
+
40
+ def edit
41
+ end
42
+
43
+ def create
44
+ @entity ||= instance_variable_set(:"@#{model_name}", model.new(entity_params))
45
+ respond_to do |format|
46
+ if @entity.save
47
+ format.html { redirect_to @entity, notice: t(:text_created) }
48
+ format.json { render json: @entity, status: :created, location: @entity }
49
+ else
50
+ format.html { render action: 'new' }
51
+ format.json { render status: :unprocessable_entity, json: { errors: @entity.errors } }
52
+ end
53
+ end
54
+ end
55
+
56
+ def update
57
+ respond_to do |format|
58
+ if @entity.update(entity_params)
59
+ format.html { redirect_to @entity, notice: t(:text_updated) }
60
+ format.json { head :no_content }
61
+ else
62
+ format.html { render action: 'edit' }
63
+ format.json { render status: :unprocessable_entity, json: { errors: @entity.errors } }
64
+ end
65
+ end
66
+ end
67
+
68
+ def destroy
69
+ @entity.destroy
70
+ respond_to do |format|
71
+ format.html { redirect_to(action: :index, notice: t(:text_destroyed)) }
72
+ format.json { head :no_content }
73
+ format.js { render js: "Symphonia.filters.removeRow('#{view_context.dom_id(@entity)}')"}
74
+ end
75
+ end
76
+
77
+ private
78
+ # Use callbacks to share common setup or constraints between actions.
79
+ def find_entity
80
+ @entity ||= instance_variable_set(:"@#{model_name}", model.find(params[:id]))
81
+ end
82
+
83
+ def safe_attributes
84
+ []
85
+ end
86
+ # Never trust parameters from the scary internet, only allow the white list through.
87
+ def entity_params
88
+ params.require(model_name).permit(safe_attributes)
89
+ end
90
+
91
+ def model_name
92
+ model.name.demodulize.underscore.to_sym
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,69 @@
1
+ require 'will_paginate/view_helpers/action_view'
2
+ module Symphonia
3
+ class BootstrapLinkRender < ::WillPaginate::ActionView::LinkRenderer
4
+
5
+ def pagination
6
+ items = @options[:page_links] ? windowed_page_numbers : []
7
+ unless @options[:page_links] == :only
8
+ items.unshift :previous_page
9
+ items.push :next_page
10
+ end
11
+ items
12
+ end
13
+
14
+ def to_html
15
+ html = pagination.map do |item|
16
+ if @options[:remote]
17
+ if item == :next_page
18
+ tag :li,next_page, class: 'page-item'
19
+ end
20
+ else
21
+ tag(:li, (item.is_a?(Integer) ?
22
+ page_number(item) :
23
+ send(item)).html_safe, class: 'page-item' + (item == current_page ? ' active' : ''))
24
+ end
25
+ end.join(@options[:link_separator])
26
+
27
+ container_classes = %w(pagination justify-content-center)
28
+ container_classes << 'pagination-sm' if @options[:small]
29
+ container_classes << 'pagination-lg' if @options[:large]
30
+ nav = tag(:ul, html.html_safe, class: container_classes.join(' '))
31
+ tag :nav, nav, class: 'd-print-none'
32
+ end
33
+
34
+ def default_url_params
35
+ @options[:query] && @options[:query].to_params || {}
36
+ end
37
+
38
+ def url(page)
39
+ @base_url_params ||= begin
40
+ url_params = merge_get_params(default_url_params)
41
+ url_params[:only_path] = true
42
+ merge_optional_params(url_params)
43
+ end
44
+
45
+ @template.url_for(@base_url_params.merge({:page => page}))
46
+ end
47
+
48
+ def page_number(page)
49
+ link_options = @options[:link_options] || {}
50
+
51
+ if page == current_page
52
+ tag(:span, page, class: 'page-link current_page')
53
+ else
54
+ link_options.merge! class: 'page-link', rel: rel_value(page)
55
+ link(page, page, {:'data-remote' => @options[:remote]}.merge(link_options))
56
+ end
57
+ end
58
+
59
+ def previous_or_next_page(page, text, classname)
60
+ if page
61
+ link(text, page, :'data-remote' => @options[:remote], class: "page-link #{classname}")
62
+ else
63
+ tag(:span, text, class: "page-link #{classname} disabled")
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end