trestle 0.10.0.pre → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +26 -0
- data/.github/workflows/rspec.yml +6 -2
- data/Gemfile +14 -5
- data/README.md +1 -1
- data/app/assets/bundle/trestle/admin.css +9 -9
- data/app/assets/bundle/trestle/admin.js +13 -13
- data/app/assets/bundle/trestle/fa-brands-400.ttf +0 -0
- data/app/assets/bundle/trestle/fa-brands-400.woff2 +0 -0
- data/app/assets/bundle/trestle/fa-regular-400.ttf +0 -0
- data/app/assets/bundle/trestle/fa-regular-400.woff2 +0 -0
- data/app/assets/bundle/trestle/fa-solid-900.ttf +0 -0
- data/app/assets/bundle/trestle/fa-solid-900.woff2 +0 -0
- data/app/assets/bundle/trestle/photoswipe-063ce7be40e10b3e6848.digested.js +6 -0
- data/app/assets/sprockets/trestle/icons/font-awesome.css.erb +1 -1
- data/app/controllers/concerns/trestle/controller/modal.rb +3 -1
- data/app/controllers/concerns/trestle/controller/turbo_stream.rb +12 -0
- data/app/controllers/concerns/trestle/resource/controller/actions.rb +3 -3
- data/app/controllers/trestle/application_controller.rb +1 -1
- data/app/helpers/trestle/modal_helper.rb +0 -5
- data/app/helpers/trestle/turbo/frame_helper.rb +29 -0
- data/app/helpers/trestle/turbo/stream_helper.rb +9 -0
- data/app/helpers/trestle/turbo/tag_builder.rb +21 -0
- data/app/helpers/trestle/url_helper.rb +2 -2
- data/app/views/layouts/trestle/admin.html.erb +1 -1
- data/app/views/layouts/trestle/admin.turbo_stream.erb +2 -9
- data/app/views/trestle/application/_header.html.erb +12 -10
- data/app/views/trestle/resource/create.turbo_stream.erb +1 -5
- data/app/views/trestle/resource/destroy.turbo_stream.erb +1 -1
- data/app/views/trestle/resource/edit.html.erb +2 -0
- data/app/views/trestle/resource/index.html.erb +5 -0
- data/app/views/trestle/resource/new.html.erb +5 -0
- data/app/views/trestle/resource/show.html.erb +2 -0
- data/app/views/trestle/resource/update.turbo_stream.erb +1 -5
- data/app/views/trestle/shared/_sidebar.html.erb +2 -2
- data/frontend/css/components/_alerts.scss +22 -20
- data/frontend/css/components/_avatar.scss +12 -12
- data/frontend/css/components/_background.scss +1 -1
- data/frontend/css/components/_breadcrumbs.scss +8 -29
- data/frontend/css/components/_buttons.scss +3 -3
- data/frontend/css/components/_datepicker.scss +3 -3
- data/frontend/css/components/_dropdown.scss +18 -26
- data/frontend/css/components/_forms.scss +4 -4
- data/frontend/css/components/_grid.scss +29 -0
- data/frontend/css/components/_media-grid.scss +1 -1
- data/frontend/css/components/_modal.scss +4 -4
- data/frontend/css/components/_pagination.scss +4 -8
- data/frontend/css/components/_popover.scss +1 -1
- data/frontend/css/components/_scopes.scss +4 -10
- data/frontend/css/components/_select.scss +8 -9
- data/frontend/css/components/_sort.scss +1 -1
- data/frontend/css/components/_table.scss +5 -5
- data/frontend/css/components/_tabs.scss +11 -18
- data/frontend/css/components/_tags.scss +16 -6
- data/frontend/css/components/_toolbars.scss +9 -9
- data/frontend/css/core/_functions.scss +0 -8
- data/frontend/css/core/_theme.scss +3 -0
- data/frontend/css/core/_typography.scss +12 -19
- data/frontend/css/index.scss +3 -1
- data/frontend/css/layout/_base.scss +4 -2
- data/frontend/css/layout/_content-header.scss +71 -0
- data/frontend/css/layout/_footer.scss +5 -7
- data/frontend/css/layout/_main-content.scss +107 -0
- data/frontend/css/layout/_navigation.scss +111 -49
- data/frontend/css/layout/_sidebar.scss +60 -34
- data/frontend/css/variables/_bootstrap.scss +30 -21
- data/frontend/css/variables/_trestle.scss +20 -17
- data/frontend/js/controllers/batch_action_controller.js +59 -0
- data/frontend/js/controllers/checkbox_select_controller.js +3 -0
- data/frontend/js/controllers/confirm_delete_controller.js +4 -4
- data/frontend/js/controllers/gallery_controller.js +2 -0
- data/frontend/js/controllers/lightbox_controller.js +0 -2
- data/lib/trestle/engine.rb +18 -16
- data/lib/trestle/form/renderer.rb +1 -1
- data/lib/trestle/resource/toolbar.rb +18 -8
- data/lib/trestle/sprockets_compressor.rb +16 -0
- data/lib/trestle/toolbar/context.rb +7 -4
- data/lib/trestle/toolbar/menu.rb +8 -5
- data/lib/trestle/version.rb +1 -1
- data/package.json +1 -1
- data/trestle.gemspec +5 -9
- data/yarn.lock +350 -363
- metadata +35 -70
- data/app/assets/bundle/trestle/photoswipe-7aa1aec9c3c1fd65c382.digested.js +0 -6
- data/app/controllers/concerns/trestle/controller/turbo.rb +0 -21
- data/app/helpers/trestle/turbo_frame_helper.rb +0 -34
- data/frontend/css/layout/_content.scss +0 -173
@@ -1,9 +1,19 @@
|
|
1
1
|
@use "sass:math";
|
2
2
|
|
3
|
+
.app-wrapper {
|
4
|
+
--sidebar-width: #{$sidebar-width};
|
5
|
+
--sidebar-width-collapsed: #{$sidebar-width-collapsed};
|
6
|
+
--sidebar-padding: #{$sidebar-padding};
|
7
|
+
--sidebar-padding-collapsed: #{$sidebar-padding-collapsed};
|
8
|
+
--sidebar-transition-duration: #{$sidebar-transition-duration};
|
9
|
+
--sidebar-transition-timing: ease-out;
|
10
|
+
--sidebar-bg: #{$sidebar-bg};
|
11
|
+
}
|
12
|
+
|
3
13
|
.app-sidebar {
|
4
|
-
background:
|
14
|
+
background: var(--sidebar-bg);
|
5
15
|
|
6
|
-
width:
|
16
|
+
width: var(--sidebar-width);
|
7
17
|
padding: 0;
|
8
18
|
|
9
19
|
flex-shrink: 0;
|
@@ -15,6 +25,8 @@
|
|
15
25
|
flex-wrap: nowrap;
|
16
26
|
|
17
27
|
align-items: stretch;
|
28
|
+
|
29
|
+
transition: width var(--sidebar-transition-duration) var(--sidebar-transition-timing);
|
18
30
|
}
|
19
31
|
|
20
32
|
.app-sidebar-header {
|
@@ -25,10 +37,12 @@
|
|
25
37
|
display: flex;
|
26
38
|
align-items: stretch;
|
27
39
|
|
40
|
+
overflow: hidden;
|
41
|
+
|
28
42
|
.navbar-toggler {
|
29
|
-
|
30
|
-
|
31
|
-
|
43
|
+
--#{$prefix}navbar-toggler-bg: #{$sidebar-mobile-toggle-bg};
|
44
|
+
--#{$prefix}navbar-toggler-color: #{$sidebar-mobile-toggle-border-color};
|
45
|
+
--#{$prefix}navbar-toggler-border-color: #{$sidebar-mobile-toggle-border-color};
|
32
46
|
|
33
47
|
outline: none;
|
34
48
|
|
@@ -37,28 +51,29 @@
|
|
37
51
|
margin-left: math.div($grid-gutter-width, 2);
|
38
52
|
margin-right: math.div($grid-gutter-width, 2);
|
39
53
|
|
40
|
-
background: var(
|
54
|
+
background: var(--#{$prefix}navbar-toggler-bg);
|
41
55
|
|
42
56
|
&:hover, &:focus {
|
43
|
-
|
44
|
-
|
57
|
+
--#{$prefix}navbar-toggler-border-color: #{$sidebar-mobile-toggle-active-border-color};
|
58
|
+
--#{$prefix}navbar-toggler-bg: #{$sidebar-mobile-toggle-active-bg};
|
45
59
|
}
|
46
60
|
}
|
47
61
|
|
48
62
|
.navbar-toggler-icon {
|
49
|
-
|
63
|
+
--#{$prefix}navbar-toggler-icon-bg: #{$sidebar-mobile-toggle-icon-bg};
|
50
64
|
}
|
51
65
|
}
|
52
66
|
|
53
67
|
.app-sidebar-title {
|
54
|
-
flex: 1;
|
68
|
+
flex: 1 0 var(--sidebar-width);
|
69
|
+
width: var(--sidebar-width);
|
55
70
|
|
56
71
|
display: flex;
|
57
72
|
align-items: center;
|
58
73
|
|
59
|
-
padding:
|
74
|
+
padding: var(--sidebar-padding);
|
60
75
|
|
61
|
-
font-size: 1.
|
76
|
+
font-size: 1.25rem;
|
62
77
|
font-weight: 500;
|
63
78
|
text-shadow: rgba(black, 0.5) 0 1px 1px;
|
64
79
|
color: white;
|
@@ -72,7 +87,7 @@
|
|
72
87
|
max-height: 100%;
|
73
88
|
|
74
89
|
& + .title-large {
|
75
|
-
margin-left:
|
90
|
+
margin-left: 0.75rem;
|
76
91
|
}
|
77
92
|
}
|
78
93
|
|
@@ -112,8 +127,9 @@
|
|
112
127
|
color: $sidebar-toggle-color;
|
113
128
|
border: none;
|
114
129
|
|
115
|
-
font-size: 1.
|
116
|
-
|
130
|
+
font-size: 1.25rem;
|
131
|
+
width: var(--sidebar-width-collapsed);
|
132
|
+
padding: 0.625rem;
|
117
133
|
|
118
134
|
cursor: pointer;
|
119
135
|
|
@@ -138,19 +154,13 @@
|
|
138
154
|
}
|
139
155
|
|
140
156
|
.app-wrapper {
|
141
|
-
|
142
|
-
margin-right: 0;
|
157
|
+
width: calc(100% + var(--sidebar-width));
|
143
158
|
|
144
|
-
|
145
|
-
|
146
|
-
transition-property: margin-left, margin-right;
|
147
|
-
}
|
148
|
-
}
|
159
|
+
translate: calc(var(--sidebar-width) * -1);
|
160
|
+
transition: translate var(--sidebar-transition-duration) ease-out;
|
149
161
|
|
150
|
-
|
151
|
-
|
152
|
-
margin-left: 0;
|
153
|
-
margin-right: -$sidebar-width;
|
162
|
+
.mobile-nav-expanded & {
|
163
|
+
translate: 0;
|
154
164
|
}
|
155
165
|
}
|
156
166
|
|
@@ -161,14 +171,14 @@
|
|
161
171
|
.app-sidebar-header {
|
162
172
|
position: absolute;
|
163
173
|
top: 0;
|
164
|
-
left:
|
174
|
+
left: var(--sidebar-width);
|
165
175
|
right: 0;
|
166
176
|
z-index: 1;
|
167
177
|
}
|
168
178
|
|
169
179
|
.app-sidebar-title {
|
170
180
|
justify-content: center;
|
171
|
-
padding:
|
181
|
+
padding: var(--sidebar-padding-collapsed);
|
172
182
|
|
173
183
|
// Match right margin with navbar toggler width:
|
174
184
|
// (margin + border + font-size * icon-width + padding)
|
@@ -182,14 +192,17 @@
|
|
182
192
|
|
183
193
|
@include media-breakpoint-between(md, xl) {
|
184
194
|
.app-sidebar {
|
185
|
-
width:
|
195
|
+
width: var(--sidebar-width-collapsed);
|
186
196
|
|
187
197
|
.app-sidebar-header {
|
188
198
|
text-align: center;
|
189
199
|
}
|
190
200
|
|
191
201
|
.app-sidebar-title {
|
192
|
-
|
202
|
+
width: var(--sidebar-width-collapsed);
|
203
|
+
flex-basis: var(--sidebar-width-collapsed);
|
204
|
+
|
205
|
+
padding: var(--sidebar-padding-collapsed);
|
193
206
|
justify-content: center;
|
194
207
|
|
195
208
|
img {
|
@@ -210,14 +223,17 @@
|
|
210
223
|
}
|
211
224
|
|
212
225
|
.sidebar-expanded & {
|
213
|
-
width:
|
226
|
+
width: var(--sidebar-width);
|
214
227
|
|
215
228
|
.app-sidebar-header {
|
216
229
|
text-align: left;
|
217
230
|
}
|
218
231
|
|
219
232
|
.app-sidebar-title {
|
220
|
-
|
233
|
+
width: var(--sidebar-width);
|
234
|
+
flex-basis: var(--sidebar-width);
|
235
|
+
|
236
|
+
padding: var(--sidebar-padding);
|
221
237
|
justify-content: flex-start;
|
222
238
|
|
223
239
|
img {
|
@@ -243,14 +259,17 @@
|
|
243
259
|
@include media-breakpoint-up(xl) {
|
244
260
|
.app-sidebar {
|
245
261
|
.sidebar-collapsed & {
|
246
|
-
width:
|
262
|
+
width: var(--sidebar-width-collapsed);
|
247
263
|
|
248
264
|
.app-sidebar-header {
|
249
265
|
text-align: center;
|
250
266
|
}
|
251
267
|
|
252
268
|
.app-sidebar-title {
|
253
|
-
|
269
|
+
width: var(--sidebar-width-collapsed);
|
270
|
+
flex-basis: var(--sidebar-width-collapsed);
|
271
|
+
|
272
|
+
padding: var(--sidebar-padding-collapsed);
|
254
273
|
justify-content: center;
|
255
274
|
|
256
275
|
img {
|
@@ -272,3 +291,10 @@
|
|
272
291
|
}
|
273
292
|
}
|
274
293
|
}
|
294
|
+
|
295
|
+
@media (prefers-reduced-motion) {
|
296
|
+
.app-sidebar,
|
297
|
+
.app-wrapper {
|
298
|
+
transition: none;
|
299
|
+
}
|
300
|
+
}
|
@@ -23,7 +23,7 @@ $min-contrast-ratio: 1.7;
|
|
23
23
|
$enable-shadows: true;
|
24
24
|
|
25
25
|
// Decrease default grid spacing
|
26
|
-
$grid-gutter-width: 1.
|
26
|
+
$grid-gutter-width: 1.25rem;
|
27
27
|
|
28
28
|
|
29
29
|
// Characters which are escaped by the escape-svg function
|
@@ -49,15 +49,17 @@ $link-decoration: none;
|
|
49
49
|
$headings-font-weight: 400;
|
50
50
|
$headings-margin-bottom: 1rem;
|
51
51
|
|
52
|
-
$
|
53
|
-
|
54
|
-
$
|
55
|
-
$
|
56
|
-
$
|
57
|
-
$
|
52
|
+
$font-size-base: 0.875rem;
|
53
|
+
|
54
|
+
$h1-font-size: 1.75rem;
|
55
|
+
$h2-font-size: 1.5rem;
|
56
|
+
$h3-font-size: 1.25rem;
|
57
|
+
$h4-font-size: 1.125rem;
|
58
|
+
$h5-font-size: 0.95rem;
|
59
|
+
$h6-font-size: 0.875rem;
|
58
60
|
|
59
61
|
$hr-color: rgba(black, 0.375);
|
60
|
-
$hr-margin-y: 1.
|
62
|
+
$hr-margin-y: 1.25rem;
|
61
63
|
|
62
64
|
|
63
65
|
// Navs
|
@@ -80,8 +82,11 @@ $nav-tabs-link-active-color: $body-color;
|
|
80
82
|
|
81
83
|
// Navbar
|
82
84
|
|
83
|
-
$navbar-
|
84
|
-
$navbar-dark-color:
|
85
|
+
$navbar-light-color: rgba(white, 0.75);
|
86
|
+
$navbar-dark-color: rgba(white, 0.75);
|
87
|
+
|
88
|
+
$navbar-toggler-padding-x: 0.375rem;
|
89
|
+
$navbar-toggler-focus-width: 0.25rem;
|
85
90
|
|
86
91
|
|
87
92
|
// Breadcrumbs
|
@@ -94,7 +99,7 @@ $breadcrumb-divider-color: #cccccc;
|
|
94
99
|
|
95
100
|
// Tables
|
96
101
|
|
97
|
-
$table-cell-padding-x: 0.
|
102
|
+
$table-cell-padding-x: 0.5rem;
|
98
103
|
$table-cell-padding-y: 0.375rem;
|
99
104
|
|
100
105
|
$table-bg: transparent;
|
@@ -105,7 +110,7 @@ $table-border-color: rgba(black, 0.13);
|
|
105
110
|
|
106
111
|
// Alerts
|
107
112
|
|
108
|
-
$alert-padding-y: 1.
|
113
|
+
$alert-padding-y: 1.25rem;
|
109
114
|
$alert-border-radius: 0.1rem;
|
110
115
|
|
111
116
|
|
@@ -134,7 +139,8 @@ $badge-padding-x: 0.6em;
|
|
134
139
|
|
135
140
|
// Buttons
|
136
141
|
|
137
|
-
$btn-padding-x-sm: 0.
|
142
|
+
$btn-padding-x-sm: 0.625rem;
|
143
|
+
$btn-padding-y-sm: 0.25rem;
|
138
144
|
|
139
145
|
|
140
146
|
// Forms
|
@@ -163,7 +169,7 @@ $form-check-padding-start: $form-check-input-width + 0.6em;
|
|
163
169
|
$form-switch-width: 2.25em;
|
164
170
|
$form-switch-focus-color: #aaaaaa;
|
165
171
|
|
166
|
-
$form-select-padding-x-sm: 0.
|
172
|
+
$form-select-padding-x-sm: 0.625rem;
|
167
173
|
$form-select-padding-x-lg: 0.75rem;
|
168
174
|
|
169
175
|
|
@@ -175,7 +181,7 @@ $dropdown-box-shadow: $box-shadow-sm;
|
|
175
181
|
$dropdown-arrow-width: 7px;
|
176
182
|
$dropdown-arrow-outer-width: $dropdown-arrow-width + 1px;
|
177
183
|
$dropdown-header-color: #111111;
|
178
|
-
$dropdown-font-size: 0.
|
184
|
+
$dropdown-font-size: 0.8125rem;
|
179
185
|
|
180
186
|
$dropdown-link-active-bg: var(--primary);
|
181
187
|
|
@@ -208,24 +214,27 @@ $tooltip-color: white;
|
|
208
214
|
|
209
215
|
// Popovers
|
210
216
|
|
211
|
-
$popover-font-size: 0.
|
217
|
+
$popover-font-size: 0.75rem;
|
212
218
|
$popover-box-shadow: $dropdown-box-shadow;
|
213
219
|
|
214
220
|
$popover-header-bg: #f7f7f7;
|
215
221
|
$popover-header-border: #ebebeb;
|
216
222
|
|
223
|
+
$popover-header-padding-x: 0.625rem;
|
224
|
+
$popover-header-padding-y: 0.375rem;
|
225
|
+
|
226
|
+
$popover-body-padding-x: 0.625rem;
|
217
227
|
$popover-body-padding-y: 0.5rem;
|
218
|
-
$popover-body-padding-x: 0.75rem;
|
219
228
|
|
220
229
|
$popover-arrow-width: $dropdown-arrow-width;
|
221
230
|
|
222
231
|
|
223
232
|
// Modals
|
224
233
|
|
225
|
-
$modal-inner-padding: 1.
|
234
|
+
$modal-inner-padding: 1.25rem;
|
226
235
|
|
227
|
-
$modal-header-padding-x: 1.
|
228
|
-
$modal-header-padding-y:
|
236
|
+
$modal-header-padding-x: 1.25rem;
|
237
|
+
$modal-header-padding-y: 1rem;
|
229
238
|
|
230
239
|
$modal-content-bg: white;
|
231
240
|
$modal-content-border-radius: 0;
|
@@ -262,7 +271,7 @@ $s2bs5-clear-hover-bg-lg: $s2bs5-clear-bg-lg;
|
|
262
271
|
$s2bs5-clear-tag-icon: $btn-close-bg;
|
263
272
|
$s2bs5-clear-tag-bg: transparent escape-svg($s2bs5-clear-tag-icon) center / $s2b25-clear-height-sm auto no-repeat;
|
264
273
|
|
265
|
-
$s2bs5-padding-x: 0.
|
274
|
+
$s2bs5-padding-x: 0.625rem;
|
266
275
|
$s2bs5-padding-y: 0.375rem;
|
267
276
|
|
268
277
|
$s2bs5-multi-item-padding-x: 0.375rem;
|
@@ -21,7 +21,7 @@ $theme-bg-variations: (
|
|
21
21
|
$header-bg: white;
|
22
22
|
$header-color: #333333;
|
23
23
|
|
24
|
-
$header-height:
|
24
|
+
$header-height: 3.125rem;
|
25
25
|
|
26
26
|
|
27
27
|
// Footer
|
@@ -29,13 +29,15 @@ $header-height: 50px;
|
|
29
29
|
$footer-bg: #f9f9f9;
|
30
30
|
$footer-color: #888888;
|
31
31
|
|
32
|
+
$footer-padding: 0.375rem 1.25rem;
|
33
|
+
|
32
34
|
|
33
35
|
// Sidebar
|
34
36
|
|
35
37
|
$sidebar-bg: #222222;
|
36
38
|
$sidebar-hover-bg: #1a1a1a;
|
37
39
|
$sidebar-active-bg: #393939;
|
38
|
-
$sidebar-active-border:
|
40
|
+
$sidebar-active-border: 0.25rem;
|
39
41
|
|
40
42
|
$sidebar-link-color: #919191;
|
41
43
|
$sidebar-group-color: #595959;
|
@@ -56,10 +58,13 @@ $sidebar-mobile-toggle-active-border-width: $sidebar-mobile-toggle-border-width;
|
|
56
58
|
$sidebar-mobile-toggle-active-border-color: $sidebar-mobile-toggle-border-color;
|
57
59
|
$sidebar-mobile-toggle-active-border: $sidebar-mobile-toggle-border-width solid $sidebar-mobile-toggle-active-border-color;
|
58
60
|
|
59
|
-
$sidebar-width:
|
60
|
-
$sidebar-width-collapsed:
|
61
|
+
$sidebar-width: 15.625rem;
|
62
|
+
$sidebar-width-collapsed: 3.5rem;
|
63
|
+
|
64
|
+
$sidebar-padding: 0.5rem 0.875rem;
|
65
|
+
$sidebar-padding-collapsed: 0.5rem 0.25rem;
|
61
66
|
|
62
|
-
$sidebar-transition-duration:
|
67
|
+
$sidebar-transition-duration: 200ms;
|
63
68
|
|
64
69
|
|
65
70
|
// Content
|
@@ -67,23 +72,21 @@ $sidebar-transition-duration: 250ms;
|
|
67
72
|
$content-header-bg: #fafafa;
|
68
73
|
$content-sidebar-bg: #f9f9f9;
|
69
74
|
|
70
|
-
$content-sidebar-width:
|
75
|
+
$content-sidebar-width: 17.5rem;
|
71
76
|
|
72
|
-
$main-content-header-bg:
|
73
|
-
$main-content-header-
|
74
|
-
$main-content-header-border: 1px solid rgba(black, 0.1);
|
77
|
+
$main-content-header-bg: $content-sidebar-bg;
|
78
|
+
$main-content-header-border: 1px solid rgba(black, 0.1);
|
75
79
|
|
76
|
-
$main-content-footer-bg:
|
77
|
-
$main-content-footer-
|
78
|
-
$main-content-footer-border: 1px solid rgba(black, 0.1);
|
80
|
+
$main-content-footer-bg: $content-sidebar-bg;
|
81
|
+
$main-content-footer-border: 1px solid rgba(black, 0.1);
|
79
82
|
|
80
83
|
|
81
84
|
// Typography
|
82
85
|
|
83
86
|
$headings-border: 1px solid rgba(black, 0.1);
|
84
87
|
|
85
|
-
$header-font-size-scale: 0.
|
86
|
-
$sidebar-font-size-scale: 0.
|
88
|
+
$header-font-size-scale: 0.8125;
|
89
|
+
$sidebar-font-size-scale: 0.8125;
|
87
90
|
|
88
91
|
$badge-hover-scale: -15%;
|
89
92
|
|
@@ -96,13 +99,13 @@ $tag-border-scale: 0;
|
|
96
99
|
$tag-hover-bg-scale: -15%;
|
97
100
|
$tag-hover-border-scale: 15%;
|
98
101
|
|
99
|
-
$tag-spacing-x: 0.
|
100
|
-
$tag-spacing-y: 0.
|
102
|
+
$tag-spacing-x: 0.25rem;
|
103
|
+
$tag-spacing-y: 0.2rem;
|
101
104
|
|
102
105
|
|
103
106
|
// Scopes
|
104
107
|
|
105
|
-
$scope-padding: 0.
|
108
|
+
$scope-padding: 0.2rem 0.625rem;
|
106
109
|
|
107
110
|
$scope-color: rgba(black, 0.4);
|
108
111
|
$scope-bg: rgba(black, 0.035);
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import ApplicationController from './application_controller'
|
2
|
+
|
3
|
+
export default class extends ApplicationController {
|
4
|
+
static outlets = ['checkbox-select']
|
5
|
+
|
6
|
+
connect () {
|
7
|
+
if (!this.hasCheckboxSelectOutlet) {
|
8
|
+
// Set default outlet if none specified
|
9
|
+
this.element.setAttribute(`data-${this.identifier}-checkbox-select-outlet`, '.trestle-table')
|
10
|
+
}
|
11
|
+
|
12
|
+
this.baseHref = this.element.href
|
13
|
+
|
14
|
+
this.update()
|
15
|
+
}
|
16
|
+
|
17
|
+
update () {
|
18
|
+
this.toggleEnabled()
|
19
|
+
this.updateHref()
|
20
|
+
}
|
21
|
+
|
22
|
+
toggleEnabled () {
|
23
|
+
this.element.classList.toggle('disabled', this.checkboxes.length === 0)
|
24
|
+
}
|
25
|
+
|
26
|
+
updateHref () {
|
27
|
+
this.element.href = this.hrefWithSelectedIds
|
28
|
+
}
|
29
|
+
|
30
|
+
get checkboxes () {
|
31
|
+
if (this.hasCheckboxSelectOutlet) {
|
32
|
+
return this.checkboxSelectOutlet.checked
|
33
|
+
} else {
|
34
|
+
return []
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
get selectedIds () {
|
39
|
+
return this.checkboxes.map(c => c.value)
|
40
|
+
}
|
41
|
+
|
42
|
+
get hrefWithSelectedIds () {
|
43
|
+
const ids = this.selectedIds
|
44
|
+
|
45
|
+
if (ids.length) {
|
46
|
+
return `${this.baseHref}?ids=${ids.join(',')}`
|
47
|
+
} else {
|
48
|
+
return this.baseHref
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
checkboxSelectOutletConnected (outlet, element) {
|
53
|
+
element.addEventListener('checkbox-select:change', this.update.bind(this))
|
54
|
+
}
|
55
|
+
|
56
|
+
checkboxSelectOutletDisconnected (outlet, element) {
|
57
|
+
element.removeEventListener('checkbox-select:change', this.update.bind(this))
|
58
|
+
}
|
59
|
+
}
|
@@ -5,6 +5,7 @@ export default class extends ApplicationController {
|
|
5
5
|
|
6
6
|
toggle () {
|
7
7
|
this.updateSelectAllState()
|
8
|
+
this.dispatch('change')
|
8
9
|
}
|
9
10
|
|
10
11
|
toggleAll () {
|
@@ -13,6 +14,8 @@ export default class extends ApplicationController {
|
|
13
14
|
this.checkboxTargets.forEach((checkbox) => {
|
14
15
|
checkbox.checked = isChecked
|
15
16
|
})
|
17
|
+
|
18
|
+
this.dispatch('change')
|
16
19
|
}
|
17
20
|
|
18
21
|
updateSelectAllState () {
|
@@ -3,9 +3,9 @@ import ConfirmController from './confirm_controller'
|
|
3
3
|
import { i18n } from '../core/i18n'
|
4
4
|
|
5
5
|
export default class extends ConfirmController {
|
6
|
-
static values = {
|
7
|
-
confirmLabel: i18n['trestle.confirmation.delete'] || 'Delete'
|
8
|
-
}
|
9
|
-
|
10
6
|
static defaultConfirmClass = 'btn-danger'
|
7
|
+
|
8
|
+
get confirmLabel () {
|
9
|
+
return this.confirmLabelValue || i18n.t('trestle.confirmation.delete', { defaultValue: 'Delete' })
|
10
|
+
}
|
11
11
|
}
|
data/lib/trestle/engine.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "turbo-rails"
|
2
|
+
|
1
3
|
module Trestle
|
2
4
|
class Engine < ::Rails::Engine
|
3
5
|
isolate_namespace Trestle
|
@@ -30,22 +32,6 @@ module Trestle
|
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
|
-
initializer "turbo.mimetype" do
|
34
|
-
Mime::Type.register "text/vnd.turbo-stream.html", :turbo_stream unless Mime[:turbo_stream]
|
35
|
-
end
|
36
|
-
|
37
|
-
initializer "turbo.renderer" do
|
38
|
-
ActiveSupport.on_load(:action_controller) do
|
39
|
-
# Compatibility fix for Rails 5.2
|
40
|
-
delegate :media_type, to: "@_response" unless instance_methods.include?(:media_type)
|
41
|
-
|
42
|
-
ActionController::Renderers.add :turbo_stream do |turbo_streams_html, options|
|
43
|
-
self.content_type = Mime[:turbo_stream] if media_type.nil?
|
44
|
-
turbo_streams_html
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
35
|
config.to_prepare do
|
50
36
|
Engine.reset_helpers!
|
51
37
|
end
|
@@ -55,6 +41,22 @@ module Trestle
|
|
55
41
|
reloader.install(app) unless app.config.eager_load
|
56
42
|
end
|
57
43
|
|
44
|
+
# For compatibility with the `sassc-rails`` gem, register a custom compressor that excludes the
|
45
|
+
# Trestle admin stylesheets as a) they are already minimized and b) libsass is not compatible with
|
46
|
+
# some of the newer CSS syntax that is used.
|
47
|
+
#
|
48
|
+
# To avoid this being necessary, it is recommended that either
|
49
|
+
# 1) `sassc-rails` is removed from the Gemfile (if not required),
|
50
|
+
# 2) the `sassc-embedded` gem is added to the Gemfile, or
|
51
|
+
# 3) `sassc-rails` is replaced with `dartsass-sprockets`
|
52
|
+
config.assets.configure do |env|
|
53
|
+
if original_compressor = config.assets.css_compressor
|
54
|
+
require "trestle/sprockets_compressor"
|
55
|
+
original_compressor = Sprockets.compressors['text/css'][original_compressor] if original_compressor.is_a?(Symbol)
|
56
|
+
config.assets.css_compressor = Trestle::SprocketsCompressor.new(original_compressor)
|
57
|
+
end
|
58
|
+
end if defined?(SassC::Rails)
|
59
|
+
|
58
60
|
def reset_helpers!
|
59
61
|
@helpers = nil
|
60
62
|
end
|
@@ -14,7 +14,7 @@ module Trestle
|
|
14
14
|
include Hook::Helpers
|
15
15
|
|
16
16
|
# Whitelisted helpers will concatenate their result to the output buffer when called.
|
17
|
-
WHITELISTED_HELPERS = [:row, :col, :render, :tab, :table, :divider, :h1, :h2, :h3, :h4, :h5, :h6, :card, :panel, :well]
|
17
|
+
WHITELISTED_HELPERS = [:row, :col, :render, :tab, :table, :divider, :h1, :h2, :h3, :h4, :h5, :h6, :card, :panel, :well, :turbo_frame_tag]
|
18
18
|
|
19
19
|
# Raw block helpers will pass their block argument directly to the method without wrapping it in a new output buffer.
|
20
20
|
RAW_BLOCK_HELPERS = [:table, :toolbar]
|
@@ -5,20 +5,30 @@ module Trestle
|
|
5
5
|
delegate :admin, :instance, to: :@template
|
6
6
|
delegate :translate, :t, to: :admin
|
7
7
|
|
8
|
-
def new
|
9
|
-
|
8
|
+
def new(label: t("buttons.new", default: "New %{model_name}"), **attrs)
|
9
|
+
return unless action?(:new)
|
10
|
+
|
11
|
+
defaults = { action: :new, style: :light, icon: "fa fa-plus", class: "btn-new-resource" }
|
12
|
+
link(label, defaults.merge(attrs))
|
10
13
|
end
|
11
14
|
|
12
|
-
def save
|
13
|
-
|
15
|
+
def save(label: t("buttons.save", default: "Save %{model_name}"), **attrs)
|
16
|
+
defaults = { style: :success }
|
17
|
+
button(label, defaults.merge(attrs))
|
14
18
|
end
|
15
19
|
|
16
|
-
def delete
|
17
|
-
|
20
|
+
def delete(label: t("buttons.delete", default: "Delete %{model_name}"), **attrs)
|
21
|
+
return unless action?(:destroy)
|
22
|
+
|
23
|
+
defaults = Trestle::Options.new(action: :destroy, style: :danger, icon: "fa fa-trash", data: { turbo_method: "delete", turbo_frame: "_top", controller: "confirm-delete", confirm_delete_placement_value: "bottom" })
|
24
|
+
link(label, instance, defaults.merge(attrs))
|
18
25
|
end
|
19
26
|
|
20
|
-
def dismiss
|
21
|
-
|
27
|
+
def dismiss(label: t("buttons.ok", default: "OK"), **attrs)
|
28
|
+
return unless @template.modal_request?
|
29
|
+
|
30
|
+
defaults = Trestle::Options.new(type: :button, style: :light, data: { bs_dismiss: "modal" })
|
31
|
+
button(label, defaults.merge(attrs))
|
22
32
|
end
|
23
33
|
alias ok dismiss
|
24
34
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Trestle
|
2
|
+
class SprocketsCompressor
|
3
|
+
def initialize(original_compressor, excluded_files: ["trestle/admin"])
|
4
|
+
@original_compressor = original_compressor
|
5
|
+
@excluded_files = excluded_files
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(input)
|
9
|
+
if @excluded_files.include?(input[:name])
|
10
|
+
input[:data]
|
11
|
+
else
|
12
|
+
@original_compressor.call(input)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -21,11 +21,10 @@ module Trestle
|
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
24
|
-
def
|
25
|
-
|
26
|
-
end
|
24
|
+
def self.ruby2_keywords(*)
|
25
|
+
end unless respond_to?(:ruby2_keywords, true)
|
27
26
|
|
28
|
-
def method_missing(name, *args, &block)
|
27
|
+
ruby2_keywords def method_missing(name, *args, &block)
|
29
28
|
result = builder.send(name, *args, &block)
|
30
29
|
|
31
30
|
if builder.builder_methods.include?(name)
|
@@ -34,6 +33,10 @@ module Trestle
|
|
34
33
|
result
|
35
34
|
end
|
36
35
|
end
|
36
|
+
|
37
|
+
def respond_to_missing?(name, include_all=false)
|
38
|
+
builder.respond_to?(name) || super
|
39
|
+
end
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|