message_train 0.7.5 → 1.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 +5 -5
- data/.gitattributes +1 -0
- data/.github/workflows/ci.yml +86 -0
- data/.gitignore +64 -0
- data/.rubocop.yml +9 -0
- data/.rubocop_todo.yml +854 -2
- data/.ruby-version +1 -1
- data/.simplecov +2 -4
- data/CHANGELOG.md +128 -0
- data/CLAUDE.md +5 -0
- data/Gemfile +30 -32
- data/LICENSE.txt +1 -1
- data/README.md +106 -35
- data/Rakefile +4 -18
- data/app/assets/stylesheets/message_train.scss +405 -67
- data/app/controllers/concerns/message_train_support.rb +2 -2
- data/app/controllers/message_train/boxes_controller.rb +4 -2
- data/app/controllers/message_train/conversations_controller.rb +1 -0
- data/app/helpers/message_train/application_helper.rb +68 -0
- data/app/helpers/message_train/attachments_helper.rb +7 -4
- data/app/helpers/message_train/conversations_helper.rb +16 -16
- data/app/helpers/message_train/messages_helper.rb +23 -10
- data/app/javascript/controllers/message_train/bulk_actions_controller.js +36 -0
- data/app/javascript/controllers/message_train/lightbox_controller.js +25 -0
- data/app/javascript/controllers/message_train/nested_form_controller.js +36 -0
- data/app/javascript/controllers/message_train/recipient_autocomplete_controller.js +31 -0
- data/app/mailers/message_train/previews/receipt_mailer_preview.rb +7 -5
- data/app/models/message_train/attachment.rb +54 -42
- data/app/models/message_train/box.rb +2 -2
- data/app/models/message_train/conversation.rb +28 -2
- data/app/models/message_train/ignore.rb +2 -2
- data/app/models/message_train/message.rb +10 -4
- data/app/models/message_train/receipt.rb +27 -4
- data/app/models/message_train/unsubscribe.rb +1 -1
- data/app/views/application/404.html.haml +1 -3
- data/app/views/kaminari/_first_page.html.haml +1 -1
- data/app/views/kaminari/_last_page.html.haml +1 -1
- data/app/views/kaminari/_next_page.html.haml +1 -1
- data/app/views/kaminari/_page.html.haml +3 -3
- data/app/views/kaminari/_paginator.html.haml +12 -11
- data/app/views/kaminari/_prev_page.html.haml +1 -1
- data/app/views/message_train/application/_attachment_fields.html.haml +10 -7
- data/app/views/message_train/application/_attachment_link.html.haml +2 -2
- data/app/views/message_train/application/_widget.html.haml +2 -4
- data/app/views/message_train/boxes/_widget.html.haml +5 -5
- data/app/views/message_train/boxes/show.html.haml +28 -45
- data/app/views/message_train/collectives/_widget.html.haml +4 -4
- data/app/views/message_train/conversations/_conversation.html.haml +11 -11
- data/app/views/message_train/conversations/_deleted_toggle.html.haml +1 -1
- data/app/views/message_train/conversations/_ignored_toggle.html.haml +2 -2
- data/app/views/message_train/conversations/_read_toggle.html.haml +2 -2
- data/app/views/message_train/conversations/_toggle.html.haml +6 -4
- data/app/views/message_train/conversations/_trashed_toggle.html.haml +2 -2
- data/app/views/message_train/conversations/show.html.haml +8 -6
- data/app/views/message_train/messages/_deleted_toggle.html.haml +1 -1
- data/app/views/message_train/messages/_form.html.haml +22 -30
- data/app/views/message_train/messages/_message.html.haml +27 -45
- data/app/views/message_train/messages/_read_toggle.html.haml +2 -2
- data/app/views/message_train/messages/_toggle.html.haml +5 -1
- data/app/views/message_train/messages/_trashed_toggle.html.haml +2 -2
- data/app/views/message_train/unsubscribes/index.html.haml +12 -15
- data/badges/coverage.json +1 -0
- data/config/importmap.rb +2 -0
- data/config/locales/en.yml +6 -3
- data/db/migrate/20150721145319_create_message_train_conversations.rb +1 -1
- data/db/migrate/20150721160322_create_message_train_messages.rb +1 -1
- data/db/migrate/20150721161144_create_message_train_attachments.rb +5 -2
- data/db/migrate/20150721161940_create_message_train_receipts.rb +1 -1
- data/db/migrate/20150721163838_create_message_train_ignores.rb +1 -1
- data/db/migrate/20150901183458_add_received_through_to_message_train_receipts.rb +1 -1
- data/db/migrate/20151004184347_add_unique_index_to_receipts.rb +1 -1
- data/db/migrate/20151124000820_create_message_train_unsubscribes.rb +1 -1
- data/db/migrate/20260827095938_remove_paperclip_columns_from_message_train_attachments.rb +8 -0
- data/db/migrate/20260827171549_remove_body_from_message_train_messages.rb +5 -0
- data/db/migrate/20260827180000_add_marking_indexes.rb +9 -0
- data/db/migrate/20260827200000_add_body_back_to_message_train_messages.rb +5 -0
- data/docs/screenshots/inbox-desktop.png +0 -0
- data/docs/screenshots/inbox-mobile.png +0 -0
- data/lib/generators/message_train/install/install_generator.rb +1 -1
- data/lib/message_train/engine.rb +11 -0
- data/lib/message_train/instance_methods.rb +13 -7
- data/lib/message_train/localization.rb +4 -3
- data/lib/message_train/version.rb +1 -1
- data/lib/message_train.rb +0 -2
- data/message_train.gemspec +57 -389
- data/spec/controllers/message_train/boxes_controller_spec.rb +13 -8
- data/spec/controllers/message_train/concerns_spec.rb +2 -2
- data/spec/controllers/message_train/conversations_controller_spec.rb +36 -7
- data/spec/controllers/message_train/messages_controller_spec.rb +4 -4
- data/spec/dummy/app/assets/stylesheets/application.scss +141 -12
- data/spec/dummy/app/controllers/application_controller.rb +1 -1
- data/spec/dummy/app/javascript/application.js +4 -0
- data/spec/dummy/app/javascript/controllers/application.js +9 -0
- data/spec/dummy/app/javascript/controllers/index.js +4 -0
- data/spec/dummy/app/models/role.rb +1 -1
- data/spec/dummy/app/views/active_storage/blobs/_blob.html.erb +14 -0
- data/spec/dummy/app/views/layouts/_top_navigation.html.haml +18 -7
- data/spec/dummy/app/views/layouts/application.html.haml +22 -26
- data/spec/dummy/bin/importmap +4 -0
- data/spec/dummy/config/application.rb +7 -20
- data/spec/dummy/config/environments/development.rb +17 -21
- data/spec/dummy/config/environments/production.rb +11 -63
- data/spec/dummy/config/environments/test.rb +21 -16
- data/spec/dummy/config/importmap.rb +7 -0
- data/spec/dummy/config/initializers/assets.rb +1 -6
- data/spec/dummy/config/routes.rb +1 -1
- data/spec/dummy/config/storage.yml +7 -0
- data/spec/dummy/db/migrate/20150721140013_devise_create_users.rb +1 -1
- data/spec/dummy/db/migrate/20150721141009_rolify_create_roles.rb +1 -1
- data/spec/dummy/db/migrate/20150721141128_create_groups.rb +1 -1
- data/spec/dummy/db/migrate/20150721150307_add_display_name_column_to_users.rb +1 -1
- data/spec/dummy/db/migrate/20160207190402_create_message_train_conversations.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190403_create_message_train_messages.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190404_create_message_train_attachments.message_train.rb +5 -2
- data/spec/dummy/db/migrate/20160207190405_create_message_train_receipts.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190406_create_message_train_ignores.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190407_add_received_through_to_message_train_receipts.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190408_add_unique_index_to_receipts.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190409_create_message_train_unsubscribes.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20260827095939_remove_paperclip_columns_from_message_train_attachments.message_train.rb +9 -0
- data/spec/dummy/db/migrate/20260827161141_create_active_storage_tables.active_storage.rb +57 -0
- data/spec/dummy/db/migrate/20260827171550_remove_body_from_message_train_messages.message_train.rb +6 -0
- data/spec/dummy/db/migrate/20260827225116_add_marking_indexes.message_train.rb +10 -0
- data/spec/dummy/db/migrate/20260828034830_add_body_back_to_message_train_messages.message_train.rb +6 -0
- data/spec/dummy/db/migrate/20260828040000_drop_action_text_tables.rb +5 -0
- data/spec/dummy/db/schema.rb +106 -72
- data/spec/dummy/db/seeds/conversations.seeds.rb +22 -22
- data/spec/dummy/db/seeds/development/conversations.seeds.rb +2 -2
- data/spec/dummy/db/seeds/groups.seeds.rb +4 -4
- data/spec/dummy/db/seeds/test/attachments.seeds.rb +4 -4
- data/spec/dummy/db/seeds/test/conversations.seeds.rb +2 -2
- data/spec/dummy/db/seeds/users.seeds.rb +8 -8
- data/spec/dummy/vendor/javascript/.keep +0 -0
- data/spec/factories/attachment.rb +5 -6
- data/spec/factories/group.rb +2 -2
- data/spec/factories/message.rb +7 -7
- data/spec/factories/user.rb +3 -3
- data/spec/features/boxes_spec.rb +38 -34
- data/spec/features/conversations_spec.rb +13 -6
- data/spec/features/messages_spec.rb +20 -20
- data/spec/features/unsubscribes_spec.rb +9 -9
- data/spec/helpers/message_train/application_helper_spec.rb +16 -18
- data/spec/helpers/message_train/attachment_helper_spec.rb +8 -18
- data/spec/helpers/message_train/boxes_helper_spec.rb +6 -6
- data/spec/helpers/message_train/collectives_helper_spec.rb +10 -10
- data/spec/helpers/message_train/conversations_helper_spec.rb +43 -85
- data/spec/helpers/message_train/messages_helper_spec.rb +41 -61
- data/spec/models/message_train/attachment_spec.rb +26 -36
- data/spec/models/message_train/box_spec.rb +2 -2
- data/spec/models/message_train/conversation_spec.rb +15 -0
- data/spec/models/message_train/message_spec.rb +5 -1
- data/spec/models/message_train/receipt_spec.rb +1 -1
- data/spec/models/message_train/unsubscribe_spec.rb +1 -1
- data/spec/rails_helper.rb +14 -13
- data/spec/support/controller_behaviors.rb +13 -13
- data/spec/support/factory_bot.rb +3 -0
- data/spec/support/feature_behaviors.rb +14 -14
- data/spec/support/loaded_site/attachments.rb +6 -2
- data/spec/support/utilities.rb +49 -20
- metadata +260 -189
- data/.travis.yml +0 -12
- data/VERSION +0 -1
- data/app/assets/javascripts/ckeditor/config.js +0 -49
- data/app/assets/javascripts/message_train.js +0 -149
- data/spec/dummy/app/assets/javascripts/application.js +0 -17
- data/spec/dummy/app/assets/stylesheets/bootstrap-everything.scss +0 -54
- data/spec/dummy/config/initializers/bootstrap_leather.rb +0 -7
- data/spec/dummy/config/initializers/paperclip.rb +0 -5
- data/spec/dummy/config/secrets.yml +0 -22
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/support/factory_girl.rb +0 -3
|
@@ -71,15 +71,19 @@ describe MessageTrain::BoxesController do
|
|
|
71
71
|
)
|
|
72
72
|
end
|
|
73
73
|
it_should_behave_like(
|
|
74
|
-
'a
|
|
75
|
-
/
|
|
74
|
+
'a redirect matching',
|
|
75
|
+
%r{^http://test\.host/messages/box/in}
|
|
76
76
|
)
|
|
77
|
+
context 'sets error' do
|
|
78
|
+
subject { flash[:error] }
|
|
79
|
+
it { is_expected.to match(/Access to Conversation \d+ denied/) }
|
|
80
|
+
end
|
|
77
81
|
end
|
|
78
82
|
describe 'without params' do
|
|
79
83
|
before do
|
|
80
84
|
put :update, params: { division: 'in' }
|
|
81
85
|
end
|
|
82
|
-
it_should_behave_like 'a
|
|
86
|
+
it_should_behave_like 'a redirect with alert', '/messages/box/in', 'Nothing to do'
|
|
83
87
|
end
|
|
84
88
|
describe 'with valid params' do
|
|
85
89
|
before do
|
|
@@ -92,8 +96,7 @@ describe MessageTrain::BoxesController do
|
|
|
92
96
|
}
|
|
93
97
|
)
|
|
94
98
|
end
|
|
95
|
-
it_should_behave_like 'a
|
|
96
|
-
it_should_behave_like 'a response without error'
|
|
99
|
+
it_should_behave_like 'a redirect with notice', '/messages/box/in', 'Update successful'
|
|
97
100
|
end
|
|
98
101
|
end
|
|
99
102
|
|
|
@@ -115,7 +118,7 @@ describe MessageTrain::BoxesController do
|
|
|
115
118
|
before do
|
|
116
119
|
delete :destroy, params: { division: 'in' }
|
|
117
120
|
end
|
|
118
|
-
it_should_behave_like 'a
|
|
121
|
+
it_should_behave_like 'a redirect with alert', '/messages/box/in', 'Nothing to do'
|
|
119
122
|
end
|
|
120
123
|
describe 'with valid params' do
|
|
121
124
|
context 'ignoring' do
|
|
@@ -130,7 +133,8 @@ describe MessageTrain::BoxesController do
|
|
|
130
133
|
)
|
|
131
134
|
end
|
|
132
135
|
it_should_behave_like(
|
|
133
|
-
'a
|
|
136
|
+
'a redirect with notice',
|
|
137
|
+
'/messages/box/in',
|
|
134
138
|
'Update successful'
|
|
135
139
|
)
|
|
136
140
|
end
|
|
@@ -146,7 +150,8 @@ describe MessageTrain::BoxesController do
|
|
|
146
150
|
)
|
|
147
151
|
end
|
|
148
152
|
it_should_behave_like(
|
|
149
|
-
'a
|
|
153
|
+
'a redirect with notice',
|
|
154
|
+
'/messages/box/in',
|
|
150
155
|
'Update successful'
|
|
151
156
|
)
|
|
152
157
|
end
|
|
@@ -37,7 +37,7 @@ describe MessageTrain::BoxesController do
|
|
|
37
37
|
end
|
|
38
38
|
it_should_behave_like(
|
|
39
39
|
'a redirect with error',
|
|
40
|
-
'/collectives/groups:first-group/box/sent',
|
|
40
|
+
'/messages/collectives/groups:first-group/box/sent',
|
|
41
41
|
'Access to that box denied'
|
|
42
42
|
)
|
|
43
43
|
end
|
|
@@ -55,7 +55,7 @@ describe MessageTrain::BoxesController do
|
|
|
55
55
|
end
|
|
56
56
|
it_should_behave_like(
|
|
57
57
|
'a redirect with error',
|
|
58
|
-
'/collectives/groups:membered-group/box/in',
|
|
58
|
+
'/messages/collectives/groups:membered-group/box/in',
|
|
59
59
|
'Access to that box denied'
|
|
60
60
|
)
|
|
61
61
|
end
|
|
@@ -57,7 +57,14 @@ describe MessageTrain::ConversationsController do
|
|
|
57
57
|
before do
|
|
58
58
|
put :update, params: { box_division: 'in', id: unread_conversation.id }
|
|
59
59
|
end
|
|
60
|
-
it_should_behave_like
|
|
60
|
+
it_should_behave_like(
|
|
61
|
+
'a redirect matching',
|
|
62
|
+
%r{^http://test\.host/messages/box/in/conversations/\d+$}
|
|
63
|
+
)
|
|
64
|
+
context 'sets alert' do
|
|
65
|
+
subject { flash[:alert] }
|
|
66
|
+
it { is_expected.to eq 'Nothing to do' }
|
|
67
|
+
end
|
|
61
68
|
end
|
|
62
69
|
describe 'with valid params' do
|
|
63
70
|
before do
|
|
@@ -71,7 +78,14 @@ describe MessageTrain::ConversationsController do
|
|
|
71
78
|
}
|
|
72
79
|
)
|
|
73
80
|
end
|
|
74
|
-
it_should_behave_like
|
|
81
|
+
it_should_behave_like(
|
|
82
|
+
'a redirect matching',
|
|
83
|
+
%r{^http://test\.host/messages/box/in/conversations/\d+$}
|
|
84
|
+
)
|
|
85
|
+
context 'sets notice' do
|
|
86
|
+
subject { flash[:notice] }
|
|
87
|
+
it { is_expected.to eq 'Update successful' }
|
|
88
|
+
end
|
|
75
89
|
end
|
|
76
90
|
end
|
|
77
91
|
|
|
@@ -101,7 +115,14 @@ describe MessageTrain::ConversationsController do
|
|
|
101
115
|
}
|
|
102
116
|
)
|
|
103
117
|
end
|
|
104
|
-
it_should_behave_like
|
|
118
|
+
it_should_behave_like(
|
|
119
|
+
'a redirect matching',
|
|
120
|
+
%r{^http://test\.host/messages/box/in/conversations/\d+$}
|
|
121
|
+
)
|
|
122
|
+
context 'sets alert' do
|
|
123
|
+
subject { flash[:alert] }
|
|
124
|
+
it { is_expected.to eq 'Nothing to do' }
|
|
125
|
+
end
|
|
105
126
|
end
|
|
106
127
|
describe 'with valid params' do
|
|
107
128
|
context 'ignoring' do
|
|
@@ -116,9 +137,13 @@ describe MessageTrain::ConversationsController do
|
|
|
116
137
|
)
|
|
117
138
|
end
|
|
118
139
|
it_should_behave_like(
|
|
119
|
-
'a
|
|
120
|
-
|
|
140
|
+
'a redirect matching',
|
|
141
|
+
%r{^http://test\.host/messages/box/in/conversations/\d+$}
|
|
121
142
|
)
|
|
143
|
+
context 'sets notice' do
|
|
144
|
+
subject { flash[:notice] }
|
|
145
|
+
it { is_expected.to eq 'Update successful' }
|
|
146
|
+
end
|
|
122
147
|
end
|
|
123
148
|
context 'unignoring' do
|
|
124
149
|
before do
|
|
@@ -132,9 +157,13 @@ describe MessageTrain::ConversationsController do
|
|
|
132
157
|
)
|
|
133
158
|
end
|
|
134
159
|
it_should_behave_like(
|
|
135
|
-
'a
|
|
136
|
-
|
|
160
|
+
'a redirect matching',
|
|
161
|
+
%r{^http://test\.host/messages/box/in/conversations/\d+$}
|
|
137
162
|
)
|
|
163
|
+
context 'sets notice' do
|
|
164
|
+
subject { flash[:notice] }
|
|
165
|
+
it { is_expected.to eq 'Update successful' }
|
|
166
|
+
end
|
|
138
167
|
end
|
|
139
168
|
end
|
|
140
169
|
end
|
|
@@ -132,7 +132,7 @@ describe MessageTrain::MessagesController do
|
|
|
132
132
|
}
|
|
133
133
|
)
|
|
134
134
|
end
|
|
135
|
-
it_should_behave_like 'a redirect to', '/box/drafts'
|
|
135
|
+
it_should_behave_like 'a redirect to', '/messages/box/drafts'
|
|
136
136
|
it_should_behave_like 'a response without error'
|
|
137
137
|
|
|
138
138
|
context "sets the flash with an alert of the messages's draft status" do
|
|
@@ -150,7 +150,7 @@ describe MessageTrain::MessagesController do
|
|
|
150
150
|
}
|
|
151
151
|
)
|
|
152
152
|
end
|
|
153
|
-
it_should_behave_like 'a redirect to', '/box/sent'
|
|
153
|
+
it_should_behave_like 'a redirect to', '/messages/box/sent'
|
|
154
154
|
it_should_behave_like 'a response without error'
|
|
155
155
|
|
|
156
156
|
context "sets the flash with a notice of the messages's creation" do
|
|
@@ -307,7 +307,7 @@ describe MessageTrain::MessagesController do
|
|
|
307
307
|
}
|
|
308
308
|
)
|
|
309
309
|
end
|
|
310
|
-
it_should_behave_like 'a redirect to', '/box/sent'
|
|
310
|
+
it_should_behave_like 'a redirect to', '/messages/box/sent'
|
|
311
311
|
it_should_behave_like 'a response without error'
|
|
312
312
|
|
|
313
313
|
context 'updates @message' do
|
|
@@ -345,7 +345,7 @@ describe MessageTrain::MessagesController do
|
|
|
345
345
|
end
|
|
346
346
|
it_should_behave_like(
|
|
347
347
|
'a redirect matching',
|
|
348
|
-
%r{/box/in/conversations/\d+}
|
|
348
|
+
%r{/messages/box/in/conversations/\d+}
|
|
349
349
|
)
|
|
350
350
|
it_should_behave_like 'a response without error'
|
|
351
351
|
|
|
@@ -1,20 +1,149 @@
|
|
|
1
|
-
// 'bootstrap-sprockets' must be imported before 'bootstrap' and 'bootstrap/variables'
|
|
2
|
-
@import 'bootstrap-sprockets';
|
|
3
|
-
@import 'bootstrap-everything';
|
|
4
|
-
@import 'bootstrap/theme';
|
|
5
1
|
@import 'message_train';
|
|
6
2
|
|
|
7
|
-
.
|
|
8
|
-
|
|
3
|
+
// Without this, the browser's default body margin (8px) keeps .nav-items'
|
|
4
|
+
// full-bleed background from actually reaching the viewport edge.
|
|
5
|
+
body {
|
|
6
|
+
margin: 0;
|
|
9
7
|
}
|
|
10
8
|
|
|
11
|
-
.
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
.top-navigation {
|
|
10
|
+
a {
|
|
11
|
+
text-decoration: none;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Logo row: plain background, left-aligned (not width-capped/centered
|
|
16
|
+
// like the nav-links bar below it).
|
|
17
|
+
.top-navigation-inner {
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
padding: var(--message-train-space-md);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// The nav-links bar sits below the logo row and is full-bleed (edge to
|
|
24
|
+
// edge) rather than width-capped like the rest of the page, so the blue
|
|
25
|
+
// reads as a distinct band across the whole viewport. Its own content
|
|
26
|
+
// (.nav-items-inner) is still width-capped/centered to line up with the
|
|
27
|
+
// logo row and page content above/below it.
|
|
28
|
+
.nav-items {
|
|
29
|
+
background: var(--message-train-color-accent);
|
|
30
|
+
color: var(--message-train-color-accent-contrast);
|
|
31
|
+
|
|
32
|
+
// Every link in here - top-level (Groups/Inbox dropdown triggers,
|
|
33
|
+
// Manage Notifications, Sign Out) and nested (the dropdown popover's
|
|
34
|
+
// own box/collective links) - should read as white against the blue
|
|
35
|
+
// bar, not just the top level.
|
|
36
|
+
a {
|
|
37
|
+
color: inherit;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// The dropdown popover (.message-train-dropdown-nav-item ul, in
|
|
41
|
+
// message_train.scss) normally gets its own light "elevated surface"
|
|
42
|
+
// background so it stands out as a floating menu over page content -
|
|
43
|
+
// here it sits over the blue bar instead, so it keeps the same blue
|
|
44
|
+
// (rather than falling back to that light surface) to stay readable
|
|
45
|
+
// with the white text above.
|
|
46
|
+
.message-train-dropdown-nav-item ul {
|
|
47
|
+
background: var(--message-train-color-accent);
|
|
48
|
+
border-color: rgba(255, 255, 255, 0.3);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.nav-items-inner {
|
|
53
|
+
box-sizing: border-box;
|
|
54
|
+
max-width: 75rem;
|
|
55
|
+
margin: 0 auto;
|
|
56
|
+
padding: var(--message-train-space-sm) var(--message-train-space-md);
|
|
57
|
+
|
|
58
|
+
// One list: each collective/box <details> dropdown and each plain
|
|
59
|
+
// account link (Manage Notifications, Sign Out) is its own <li>, so
|
|
60
|
+
// this is valid list markup throughout rather than a details element
|
|
61
|
+
// sitting loose alongside a <ul>. Mobile-first: stacked vertically by
|
|
62
|
+
// default (gap alone separates items, no divider lines), one row only
|
|
63
|
+
// once there's room (same 48rem breakpoint the dropdowns themselves
|
|
64
|
+
// switch at) - subtle left borders between adjacent items only make
|
|
65
|
+
// sense once they're actually side by side.
|
|
66
|
+
//
|
|
67
|
+
// Direct child only (> li) - a dropdown's own popover <ul>/<li> (in
|
|
68
|
+
// message_train.scss) is nested two levels deeper (li > details > ul >
|
|
69
|
+
// li), so it's naturally excluded here without extra scoping.
|
|
70
|
+
> ul {
|
|
71
|
+
display: flex;
|
|
72
|
+
flex-direction: column;
|
|
73
|
+
align-items: flex-start;
|
|
74
|
+
gap: var(--message-train-space-md);
|
|
75
|
+
list-style: none;
|
|
76
|
+
margin: 0;
|
|
77
|
+
padding: 0;
|
|
78
|
+
|
|
79
|
+
@media (min-width: 48rem) {
|
|
80
|
+
flex-direction: row;
|
|
81
|
+
align-items: center;
|
|
82
|
+
flex-wrap: wrap;
|
|
83
|
+
// The list is usually narrower than the 75rem-capped bar, so
|
|
84
|
+
// without this it hugs the left edge of that (invisible) cap
|
|
85
|
+
// instead of actually centering in the bar.
|
|
86
|
+
justify-content: center;
|
|
87
|
+
|
|
88
|
+
> li + li {
|
|
89
|
+
border-top: none;
|
|
90
|
+
border-left: 1px solid rgba(255, 255, 255, 0.3);
|
|
91
|
+
padding-top: 0;
|
|
92
|
+
padding-left: var(--message-train-space-md);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Heading hierarchy: h1 (site-brand, in the persistent top nav) is the
|
|
99
|
+
// largest/heaviest per TYPOGRAPHY.md's Hierarchy rule, h2 (page title)
|
|
100
|
+
// and h3 (subtitle) step down from there. Left unsized, the browser's UA
|
|
101
|
+
// default made h2 render bigger than h1 - exactly backwards.
|
|
102
|
+
h1.site-brand {
|
|
103
|
+
margin: 0;
|
|
104
|
+
font-size: var(--message-train-fs-2xl);
|
|
105
|
+
font-weight: 700;
|
|
106
|
+
|
|
107
|
+
a {
|
|
108
|
+
display: inline-flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
gap: var(--message-train-space-sm);
|
|
111
|
+
text-decoration: none;
|
|
112
|
+
color: inherit;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
main.content {
|
|
117
|
+
padding: var(--message-train-space-md);
|
|
118
|
+
|
|
119
|
+
> h2 {
|
|
120
|
+
margin: 0 0 var(--message-train-space-xs);
|
|
121
|
+
font-size: var(--message-train-fs-xl);
|
|
122
|
+
font-weight: 600;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
> h3 {
|
|
126
|
+
margin: 0 0 var(--message-train-space-md);
|
|
127
|
+
font-size: var(--message-train-fs-base);
|
|
128
|
+
font-weight: 400;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Mobile-first (RESPONSIVE.md): single column with the sidebar widget
|
|
133
|
+
// stacking below the main content by default; a real side-by-side
|
|
134
|
+
// sidebar only once there's room for both without cramming either.
|
|
135
|
+
.page-grid {
|
|
136
|
+
display: grid;
|
|
137
|
+
grid-template-columns: 1fr;
|
|
138
|
+
gap: var(--message-train-space-xl);
|
|
139
|
+
|
|
140
|
+
@media (min-width: 48rem) {
|
|
141
|
+
grid-template-columns: 1fr 18rem;
|
|
142
|
+
align-items: start;
|
|
143
|
+
}
|
|
14
144
|
}
|
|
15
145
|
|
|
16
146
|
.logo {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
margin: -.5em 1em -.5em 0;
|
|
147
|
+
height: 1.5em;
|
|
148
|
+
width: auto;
|
|
20
149
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Import and register all your controllers from the importmap via controllers/**/*_controller
|
|
2
|
+
import { application } from "controllers/application"
|
|
3
|
+
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
|
|
4
|
+
eagerLoadControllersFrom("controllers", application)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
|
|
2
|
+
<% if blob.representable? %>
|
|
3
|
+
<%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
|
|
4
|
+
<% end %>
|
|
5
|
+
|
|
6
|
+
<figcaption class="attachment__caption">
|
|
7
|
+
<% if caption = blob.try(:caption) %>
|
|
8
|
+
<%= caption %>
|
|
9
|
+
<% else %>
|
|
10
|
+
<span class="attachment__name"><%= blob.filename %></span>
|
|
11
|
+
<span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
|
|
12
|
+
<% end %>
|
|
13
|
+
</figcaption>
|
|
14
|
+
</figure>
|
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
%nav.top-navigation
|
|
2
|
+
.top-navigation-inner
|
|
3
|
+
%h1.site-brand
|
|
4
|
+
%a{ href: '/' }
|
|
5
|
+
%img.logo{ src: image_path('logo.svg'), alt: '' }
|
|
6
|
+
= MessageTrain.configuration.site_name
|
|
7
|
+
- if user_signed_in?
|
|
8
|
+
.nav-items
|
|
9
|
+
.nav-items-inner
|
|
10
|
+
%ul
|
|
11
|
+
- collective_boxes_html = collective_boxes_dropdown_list(current_user)
|
|
12
|
+
- if collective_boxes_html.present?
|
|
13
|
+
%li= collective_boxes_html
|
|
14
|
+
- boxes_html = boxes_dropdown_list(current_user)
|
|
15
|
+
- if boxes_html.present?
|
|
16
|
+
%li= boxes_html
|
|
17
|
+
%li= link_to 'Manage Notifications', message_train.unsubscribes_path
|
|
18
|
+
%li= link_to 'Sign Out', '/users/sign_out', method: :delete
|
|
@@ -1,29 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
!!!
|
|
2
|
+
%html
|
|
3
|
+
%head
|
|
4
|
+
%title= content_for?(:title) ? content_for(:title) : MessageTrain.configuration.site_name
|
|
5
|
+
%meta{name: 'viewport', content: 'width=device-width, initial-scale=1'}
|
|
6
|
+
= stylesheet_link_tag 'application'
|
|
7
|
+
= javascript_importmap_tags
|
|
8
|
+
= csrf_meta_tags
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
%body
|
|
11
|
+
= render 'layouts/top_navigation'
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
%main.content
|
|
14
|
+
- if content_for?(:title)
|
|
15
|
+
%h2= content_for(:title)
|
|
16
|
+
- if content_for?(:subtitle)
|
|
17
|
+
%h3= content_for(:subtitle)
|
|
18
|
+
#alert_area
|
|
19
|
+
- flash.each do |type, message|
|
|
20
|
+
.alert{class: flash_alert_class(type)}= message
|
|
12
21
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
= render_hero_unit
|
|
18
|
-
.row
|
|
19
|
-
- if user_signed_in?
|
|
20
|
-
= message_train_widget
|
|
21
|
-
= render_widgets 'md', 3
|
|
22
|
-
.col-md-9.content
|
|
23
|
-
= render_h1 # For the h1 tag containing the title alone
|
|
24
|
-
#alert_area
|
|
25
|
-
= alert_flash_messages
|
|
26
|
-
= yield
|
|
27
|
-
|
|
28
|
-
%footer
|
|
29
|
-
= render_footer_javascript
|
|
22
|
+
.page-grid
|
|
23
|
+
.page-main= yield
|
|
24
|
+
- if user_signed_in?
|
|
25
|
+
%aside.page-sidebar= message_train_widget
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative 'boot'
|
|
2
2
|
|
|
3
|
+
require 'rails'
|
|
3
4
|
# Pick the frameworks you want:
|
|
4
5
|
require 'active_record/railtie'
|
|
6
|
+
require 'active_storage/engine'
|
|
5
7
|
require 'action_controller/railtie'
|
|
6
8
|
require 'action_mailer/railtie'
|
|
9
|
+
require 'action_mailbox/engine'
|
|
7
10
|
require 'action_view/railtie'
|
|
8
|
-
require 'sprockets/railtie'
|
|
9
11
|
# require 'rails/test_unit/railtie'
|
|
10
12
|
|
|
11
13
|
Bundler.require(*Rails.groups)
|
|
@@ -13,22 +15,7 @@ require 'message_train'
|
|
|
13
15
|
|
|
14
16
|
module Dummy
|
|
15
17
|
class Application < Rails::Application
|
|
16
|
-
|
|
17
|
-
# here. Application configuration should go into files in
|
|
18
|
-
# config/initializers -- all .rb files in that directory are automatically
|
|
19
|
-
# loaded.
|
|
20
|
-
|
|
21
|
-
# Set Time.zone default to the specified zone and make Active Record
|
|
22
|
-
# auto-convert to this zone. Run 'rake -D time' for a list of tasks for
|
|
23
|
-
# finding time zone names. Default is UTC.
|
|
24
|
-
# config.time_zone = 'Central Time (US & Canada)'
|
|
25
|
-
|
|
26
|
-
# The default locale is :en and all translations from
|
|
27
|
-
# config/locales/*.rb,yml are auto loaded.
|
|
28
|
-
# config.i18n.load_path += Dir[
|
|
29
|
-
# Rails.root.join('my', 'locales', '*.{rb,yml}').to_s
|
|
30
|
-
# ]
|
|
31
|
-
# config.i18n.default_locale = :de
|
|
18
|
+
config.load_defaults 8.1
|
|
32
19
|
|
|
33
20
|
config.generators do |g|
|
|
34
21
|
g.orm :active_record
|
|
@@ -40,10 +27,10 @@ module Dummy
|
|
|
40
27
|
|
|
41
28
|
config.time_zone = 'America/Denver'
|
|
42
29
|
config.active_record.default_timezone = :local
|
|
30
|
+
config.active_storage.variant_processor = :mini_magick
|
|
43
31
|
end
|
|
44
32
|
end
|
|
45
33
|
|
|
46
|
-
|
|
34
|
+
FactoryBot.definition_file_paths << MessageTrain::Engine.root.join(
|
|
47
35
|
'spec/factories'
|
|
48
36
|
)
|
|
49
|
-
FactoryGirl.reload
|
|
@@ -2,18 +2,24 @@ Rails.application.configure do
|
|
|
2
2
|
# Settings specified here will take precedence over those in
|
|
3
3
|
# config/application.rb.
|
|
4
4
|
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
# since you don't have to restart the web server when you make code changes.
|
|
8
|
-
config.cache_classes = false
|
|
5
|
+
# Make code changes take effect immediately without server restart.
|
|
6
|
+
config.enable_reloading = true
|
|
9
7
|
|
|
10
8
|
# Do not eager load code on boot.
|
|
11
9
|
config.eager_load = false
|
|
12
10
|
|
|
13
|
-
# Show full error reports
|
|
14
|
-
config.consider_all_requests_local
|
|
11
|
+
# Show full error reports.
|
|
12
|
+
config.consider_all_requests_local = true
|
|
13
|
+
|
|
14
|
+
# Enable/disable Action Controller caching. By default Action Controller caching is disabled.
|
|
15
15
|
config.action_controller.perform_caching = false
|
|
16
16
|
|
|
17
|
+
# Change to :null_store to avoid any caching.
|
|
18
|
+
config.cache_store = :memory_store
|
|
19
|
+
|
|
20
|
+
# Store uploaded files on the local file system (see config/storage.yml for options).
|
|
21
|
+
config.active_storage.service = :local
|
|
22
|
+
|
|
17
23
|
# Don't care if the mailer can't send.
|
|
18
24
|
config.action_mailer.raise_delivery_errors = false
|
|
19
25
|
config.action_mailer.default_url_options = { host: 'localhost:3000' }
|
|
@@ -24,20 +30,10 @@ Rails.application.configure do
|
|
|
24
30
|
# Raise an error on page load if there are pending migrations.
|
|
25
31
|
config.active_record.migration_error = :page_load
|
|
26
32
|
|
|
27
|
-
# Debug mode disables concatenation and preprocessing of assets.
|
|
28
|
-
# This option may cause significant delays in view rendering with a large
|
|
29
|
-
# number of complex assets.
|
|
30
|
-
config.assets.debug = true
|
|
31
|
-
|
|
32
|
-
# Asset digests allow you to set far-future HTTP expiration dates on all
|
|
33
|
-
# assets, yet still be able to expire them through the digest params.
|
|
34
|
-
config.assets.digest = true
|
|
35
|
-
|
|
36
|
-
# Adds additional error checking when serving assets at runtime.
|
|
37
|
-
# Checks for improperly declared sprockets dependencies.
|
|
38
|
-
# Raises helpful error messages.
|
|
39
|
-
config.assets.raise_runtime_errors = true
|
|
40
|
-
|
|
41
33
|
# Raises error for missing translations
|
|
42
|
-
# config.
|
|
34
|
+
# config.i18n.raise_on_missing_translations = true
|
|
35
|
+
|
|
36
|
+
config.secret_key_base = 'ac4907450d833ae9cdd320e25bdeedbf3ecb2617dd15e6' \
|
|
37
|
+
'28bd9704882a26eb298f6cc0d5a11543d287de47f39c60' \
|
|
38
|
+
'c47e81290600189fe72205f34e84143260c9'
|
|
43
39
|
end
|