symphonia 4.2.0 → 5.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +27 -1
  3. data/app/assets/javascripts/symphonia/application.js +3 -3
  4. data/app/assets/stylesheets/symphonia/_font_awesome.scss +8 -6
  5. data/app/assets/stylesheets/symphonia/_layout.scss +33 -1
  6. data/app/assets/stylesheets/symphonia/basic.scss +3 -99
  7. data/app/assets/stylesheets/symphonia/filters.scss +3 -5
  8. data/app/assets/stylesheets/symphonia/symphonia_bootstrap.scss +1 -1
  9. data/app/controllers/symphonia/accounts_controller.rb +7 -3
  10. data/app/controllers/symphonia/application_controller.rb +2 -1
  11. data/app/controllers/symphonia/users_controller.rb +17 -29
  12. data/app/helpers/symphonia/application_helper.rb +48 -26
  13. data/app/models/symphonia/preference.rb +5 -5
  14. data/app/models/symphonia/user.rb +3 -35
  15. data/app/models/symphonia/user_ability.rb +46 -0
  16. data/app/views/common/403.html.erb +4 -3
  17. data/app/views/layouts/symphonia/application.html.erb +4 -4
  18. data/app/views/symphonia/accounts/_detail.html.erb +21 -18
  19. data/app/views/symphonia/common/_filters.html.erb +15 -15
  20. data/app/views/symphonia/common/_share_links.html.erb +2 -3
  21. data/app/views/symphonia/users/_form.html.erb +1 -6
  22. data/app/views/symphonia/users/show.html.erb +15 -20
  23. data/config/locales/cs.yml +3 -2
  24. data/db/migrate/20130714140500_create_users.rb +0 -2
  25. data/db/seeds.rb +3 -3
  26. data/lib/generators/symphonia/entity_controller/entity_controller_generator.rb +2 -2
  27. data/lib/generators/symphonia/entity_controller/templates/{controller.rb → controller.rb.tt} +0 -0
  28. data/lib/symphonia/admin_constraint.rb +1 -1
  29. data/lib/symphonia/base_controller.rb +9 -17
  30. data/lib/symphonia/controller_extensions.rb +5 -15
  31. data/lib/symphonia/engine.rb +12 -40
  32. data/lib/symphonia/form_builder.rb +17 -16
  33. data/lib/symphonia/menu_manager.rb +15 -11
  34. data/lib/symphonia/object.rb +9 -9
  35. data/lib/symphonia/spec_helper.rb +8 -4
  36. data/lib/symphonia/user_management.rb +1 -1
  37. data/lib/symphonia/version.rb +1 -1
  38. data/lib/symphonia.rb +12 -9
  39. data/spec/factories/factories.rb +0 -4
  40. data/spec/models/user_spec.rb +39 -2
  41. data/spec/spec_helper.rb +0 -1
  42. data/spec/support/stub_users.rb +7 -7
  43. metadata +39 -124
  44. data/app/controllers/symphonia/roles_controller.rb +0 -39
  45. data/app/models/symphonia/role.rb +0 -55
  46. data/app/views/symphonia/roles/_form.html.erb +0 -26
  47. data/app/views/symphonia/roles/edit.html.erb +0 -5
  48. data/app/views/symphonia/roles/index.html.erb +0 -6
  49. data/app/views/symphonia/roles/new.html.erb +0 -4
  50. data/app/views/symphonia/roles/show.html.erb +0 -11
  51. data/db/migrate/20130714140501_create_roles.rb +0 -18
  52. data/db/migrate/20210509141420_roles_change_permissions_to_json.rb +0 -18
  53. data/db/migrate/20210509180525_roles_change_permissions_to_native_json.rb +0 -7
  54. data/lib/symphonia/permissions.rb +0 -93
  55. data/spec/controllers/roles_controller_spec.rb +0 -12
  56. data/spec/models/role_spec.rb +0 -13
  57. data/spec/requests/roles_spec.rb +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b1926adf23dfcc6193affda2c0eaf6edcf7729eba7ee21fde5d65d7ffe6fa64
