mumuki-laboratory 9.12.1 → 9.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/app/controllers/application_controller.rb +7 -3
- data/app/controllers/book_controller.rb +6 -0
- data/app/controllers/chapters_controller.rb +9 -0
- data/app/controllers/discussions_controller.rb +9 -0
- data/app/controllers/exercises_controller.rb +5 -0
- data/app/controllers/faqs_controller.rb +4 -0
- data/app/controllers/lessons_controller.rb +9 -0
- data/app/controllers/users_controller.rb +4 -0
- data/app/helpers/concerns/with_student_path_navigation.rb +1 -1
- data/app/helpers/content_view_helper.rb +8 -0
- data/app/helpers/discussions_helper.rb +1 -1
- data/app/helpers/links_helper.rb +5 -1
- data/app/helpers/menu_bar_helper.rb +2 -3
- data/app/helpers/overlapped_buttons_helper.rb +2 -1
- data/app/views/book/show.html.erb +16 -7
- data/app/views/chapters/show.html.erb +1 -0
- data/app/views/discussions/_new_message.html.erb +1 -1
- data/app/views/discussions/show.html.erb +5 -5
- data/app/views/exercise_solutions/_results.html.erb +1 -1
- data/app/views/guides/_guide.html.erb +2 -2
- data/app/views/layouts/_progress_bar.html.erb +1 -0
- data/app/views/layouts/_progress_listing.html.erb +1 -0
- data/app/views/layouts/application.html.erb +4 -0
- data/app/views/layouts/exercise_inputs/forms/_kids_form.html.erb +1 -1
- data/app/views/layouts/exercise_inputs/forms/_problem_form.html.erb +6 -2
- data/app/views/layouts/exercise_inputs/read_only_editors/_hidden.html.erb +0 -0
- data/app/views/layouts/exercise_inputs/read_only_editors/_upload.html.erb +0 -0
- data/lib/mumuki/laboratory/controllers.rb +1 -0
- data/lib/mumuki/laboratory/controllers/authorization.rb +5 -1
- data/lib/mumuki/laboratory/controllers/validate_access_mode.rb +15 -0
- data/lib/mumuki/laboratory/version.rb +1 -1
- data/spec/features/menu_bar_spec.rb +3 -2
- data/spec/features/not_found_private_flow_spec.rb +1 -1
- data/spec/features/read_only_flow_spec.rb +920 -0
- metadata +13 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 331d677d1f93dd36a842d9b39bd78a364e3cfdfe6b87711a52b8dbd0fdd3c678
|
|
4
|
+
data.tar.gz: 159c5b4bf7abb35721da25fea0f11c861fe2df4243c505a4bc8b3c6f523f6207
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b575ed92e419931d69aae5b043f7e29a792c9d9180746e1be3c6bd1261b29394d656a5d97231a6f419181c97daf0dd01b40637c62ab7cc35ee52fd31f84de2b6
|
|
7
|
+
data.tar.gz: 84a684078c62aa1f15c070a3af71f82c6afce2ea657c0b8de0017954c2d020e7a3eb9c5014031746440bfd44b363386cbae0d8f1d6a9e58ee16cb2cb7368257e
|
data/README.md
CHANGED
|
@@ -559,15 +559,16 @@ Before using the API, you must create an `ApiClient` using `rails c`, which will
|
|
|
559
559
|
|
|
560
560
|
Before using the API, take a look to the roles hierarchy:
|
|
561
561
|
|
|
562
|
-
.
|
|
563
563
|
|
|
564
564
|
Permissions are bound to a scope, that states in which context the operation can be performed. Scopes are simply two-level contexts, expressed as slugss `<first>/<second>`, without any explicit semantic. They exact meaning depends on the role:
|
|
565
565
|
|
|
566
|
+
* ex_student: `organization/course`
|
|
566
567
|
* student: `organization/course`
|
|
567
568
|
* teacher and headmaster: `organization/course`
|
|
568
569
|
* writer and editor: `organization/content`
|
|
569
570
|
* janitor: `organization/_`
|
|
570
|
-
* moderator: `organization/_`
|
|
571
|
+
* moderator and forum_supervisor: `organization/_`
|
|
571
572
|
* admin: `_/_`
|
|
572
573
|
* owner: `_/_`
|
|
573
574
|
|
|
@@ -24,7 +24,6 @@ class ApplicationController < ActionController::Base
|
|
|
24
24
|
before_action :redirect_to_proper_context!, if: :immersive_context_wrong?
|
|
25
25
|
|
|
26
26
|
before_action :authorize_if_private!
|
|
27
|
-
before_action :validate_active_organization!
|
|
28
27
|
before_action :validate_user_profile!, if: :current_user?
|
|
29
28
|
before_action :validate_accepted_role_terms!, if: :current_user?
|
|
30
29
|
|
|
@@ -43,7 +42,8 @@ class ApplicationController < ActionController::Base
|
|
|
43
42
|
:current_immersive_organizations,
|
|
44
43
|
:theme_stylesheet_url,
|
|
45
44
|
:extension_javascript_url,
|
|
46
|
-
:current_immersive_path
|
|
45
|
+
:current_immersive_path,
|
|
46
|
+
:current_access_mode
|
|
47
47
|
|
|
48
48
|
add_flash_types :info
|
|
49
49
|
|
|
@@ -72,7 +72,7 @@ class ApplicationController < ActionController::Base
|
|
|
72
72
|
|
|
73
73
|
def validate_active_organization!
|
|
74
74
|
return if current_user&.teacher_here?
|
|
75
|
-
Organization.current.
|
|
75
|
+
Organization.current.validate_active_for! current_user
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
# required by Mumukit::Login
|
|
@@ -160,4 +160,8 @@ class ApplicationController < ActionController::Base
|
|
|
160
160
|
def leave_organization!
|
|
161
161
|
Mumukit::Platform::Organization.leave!
|
|
162
162
|
end
|
|
163
|
+
|
|
164
|
+
def current_access_mode
|
|
165
|
+
Organization.current.access_mode(current_user)
|
|
166
|
+
end
|
|
163
167
|
end
|
|
@@ -3,6 +3,7 @@ require 'addressable/uri'
|
|
|
3
3
|
# It acts as a guide container in monolesson contexts
|
|
4
4
|
class ChaptersController < GuideContainerController
|
|
5
5
|
include Mumuki::Laboratory::Controllers::ImmersiveNavigation
|
|
6
|
+
include Mumuki::Laboratory::Controllers::ValidateAccessMode
|
|
6
7
|
|
|
7
8
|
def subject
|
|
8
9
|
@chapter ||= Chapter.find_by(id: params[:id])
|
|
@@ -14,4 +15,12 @@ class ChaptersController < GuideContainerController
|
|
|
14
15
|
@monolesson = subject.monolesson
|
|
15
16
|
@guide = @monolesson&.guide
|
|
16
17
|
end
|
|
18
|
+
|
|
19
|
+
def authorization_minimum_role
|
|
20
|
+
:ex_student
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def subject_container
|
|
24
|
+
subject.topic
|
|
25
|
+
end
|
|
17
26
|
end
|
|
@@ -7,6 +7,7 @@ class DiscussionsController < ApplicationController
|
|
|
7
7
|
before_action :discussion_filter_params, only: :index
|
|
8
8
|
before_action :read_discussion, only: :show
|
|
9
9
|
before_action :authorize_moderator!, only: [:responsible]
|
|
10
|
+
before_action :validate_access_mode!
|
|
10
11
|
|
|
11
12
|
helper_method :discussion_filter_params
|
|
12
13
|
|
|
@@ -99,4 +100,12 @@ class DiscussionsController < ApplicationController
|
|
|
99
100
|
def discussion_filter_params
|
|
100
101
|
@filter_params ||= params.permit(Discussion.permitted_query_params)
|
|
101
102
|
end
|
|
103
|
+
|
|
104
|
+
def authorization_minimum_role
|
|
105
|
+
:ex_student
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def validate_access_mode!
|
|
109
|
+
current_access_mode.validate_discuss_here! subject
|
|
110
|
+
end
|
|
102
111
|
end
|
|
@@ -2,6 +2,7 @@ class ExercisesController < ApplicationController
|
|
|
2
2
|
include Mumuki::Laboratory::Controllers::Content
|
|
3
3
|
include Mumuki::Laboratory::Controllers::ExerciseSeed
|
|
4
4
|
include Mumuki::Laboratory::Controllers::ImmersiveNavigation
|
|
5
|
+
include Mumuki::Laboratory::Controllers::ValidateAccessMode
|
|
5
6
|
|
|
6
7
|
before_action :set_guide!, only: :show
|
|
7
8
|
before_action :set_assignment!, only: :show, if: :current_user?
|
|
@@ -50,4 +51,8 @@ class ExercisesController < ApplicationController
|
|
|
50
51
|
:guide_id, :number,
|
|
51
52
|
:layout, :expectations_yaml)
|
|
52
53
|
end
|
|
54
|
+
|
|
55
|
+
def authorization_minimum_role
|
|
56
|
+
:ex_student
|
|
57
|
+
end
|
|
53
58
|
end
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
class LessonsController < GuideContainerController
|
|
2
2
|
include Mumuki::Laboratory::Controllers::ImmersiveNavigation
|
|
3
|
+
include Mumuki::Laboratory::Controllers::ValidateAccessMode
|
|
3
4
|
|
|
4
5
|
private
|
|
5
6
|
|
|
6
7
|
def subject
|
|
7
8
|
@lesson ||= Lesson.find_by(id: params[:id])
|
|
8
9
|
end
|
|
10
|
+
|
|
11
|
+
def authorization_minimum_role
|
|
12
|
+
:ex_student
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def subject_container
|
|
16
|
+
subject.guide
|
|
17
|
+
end
|
|
9
18
|
end
|
|
@@ -9,7 +9,7 @@ module WithStudentPathNavigation
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def next_exercise_button(exercise)
|
|
12
|
-
next_button(exercise) || next_button(exercise.guide.lesson)
|
|
12
|
+
next_button(exercise) || next_button(exercise.guide.lesson) if show_content_element?
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def close_modal_button
|
|
@@ -7,6 +7,14 @@ module ContentViewHelper
|
|
|
7
7
|
content.name
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
def show_content?(content)
|
|
11
|
+
current_access_mode.show_content?(content)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def show_content_element?
|
|
15
|
+
current_access_mode.show_content_element?
|
|
16
|
+
end
|
|
17
|
+
|
|
10
18
|
private
|
|
11
19
|
|
|
12
20
|
def content_type_number(content)
|
|
@@ -8,7 +8,7 @@ module DiscussionsHelper
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def solve_discussions_link
|
|
11
|
-
discussions_link others_discussions_icon(t(:solve_doubts)), discussions_path(solve_discussion_params_for(current_user)), class: 'dropdown-item'
|
|
11
|
+
discussions_link others_discussions_icon(t(:solve_doubts)), discussions_path(solve_discussion_params_for(current_user)), class: 'dropdown-item' if current_access_mode.resolve_discussions_here?
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def user_discussions_link
|
data/app/helpers/links_helper.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
module MenuBarHelper
|
|
2
2
|
def menu_bar_links
|
|
3
3
|
[
|
|
4
|
-
menu_link_to_profile,
|
|
5
4
|
menu_link_to_classroom,
|
|
6
5
|
menu_link_to_bibliotheca,
|
|
7
6
|
solve_discussions_link,
|
|
@@ -18,7 +17,7 @@ module MenuBarHelper
|
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
def menu_link_to_profile
|
|
21
|
-
menu_item('user', :my_account, user_path)
|
|
20
|
+
li_tag menu_item('user', :my_account, user_path)
|
|
22
21
|
end
|
|
23
22
|
|
|
24
23
|
def menu_link_to_classroom
|
|
@@ -36,7 +35,7 @@ module MenuBarHelper
|
|
|
36
35
|
end
|
|
37
36
|
|
|
38
37
|
def logout_menu_link
|
|
39
|
-
li_tag menu_item('sign-out-alt', :sign_out, logout_path(origin: url_for))
|
|
38
|
+
li_tag menu_item('sign-out-alt', :sign_out, logout_path(origin: url_for, organization: Organization.current))
|
|
40
39
|
end
|
|
41
40
|
|
|
42
41
|
def menu_item(icon, name, url, css_class = nil, **translation_params)
|
|
@@ -16,7 +16,8 @@ module OverlappedButtonsHelper
|
|
|
16
16
|
{class: 'mu-content-toolbar-item mu-restart-guide',
|
|
17
17
|
data: {confirm: t(:confirm_restart)}, method: :delete, 'data-bs-placement': 'top'})
|
|
18
18
|
|
|
19
|
-
link_to overlapped_button_icon(:undo), guide_progress_path(guide), all_options
|
|
19
|
+
link_to overlapped_button_icon(:undo), guide_progress_path(guide), all_options if show_content_element?
|
|
20
|
+
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
private
|
|
@@ -6,16 +6,25 @@
|
|
|
6
6
|
<%= render partial: 'book/header' %>
|
|
7
7
|
|
|
8
8
|
<% @book.next_lesson_for(current_user).try do |lesson| %>
|
|
9
|
-
|
|
10
|
-
<
|
|
11
|
-
<%=
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
<% if show_content_element? %>
|
|
10
|
+
<div class="actions">
|
|
11
|
+
<a href="<%= lesson_path(lesson) %>" class="btn btn-complementary">
|
|
12
|
+
<%= t book_practice_key_for(current_user) %>
|
|
13
|
+
</a>
|
|
14
|
+
</div>
|
|
15
|
+
<% else %>
|
|
16
|
+
<br>
|
|
17
|
+
<% end %>
|
|
14
18
|
<% end %>
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
<% if show_content?(@book) %>
|
|
21
|
+
<h2><%= t(:chapters) %></h2>
|
|
22
|
+
<% end %>
|
|
17
23
|
|
|
18
24
|
<% @book.chapter_visibilities_in(current_workspace).each do |it, enabled| %>
|
|
25
|
+
|
|
26
|
+
<% next unless show_content?(it.topic) %>
|
|
27
|
+
|
|
19
28
|
<div class="chapter-container">
|
|
20
29
|
<div class="chapter <%= enabled ? '' : 'mu-locked' %>">
|
|
21
30
|
<h3><%= it.number %>. <%= link_to_path_element it, mode: :plain %></h3>
|
|
@@ -24,7 +33,7 @@
|
|
|
24
33
|
</div>
|
|
25
34
|
</div>
|
|
26
35
|
|
|
27
|
-
<% unless enabled
|
|
36
|
+
<% unless enabled %>
|
|
28
37
|
<div class="text-center mu-lock">
|
|
29
38
|
<i class="fas fa-lock fa-5x"></i>
|
|
30
39
|
<p><%= t :locked_content %></p>
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
<h3><%= t(:lessons) %></h3>
|
|
29
29
|
|
|
30
30
|
<% @chapter.lessons.includes(guide: :exercises).each do |lesson| %>
|
|
31
|
+
<% next unless show_content?(lesson.guide) %>
|
|
31
32
|
<h4><%= lesson.number %>. <%= link_to_path_element lesson, mode: :plain %></h4>
|
|
32
33
|
<%= render partial: 'layouts/progress_listing', locals: { guide: lesson.guide } %>
|
|
33
34
|
<% end %>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<%= form_for [@discussion, Message.new] do |f| %>
|
|
2
|
-
<%= render layout: 'discussions/message_container', locals: {user: user} do %>
|
|
2
|
+
<%= render layout: 'discussions/message_container', locals: { user: user } do %>
|
|
3
3
|
<div class="discussion-message-bubble">
|
|
4
4
|
<div class="discussion-message-bubble-header">
|
|
5
5
|
<div class="discussion-message-bubble-title">
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<div>
|
|
6
6
|
<div class="discussion-context">
|
|
7
|
-
<%= render partial: 'exercises/read_only', locals: {exercise: @debatable} %>
|
|
7
|
+
<%= render partial: 'exercises/read_only', locals: { exercise: @debatable } %>
|
|
8
8
|
</div>
|
|
9
9
|
</div>
|
|
10
10
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
<div class="d-flex flex-wrap">
|
|
15
15
|
<h3 class="flex-grow-1 me-3"><%= t :messages %></h3>
|
|
16
|
-
<% if current_user && @discussion.persisted? %>
|
|
16
|
+
<% if current_user && @discussion.persisted? && current_access_mode.show_discussion_element? %>
|
|
17
17
|
<span class="d-flex">
|
|
18
18
|
<% if @discussion.can_toggle_responsible?(current_user) %>
|
|
19
19
|
<div class="discussion-responsible me-1">
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
<% if @discussion.has_messages? %>
|
|
41
41
|
<div class="discussion-messages">
|
|
42
42
|
<% if @discussion.description.present? %>
|
|
43
|
-
<%= render partial: 'discussions/description_message', locals: {discussion: @discussion} %>
|
|
43
|
+
<%= render partial: 'discussions/description_message', locals: { discussion: @discussion } %>
|
|
44
44
|
<% end %>
|
|
45
45
|
<% @discussion.visible_messages.each do |message| %>
|
|
46
|
-
|
|
46
|
+
<%= render partial: 'discussions/message', locals: { user: message.sender_user, message: message } %>
|
|
47
47
|
<% end %>
|
|
48
48
|
<% if @discussion.commentable_by?(current_user) %>
|
|
49
49
|
<hr class="message-divider">
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
</div>
|
|
52
52
|
<% end %>
|
|
53
53
|
|
|
54
|
-
<%= render partial: 'discussions/new_message', locals: {user: current_user} if @discussion.commentable_by?(current_user) %>
|
|
54
|
+
<%= render partial: 'discussions/new_message', locals: { user: current_user } if @discussion.commentable_by?(current_user) && current_access_mode.show_discussion_element? %>
|
|
55
55
|
|
|
56
56
|
<% end %>
|
|
57
57
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<% unless assignment.manual_evaluation_comment? %>
|
|
14
14
|
<%= render layout: 'exercise_solutions/assistant_rules_box', locals: {assignment: assignment } do %>
|
|
15
15
|
<%= render partial: 'exercise_solutions/contextualization_results_body', locals: {contextualization: assignment} %>
|
|
16
|
-
<% if should_render_need_help_dropdown?(assignment) %>
|
|
16
|
+
<% if should_render_need_help_dropdown?(assignment) && current_access_mode.show_discussion_element? %>
|
|
17
17
|
<div class="notify-problem-box">
|
|
18
18
|
<div class="dropdown">
|
|
19
19
|
<%= link_to fa_icon(:'question-circle', text: t(:need_help)), "", {'data-bs-toggle': 'dropdown'} %>
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
</div>
|
|
29
29
|
<% end %>
|
|
30
30
|
|
|
31
|
-
<% if !@stats.try(:done?) && @next_exercise %>
|
|
31
|
+
<% if !@stats.try(:done?) && @next_exercise && show_content_element? %>
|
|
32
32
|
<div class="text-box">
|
|
33
33
|
<div class="actions">
|
|
34
34
|
<%= link_to t(lesson_practice_key_for(@stats)), exercise_path(@next_exercise), class: 'btn btn-complementary' %>
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
</div>
|
|
37
37
|
<% end %>
|
|
38
38
|
|
|
39
|
-
<% if @stats&.done? %>
|
|
39
|
+
<% if @stats&.done? && show_content_element? %>
|
|
40
40
|
<div class="text-box">
|
|
41
41
|
<div class="actions">
|
|
42
42
|
<%= next_lesson_button @guide %>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<div class="progress-list-flex">
|
|
2
2
|
<% assignments = guide.assignments_for(current_user) %>
|
|
3
3
|
<% assignments.each do |assignment| %>
|
|
4
|
+
<% next unless show_content?(assignment.exercise) %>
|
|
4
5
|
<% exercise = assignment.exercise %>
|
|
5
6
|
<a
|
|
6
7
|
<%= turbolinks_enable_for exercise %>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<ul class="progress-listing">
|
|
2
2
|
<% guide.assignments_for(current_user).each do |assignment| %>
|
|
3
|
+
<% next unless show_content?(assignment.exercise) %>
|
|
3
4
|
<% cache [assignment.exercise, assignment.status, Organization.current.name, current_user?] do %>
|
|
4
5
|
<li <%= turbolinks_enable_for(assignment.exercise) %>>
|
|
5
6
|
<%= assignment_status_icon assignment %>
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
<%= profile_picture_for current_user %>
|
|
21
21
|
</div>
|
|
22
22
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="profileDropdown">
|
|
23
|
+
<% if profile_enabled_here? %>
|
|
24
|
+
<%= menu_link_to_profile %>
|
|
25
|
+
<li class="dropdown-divider"></li>
|
|
26
|
+
<% end %>
|
|
23
27
|
<%= menu_bar_list_items %>
|
|
24
28
|
<% if any_menu_bar_links? %>
|
|
25
29
|
<li class="dropdown-divider"></li>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<%= render_exercise_input_editor f, exercise %>
|
|
5
5
|
|
|
6
6
|
<div class="actions mu-submit-button mu-kids-submit-button">
|
|
7
|
-
<%= render_submit_button(@assignment) %>
|
|
7
|
+
<%= render_submit_button(@assignment) if current_access_mode.submit_solutions_here? %>
|
|
8
8
|
</div>
|
|
9
9
|
<div class="actions mu-kids-reset-button"></div>
|
|
10
10
|
<img class="mu-kids-compass-rose" src="/compass_rose.svg">
|
|
@@ -34,11 +34,15 @@
|
|
|
34
34
|
remote: true,
|
|
35
35
|
html: {role: 'form', class: "new_solution mu-editor mu-editor-overlap mu-form #{pending_messages_filter(@assignment)}"}) do |f| %>
|
|
36
36
|
<div class="mb-3">
|
|
37
|
-
|
|
37
|
+
<% if current_access_mode.submit_solutions_here? %>
|
|
38
|
+
<%= render_exercise_input_editor f, exercise %>
|
|
39
|
+
<% else %>
|
|
40
|
+
<%= render_exercise_read_only_editor exercise, @assignment.solution %>
|
|
41
|
+
<% end %>
|
|
38
42
|
</div>
|
|
39
43
|
|
|
40
44
|
<div class="actions mu-submit-button">
|
|
41
|
-
<%= render_submit_button(@assignment) %>
|
|
45
|
+
<%= render_submit_button(@assignment) if current_access_mode.submit_solutions_here? %>
|
|
42
46
|
</div>
|
|
43
47
|
<% end %>
|
|
44
48
|
</div>
|