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.
- checksums.yaml +4 -4
- data/README.md +27 -1
- data/app/assets/javascripts/symphonia/application.js +3 -3
- data/app/assets/stylesheets/symphonia/_font_awesome.scss +8 -6
- data/app/assets/stylesheets/symphonia/_layout.scss +33 -1
- data/app/assets/stylesheets/symphonia/basic.scss +3 -99
- data/app/assets/stylesheets/symphonia/filters.scss +3 -5
- data/app/assets/stylesheets/symphonia/symphonia_bootstrap.scss +1 -1
- data/app/controllers/symphonia/accounts_controller.rb +7 -3
- data/app/controllers/symphonia/application_controller.rb +2 -1
- data/app/controllers/symphonia/users_controller.rb +17 -29
- data/app/helpers/symphonia/application_helper.rb +48 -26
- data/app/models/symphonia/preference.rb +5 -5
- data/app/models/symphonia/user.rb +3 -35
- data/app/models/symphonia/user_ability.rb +46 -0
- data/app/views/common/403.html.erb +4 -3
- data/app/views/layouts/symphonia/application.html.erb +4 -4
- data/app/views/symphonia/accounts/_detail.html.erb +21 -18
- data/app/views/symphonia/common/_filters.html.erb +15 -15
- data/app/views/symphonia/common/_share_links.html.erb +2 -3
- data/app/views/symphonia/users/_form.html.erb +1 -6
- data/app/views/symphonia/users/show.html.erb +15 -20
- data/config/locales/cs.yml +3 -2
- data/db/migrate/20130714140500_create_users.rb +0 -2
- data/db/seeds.rb +3 -3
- data/lib/generators/symphonia/entity_controller/entity_controller_generator.rb +2 -2
- data/lib/generators/symphonia/entity_controller/templates/{controller.rb → controller.rb.tt} +0 -0
- data/lib/symphonia/admin_constraint.rb +1 -1
- data/lib/symphonia/base_controller.rb +9 -17
- data/lib/symphonia/controller_extensions.rb +5 -15
- data/lib/symphonia/engine.rb +12 -40
- data/lib/symphonia/form_builder.rb +17 -16
- data/lib/symphonia/menu_manager.rb +15 -11
- data/lib/symphonia/object.rb +9 -9
- data/lib/symphonia/spec_helper.rb +8 -4
- data/lib/symphonia/user_management.rb +1 -1
- data/lib/symphonia/version.rb +1 -1
- data/lib/symphonia.rb +12 -9
- data/spec/factories/factories.rb +0 -4
- data/spec/models/user_spec.rb +39 -2
- data/spec/spec_helper.rb +0 -1
- data/spec/support/stub_users.rb +7 -7
- metadata +39 -124
- data/app/controllers/symphonia/roles_controller.rb +0 -39
- data/app/models/symphonia/role.rb +0 -55
- data/app/views/symphonia/roles/_form.html.erb +0 -26
- data/app/views/symphonia/roles/edit.html.erb +0 -5
- data/app/views/symphonia/roles/index.html.erb +0 -6
- data/app/views/symphonia/roles/new.html.erb +0 -4
- data/app/views/symphonia/roles/show.html.erb +0 -11
- data/db/migrate/20130714140501_create_roles.rb +0 -18
- data/db/migrate/20210509141420_roles_change_permissions_to_json.rb +0 -18
- data/db/migrate/20210509180525_roles_change_permissions_to_native_json.rb +0 -7
- data/lib/symphonia/permissions.rb +0 -93
- data/spec/controllers/roles_controller_spec.rb +0 -12
- data/spec/models/role_spec.rb +0 -13
- data/spec/requests/roles_spec.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71cb8a41bead7977d784fbb826c54a059b74f9cc75f43de46e67bbb8fd547cea
|
4
|
+
data.tar.gz: aa49eb8c8b095422abd9bb3c65105c3bfc79bf3cb82d2e8ea6655751cc9f15a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98a480e8c8c1e1a31c887c313fc6bd682774cc397277ff7edf10da58583d59badca233903adb447d131d98b704573d2dbdd8fd90e61465ae146eb126a4e85c36
|
7
|
+
data.tar.gz: bc42c7d29dcb974fee96e7749315449c77f44843a2b8cde034a5964dc4aec0c9fdfa25a5224605165b75453e24a23b6ca53d35ef59b2e3c620e1b00f6fe11216
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Symphonia
|
2
|
-
|
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
|
-
|
11
|
-
|
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
|
1
|
+
@import "font-awesome";
|
2
2
|
/* Font awesome aliases */
|
3
3
|
.fa-add {
|
4
|
-
|
4
|
+
//@include fa-icon-solid($fa-var-circle-plus);
|
5
|
+
@extend .fa-circle-plus !optional;
|
5
6
|
}
|
6
7
|
.fa-delete, .fa-del {
|
7
|
-
@
|
8
|
+
@include fa-icon-solid($fa-var-trash-can);
|
8
9
|
}
|
9
10
|
.fa-back {
|
10
|
-
@
|
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
|
-
@
|
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 .
|
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
|
-
|
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
|
-
|
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,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.
|
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]
|
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.
|
155
|
+
User.find_by(email: mail)
|
152
156
|
end
|
153
157
|
|
154
158
|
def find_account_by_token(id)
|
@@ -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 :
|
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 ||=
|
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
|
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] &&
|
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
|
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
|
118
|
-
@user
|
104
|
+
def user
|
105
|
+
@user ||= Symphonia::User.find(params[:id])
|
119
106
|
end
|
120
107
|
|
121
108
|
def authorize
|
122
|
-
|
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
|
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
|
-
|
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 <<
|
27
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
67
|
-
|
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
|
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
|
-
(
|
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"
|
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
|
-
|
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
|
-
|
149
|
-
header_tag +
|
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
|
-
|
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
|
-
|
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(
|
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(
|
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
|
-
|
242
|
-
|
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.
|
336
|
-
@c.
|
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.
|
339
|
-
content << @c.
|
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
|
-
|
7
|
-
|
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
|