mumuki-laboratory 7.6.2 → 7.8.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 +203 -2
- data/Rakefile +9 -0
- data/app/assets/javascripts/mumuki_laboratory/application.js +0 -1
- data/app/assets/javascripts/mumuki_laboratory/application/alias-modes.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/assets-loader.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/bridge.js +82 -47
- data/app/assets/javascripts/mumuki_laboratory/application/button.js +90 -1
- data/app/assets/javascripts/mumuki_laboratory/application/codemirror-builder.js +28 -25
- data/app/assets/javascripts/mumuki_laboratory/application/codemirror.js +8 -9
- data/app/assets/javascripts/mumuki_laboratory/application/confirmation.js +2 -2
- data/app/assets/javascripts/mumuki_laboratory/application/console.js +41 -43
- data/app/assets/javascripts/mumuki_laboratory/application/csrf-token.js +9 -12
- data/app/assets/javascripts/mumuki_laboratory/application/custom-editor.js +46 -8
- data/app/assets/javascripts/mumuki_laboratory/application/discussions.js +15 -16
- data/app/assets/javascripts/mumuki_laboratory/application/editors.js +104 -0
- data/app/assets/javascripts/mumuki_laboratory/application/elipsis.js +5 -4
- data/app/assets/javascripts/mumuki_laboratory/application/exercise.js +32 -0
- data/app/assets/javascripts/mumuki_laboratory/application/inputs.js +4 -2
- data/app/assets/javascripts/mumuki_laboratory/application/interval.js +2 -4
- data/app/assets/javascripts/mumuki_laboratory/application/kids.js +74 -37
- data/app/assets/javascripts/mumuki_laboratory/application/load-analytics.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/load-error-svg.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/messages.js +2 -2
- data/app/assets/javascripts/mumuki_laboratory/application/multiple-choice.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/multiple-scenarios.js +3 -6
- data/app/assets/javascripts/mumuki_laboratory/application/pin.js +3 -5
- data/app/assets/javascripts/mumuki_laboratory/application/progress.js +27 -6
- data/app/assets/javascripts/mumuki_laboratory/application/results-renderer.js +60 -0
- data/app/assets/javascripts/mumuki_laboratory/application/speech-bubble-renderer.js +12 -5
- data/app/assets/javascripts/mumuki_laboratory/application/submission.js +122 -55
- data/app/assets/javascripts/mumuki_laboratory/application/submissions-store.js +93 -0
- data/app/assets/javascripts/mumuki_laboratory/application/sync-mode.js +75 -0
- data/app/assets/javascripts/mumuki_laboratory/application/timer.js +5 -6
- data/app/assets/javascripts/mumuki_laboratory/application/tooltip.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/upload.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/user.js +1 -1
- data/app/assets/stylesheets/mumuki_laboratory/application/_modules.scss +1 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_discussion.scss +43 -5
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_gs-board.scss +3 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids.scss +3 -4
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kindergarten.scss +55 -0
- data/app/controllers/application_controller.rb +1 -0
- data/app/controllers/assets_controller.rb +2 -0
- data/app/controllers/concerns/with_authorization.rb +4 -0
- data/app/controllers/concerns/with_user_discussion_validation.rb +14 -0
- data/app/controllers/discussions_controller.rb +6 -14
- data/app/controllers/discussions_messages_controller.rb +10 -1
- data/app/controllers/exercise_solutions_controller.rb +4 -2
- data/app/helpers/application_helper.rb +9 -5
- data/app/helpers/discussions_helper.rb +37 -23
- data/app/helpers/exercise_input_helper.rb +1 -1
- data/app/helpers/{locale_helper.rb → globals_helper.rb} +6 -2
- data/app/helpers/icons_helper.rb +3 -3
- data/app/mailers/user_mailer.rb +24 -11
- data/app/views/book/show.html.erb +1 -1
- data/app/views/book_discussions/index.html.erb +3 -3
- data/app/views/discussions/_message.html.erb +20 -8
- data/app/views/discussions/index.html.erb +0 -1
- data/app/views/discussions/new.html.erb +33 -0
- data/app/views/discussions/show.html.erb +18 -46
- data/app/views/exercise_solutions/_contextualization_results_container.html.erb +1 -1
- data/app/views/exercise_solutions/_results_title.html.erb +2 -2
- data/app/views/exercises/_read_only.html.erb +33 -6
- data/app/views/exercises/show.html.erb +2 -0
- data/app/views/layouts/_copyright.html.erb +1 -1
- data/app/views/layouts/_discussions.html.erb +21 -3
- data/app/views/layouts/_main.html.erb +1 -2
- data/app/views/layouts/_progress.html.erb +1 -1
- data/app/views/layouts/_progress_bar.html.erb +7 -1
- data/app/views/layouts/_test_results.html.erb +1 -1
- data/app/views/layouts/application.html.erb +1 -1
- data/app/views/layouts/exercise_inputs/editors/_custom.html.erb +1 -1
- data/app/views/layouts/exercise_inputs/forms/_kids_form.html.erb +1 -1
- data/app/views/layouts/exercise_inputs/forms/_problem_form.html.erb +1 -1
- data/app/views/layouts/exercise_inputs/layouts/_input_bottom.html.erb +1 -1
- data/app/views/layouts/exercise_inputs/layouts/_input_kindergarten.html.erb +40 -0
- data/app/views/layouts/exercise_inputs/layouts/{_input_kids.html.erb → _input_primary.html.erb} +1 -1
- data/app/views/layouts/exercise_inputs/layouts/_input_right.html.erb +1 -1
- data/app/views/layouts/modals/_kids_context.html.erb +1 -8
- data/app/views/user_mailer/1st_reminder.html.erb +1 -1
- data/app/views/user_mailer/1st_reminder.text.erb +1 -1
- data/app/views/user_mailer/2nd_reminder.html.erb +1 -1
- data/app/views/user_mailer/2nd_reminder.text.erb +1 -1
- data/app/views/user_mailer/3rd_reminder.html.erb +1 -1
- data/app/views/user_mailer/3rd_reminder.text.erb +1 -1
- data/app/views/user_mailer/no_submissions_reminder.html.erb +1 -1
- data/app/views/user_mailer/no_submissions_reminder.text.erb +1 -1
- data/config/routes.rb +2 -1
- data/lib/mumuki/laboratory/controllers.rb +1 -0
- data/lib/mumuki/laboratory/controllers/incognito_mode.rb +28 -0
- data/lib/mumuki/laboratory/controllers/results_rendering.rb +1 -2
- data/lib/mumuki/laboratory/locales/en.yml +14 -6
- data/lib/mumuki/laboratory/locales/es-CL.yml +292 -0
- data/lib/mumuki/laboratory/locales/es.yml +13 -5
- data/lib/mumuki/laboratory/locales/pt.yml +12 -6
- data/lib/mumuki/laboratory/version.rb +1 -1
- data/spec/controllers/confirmations_controller_spec.rb +1 -1
- data/spec/controllers/discussions_messages_controller_spec.rb +73 -0
- data/spec/controllers/exercise_solutions_controller_spec.rb +41 -6
- data/spec/dummy/db/schema.rb +13 -1
- data/spec/features/chapter_spec.rb +17 -0
- data/spec/features/discussion_flow_spec.rb +190 -0
- data/spec/features/exercise_flow_spec.rb +48 -3
- data/spec/features/home_public_flow_spec.rb +16 -0
- data/spec/features/menu_bar_spec.rb +88 -7
- data/spec/helpers/breadcrumbs_helper_spec.rb +1 -1
- data/spec/javascripts/bridge-spec.js +5 -0
- data/spec/javascripts/csrf-token-spec.js +7 -0
- data/spec/javascripts/editors-spec.js +54 -0
- data/spec/javascripts/elipsis-spec.js +25 -0
- data/spec/javascripts/exercise-spec.js +22 -0
- data/spec/javascripts/global-spec.js +6 -0
- data/spec/javascripts/results-renderers-spec.js +17 -0
- data/spec/javascripts/spec-helper.js +34 -0
- data/spec/javascripts/speech-bubble-renderer-spec.js +11 -0
- data/spec/javascripts/submissions-store-spec.js +44 -0
- data/spec/javascripts/sync-mode-spec.js +15 -0
- data/spec/javascripts/timeout-spec.js +5 -0
- data/spec/javascripts/timer-spec.js +5 -0
- data/spec/mailers/user_mailer_spec.rb +18 -3
- data/spec/teaspoon_env.rb +193 -0
- metadata +50 -11
- data/app/helpers/version_helper.rb +0 -5
- data/app/views/layouts/modals/_new_discussion.html.erb +0 -27
- data/vendor/assets/javascripts/hotjar.js +0 -8
@@ -23,31 +23,32 @@ module DiscussionsHelper
|
|
23
23
|
fixed_fa_icon 'comment', text: text
|
24
24
|
end
|
25
25
|
|
26
|
-
def discussions_link(item, path, html_options=nil
|
27
|
-
|
26
|
+
def discussions_link(item, path, html_options = nil)
|
27
|
+
return unless current_user&.can_discuss_here?
|
28
|
+
link_to item, path, html_options
|
28
29
|
end
|
29
30
|
|
30
|
-
def item_discussion_path(discussion, params={})
|
31
|
+
def item_discussion_path(discussion, params = {})
|
31
32
|
polymorphic_path([discussion.item, discussion], params)
|
32
33
|
end
|
33
34
|
|
34
|
-
def item_discussions_path(item, params={})
|
35
|
+
def item_discussions_path(item, params = {})
|
35
36
|
polymorphic_path([item, :discussions], params)
|
36
37
|
end
|
37
38
|
|
38
39
|
def solve_discussion_params_for(user)
|
39
40
|
if user&.moderator_here?
|
40
|
-
{
|
41
|
+
{status: :pending_review, sort: :responses_count_asc, requires_moderator_response: true}
|
41
42
|
else
|
42
|
-
{
|
43
|
+
{status: :opened, sort: :responses_count_desc}
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
46
47
|
def default_discussions_params
|
47
|
-
{
|
48
|
+
{status: :solved, sort: :upvotes_count_desc}
|
48
49
|
end
|
49
50
|
|
50
|
-
def user_avatar(user, image_class='')
|
51
|
+
def user_avatar(user, image_class = '')
|
51
52
|
image_tag user.profile_picture, height: 40, class: "img-circle #{image_class}"
|
52
53
|
end
|
53
54
|
|
@@ -67,7 +68,7 @@ module DiscussionsHelper
|
|
67
68
|
%Q{
|
68
69
|
<span class="discussion-icon fa-stack fa-xs">
|
69
70
|
<i class="fa fa-comment-o fa-stack-2x"></i>
|
70
|
-
<i class="fa fa-stack-1x">#{discussion.
|
71
|
+
<i class="fa fa-stack-1x">#{discussion.validated_messages_count}</i>
|
71
72
|
</span>
|
72
73
|
}.html_safe
|
73
74
|
end
|
@@ -91,22 +92,16 @@ module DiscussionsHelper
|
|
91
92
|
end
|
92
93
|
|
93
94
|
def new_discussion_link(teaser_text, link_text)
|
94
|
-
return '' unless Organization.current.can_create_discussions?(current_user)
|
95
|
-
|
96
95
|
%Q{
|
97
96
|
<h4>
|
98
97
|
<span>#{t(teaser_text)}</span>
|
99
|
-
|
100
|
-
<span class="discussion-create">
|
101
|
-
#{t(link_text)}
|
102
|
-
</span>
|
103
|
-
</a>
|
98
|
+
#{link_to t(link_text), new_exercise_discussion_path(@debatable, anchor: 'new-discussion-description-container') }
|
104
99
|
</h4>
|
105
100
|
}.html_safe
|
106
101
|
end
|
107
102
|
|
108
103
|
def discussion_count_for_status(status, discussions)
|
109
|
-
discussions.scoped_query_by(discussion_filter_params, :status).by_status(status).count
|
104
|
+
discussions.scoped_query_by(discussion_filter_params, excluded_params: [:status], excluded_methods: [:page]).by_status(status).count
|
110
105
|
end
|
111
106
|
|
112
107
|
def discussions_reset_query_link
|
@@ -117,8 +112,10 @@ module DiscussionsHelper
|
|
117
112
|
Mumuki::Domain::Status::Discussion::STATUSES
|
118
113
|
end
|
119
114
|
|
115
|
+
#TODO: this one uses a long method chain in order to take advantage of eager load
|
116
|
+
# Delegate it once again when polymorphic association is removed
|
120
117
|
def discussions_languages(discussions)
|
121
|
-
discussions.map { |it| it.language.name }.uniq
|
118
|
+
@languages ||= discussions.map { |it| it.exercise.language.name }.uniq
|
122
119
|
end
|
123
120
|
|
124
121
|
def discussion_status_filter_link(status, discussions)
|
@@ -132,14 +129,14 @@ module DiscussionsHelper
|
|
132
129
|
|
133
130
|
def discussion_status_filter(status, discussions_count)
|
134
131
|
%Q{
|
135
|
-
|
132
|
+
#{discussion_status_fa_icon(status)}
|
136
133
|
<span>
|
137
134
|
#{t("#{status}_count", count: discussions_count)}
|
138
135
|
</span>
|
139
136
|
}.html_safe
|
140
137
|
end
|
141
138
|
|
142
|
-
def discussion_dropdown_filter(label, filters, &block)
|
139
|
+
def discussion_dropdown_filter(label, filters, can_select_all = false, &block)
|
143
140
|
if filters.present?
|
144
141
|
%Q{
|
145
142
|
<div class="dropdown discussions-toolbar-filter">
|
@@ -147,6 +144,7 @@ module DiscussionsHelper
|
|
147
144
|
#{t label} #{fa_icon :'caret-down', class: 'fa-xs'}
|
148
145
|
</a>
|
149
146
|
<ul class="dropdown-menu" aria-labelledby="dropdown-#{label}">
|
147
|
+
#{discussion_filter_unselect_item(label, can_select_all)}
|
150
148
|
#{discussion_filter_list(label, filters, &block)}
|
151
149
|
</ul>
|
152
150
|
</div>
|
@@ -159,7 +157,15 @@ module DiscussionsHelper
|
|
159
157
|
end
|
160
158
|
|
161
159
|
def discussion_filter_item(label, filter, &block)
|
162
|
-
content_tag(:li, discussion_filter_link(label, filter, &block), class:
|
160
|
+
content_tag(:li, discussion_filter_link(label, filter, &block), class: ('selected' if discussion_filter_selected?(label, filter)))
|
161
|
+
end
|
162
|
+
|
163
|
+
def discussion_filter_unselect_item(label, can_select_all)
|
164
|
+
if can_select_all
|
165
|
+
content_tag(:li,
|
166
|
+
link_to(t(:all), discussion_filter_params_without_page.except(label)),
|
167
|
+
class: ('selected' unless discussion_filter_params.include?(label)))
|
168
|
+
end
|
163
169
|
end
|
164
170
|
|
165
171
|
def discussion_filter_selected?(label, filter)
|
@@ -167,10 +173,18 @@ module DiscussionsHelper
|
|
167
173
|
end
|
168
174
|
|
169
175
|
def discussion_filter_link(label, filter, &block)
|
170
|
-
link_to capture(filter, &block),
|
176
|
+
link_to capture(filter, &block), discussion_filter_params_without_page.merge(Hash[label, filter])
|
171
177
|
end
|
172
178
|
|
173
179
|
def discussion_info(discussion)
|
174
|
-
|
180
|
+
"#{t(:time_since, time: time_ago_in_words(discussion.created_at))} · #{t(:message_count, count: discussion.messages.size)}"
|
181
|
+
end
|
182
|
+
|
183
|
+
def discussion_filter_params_without_page
|
184
|
+
discussion_filter_params.except(:page)
|
185
|
+
end
|
186
|
+
|
187
|
+
def should_show_approved_for?(user, message)
|
188
|
+
!user&.moderator_here? && message.approved? && !message.from_moderator?
|
175
189
|
end
|
176
190
|
end
|
@@ -75,7 +75,7 @@ module ExerciseInputHelper
|
|
75
75
|
|
76
76
|
def render_custom_editor(exercise, read_only=false)
|
77
77
|
custom_editor_tag = "mu-#{exercise.language}-custom-editor"
|
78
|
-
"<#{custom_editor_tag} class='#{custom_editor_tag}' #{custom_editor_read_only if read_only}> </#{custom_editor_tag}>".html_safe
|
78
|
+
"<#{custom_editor_tag} id='#{custom_editor_tag}' class='#{custom_editor_tag}' #{custom_editor_read_only if read_only}> </#{custom_editor_tag}>".html_safe
|
79
79
|
end
|
80
80
|
|
81
81
|
def custom_editor_read_only
|
@@ -1,10 +1,14 @@
|
|
1
|
-
module
|
2
|
-
def
|
1
|
+
module GlobalsHelper
|
2
|
+
def globals_tags
|
3
3
|
%Q{
|
4
4
|
<script type="text/javascript">
|
5
5
|
window.mumukiLocale = #{raw Organization.current.locale_json};
|
6
6
|
mumuki.locale = '#{Organization.current.locale}';
|
7
7
|
moment.locale('#{Organization.current.locale}');
|
8
|
+
|
9
|
+
mumuki.incognitoUser = #{current_incognito_user?};
|
10
|
+
|
11
|
+
mumuki.version = '#{Mumuki::Laboratory::VERSION}';
|
8
12
|
</script>
|
9
13
|
}.html_safe
|
10
14
|
end
|
data/app/helpers/icons_helper.rb
CHANGED
@@ -3,7 +3,7 @@ module IconsHelper
|
|
3
3
|
fa_icon *icon_for(status_like.to_submission_status)
|
4
4
|
end
|
5
5
|
|
6
|
-
def fixed_fa_icon(name, options={})
|
6
|
+
def fixed_fa_icon(name, options = {})
|
7
7
|
fa_icon name, options.merge(class: 'fa-fw fixed-icon')
|
8
8
|
end
|
9
9
|
|
@@ -47,12 +47,12 @@ module IconsHelper
|
|
47
47
|
iconizable.iconize[:type].to_s
|
48
48
|
end
|
49
49
|
|
50
|
-
def label_for_contextualization(contextualization)
|
50
|
+
def label_for_contextualization(contextualization, **options)
|
51
51
|
iconized = contextualization.iconize
|
52
52
|
%Q{
|
53
53
|
<span class="text-#{iconized[:class]} status-label">
|
54
54
|
#{fa_icon "#{iconized[:type]}"}
|
55
|
-
<span>#{t contextualization.visible_status}</span>
|
55
|
+
<span class="#{options[:class]}">#{t contextualization.visible_status}</span>
|
56
56
|
</span>
|
57
57
|
}.html_safe
|
58
58
|
end
|
data/app/mailers/user_mailer.rb
CHANGED
@@ -1,24 +1,37 @@
|
|
1
1
|
class UserMailer < ApplicationMailer
|
2
|
+
def welcome_email(user, organization)
|
3
|
+
with_locale(user, organization) do
|
4
|
+
organization_name = organization.display_name || t(:your_new_organization)
|
5
|
+
build_email t(:welcome, name: organization_name), { inline: organization.welcome_email_template }
|
6
|
+
end
|
7
|
+
end
|
2
8
|
|
3
9
|
def we_miss_you_reminder(user, cycles)
|
4
|
-
|
10
|
+
with_locale(user) do
|
11
|
+
build_email t(:we_miss_you), "#{cycles.ordinalize}_reminder"
|
12
|
+
end
|
5
13
|
end
|
6
14
|
|
7
15
|
def no_submissions_reminder(user)
|
8
|
-
|
16
|
+
with_locale(user) do
|
17
|
+
build_email t(:start_using_mumuki), 'no_submissions_reminder'
|
18
|
+
end
|
9
19
|
end
|
10
20
|
|
11
|
-
|
12
|
-
|
13
|
-
def send_reminder!(user, subject, template_name)
|
21
|
+
def with_locale(user, organization = nil, &block)
|
14
22
|
@user = user
|
15
23
|
@unsubscribe_code = User.unsubscription_verifier.generate(user.id)
|
16
|
-
@organization = user.last_organization
|
24
|
+
@organization = organization || user.last_organization
|
17
25
|
|
18
|
-
I18n.with_locale(@organization.locale)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
26
|
+
I18n.with_locale(@organization.locale, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def build_email(subject, template)
|
32
|
+
mail to: @user.email,
|
33
|
+
subject: subject,
|
34
|
+
content_type: 'text/html',
|
35
|
+
body: render(template)
|
23
36
|
end
|
24
37
|
end
|
@@ -36,7 +36,7 @@
|
|
36
36
|
<div class="chapter-container">
|
37
37
|
<div class="chapter <%= enabled ? '' : 'mu-locked' %>">
|
38
38
|
<h3><%= it.number %>. <%= link_to_path_element it, mode: :plain %></h3>
|
39
|
-
<div class="text-box" <%= 'aria-label=""' unless enabled
|
39
|
+
<div class="text-box" <%= 'aria-label=""' unless enabled %>>
|
40
40
|
<%= it.description_teaser_html %>
|
41
41
|
</div>
|
42
42
|
</div>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<%= content_for :breadcrumbs do %>
|
2
|
-
<%=
|
2
|
+
<%= header_breadcrumbs %> <%= breadcrumb_list_item(t(:discussions), 'last') %>
|
3
3
|
<% end %>
|
4
4
|
|
5
5
|
<%= content_for :extra_filters do %>
|
6
|
-
<%= discussion_dropdown_filter :language, discussions_languages(@discussions) do |language_filter| %>
|
6
|
+
<%= discussion_dropdown_filter :language, discussions_languages(@discussions), true do |language_filter| %>
|
7
7
|
<%= language_filter.capitalize %>
|
8
8
|
<% end %>
|
9
9
|
<% end %>
|
@@ -18,6 +18,6 @@
|
|
18
18
|
<% if @discussions.empty? %>
|
19
19
|
<h4><%= t :no_questions %></h4>
|
20
20
|
<% else %>
|
21
|
-
|
21
|
+
<%= render partial: 'layouts/discussions' %>
|
22
22
|
<% end %>
|
23
23
|
</div>
|
@@ -7,16 +7,28 @@
|
|
7
7
|
<%= t(:time_since, time: time_ago_in_words(message.created_at)) %>
|
8
8
|
</span>
|
9
9
|
<% if user.moderator_here? %>
|
10
|
-
<%= fa_icon(:star,
|
10
|
+
<%= fa_icon(:star, 'data-toggle': 'tooltip', title: (t :moderator), class: 'moderator-star') %>
|
11
11
|
<% end %>
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
<%=
|
16
|
-
|
12
|
+
<span class="actions">
|
13
|
+
<% if message.authorized? current_user %>
|
14
|
+
<% if current_user&.moderator_here? %>
|
15
|
+
<a class="discussion-message-approved <%= 'selected' if message.approved? %>" onclick="mumuki.Forum.discussionMessageToggleApprove('<%= approve_discussion_message_url(@discussion, message) %>', $(this))">
|
16
|
+
<%= fa_icon(:check, class: 'fa-xs') %>
|
17
|
+
</a>
|
18
|
+
<% if message.from_initiator? %>
|
19
|
+
<a class="discussion-message-not-actually-a-question <%= 'selected' if message.not_actually_a_question? %>" onclick="mumuki.Forum.discussionMessageToggleNotActuallyAQuestion('<%= question_discussion_message_url(@discussion, message) %>', $(this))">
|
20
|
+
<%= fa_icon('question-circle-o', class: 'fa-xs') %>
|
21
|
+
</a>
|
22
|
+
<% end %>
|
23
|
+
<% end %>
|
17
24
|
<%= link_to fa_icon('trash-o'), discussion_message_path(@discussion, message), method: :delete, data: { confirm: t(:are_you_sure, action: t(:destroy_message)) } %>
|
18
|
-
|
19
|
-
|
25
|
+
<% end %>
|
26
|
+
<% if should_show_approved_for?(current_user, message) %>
|
27
|
+
<span class="discussion-message-approved selected">
|
28
|
+
<%= fa_icon(:check, class: 'fa-xs', 'data-toggle': 'tooltip', title: (t :approved_message)) %>
|
29
|
+
</span>
|
30
|
+
<% end %>
|
31
|
+
</span>
|
20
32
|
</div>
|
21
33
|
</div>
|
22
34
|
<div class="discussion-message-bubble-content">
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<%= content_for :breadcrumbs do %>
|
2
|
+
<%= breadcrumbs_for_discussion @discussion, @debatable %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<%= form_for [@debatable, @discussion] do |f| %>
|
6
|
+
<div>
|
7
|
+
<div class="discussion-context">
|
8
|
+
<%= render partial: 'exercises/read_only', locals: {exercise: @debatable} %>
|
9
|
+
</div>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<hr class="message-divider">
|
13
|
+
|
14
|
+
<%= render layout: 'discussions/message_container', locals: {user: @discussion.initiator} do %>
|
15
|
+
<div class="discussion-message-bubble" id="new-discussion-description-container">
|
16
|
+
<div class="discussion-message-bubble-header">
|
17
|
+
<div class="discussion-message-bubble-title">
|
18
|
+
<%= @discussion.initiator.name %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
<div class="discussion-message-bubble-content">
|
22
|
+
<div class="container-fluid">
|
23
|
+
<div class="row">
|
24
|
+
<div class="discussion-new-message-content">
|
25
|
+
<%= f.editor :description, '', {id: 'new-discussion-message', class: 'form-control', placeholder: t(:discussion_description_placeholder)} %>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
<%= f.submit t(:save), class: 'btn btn-success btn-block discussion-new-message-button' %>
|
32
|
+
<% end %>
|
33
|
+
<% end %>
|
@@ -3,55 +3,25 @@
|
|
3
3
|
<% end %>
|
4
4
|
|
5
5
|
<div>
|
6
|
-
<div class="row">
|
7
|
-
<% if current_user %>
|
8
|
-
<div class="mu-inline-block-right hidden-xs discussion-user-menu">
|
9
|
-
<h3>
|
10
|
-
<% if @discussion.subscribable? %>
|
11
|
-
<a class="discussion-subscription" onclick="mumuki.Forum.discussionSubscription('<%= subscription_discussion_url(@discussion) %>')">
|
12
|
-
<%= fa_icon(:eye, class: 'fa-xs') %>
|
13
|
-
<%= span_toggle t(:subscribe), t(:unsubscribe), current_user.subscribed_to?(@discussion) %>
|
14
|
-
</a>
|
15
|
-
<% end %>
|
16
|
-
<% if @discussion.solved? %>
|
17
|
-
<a class="discussion-upvote" onclick="mumuki.Forum.discussionUpvote('<%= upvote_discussion_url(@discussion) %>')">
|
18
|
-
<%= fa_icon(:star, class: 'fa-xs') %>
|
19
|
-
<%= span_toggle t(:upvote), t(:undo_upvote), current_user.upvoted?(@discussion) %>
|
20
|
-
</a>
|
21
|
-
<% end %>
|
22
|
-
</h3>
|
23
|
-
</div>
|
24
|
-
<% end %>
|
25
|
-
<div class="mu-inline-block-left">
|
26
|
-
<div class="discussion-header">
|
27
|
-
<h3 class="discussion-title">
|
28
|
-
<%= @discussion.title %>
|
29
|
-
</h3>
|
30
|
-
</div>
|
31
|
-
<div class="discussion-description">
|
32
|
-
<%= label_for_contextualization(@discussion) %> ·
|
33
|
-
<span class="discussion-info">
|
34
|
-
<span class="discussion-initiator-name">
|
35
|
-
<%= @discussion.initiator.name %>
|
36
|
-
</span>
|
37
|
-
<%= discussion_info(@discussion) %>
|
38
|
-
</span>
|
39
|
-
</div>
|
40
|
-
</div>
|
41
|
-
</div>
|
42
|
-
|
43
6
|
<div class="discussion-context">
|
44
7
|
<%= render partial: 'exercises/read_only', locals: {exercise: @debatable} %>
|
45
8
|
</div>
|
46
|
-
|
47
9
|
</div>
|
48
10
|
|
49
11
|
<% if @discussion.has_messages? || @discussion.commentable_by?(current_user) %>
|
50
12
|
<hr class="message-divider">
|
51
13
|
|
52
|
-
<
|
53
|
-
|
54
|
-
|
14
|
+
<div>
|
15
|
+
<h3>
|
16
|
+
<%= t :messages %>
|
17
|
+
<% if @discussion.last_moderator_access_visible_for?(current_user) %>
|
18
|
+
<small class="pull-right">
|
19
|
+
<span><%= t :last_seen, name: @discussion.last_moderator_access_by.full_name %></span>
|
20
|
+
<span><%= t :time_since, time: time_ago_in_words(@discussion.last_moderator_access_at) %></span>
|
21
|
+
</small>
|
22
|
+
<% end %>
|
23
|
+
</h3>
|
24
|
+
</div>
|
55
25
|
|
56
26
|
<% if @discussion.has_messages? %>
|
57
27
|
<div class="discussion-messages">
|
@@ -71,8 +41,10 @@
|
|
71
41
|
|
72
42
|
<% end %>
|
73
43
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
44
|
+
<% if current_user&.moderator_here? %>
|
45
|
+
<div class="discussion-actions">
|
46
|
+
<% @discussion.reachable_statuses_for(current_user).each do |status| %>
|
47
|
+
<%= discussion_update_status_button(status) %>
|
48
|
+
<% end %>
|
49
|
+
</div>
|
50
|
+
<% end %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div class="<%= "bs-callout bs-callout-#{icon_class_for contextualization}" %>">
|
1
|
+
<div class="<%= "bs-callout bs-callout-#{icon_class_for contextualization.submission_status}" %>">
|
2
2
|
<%= render partial: 'exercise_solutions/results_title', locals: {contextualization: contextualization} %>
|
3
3
|
<%= yield %>
|
4
4
|
</div>
|