4
- data.tar.gz: 16cd15eb367b3f597e6fc67f60d8d8de7941010d08ec42b5b02baecf3fddf623
3
+ metadata.gz: 71cb8a41bead7977d784fbb826c54a059b74f9cc75f43de46e67bbb8fd547cea
4
+ data.tar.gz: aa49eb8c8b095422abd9bb3c65105c3bfc79bf3cb82d2e8ea6655751cc9f15a2
5
5
  SHA512:
6
- metadata.gz: c3b96b59bd3014de2cd86cbf53a5c4bfe1c30f4f1ee6d1b9a60a71c98784c33c1a8b270471dfe8a5db35f80c00f02c931e3d54c98e712000737828e805226480
7
- data.tar.gz: 31b3f194941fb8661419af1f52a1ab9c4423f40da86443846876f9996505127903002473ec7c1923f91891858851201bb134420feb1210f7ecf061f182ae11bb
6
+ metadata.gz: 98a480e8c8c1e1a31c887c313fc6bd682774cc397277ff7edf10da58583d59badca233903adb447d131d98b704573d2dbdd8fd90e61465ae146eb126a4e85c36
7
+ data.tar.gz: bc42c7d29dcb974fee96e7749315449c77f44843a2b8cde034a5964dc4aec0c9fdfa25a5224605165b75453e24a23b6ca53d35ef59b2e3c620e1b00f6fe11216
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Symphonia
2
- > simple core toolkit for my rails apps
2
+
3
+ simple core toolkit for my rails apps
3
4
 
4
5
  ## Installation
5
6
 
@@ -13,6 +14,7 @@ after `bundle install` run post-installation: `rails g symphonia:setup`
13
14
 
14
15
  > Setup prepare `config/initializers/settings.rb`, create `spec/spec_helper.rb`, add stylesheets and javascripts references and copy basic layout.
15
16
 
17
+ ## Configuration
16
18
 
17
19
  ## Upgrade to v4.0
18
20
  1. update Gemfile:
@@ -30,3 +32,27 @@ And `bundle update`
30
32
  export THOR_MERGE=vimdiff
31
33
  rails app:update
