biovision 0.4.210512.0 → 0.12.211124.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -5
- data/app/assets/stylesheets/biovision/admin/layout.scss +34 -0
- data/app/assets/stylesheets/biovision/biovision.scss +56 -26
- data/app/assets/stylesheets/biovision/components/filters.scss +0 -2
- data/app/assets/stylesheets/biovision/components/forms.scss +40 -10
- data/app/assets/stylesheets/biovision/themes/default_theme/layout/header.scss +10 -0
- data/app/controllers/admin/biovision_components_controller.rb +10 -0
- data/app/controllers/admin/components_controller.rb +9 -5
- data/app/controllers/admin/users_controller.rb +2 -1
- data/app/controllers/admin_controller.rb +2 -22
- data/app/controllers/concerns/component_stories.rb +22 -0
- data/app/controllers/concerns/crud_entities.rb +12 -4
- data/app/controllers/concerns/my_crud_entities.rb +146 -0
- data/app/controllers/concerns/processed_forms.rb +28 -0
- data/app/controllers/concerns/restricted_access.rb +37 -0
- data/app/controllers/errors_controller.rb +37 -0
- data/app/controllers/my/components_controller.rb +21 -0
- data/app/controllers/my/index_controller.rb +1 -3
- data/app/controllers/my/profiles_controller.rb +2 -0
- data/app/controllers/oembed_controller.rb +12 -0
- data/app/controllers/profile_controller.rb +2 -0
- data/app/controllers/users_controller.rb +2 -0
- data/app/helpers/biovision_helper.rb +16 -1
- data/app/helpers/entity_helper.rb +77 -0
- data/app/helpers/my_helper.rb +34 -0
- data/app/lib/biovision/components/base/component_parameters.rb +6 -3
- data/app/lib/biovision/components/base/component_privileges.rb +4 -3
- data/app/lib/biovision/components/base/component_stories.rb +30 -0
- data/app/lib/biovision/components/base/entity_links.rb +16 -2
- data/app/lib/biovision/components/base/image_handling.rb +33 -0
- data/app/lib/biovision/components/base_component.rb +6 -27
- data/app/lib/biovision/components/content/oembed/receiver.rb +98 -0
- data/app/lib/biovision/components/content/oembed/twitter_receiver.rb +20 -0
- data/app/lib/biovision/components/content/oembed/vimeo_receiver.rb +20 -0
- data/app/lib/biovision/components/content/oembed/youtube_receiver.rb +20 -0
- data/app/lib/biovision/components/content_component.rb +14 -3
- data/app/lib/biovision/components/users_component.rb +6 -0
- data/app/lib/biovision/helpers/data_helper.rb +31 -4
- data/app/lib/biovision/helpers/export_helper.rb +97 -0
- data/app/lib/biovision/migrations/component_migration.rb +3 -1
- data/app/lib/biovision/stories/component_story.rb +55 -0
- data/app/models/biovision_component.rb +14 -1
- data/app/models/code.rb +3 -3
- data/app/models/concerns/checkable.rb +2 -1
- data/app/models/concerns/has_uploaded_file.rb +26 -0
- data/app/models/concerns/simple_tag.rb +30 -0
- data/app/models/concerns/toggleable.rb +2 -1
- data/app/models/concerns/tree_structure.rb +2 -0
- data/app/models/metric.rb +4 -0
- data/app/models/oembed_domain.rb +25 -0
- data/app/models/oembed_link.rb +19 -0
- data/app/models/oembed_receiver.rb +15 -0
- data/app/models/role.rb +4 -12
- data/app/models/simple_image.rb +29 -2
- data/app/models/simple_image_tag.rb +1 -16
- data/app/models/uploaded_file.rb +62 -0
- data/app/models/uploaded_file_tag.rb +15 -0
- data/app/models/uploaded_file_tag_file.rb +13 -0
- data/app/models/user.rb +10 -0
- data/app/models/user_role.rb +0 -1
- data/app/uploaders/simple_file_uploader.rb +2 -6
- data/app/uploaders/simple_image_uploader.rb +3 -20
- data/app/uploaders/uploaders/path_slug.rb +22 -0
- data/app/views/admin/agents/index.html.erb +1 -1
- data/app/views/admin/biovision_components/_nav_item.html.erb +6 -0
- data/app/views/admin/biovision_components/entity/_in_list.html.erb +12 -0
- data/app/views/admin/biovision_components/index.html.erb +11 -0
- data/app/views/admin/components/links/_base.html.erb +1 -1
- data/app/views/admin/dynamic_blocks/_form.html.erb +1 -1
- data/app/views/admin/dynamic_blocks/entity/_in_list.html.erb +1 -1
- data/app/views/admin/dynamic_blocks/index.html.erb +1 -1
- data/app/views/admin/dynamic_blocks/show.html.erb +3 -3
- data/app/views/admin/dynamic_pages/entity/_in_list.html.erb +1 -1
- data/app/views/admin/dynamic_pages/index.html.erb +1 -6
- data/app/views/admin/dynamic_pages/show.html.erb +1 -1
- data/app/views/admin/index/index.html.erb +1 -1
- data/app/views/admin/ip_addresses/index.html.erb +2 -2
- data/app/views/admin/navigation_groups/index.html.erb +1 -6
- data/app/views/admin/tokens/entity/_in_list.html.erb +1 -1
- data/app/views/admin/tokens/index.html.erb +1 -6
- data/app/views/admin/tokens/show.html.erb +1 -1
- data/app/views/admin/users/entity/_in_list.html.erb +2 -4
- data/app/views/admin/users/index.html.erb +1 -1
- data/app/views/admin/users/show.html.erb +18 -12
- data/app/views/admin/widgets/_filters.html.erb +7 -2
- data/app/views/admin/widgets/filters/_text.html.erb +7 -0
- data/app/views/errors/error.html.erb +1 -0
- data/app/views/layouts/admin/_header.html.erb +7 -2
- data/app/views/layouts/application/header/_authentication.html.erb +4 -1
- data/app/views/my/components/index.html.erb +25 -0
- data/app/views/my/components/show.html.erb +21 -0
- data/app/views/my/index/_cards.html.erb +15 -0
- data/app/views/my/index/_email.html.erb +14 -0
- data/app/views/my/index/_navigation.html.erb +33 -0
- data/app/views/my/index/index.html.erb +3 -50
- data/app/views/my/profiles/show.html.erb +13 -0
- data/app/views/shared/admin/_list.html.erb +10 -19
- data/app/views/shared/admin/_list_with_priority.html.erb +10 -19
- data/app/views/shared/admin/_priority.html.erb +6 -5
- data/app/views/shared/admin/_toggle.html.erb +5 -10
- data/app/views/shared/entity/_date_field.html.erb +6 -0
- data/app/views/shared/entity/_linked_entity.html.erb +1 -1
- data/app/views/shared/entity/_list.html.erb +22 -0
- data/app/views/shared/entity/_list_with_priority.html.erb +22 -0
- data/app/views/shared/entity/_priority_icons.html.erb +8 -0
- data/app/views/shared/entity/_toggle.html.erb +12 -0
- data/app/views/shared/forms/_field.html.erb +5 -1
- data/app/views/shared/forms/_field_with_search.html.erb +17 -0
- data/app/views/shared/forms/_meta_texts.html.erb +1 -1
- data/app/views/shared/forms/_simple_entity_link.html.erb +14 -0
- data/app/views/shared/my/_list.html.erb +10 -19
- data/app/views/shared/my/_list_with_priority.html.erb +10 -19
- data/app/views/shared/my/entity/edit.html.erb +25 -0
- data/app/views/shared/my/entity/new.html.erb +18 -0
- data/app/views/simple_images/_simple_image.jbuilder +13 -0
- data/config/locales/biovision-ru.yml +4 -0
- data/config/locales/components-ru.yml +23 -2
- data/config/locales/content-ru.yml +8 -0
- data/config/locales/users-ru.yml +4 -1
- data/config/routes.rb +21 -0
- data/db/migrate/20200224000010_create_users_component.rb +0 -11
- data/db/migrate/20200404000000_create_simple_images.rb +1 -0
- data/db/migrate/20210405000000_create_acl.rb +0 -1
- data/db/migrate/20210421000000_create_content_component.rb +21 -0
- data/db/migrate/20210616000000_create_uploaded_files.rb +52 -0
- data/db/migrate/amends/20210816060606_create_oembed_receivers.rb +21 -0
- data/db/migrate/amends/20210907070707_add_checksum_to_simple_images.rb +13 -0
- data/lib/biovision/base_methods.rb +0 -27
- data/lib/biovision/version.rb +1 -1
- data/lib/tasks/components.rake +51 -0
- metadata +53 -4
- data/app/models/biovision_component_user.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15e12d204f5f1ae12b72abc285f96f67db06d5b8789a015e3a649e1bba06b263
|
4
|
+
data.tar.gz: 75b5e459c5f0b3a1f938cf08bcc97bb49dbae3cabdacb5a490ed807f8c2cfde1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e09f7a61ec614d7f8cf213e352923af9e21c9a801bb54fb3ad315622dc00dada8a34959057291ad0a9fc5871be8a388741a6351b8cfe34518826414cd6850774
|
7
|
+
data.tar.gz: c8fa00223d9a133f0bb0afb64d6493172aa9f0f7d3ac73b01f2e462af9040e0a417a097b4dc8cf8cbcb28bcfad8e155560145d1d50be6cd24f8a66b7dd9ccbf9
|
data/README.md
CHANGED
@@ -29,12 +29,9 @@
|
|
29
29
|
## Добавления в `Gemfile`
|
30
30
|
|
31
31
|
```ruby
|
32
|
-
gem 'dotenv-rails'
|
33
|
-
|
34
|
-
# gem 'autoprefixer-rails', group: :production
|
35
|
-
|
36
|
-
gem 'biovision', git: 'https://github.com/Biovision/biovision.git'
|
37
32
|
# gem 'biovision', path: '/Users/maxim/Projects/Biovision/gems/biovision'
|
33
|
+
gem 'biovision', git: 'https://github.com/Biovision/biovision.git'
|
34
|
+
gem 'dotenv-rails'
|
38
35
|
|
39
36
|
group :development, :test do
|
40
37
|
gem 'database_cleaner'
|
@@ -136,6 +133,11 @@ concern :search do
|
|
136
133
|
get :search, on: :collection
|
137
134
|
end
|
138
135
|
|
136
|
+
concern :stories do
|
137
|
+
post 'stories/:slug' => :collection_story, on: :collection, as: :story
|
138
|
+
post 'stories/:slug' => :member_story, on: :member, as: :story
|
139
|
+
end
|
140
|
+
|
139
141
|
root 'index#index'
|
140
142
|
```
|
141
143
|
|
@@ -73,4 +73,38 @@ h2 {
|
|
73
73
|
padding: var(--spacer-xs);
|
74
74
|
}
|
75
75
|
|
76
|
+
.breadcrumbs {
|
77
|
+
margin-bottom: var(--spacer-s);
|
78
|
+
}
|
79
|
+
|
80
|
+
.header-authentication {
|
81
|
+
align-items: center;
|
82
|
+
display: flex;
|
83
|
+
gap: var(--spacer-xxs);
|
84
|
+
margin: 0 0 0 auto;
|
85
|
+
|
86
|
+
.avatar {
|
87
|
+
border-radius: 50%;
|
88
|
+
box-shadow: var(--block-shadow);
|
89
|
+
display: inline-block;
|
90
|
+
height: 2.4rem;
|
91
|
+
overflow: hidden;
|
92
|
+
width: 2.4rem;
|
93
|
+
|
94
|
+
img {
|
95
|
+
height: 100%;
|
96
|
+
object-fit: cover;
|
97
|
+
width: 100%;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
.current-user {
|
102
|
+
align-items: center;
|
103
|
+
color: inherit;
|
104
|
+
display: flex;
|
105
|
+
font-size: var(--font-size-decreased);
|
106
|
+
gap: var(--spacer-xs);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
76
110
|
@import "biovision/admin/components";
|
@@ -91,45 +91,75 @@ textarea {
|
|
91
91
|
.proportional-container {
|
92
92
|
padding: 0;
|
93
93
|
position: relative;
|
94
|
+
}
|
94
95
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
height: 100%;
|
99
|
-
left: 0;
|
100
|
-
position: absolute;
|
101
|
-
right: 0;
|
102
|
-
top: 0;
|
103
|
-
width: 100%;
|
104
|
-
}
|
105
|
-
|
106
|
-
&::before {
|
107
|
-
content: '\A';
|
108
|
-
display: block;
|
96
|
+
@supports (aspect-ratio: 1 / 1) {
|
97
|
+
.r-1x1 {
|
98
|
+
aspect-ratio: 1 / 1;
|
109
99
|
}
|
110
100
|
|
111
|
-
|
112
|
-
|
101
|
+
.r-5x4 {
|
102
|
+
aspect-ratio: 5 / 4;
|
113
103
|
}
|
114
104
|
|
115
|
-
|
116
|
-
|
105
|
+
.r-4x3 {
|
106
|
+
aspect-ratio: 4 / 3;
|
117
107
|
}
|
118
108
|
|
119
|
-
|
120
|
-
|
109
|
+
.r-3x2 {
|
110
|
+
aspect-ratio: 3 / 2;
|
121
111
|
}
|
122
112
|
|
123
|
-
|
124
|
-
|
113
|
+
.r-16x9 {
|
114
|
+
aspect-ratio: 16 / 9;
|
125
115
|
}
|
126
116
|
|
127
|
-
|
128
|
-
|
117
|
+
.r-2x1 {
|
118
|
+
aspect-ratio: 2 / 1;
|
129
119
|
}
|
120
|
+
}
|
130
121
|
|
131
|
-
|
132
|
-
|
122
|
+
@supports not(aspect-ratio: 1/1) {
|
123
|
+
.proportional-container {
|
124
|
+
> * {
|
125
|
+
bottom: 0;
|
126
|
+
display: block;
|
127
|
+
height: 100%;
|
128
|
+
left: 0;
|
129
|
+
position: absolute;
|
130
|
+
right: 0;
|
131
|
+
top: 0;
|
132
|
+
width: 100%;
|
133
|
+
}
|
134
|
+
|
135
|
+
&::before {
|
136
|
+
content: '\A';
|
137
|
+
display: block;
|
138
|
+
}
|
139
|
+
|
140
|
+
&.r-1x1::before {
|
141
|
+
padding-top: 100%;
|
142
|
+
}
|
143
|
+
|
144
|
+
&.r-5x4::before {
|
145
|
+
padding-top: 80%;
|
146
|
+
}
|
147
|
+
|
148
|
+
&.r-4x3::before {
|
149
|
+
padding-top: 75%;
|
150
|
+
}
|
151
|
+
|
152
|
+
&.r-3x2::before {
|
153
|
+
padding-top: 66.67%;
|
154
|
+
}
|
155
|
+
|
156
|
+
&.r-16x9::before {
|
157
|
+
padding-top: 56.25%;
|
158
|
+
}
|
159
|
+
|
160
|
+
&.r-2x1::before {
|
161
|
+
padding-top: 50%;
|
162
|
+
}
|
133
163
|
}
|
134
164
|
}
|
135
165
|
|
@@ -2,6 +2,12 @@ $form-control-color: hsl(220, 75%, 75%) !default;
|
|
2
2
|
$form-field-error: #f00 !default;
|
3
3
|
$form-input-bg: #fff !default;
|
4
4
|
|
5
|
+
:root {
|
6
|
+
--form-control-color: #{$form-control-color};
|
7
|
+
--form-field-error: #{$form-field-error};
|
8
|
+
--form-input-bg: #{$form-input-bg};
|
9
|
+
}
|
10
|
+
|
5
11
|
form {
|
6
12
|
margin: 0;
|
7
13
|
padding: 0;
|
@@ -18,7 +24,7 @@ form {
|
|
18
24
|
}
|
19
25
|
|
20
26
|
.check-result-error {
|
21
|
-
color:
|
27
|
+
color: var(--form-field-error);
|
22
28
|
|
23
29
|
&::before {
|
24
30
|
content: '\261D';
|
@@ -50,8 +56,14 @@ form {
|
|
50
56
|
margin: var(--spacer-xs) 0;
|
51
57
|
}
|
52
58
|
|
59
|
+
.meta-texts {
|
60
|
+
label {
|
61
|
+
width: 100%;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
53
65
|
.errors {
|
54
|
-
color:
|
66
|
+
color: var(--form-field-error);
|
55
67
|
padding: var(--spacer-xxs) var(--spacer-xxs) 0 var(--spacer-s);
|
56
68
|
|
57
69
|
li {
|
@@ -62,7 +74,7 @@ form {
|
|
62
74
|
}
|
63
75
|
|
64
76
|
&:last-of-type {
|
65
|
-
border-bottom: .1rem solid
|
77
|
+
border-bottom: .1rem solid var(--form-field-error);
|
66
78
|
padding-bottom: var(--spacer-xs);
|
67
79
|
}
|
68
80
|
}
|
@@ -151,7 +163,7 @@ form {
|
|
151
163
|
|
152
164
|
.input-select,
|
153
165
|
.input-text {
|
154
|
-
background-color:
|
166
|
+
background-color: var(--form-input-bg);
|
155
167
|
border: .1rem solid var(--input-border);
|
156
168
|
border-radius: var(--spacer-xxs);
|
157
169
|
font-size: var(--font-size-normal);
|
@@ -169,12 +181,12 @@ form {
|
|
169
181
|
-moz-appearance: none;
|
170
182
|
-webkit-appearance: none;
|
171
183
|
appearance: none;
|
172
|
-
background:
|
184
|
+
background: var(--form-input-bg) image_url('biovision/icons/dropdown.svg') no-repeat center right var(--spacer-xs) / 1.1rem auto;
|
173
185
|
padding-right: 3.2rem;
|
174
186
|
}
|
175
187
|
|
176
188
|
.floating-label {
|
177
|
-
display: block;
|
189
|
+
display: inline-block;
|
178
190
|
padding: 1.4rem 0 0 0;
|
179
191
|
position: relative;
|
180
192
|
|
@@ -198,17 +210,17 @@ form {
|
|
198
210
|
|
199
211
|
.flag-label {
|
200
212
|
align-items: flex-start;
|
201
|
-
display: flex;
|
213
|
+
display: inline-flex;
|
214
|
+
gap: var(--spacer-xxs);
|
202
215
|
|
203
216
|
input {
|
204
217
|
-moz-appearance: none;
|
205
218
|
-webkit-appearance: none;
|
206
219
|
appearance: none;
|
207
|
-
border: .2rem solid
|
220
|
+
border: .2rem solid var(--form-control-color);
|
208
221
|
border-radius: .2rem;
|
209
222
|
display: inline-block;
|
210
223
|
height: 1.6rem;
|
211
|
-
margin-right: var(--spacer-xxs);
|
212
224
|
outline: none;
|
213
225
|
width: 1.6rem;
|
214
226
|
|
@@ -221,7 +233,7 @@ form {
|
|
221
233
|
}
|
222
234
|
|
223
235
|
&:checked {
|
224
|
-
background: radial-gradient(#fff, #fff 25%,
|
236
|
+
background: radial-gradient(#fff, #fff 25%, var(--form-control-color) 25%, var(--form-control-color));
|
225
237
|
}
|
226
238
|
|
227
239
|
&:disabled {
|
@@ -260,3 +272,21 @@ form {
|
|
260
272
|
padding: 0;
|
261
273
|
}
|
262
274
|
}
|
275
|
+
|
276
|
+
.searchable-list {
|
277
|
+
.current {
|
278
|
+
margin: var(--spacer-xs) 0;
|
279
|
+
}
|
280
|
+
|
281
|
+
ul {
|
282
|
+
list-style: none;
|
283
|
+
}
|
284
|
+
|
285
|
+
.text {
|
286
|
+
display: inline-block;
|
287
|
+
|
288
|
+
&:empty {
|
289
|
+
display: none;
|
290
|
+
}
|
291
|
+
}
|
292
|
+
}
|
@@ -25,11 +25,13 @@
|
|
25
25
|
.header-authentication {
|
26
26
|
align-items: center;
|
27
27
|
display: flex;
|
28
|
+
gap: var(--spacer-xxs);
|
28
29
|
margin: 0 0 0 auto;
|
29
30
|
|
30
31
|
.avatar {
|
31
32
|
display: inline-block;
|
32
33
|
height: 2.4rem;
|
34
|
+
overflow: hidden;
|
33
35
|
width: 2.4rem;
|
34
36
|
|
35
37
|
img {
|
@@ -38,4 +40,12 @@
|
|
38
40
|
width: 100%;
|
39
41
|
}
|
40
42
|
}
|
43
|
+
|
44
|
+
.current-user {
|
45
|
+
align-items: center;
|
46
|
+
color: inherit;
|
47
|
+
display: flex;
|
48
|
+
font-size: var(--font-size-decreased);
|
49
|
+
gap: var(--spacer-xs);
|
50
|
+
}
|
41
51
|
}
|
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
# Handling components
|
4
4
|
class Admin::ComponentsController < AdminController
|
5
|
+
include ProcessedForms
|
6
|
+
|
5
7
|
# skip_before_action :restrict_access, only: :index
|
6
8
|
skip_before_action :verify_authenticity_token, only: :ckeditor
|
7
9
|
|
8
10
|
# get /admin/components
|
9
11
|
def index
|
10
|
-
@collection = BiovisionComponent.list_for_administration
|
12
|
+
@collection = BiovisionComponent.active.list_for_administration
|
11
13
|
end
|
12
14
|
|
13
15
|
# get /admin/components/:slug
|
@@ -52,10 +54,11 @@ class Admin::ComponentsController < AdminController
|
|
52
54
|
@collection = list.page(current_page)
|
53
55
|
end
|
54
56
|
|
57
|
+
# post /admin/components/:slug/images
|
55
58
|
def create_image
|
56
59
|
if @handler.permit?('simple_images.create')
|
57
|
-
@entity = @handler.
|
58
|
-
if @entity
|
60
|
+
@entity = @handler.upload_image(image_parameters)
|
61
|
+
if @entity
|
59
62
|
render 'image', formats: :json
|
60
63
|
else
|
61
64
|
form_processed_with_error(:new_image)
|
@@ -72,7 +75,7 @@ class Admin::ComponentsController < AdminController
|
|
72
75
|
biovision_component: @handler.component
|
73
76
|
}.merge(owner_for_entity(true))
|
74
77
|
|
75
|
-
@entity =
|
78
|
+
@entity = @handler.upload_image(parameters)
|
76
79
|
|
77
80
|
render json: {
|
78
81
|
uploaded: 1,
|
@@ -104,7 +107,8 @@ class Admin::ComponentsController < AdminController
|
|
104
107
|
%w[images] => 'simple_images.view',
|
105
108
|
%w[create_image ckeditor] => 'simple_images.create',
|
106
109
|
%w[settings] => 'settings.view',
|
107
|
-
%w[update_settings update_parameter delete_parameter] => 'settings.edit'
|
110
|
+
%w[update_settings update_parameter delete_parameter] => 'settings.edit',
|
111
|
+
%w[show] => 'view'
|
108
112
|
)
|
109
113
|
end
|
110
114
|
end
|
@@ -4,6 +4,7 @@
|
|
4
4
|
class Admin::UsersController < AdminController
|
5
5
|
include Authentication
|
6
6
|
include CrudEntities
|
7
|
+
include ProcessedForms
|
7
8
|
include ToggleableEntity
|
8
9
|
|
9
10
|
before_action :set_entity, except: %i[check create index new search]
|
@@ -29,7 +30,7 @@ class Admin::UsersController < AdminController
|
|
29
30
|
|
30
31
|
# post /admin/users/:id/authenticate
|
31
32
|
def authenticate
|
32
|
-
|
33
|
+
if component_handler.permit?('log_in', @entity) && !@entity.super_user?
|
33
34
|
cookies['pt'] = {
|
34
35
|
value: cookies['token'],
|
35
36
|
expires: 1.year.from_now,
|
@@ -2,27 +2,7 @@
|
|
2
2
|
|
3
3
|
# Common administrative controller
|
4
4
|
class AdminController < ApplicationController
|
5
|
-
|
6
|
-
|
7
|
-
private
|
8
|
-
|
9
|
-
def restrict_access
|
10
|
-
user_action = "#{controller_name}.#{role_end_from_action}"
|
11
|
-
role_name = "#{component_handler.slug}.#{user_action}"
|
12
|
-
error = t('admin.errors.unauthorized.missing_role', role: role_name)
|
5
|
+
include RestrictedAccess
|
13
6
|
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def role_end_from_action
|
18
|
-
role = action_to_role_map.select { |k| k.include?(action_name) }.values.last
|
19
|
-
role || 'default'
|
20
|
-
end
|
21
|
-
|
22
|
-
def action_to_role_map
|
23
|
-
{
|
24
|
-
%w[index show search] => 'view',
|
25
|
-
%w[create destroy edit new priority toggle update] => 'edit'
|
26
|
-
}
|
27
|
-
end
|
7
|
+
before_action :restrict_access
|
28
8
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Adds method for working with component stories
|
4
|
+
module ComponentStories
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
# Perform story
|
8
|
+
#
|
9
|
+
# Parameters:
|
10
|
+
# slug: story slug app/lib/biovision/components/.../stories/<slug>_story.rb
|
11
|
+
# entity_id: optional parameter for setting entity context
|
12
|
+
#
|
13
|
+
# post [...]/stories/:slug
|
14
|
+
def story
|
15
|
+
story_parameters = params[:parameters]&.permit!.to_h
|
16
|
+
entity_id = param_from_request(:entity_id)
|
17
|
+
story_handler = component_handler.story(params[:slug], entity_id)
|
18
|
+
result = story_handler.perform(story_parameters)
|
19
|
+
|
20
|
+
render json: { meta: { result: result } }
|
21
|
+
end
|
22
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# Adds method for CRUD
|
4
4
|
module CrudEntities
|
5
5
|
extend ActiveSupport::Concern
|
6
|
+
include ProcessedForms
|
6
7
|
|
7
8
|
# get [scope]/[table_name]/search?q=
|
8
9
|
def search
|
@@ -13,8 +14,8 @@ module CrudEntities
|
|
13
14
|
# get [scope]/[table_name]
|
14
15
|
def index
|
15
16
|
@filter = params[:filter]&.permit!.to_h
|
16
|
-
data_helper = Biovision::Helpers::DataHelper.new(model_class)
|
17
|
-
@collection = data_helper.administrative_collection(current_page
|
17
|
+
data_helper = Biovision::Helpers::DataHelper.new(model_class, @filter)
|
18
|
+
@collection = data_helper.administrative_collection(current_page)
|
18
19
|
end
|
19
20
|
|
20
21
|
# get [scope]/[table_name]/:id
|
@@ -108,7 +109,7 @@ module CrudEntities
|
|
108
109
|
if model_class.respond_to?(:creation_parameters)
|
109
110
|
explicit_creation_parameters
|
110
111
|
else
|
111
|
-
|
112
|
+
implicit_creation_parameters
|
112
113
|
end
|
113
114
|
end
|
114
115
|
|
@@ -120,13 +121,20 @@ module CrudEntities
|
|
120
121
|
parameters
|
121
122
|
end
|
122
123
|
|
124
|
+
def implicit_creation_parameters
|
125
|
+
parameters = entity_parameters
|
126
|
+
parameters.merge!(tracking_for_entity) if model_class.include?(HasTrack)
|
127
|
+
parameters.merge!(owner_for_entity) if model_class.include?(HasOwner)
|
128
|
+
parameters
|
129
|
+
end
|
130
|
+
|
123
131
|
def entity_parameters
|
124
132
|
permitted = model_class.entity_parameters
|
125
133
|
params.require(model_key).permit(permitted)
|
126
134
|
end
|
127
135
|
|
128
136
|
def apply_meta
|
129
|
-
new_data = params[:meta]
|
137
|
+
new_data = params[:meta]&.permit!.to_h
|
130
138
|
@entity.meta = new_data
|
131
139
|
end
|
132
140
|
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Adds methods for CRUD in My namespace
|
4
|
+
module MyCrudEntities
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
included ProcessedForms
|
7
|
+
|
8
|
+
# get [scope]/[table_name]/search?q=
|
9
|
+
def search
|
10
|
+
q = param_from_request(:q)
|
11
|
+
@collection = model_class.search(q).list_for_owner(current_user).page(current_page)
|
12
|
+
end
|
13
|
+
|
14
|
+
# get [scope]/[table_name]
|
15
|
+
def index
|
16
|
+
@filter = params[:filter]&.permit!.to_h
|
17
|
+
data_helper = Biovision::Helpers::DataHelper.new(model_class, @filter)
|
18
|
+
@collection = data_helper.personal_collection(current_user, current_page)
|
19
|
+
end
|
20
|
+
|
21
|
+
# get [scope]/[table_name]/:id
|
22
|
+
def show
|
23
|
+
end
|
24
|
+
|
25
|
+
# post [scope]/[table_name]/check
|
26
|
+
def check
|
27
|
+
@entity = model_class.instance_for_check(params[:entity_id], entity_parameters)
|
28
|
+
|
29
|
+
render 'shared/forms/check'
|
30
|
+
end
|
31
|
+
|
32
|
+
# get [scope]/[table_name]/new
|
33
|
+
def new
|
34
|
+
@entity = model_class.new
|
35
|
+
render view_for_new
|
36
|
+
end
|
37
|
+
|
38
|
+
# post [scope]/[table_name]
|
39
|
+
def create
|
40
|
+
@entity = component_handler.new_entity(model_class, creation_parameters)
|
41
|
+
apply_meta if @entity.respond_to?(:meta=)
|
42
|
+
if @entity.save
|
43
|
+
form_processed_ok(path_after_save)
|
44
|
+
else
|
45
|
+
form_processed_with_error(view_for_new)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# get [scope]/[table_name]/:id/edit
|
50
|
+
def edit
|
51
|
+
render view_for_edit
|
52
|
+
end
|
53
|
+
|
54
|
+
# patch [scope]/[table_name]/:id
|
55
|
+
def update
|
56
|
+
apply_meta if @entity.respond_to?(:meta=)
|
57
|
+
|
58
|
+
if component_handler.update_entity(@entity, entity_parameters)
|
59
|
+
form_processed_ok(path_after_save)
|
60
|
+
else
|
61
|
+
form_processed_with_error(view_for_edit)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# delete [scope]/[table_name]/:id
|
66
|
+
def destroy
|
67
|
+
flash[:notice] = t('.success') if @entity.destroy
|
68
|
+
redirect_to path_after_destroy
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def view_for_new
|
74
|
+
default_view = "#{controller_path}/new"
|
75
|
+
lookup_context.exists?(default_view) ? default_view : 'shared/my/entity/new'
|
76
|
+
end
|
77
|
+
|
78
|
+
def view_for_edit
|
79
|
+
default_view = "#{controller_path}/edit"
|
80
|
+
lookup_context.exists?(default_view) ? default_view : 'shared/my/entity/edit'
|
81
|
+
end
|
82
|
+
|
83
|
+
def model_class
|
84
|
+
@model_class ||= controller_name.classify.constantize
|
85
|
+
end
|
86
|
+
|
87
|
+
def model_key
|
88
|
+
model_class.model_name.to_s.underscore
|
89
|
+
end
|
90
|
+
|
91
|
+
def path_after_save
|
92
|
+
if @entity.respond_to?(:my_url)
|
93
|
+
@entity.my_url
|
94
|
+
else
|
95
|
+
scope = self.class.module_parent.to_s.downcase
|
96
|
+
prefix = scope.blank? ? '' : "/#{scope}"
|
97
|
+
key = model_class.column_names.include?('uuid') ? @entity.uuid : @entity.id
|
98
|
+
"#{prefix}/#{model_class.table_name}/#{key}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def path_after_destroy
|
103
|
+
scope = self.class.module_parent.to_s.downcase
|
104
|
+
prefix = scope.blank? ? '' : "/#{scope}"
|
105
|
+
"#{prefix}/#{model_class.table_name}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def set_entity
|
109
|
+
id = params[:id].to_s
|
110
|
+
has_uuid = model_class.column_names.include?('uuid')
|
111
|
+
key = id.include?('-') && has_uuid ? :uuid : :id
|
112
|
+
@entity = model_class.owned_by(current_user).find_by(key => params[:id])
|
113
|
+
handle_http_404("Cannot find #{model_class.model_name}") if @entity.nil?
|
114
|
+
end
|
115
|
+
|
116
|
+
def creation_parameters
|
117
|
+
if model_class.respond_to?(:creation_parameters)
|
118
|
+
explicit_creation_parameters
|
119
|
+
else
|
120
|
+
implicit_creation_parameters
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def explicit_creation_parameters
|
125
|
+
permitted = model_class.creation_parameters
|
126
|
+
parameters = params.require(model_key).permit(permitted)
|
127
|
+
parameters.merge!(tracking_for_entity) if model_class.include?(HasTrack)
|
128
|
+
parameters.merge(owner_for_entity)
|
129
|
+
end
|
130
|
+
|
131
|
+
def implicit_creation_parameters
|
132
|
+
parameters = entity_parameters
|
133
|
+
parameters.merge!(tracking_for_entity) if model_class.include?(HasTrack)
|
134
|
+
parameters.merge(owner_for_entity)
|
135
|
+
end
|
136
|
+
|
137
|
+
def entity_parameters
|
138
|
+
permitted = model_class.entity_parameters
|
139
|
+
params.require(model_key).permit(permitted)
|
140
|
+
end
|
141
|
+
|
142
|
+
def apply_meta
|
143
|
+
new_data = params[:meta].permit!
|
144
|
+
@entity.meta = new_data
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Adds method for redirects after processed forms
|
4
|
+
module ProcessedForms
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
# @param [String] next_page
|
10
|
+
def form_processed_ok(next_page)
|
11
|
+
respond_to do |format|
|
12
|
+
format.js { render(js: "document.location.href = '#{next_page}'") }
|
13
|
+
format.json { render(json: { links: { next: next_page } }) }
|
14
|
+
format.html { redirect_to(next_page) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param [Symbol|String] view_to_render
|
19
|
+
# @param [Array] errors
|
20
|
+
def form_processed_with_error(view_to_render, errors = [])
|
21
|
+
@errors = errors
|
22
|
+
respond_to do |format|
|
23
|
+
format.js { render('shared/forms/errors', status: :bad_request) }
|
24
|
+
format.json { render('shared/forms/errors', status: :bad_request) }
|
25
|
+
format.html { render(view_to_render, status: :bad_request) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|