32
34
  ```
35
+ ## Upgrade to v5.0
36
+ Version 5 remove sprockets bootstrap, font-awesome and others CSS/JS things. It expect that assets will be managed by webpacker (or similar) FE technology.
37
+
38
+ Also remove `Role` model and whole permissions custom logic. Its replace standardized CanCanCan gem (https://github.com/CanCanCommunity/cancancan/tree/develop/docs)
39
+
40
+ ### Sprockets fallback
41
+ For fallback add to Gemfile
42
+ ```ruby
43
+ gem "bootstrap", "~> 4.6"
44
+ gem "jquery-rails"
45
+ gem "jquery-ui-rails"
46
+ gem "listen"
47
+ gem "sass-rails"
48
+ gem "turbolinks"
49
+ gem 'font-awesome-sass', '~> 6.2.0'
50
+ ```
51
+ in your "app/assets/stylessheets/general.scss" make sure symphonia is imported
52
+ ```scss
53
+ @import 'symphonia/basic';
54
+ @import 'symphonia/layout';
55
+ ```
56
+
57
+ ### CanCanCan
58
+ For user there is `Symphonia::UserAbility` which defined permissions for User model + for admin add basic CRUD operation for `:all`.
@@ -7,8 +7,8 @@
7
7
  //= require symphonia/_core
8
8
  //= require symphonia/Sortable
9
9
 
10
- //= require bootstrap-datepicker/core
11
- //= require bootstrap-datepicker/locales/bootstrap-datepicker.cs.js
10
+ // require bootstrap-datepicker/core
11
+ // require bootstrap-datepicker/locales/bootstrap-datepicker.cs.js
12
12
 
13
13
  //= require_self
14
14
  //= require symphonia/symphonia_bootstrap_dialog
@@ -155,4 +155,4 @@ SymphoniaCheckboxes = {
155
155
 
156
156
  return input;
157
157
  }
158
- };
158
+ };
@@ -1,25 +1,27 @@
1
- @import 'font-awesome';
1
+ @import "font-awesome";
2
2
  /* Font awesome aliases */
3
3
  .fa-add {
4
- @extend .fa-plus-circle !optional;
4
+ //@include fa-icon-solid($fa-var-circle-plus);
5
+ @extend .fa-circle-plus !optional;
5
6
  }
6
7
  .fa-delete, .fa-del {
7
- @extend .fa-trash-o !optional;
8
+ @include fa-icon-solid($fa-var-trash-can);
8
9
  }
9
10
  .fa-back {
10
- @extend .fa-chevron-left !optional;
11
+ @include fa-icon-solid($fa-var-chevron-left);
11
12
  }
12
13
  .fa-true {
13
14
  @extend .fa-check !optional;
15
+ @include fa-icon-solid($fa-var-check);
14
16
  }
15
17
  .fa-false {
16
- @extend .fa-times !optional;
18
+ @include fa-icon-solid($fa-var-times);
17
19
  }
18
20
  .fa-notice {
19
21
  @extend .fa-check-circle !optional;
20
22
  }
21
23
  .fa-error {
22
- @extend .fa-times-circle !optional;
24
+ @extend .circle-exclamation !optional;
23
25
  }
24
26
  .alert .fa-info {
25
27
  @extend .fa-info-circle !optional;
@@ -1,4 +1,4 @@
1
- @import "bootstrap";
1
+ @import "/bootstrap";
2
2
 
3
3
  // fixed navbar
4
4
  body > .container {
@@ -38,3 +38,35 @@ footer.footer {
38
38
  @extend .d-print-none;
39
39
  }
40
40
  }
41
+
42
+ /* TABLE */
43
+ @mixin inactive-row {
44
+ opacity: 0.5
45
+ }
46
+ td.price {
47
+ text-align: right;
48
+ }
49
+ table.table {
50
+ th a.asc {
51
+ &:after {
52
+ content: "\2191";
53
+ }
54
+ }
55
+ th a.desc {
56
+ &:after {
57
+ content: "\2193";
58
+ }
59
+ }
60
+ tr.status {
61
+ &--lock, &--inactive, &--archived {
62
+ @include inactive-row;
63
+ }
64
+ }
65
+ .buttons {
66
+ text-align: right;
67
+ }
68
+ }
69
+
70
+ /* FORM */
71
+ .required label, label[required], label.required, .has-error {color: red !important;}
72
+ .required label:after, label[required]:after, label.required:after { content: '* '}
@@ -1,85 +1,13 @@
1
- @import "_font_awesome";
1
+ @import "./_font_awesome";
2
2
 
3
3
  .page-header.title, .page-header.title h1 {
4
4
  margin-top: 0;
5
5
  }
6
- @mixin inactive-row {
7
- opacity: 0.5
8
- }
6
+
9
7
  .reorder, .reorder label {
10
8
  cursor: move;
11
9
  }
12
10
 
13
- .flash {
14
- border: 1px solid;
15
- margin: 10px 0px;
16
- padding:15px 10px 15px 10px;
17
- background-repeat: no-repeat;
18
- background-position: 10px center;
19
- position:relative;
20
- line-height: 30px;
21
- &>i.icon:first-child {
22
- font-family: FontAwesome;
23
- font-size: 30px;
24
-
25
- font-style: normal;
26
- position:absolute;
27
- top: 50%;
28
- margin-top: -15px;
29
- }
30
- &>span.flash-content {
31
- padding-left: 35px;
32
-
33
- }
34
- }
35
- .info {
36
- color: #00529B;
37
- background-color: #BDE5F8;
38
- }
39
- .notice {
40
- color: #4F8A10;
41
- background-color: #DFF2BF;
42
- &>i.icon:first-child:before {
43
- content: "\f05d"
44
- }
45
- }
46
-
47
- .nodata, .no-data {
48
- @extend .flash;
49
- @extend .info;
50
- text-align: center;
51
- border-width: 3px;
52
- }
53
-
54
- div.error_explanation {
55
- color: #D63301;
56
- background-color: #FFCCBA;
57
- border: 1px solid rgba(255,0,0,0.5);
58
- position: relative;
59
- margin: 0 0 25px 0;
60
- h2 {
61
- display: none;
62
- }
63
- ul {
64
- margin: 0;
65
- li {
66
- line-height: 25px;
67
- }
68
- }
69
- &>p {
70
- background-color: rgba(255,255,255,0.5);
71
- margin: 0;
72
- padding: 5px;
73
- text-shadow: 0 0 5px #FFFFFF;
74
- }
75
- &>p:before {
76
- font-family: FontAwesome;
77
- margin-right: 5px;
78
- font-size: 20px;
79
- content: "\f071";
80
- }
81
- }
82
-
83
11
  #account-extra-details {
84
12
  dt {
85
13
  width: 40%;
@@ -115,8 +43,6 @@ td.buttons {
115
43
  .contextual {@extend .pull-right !optional}
116
44
  .contextual input, .contextual select {font-size:0.9em;}
117
45
 
118
- .required label, label[required], label.required, .has-error {color: red !important;}
119
- .required label:after, label[required]:after, label.required:after { content: '* '}
120
46
  textarea {width: 99%;}
121
47
 
122
48
  #internal_static_page_sign {
@@ -142,29 +68,7 @@ textarea {width: 99%;}
142
68
  }
143
69
  }
144
70
  }
145
- td.price {
146
- text-align: right;
147
- }
148
- table.table {
149
- th a.asc {
150
- &:after {
151
- content: "\2191";
152
- }
153
- }
154
- th a.desc {
155
- &:after {
156
- content: "\2193";
157
- }
158
- }
159
- tr.status {
160
- &--lock, &--inactive, &--archived {
161
- @include inactive-row;
162
- }
163
- }
164
- .buttons {
165
- text-align: right;
166
- }
167
- }
71
+
168
72
 
169
73
  .highlight {
170
74
  animation-duration: 1s;
@@ -1,13 +1,11 @@
1
1
  #symphonia_query_options_form {
2
2
  .filter-custom-date {
3
- &>* {
3
+ & > * {
4
4
  width: 49%;
5
- //&:last-child {
6
- // float:right;
7
- //}
8
5
  }
9
6
  }
10
7
  }
8
+
11
9
  #query_data {
12
10
  table.table {
13
11
  .price {
@@ -16,4 +14,4 @@
16
14
  }
17
15
  }
18
16
  }
19
- }
17
+ }
@@ -1,2 +1,2 @@
1
1
  @import "layout";
2
- @import "bootstrap-datepicker3";
2
+ // @import "bootstrap-datepicker3";
@@ -48,7 +48,7 @@ module Symphonia
48
48
  @user.attributes = user_params
49
49
  respond_to do |format|
50
50
  @user.edited_by = User.current.logged_in? && User.current
51
- @user.edited_at = Time.now
51
+ @user.edited_at = Time.current
52
52
  if @user.save
53
53
  format.html { redirect_to({ action: 'show' }, notice: t(:text_updated)) }
54
54
  format.json { head :no_content }
@@ -104,7 +104,7 @@ module Symphonia
104
104
  @user = find_account_by_token(params.require(:id))
105
105
  return render_404 if @user.nil?
106
106
 
107
- if params[:password] # && params[:password_confirmation]
107
+ if params[:password].present?
108
108
  @user.password = params[:password]
109
109
  end
110
110
 
@@ -147,8 +147,12 @@ module Symphonia
147
147
  User.current
148
148
  end
149
149
 
150
+ def current_ability
151
+ @current_ability ||= UserAbility.new current_user
152
+ end
153
+
150
154
  def find_account_by_mail(mail)
151
- User.where(email: mail).first
155
+ User.find_by(email: mail)
152
156
  end
153
157
 
154
158
  def find_account_by_token(id)
@@ -4,5 +4,6 @@ module Symphonia
4
4
  include ControllerExtensions
5
5
 
6
6
  helper Symphonia::BootstrapModalHelper
7
+
7
8
  end
8
- end
9
+ end
@@ -2,10 +2,10 @@ module Symphonia
2
2
  class UsersController < ApplicationController
3
3
 
4
4
  helper Symphonia::RendererHelper
5
+ include ::CanCan::ControllerAdditions
5
6
 
6
- before_action :find_user, except: %i[index new create show]
7
+ before_action :user, except: %i[index new create show]
7
8
  before_action :authorize, except: [:show]
8
- before_action -> { menu_item(:my_account) }, only: %i[current edit_current update_current]
9
9
 
10
10
  def index
11
11
  @query = Symphonia::User.query.new
@@ -22,8 +22,8 @@ module Symphonia
22
22
 
23
23
  def show
24
24
  @user = Symphonia::User.find(params[:id]) if params[:id]
25
- @user ||= Symphonia::User.current
26
- authorize
25
+ @user ||= current_user
26
+ authorize! :show, @user
27
27
  respond_to do |format|
28
28
  format.html
29
29
  format.json { render json: @user, except: %w[crypted_password password_salt persistence_token perishable_token] }
@@ -32,7 +32,6 @@ module Symphonia
32
32
 
33
33
  def new
34
34
  @user = Symphonia::User.new
35
- @roles = Symphonia::Role.sorted
36
35
  respond_to do |format|
37
36
  format.html
38
37
  end
@@ -46,27 +45,18 @@ module Symphonia
46
45
  format.xml { render xml: @user, status: :created, location: @user }
47
46
  format.json { render json: @user, status: :created, location: @user }
48
47
  else
49
- format.html do
50
- @roles = Symphonia::Role.sorted
51
- render action: 'new'
52
- end
48
+ format.html { render action: 'new' }
53
49
  format.xml { render xml: @user.errors, status: :unprocessable_entity }
54
50
  format.json { render json: @user.errors, status: :unprocessable_entity }
55
51
  end
56
52
  end
57
53
  end
58
54
 
59
- def edit
60
- @roles = Role.all
61
- end
55
+ def edit; end
62
56
 
63
57
  def update
64
58
  @user.attributes = user_params
65
- @user.admin = params[:admin] if params[:admin] && Symphonia::User.current.admin?
66
- if params[:role_id].present? && Symphonia::User.current.admin?
67
- @role = Role.find(params[:role_id])
68
- @user.role = @role
69
- end
59
+ @user.admin = params[:admin] if params[:admin] && current_user.admin?
70
60
  respond_to do |format|
71
61
  @user.edited_by = current_user
72
62
  @user.edited_at = DateTime.now
@@ -74,10 +64,7 @@ module Symphonia
74
64
  format.html { redirect_back_or_default user_path(@user), notice: t(:text_updated) }
75
65
  format.any(:json, :xml) { head :no_content }
76
66
  else
77
- format.html do
78
- @roles = Symphonia::Role.sorted
79
- render action: 'edit'
80
- end
67
+ format.html { render action: 'edit' }
81
68
  format.xml { render xml: @user.errors, status: :unprocessable_entity }
82
69
  format.json { render json: @user.errors, status: :unprocessable_entity }
83
70
  end
@@ -114,22 +101,23 @@ module Symphonia
114
101
 
115
102
  private
116
103
 
117
- def find_user
118
- @user = Symphonia::User.find(params[:id])
104
+ def user
105
+ @user ||= Symphonia::User.find(params[:id])
119
106
  end
120
107
 
121
108
  def authorize
122
- if User.current.logged_in? && User.current.id == @user&.id
123
- true
124
- else
125
- super
126
- end
109
+ authorize! action_name.to_sym, @user
127
110
  end
128
111
 
129
112
  def user_params
130
113
  allowed = [:login, :first_name, :last_name, :password, :password_confirmation, :email, :mail, preference_ids: []]
131
- allowed.concat(%i[admin role_id]) if Symphonia::User.current.admin?
114
+ allowed << :admin if current_user.admin?
132
115
  params.require(:user).permit(allowed)
133
116
  end
117
+
118
+ def current_ability
119
+ @current_ability ||= UserAbility.new current_user
120
+ end
121
+
134
122
  end
135
123
  end
@@ -1,7 +1,6 @@
1
- # require 'symphonia/bootstrap_link_render'
2
1
  module Symphonia
3
2
  module ApplicationHelper
4
- include FontAwesome::Rails::IconHelper
3
+
5
4
  include FormHelper
6
5
 
7
6
  def bootstrap_class_for(flash_type)
@@ -23,8 +22,8 @@ module Symphonia
23
22
  def render_flash_messages(flash_messages = nil)
24
23
  s = ''
25
24
  Array(flash_messages || flash).each do |type, message|
26
- s << content_tag(:div, class: "d-print-none alert #{bootstrap_class_for(type)}") do
27
- content_tag(:button, '', class: 'fa fa-times-circle-o close', data: { dismiss: 'alert' }) + Array.wrap(message).collect { |m| fa_icon(type, text: m) }.join("<br>").html_safe
25
+ s << tag.div(class: "d-print-none alert #{bootstrap_class_for(type)}") do
26
+ tag.button('', class: 'fa fa-circle-xmark close', data: { dismiss: 'alert' }) + Array.wrap(message).collect { |m| icon(type, text: m) }.join("<br>").html_safe
28
27
  end
29
28
  end
30
29
 
@@ -38,11 +37,13 @@ module Symphonia
38
37
  end
39
38
  options[:container_class] ||= 'mr-auto'
40
39
 
41
- content_tag(:ul, s.html_safe, itemscope: '', itemtype: 'http://schema.org/BreadcrumbList', class: "navbar-nav #{options[:container_class]}", id: menu.to_s)
40
+ tag.ul(s.html_safe, itemscope: '', itemtype: 'http://schema.org/BreadcrumbList', class: "navbar-nav #{options[:container_class]}", id: menu.to_s)
42
41
  end
43
42
 
44
43
  def render_menu_node(menu, item, options = {})
45
44
  condition = item[:if] ? item[:if].call : true
45
+ return nil unless condition
46
+
46
47
  selected = @menu_item.to_sym == menu
47
48
  label = case item[:label].class.name
48
49
  when 'NilClass'
@@ -57,16 +58,16 @@ module Symphonia
57
58
  raise "MenuManager error: Label is unknown type: #{item[:label].class}"
58
59
  end
59
60
  if item[:children].blank?
60
- return content_tag(:li, render_menu_link(item, label, options), class: "nav-item #{menu} #{'active' if selected} #{options[:class]}", id: item[:id]) if condition
61
+ tag.li(render_menu_link(item, label, options), class: "nav-item #{menu} #{'active' if selected} #{options[:class]}", id: item[:id])
61
62
  else
62
63
  children = ''
63
64
  item[:children].each do |child, subitem|
64
65
  children << render_menu_node(menu, subitem, class: 'dropdown-item').to_s
65
66
  end
66
- unless children.blank?
67
- return content_tag(:li, class: "nav-item dropdown #{menu}") do
67
+ if children.present?
68
+ tag.li(class: "nav-item dropdown #{menu}") do
68
69
  concat render_menu_link(item.merge({ class: 'dropdown-toggle', data: { toggle: 'dropdown' } }), label, { is_submenu: true })
69
- concat content_tag(:ul, children.html_safe, class: 'dropdown-menu')
70
+ concat tag.ul(children.html_safe, class: 'dropdown-menu')
70
71
  end
71
72
  end
72
73
  end
@@ -87,7 +88,7 @@ module Symphonia
87
88
  item[:url]
88
89
  end
89
90
  link_to(
90
- (content_tag(:i, '', class: "#{item[:icon]}") + "\n" + content_tag(:span, label, itemprop: 'title')).html_safe,
91
+ (tag.i('', class: "#{item[:icon]}") + "\n" + tag.span(label, itemprop: 'title')).html_safe,
91
92
  url,
92
93
  class: "nav-link #{item[:class]}",
93
94
  data: item[:data],
@@ -133,20 +134,21 @@ module Symphonia
133
134
  ''
134
135
  else
135
136
  html_title(header_text.dup)
136
- header_text << "\n" + content_tag(:small, small, class: 'text-muted') if small.present?
137
+ header_text << ("\n" << tag.small(small, class: 'text-muted')) if small.present?
137
138
  s = ''
138
139
  if options[:back] && !request.xhr?
139
140
  back_url = options[:back] unless options[:back].is_a? TrueClass
140
141
  s << link_to_back(back_url)
141
142
  end
142
143
  s << capture(&block).to_s if block_given?
143
- header_tag = content_tag request.xhr? && :h5 || :h1, id: 'page_header', class: s.present? && "col-6" || nil do
144
+ header_class = (s.present? && "col-6") || nil
145
+ header_tag = content_tag(((request.xhr? && :h5) || :h1), id: 'page_header', class: header_class) do
144
146
  header_text.html_safe
145
147
  end
146
148
  return header_tag if s.blank?
147
149
 
148
- content_tag :div, class: "row" do
149
- header_tag + content_tag(:div, s.html_safe, class: "col-6 text-right")
150
+ tag.div(class: "row") do
151
+ header_tag + tag.div(s.html_safe, class: "col-6 text-right")
150
152
  end
151
153
  end
152
154
  end
@@ -154,7 +156,7 @@ module Symphonia
154
156
  alias_method :page_header, :title
155
157
 
156
158
  def render_no_data(message = nil)
157
- content_tag(:div, message || t(:text_no_data), class: 'nodata')
159
+ tag.div(icon("circle-info", text: message || t(:text_no_data)), class: 'alert alert-info text-center nodata')
158
160
  end
159
161
 
160
162
  def content_for(name, content = nil, &block)
@@ -175,7 +177,7 @@ module Symphonia
175
177
  end
176
178
 
177
179
  def format_html(text)
178
- content_tag(:div, (defined?(Ckeditor) ? text.html_safe : format_text(text)), class: 'formatted-text')
180
+ tag.div((defined?(Ckeditor) ? text.html_safe : format_text(text)), class: 'formatted-text')
179
181
  end
180
182
 
181
183
  def format_price(value, options = {})
@@ -183,7 +185,7 @@ module Symphonia
183
185
  end
184
186
 
185
187
  def multiselect_toggler(id = nil)
186
- link_to(fa_icon(:plus), 'javascript:void(0);', onclick: "toggleMultiSelect(#{id || 'this'});return false", class: 'btn fa fa-border')
188
+ link_to(icon('plus'), 'javascript:void(0);', onclick: "toggleMultiSelect(#{id || 'this'});return false", class: 'btn fa fa-border')
187
189
  end
188
190
 
189
191
  def link_to_back(url = nil)
@@ -191,14 +193,12 @@ module Symphonia
191
193
  end
192
194
 
193
195
  def link_to_new_entity(options = {})
194
- return '' if !options.has_key?(:skip_permission_check) && !User.current.allowed_to?(:"manage_#{controller_name}")
195
-
196
196
  anchor = options.has_key?(:anchor) ? options.delete(:anchor) : 'page_header'
197
197
  label = options.delete(:label) || t("label_#{controller_name.singularize}_new")
198
198
  model = controller.try(:model) || controller_name.singularize
199
199
  url = options.delete(:url) || new_polymorphic_path(model, anchor: anchor)
200
200
 
201
- link_to(fa_icon('add', text: label), url, { class: 'btn btn-primary' }.merge(options))
201
+ link_to(icon('square-plus', text: label), url, { class: 'btn btn-primary' }.merge(options))
202
202
  end
203
203
 
204
204
  # change the default link renderer for will_paginate
@@ -238,8 +238,30 @@ module Symphonia
238
238
  javascript_tag("$(document).ready(function() {#{js.html_safe}})".html_safe)
239
239
  end
240
240
 
241
- def icon(fa, text = nil, **options)
242
- fa_icon(fa, (text && { text: content_tag(:span, text, class: 'd-none d-sm-inline') } || {}).merge(options))
241
+ # prepend FontAwesome::Sass::Rails::ViewHelpers
242
+ def icon(icon, text = nil, html_options = {})
243
+ if text.is_a?(Hash)
244
+ html_options = text
245
+ text = nil
246
+ end
247
+
248
+ text_content = if text
249
+ tag.span(text, class: 'd-none d-sm-inline')
250
+ elsif html_options[:text]
251
+ html_options.delete(:text)
252
+ end
253
+ html_options[:title] ||= text
254
+ html_options[:class] = "fa-regular fa-#{icon}"
255
+ html_options['aria-hidden'] ||= true
256
+
257
+ html = tag.i(nil, **html_options)
258
+ html << ' ' << text_content.to_s if text_content.present?
259
+ html
260
+ end
261
+
262
+ def fa_icon(fa, options = {})
263
+ ActiveSupport::Deprecation.warn "use `icon` instead"
264
+ icon(fa, options.delete(:text), options)
243
265
  end
244
266
 
245
267
  # Render original template from engine
@@ -332,11 +354,11 @@ module Symphonia
332
354
 
333
355
  def to_html
334
356
  html = "<div id='#{@modal_id}' style='' class='modal fade' role='dialog'><div class='modal-dialog #{'modal-lg' if size.present?}'><div class='modal-content'>"
335
- html << @c.content_tag(:div, class: 'modal-header') do
336
- @c.content_tag(:button, '', class: 'close fa fa-times', data: { dismiss: 'modal' }, 'aria-hidden' => true) + @c.content_tag(:h4, @title, class: 'modal-title') + @header.to_s
357
+ html << @c.tag.div(class: 'modal-header') do
358
+ @c.tag.button('', class: 'close fa fa-times', data: { dismiss: 'modal' }, 'aria-hidden' => true) + @c.tag.h4(@title, class: 'modal-title') + @header.to_s
337
359
  end
338
- content = @c.content_tag(:div, @c.content_tag(:div, body.html_safe, class: 'modal-content-inner-container container-fluid'), class: 'modal-body')
339
- content << @c.content_tag(:div, footer.html_safe, class: 'modal-footer')
360
+ content = @c.tag.div(@c.tag.div(body.html_safe, class: 'modal-content-inner-container container-fluid'), class: 'modal-body')
361
+ content << @c.tag.div(footer.html_safe, class: 'modal-footer')
340
362
 
341
363
  html << content.html_safe
342
364
  html << '</div></div></div>'
@@ -3,10 +3,10 @@ module Symphonia
3
3
  self.table_name = 'preferences'
4
4
 
5
5
  validates :name, uniqueness: true
6
- # has_and_belongs_to_many :symphonia_units, association_foreign_key: 'user_id'
7
- has_and_belongs_to_many :users, join_table: 'preferences_users', association_foreign_key: 'user_id', class_name: 'Symphonia::User'
6
+ has_and_belongs_to_many :users, join_table: 'preferences_users', association_foreign_key: 'user_id',
7
+ class_name: 'Symphonia::User'
8
8
 
9
- scope :visible, ->(user = Symphonia::User.current) { user.admin? ? all : where(restrict: false)}
10
- end
9
+ scope :visible, ->(user = Symphonia::User.current) { user.admin? ? all : where(restrict: false) }
11
10
 
12
- end
11
+ end
12
+ end