mumuki-laboratory 8.6.1 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/mumuki_laboratory/application/_layout.scss +3 -0
  3. data/app/assets/stylesheets/mumuki_laboratory/application/_modules.scss +1 -0
  4. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_content_show.scss +15 -2
  5. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_medal.scss +1 -1
  6. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_menu.scss +35 -0
  7. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_profile.scss +11 -0
  8. data/app/controllers/api/base_controller.rb +0 -1
  9. data/app/controllers/api/courses_controller.rb +1 -1
  10. data/app/controllers/api/organizations_controller.rb +5 -2
  11. data/app/controllers/api/roles_controller.rb +4 -0
  12. data/app/controllers/api/users_controller.rb +6 -1
  13. data/app/controllers/concerns/with_authorization.rb +1 -16
  14. data/app/controllers/concerns/with_user_params.rb +4 -0
  15. data/app/controllers/discussions_messages_controller.rb +0 -1
  16. data/app/controllers/users_controller.rb +8 -5
  17. data/app/helpers/breadcrumbs_helper.rb +4 -0
  18. data/app/helpers/content_view_helper.rb +19 -0
  19. data/app/helpers/links_helper.rb +2 -2
  20. data/app/helpers/menu_bar_helper.rb +1 -1
  21. data/app/helpers/user_menu_helper.rb +18 -0
  22. data/app/views/chapters/show.html.erb +15 -14
  23. data/app/views/complements/show.html.erb +1 -1
  24. data/app/views/exams/show.html.erb +1 -1
  25. data/app/views/{layouts → exercises}/_exercise_skipped.html.erb +0 -0
  26. data/app/views/exercises/_exercise_title_icons.html.erb +4 -0
  27. data/app/views/exercises/show.html.erb +4 -7
  28. data/app/views/{layouts → guides}/_guide.html.erb +0 -0
  29. data/app/views/guides/_guide_container.html.erb +24 -0
  30. data/app/views/{layouts → guides}/_guide_title_icons.html.erb +1 -3
  31. data/app/views/layouts/_progress_listing.html.erb +1 -1
  32. data/app/views/layouts/_user_menu.html.erb +21 -0
  33. data/app/views/lessons/show.html.erb +1 -1
  34. data/app/views/users/_user_form.html.erb +10 -8
  35. data/app/views/users/discussions.html.erb +28 -0
  36. data/app/views/users/edit.html.erb +1 -1
  37. data/app/views/users/messages.html.erb +27 -0
  38. data/app/views/users/show.html.erb +4 -51
  39. data/app/views/users/terms.html.erb +1 -1
  40. data/config/routes.rb +3 -0
  41. data/lib/mumuki/laboratory/locales/en.yml +3 -1
  42. data/lib/mumuki/laboratory/locales/es-CL.yml +3 -1
  43. data/lib/mumuki/laboratory/locales/es.yml +3 -1
  44. data/lib/mumuki/laboratory/locales/pt.yml +3 -1
  45. data/lib/mumuki/laboratory/version.rb +1 -1
  46. data/spec/controllers/organizations_api_controller_spec.rb +16 -9
  47. data/spec/dummy/db/schema.rb +23 -0
  48. data/spec/features/exercise_flow_spec.rb +3 -3
  49. data/spec/features/login_flow_spec.rb +1 -1
  50. data/spec/features/menu_bar_spec.rb +24 -24
  51. data/spec/features/profile_flow_spec.rb +5 -7
  52. metadata +17 -10
  53. data/app/views/layouts/_guide_container.html.erb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 824e346e9d3113f3b3d48c8ed7e23c846e26a54fb5ed7e4c4bb5a9307323b4d7
4
- data.tar.gz: e28b9bdf65007abda370a36b760adeaf7989ab9e4c94c52ebaa09bcd3f14fb79
3
+ metadata.gz: 96b344d472912c433732e101f0754c229aa8c406e47a2ff54503a9625bb78f5a
4
+ data.tar.gz: b73fba56c2c87069b1e402ce010eaa17d296220c92df9cc241d92e9aa92eb909
5
5
  SHA512:
6
- metadata.gz: 46a32c31bb80eca3fa50fc45c37875a36894cf3fbc2192f339c138763afeac44a811ab336650460a7e7f150323601d92cab90c91e967668916462d21026eb72a
7
- data.tar.gz: c9ecc5bd9523a72129d3914317fa29c596038b99f3733de72fc71c27b5c1be3295d9f79ddff39d3cf39c8cfb22bd873581442c4c9121680cdd68901990a11b54
6
+ metadata.gz: b2557a3374e33d3a273b4df24cdd5eb3e46d0e997af5a862c6b6a6cd792a63c4a78e6c248927efeaf964d275139923cea0292a204b92448a965614c2b1f0f82f
7
+ data.tar.gz: 2667001640a346bd3517445621adb899599b52a44d7c40625a6ae67e7a46e7c5c2d935501358b5a28e5ebeb6aa7a0da58cc4af0cf74fb2a7706d738577d47837
@@ -122,6 +122,9 @@ hr {
122
122
 
123
123
  /* TODO: move to mumuki-styles */
124
124
  .mu-inline-block-left {
125
+ display: flex;
126
+ align-items: center;
127
+
125
128
  margin-left: 15px;
126
129
  }
127
130
 
@@ -27,4 +27,5 @@
27
27
  @import "modules/terms";
28
28
  @import "modules/timer";
29
29
  @import "modules/upload";
30
+ @import "modules/user_menu";
30
31
  @import "modules/user_profile";
@@ -1,3 +1,16 @@
1
- .chapter-description {
2
- display: inline-block;
1
+ .mu-chapter-description p {
2
+ display: inline-block
3
+ }
4
+
5
+ .mu-content-title-icons {
6
+ display: flex;
7
+ align-items: center;
8
+
9
+ font-size: 150%;
10
+ margin-left: 15px;
11
+ margin-right: 15px;
12
+
13
+ i {
14
+ margin-left: 5px;
15
+ }
3
16
  }
@@ -28,7 +28,7 @@
28
28
  left: 20px;
29
29
  top: 17px;
30
30
 
31
- margin-right: 30px;
31
+ margin-right: 40px;
32
32
  margin-bottom: 15px;
33
33
  }
34
34
 
@@ -0,0 +1,35 @@
1
+ .mu-user-menu {
2
+ display: flex;
3
+ }
4
+
5
+ .mu-user-menu-header {
6
+ font-size: 15px;
7
+ color: $mu-color-disabled;
8
+ text-transform: uppercase;
9
+ margin-bottom: 30px;
10
+ }
11
+
12
+ .mu-user-menu-item {
13
+ font-size: 17px;
14
+ margin-bottom: 5px;
15
+
16
+ a {
17
+ color: $brand-primary;
18
+ &.active {
19
+ font-weight: bold;
20
+ }
21
+ }
22
+ }
23
+
24
+ .mu-user-menu-divider {
25
+ &.vertical {
26
+ border-left: 2px solid $mu-color-separator;
27
+ }
28
+
29
+ &.horizontal {
30
+ border-top: 2px solid $mu-color-separator;
31
+
32
+ margin: 25px 0;
33
+ width: 100%
34
+ }
35
+ }
@@ -31,11 +31,19 @@
31
31
  }
32
32
  }
33
33
 
34
+ .mu-profile-info {
35
+ display: flex;
36
+ flex-wrap: wrap;
37
+
38
+ margin-top: 20px;
39
+ }
40
+
34
41
  .mu-profile-info-left {
35
42
  display: flex;
36
43
  flex-direction: column;
37
44
  align-items: center;
38
45
  text-align: center;
46
+ flex-grow: 1;
39
47
 
40
48
  .mu-level-progress {
41
49
  position: relative;
@@ -62,8 +70,11 @@
62
70
  }
63
71
 
64
72
  .mu-profile-info-right {
73
+ flex-grow: 2;
74
+
65
75
  font-size: 20px;
66
76
  margin-top: 5px;
77
+
67
78
  div {
68
79
  margin-bottom: 15px;
69
80
  .italic {
@@ -5,7 +5,6 @@ module Api
5
5
  protect_from_forgery with: :null_session
6
6
 
7
7
  include Mumuki::Laboratory::Controllers::DynamicErrors
8
- include WithAuthorization
9
8
  include Mumuki::Laboratory::Controllers::CurrentOrganization
10
9
 
11
10
  before_action :set_current_organization!
@@ -18,7 +18,7 @@ module Api
18
18
  @course = Course.new course_params
19
19
  end
20
20
 
21
- def protection_slug
21
+ def authorization_slug
22
22
  @course.slug
23
23
  end
24
24
  end
@@ -2,8 +2,7 @@ module Api
2
2
  class OrganizationsController < BaseController
3
3
  include OrganizationsControllerTemplate
4
4
 
5
- before_action :authorize_janitor!, only: [:show, :index]
6
- before_action :authorize_admin!, only: [:update, :create]
5
+ before_action :authorize_admin!
7
6
 
8
7
  def index
9
8
  render json: { organizations: Organization.accessible_as(current_user, :janitor) }
@@ -22,6 +21,10 @@ module Api
22
21
  @organization.update! organization_params
23
22
  render json: @organization.to_resource_h
24
23
  end
24
+
25
+ def authorization_slug
26
+ '_/_'
27
+ end
25
28
  end
26
29
 
27
30
  end
@@ -48,6 +48,10 @@ module Api
48
48
  def set_slug!
49
49
  @slug = Mumukit::Auth::Slug.join_s params.to_unsafe_h
50
50
  end
51
+
52
+ def authorization_slug
53
+ @slug
54
+ end
51
55
  end
52
56
 
53
57
  end
@@ -9,8 +9,13 @@ module Api
9
9
  end
10
10
 
11
11
  def update
12
- @user.update_and_notify! user_params.except([:email, :permissions, :uid])
12
+ @user.assign_attributes user_name_params
13
+ @user.verify_name!
13
14
  render json: @user.to_resource_h
14
15
  end
16
+
17
+ def authorization_slug
18
+ '_/_'
19
+ end
15
20
  end
16
21
  end
@@ -1,27 +1,12 @@
1
1
  module WithAuthorization
2
2
  extend ActiveSupport::Concern
3
3
 
4
- def authorize_janitor!
5
- authorize! :janitor
6
- end
7
-
8
- def authorize_admin!
9
- authorize! :admin
10
- end
11
-
12
- def authorize_owner!
13
- authorize! :owner
14
- end
15
-
16
- def authorize_moderator!
17
- authorize! :moderator
18
- end
19
-
20
4
  def authorization_slug
21
5
  protection_slug || '_/_'
22
6
  end
23
7
 
24
8
  def protection_slug
9
+ warn "protection_slug is nil, which is not probably what you want" unless @slug
25
10
  @slug
26
11
  end
27
12
  end
@@ -5,6 +5,10 @@ module WithUserParams
5
5
  params.require(:user).permit(*permissible_params).to_h
6
6
  end
7
7
 
8
+ def user_name_params
9
+ params.require(:user).permit(:first_name, :last_name).to_h
10
+ end
11
+
8
12
  def permissible_params
9
13
  User.profile_fields
10
14
  end
@@ -1,5 +1,4 @@
1
1
  class DiscussionsMessagesController < AjaxController
2
- include WithAuthorization
3
2
  include WithUserDiscussionValidation
4
3
 
5
4
  before_action :set_discussion!, only: [:create, :destroy]
@@ -5,11 +5,6 @@ class UsersController < ApplicationController
5
5
  before_action :set_user!
6
6
  skip_before_action :validate_accepted_role_terms!
7
7
 
8
- def show
9
- @messages = current_user.messages.to_a
10
- @watched_discussions = current_user.watched_discussions_in_organization
11
- end
12
-
13
8
  def update
14
9
  current_user.update_and_notify! user_params
15
10
  current_user.accept_profile_terms!
@@ -27,6 +22,14 @@ class UsersController < ApplicationController
27
22
  @profile_terms ||= Term.profile_terms_for(current_user)
28
23
  end
29
24
 
25
+ def messages
26
+ @messages ||= current_user.messages_in_organization
27
+ end
28
+
29
+ def discussions
30
+ @watched_discussions = current_user.watched_discussions_in_organization
31
+ end
32
+
30
33
  def unsubscribe
31
34
  user_id = User.unsubscription_verifier.verify(params[:id])
32
35
  User.find(user_id).unsubscribe_from_reminders!
@@ -41,6 +41,10 @@ module BreadcrumbsHelper
41
41
  discussion.friendly.truncate_words(4)
42
42
  end
43
43
 
44
+ def breadcrumbs_for_my_account
45
+ header_breadcrumbs + breadcrumb_list_item(t(:my_account), 'last')
46
+ end
47
+
44
48
  private
45
49
 
46
50
  def breadcrumbs_for_linkable(e, extra=nil, last='')
@@ -0,0 +1,19 @@
1
+ module ContentViewHelper
2
+ def full_title_for(content)
3
+ "#{t(content_type_number(content), number: content.number)}: #{content.name}"
4
+ end
5
+
6
+ def short_title_for(content)
7
+ content.name
8
+ end
9
+
10
+ private
11
+
12
+ def content_type_number(content)
13
+ "#{content_type(content)}_number"
14
+ end
15
+
16
+ def content_type(content)
17
+ content.model_name.element
18
+ end
19
+ end
@@ -26,7 +26,7 @@ module LinksHelper
26
26
  if current_user&.teacher_here? && item.teacher_info.present?
27
27
  %Q{
28
28
  <a
29
- class="mu-content-toolbar-item mu-popover"
29
+ class="mu-popover"
30
30
  data-toggle="popover"
31
31
  data-html="true"
32
32
  title="#{t :teacher_info}"
@@ -80,7 +80,7 @@ module LinksHelper
80
80
  return unless current_user&.writer?
81
81
 
82
82
  url = yield
83
- link_to fixed_fa_icon('pencil-alt'), url, class: "mu-content-toolbar-item", target: "_blank", title: t(:edit)
83
+ link_to fixed_fa_icon('pencil-alt'), url, target: "_blank", title: t(:edit)
84
84
  end
85
85
 
86
86
  def url_for_bibliotheca_guide(guide)
@@ -18,7 +18,7 @@ module MenuBarHelper
18
18
  end
19
19
 
20
20
  def link_to_profile
21
- menu_item('user', :profile, user_path)
21
+ menu_item('user', :my_account, user_path)
22
22
  end
23
23
 
24
24
  def link_to_classroom
@@ -0,0 +1,18 @@
1
+ module UserMenuHelper
2
+ def profile_user_menu_link
3
+ user_menu_link t(:my_profile), user_path, 'show'
4
+ end
5
+
6
+ def messages_user_menu_link
7
+ user_menu_link t(:messages), messages_user_path, 'messages'
8
+ end
9
+
10
+ def discussions_user_menu_link
11
+ user_menu_link t(:discussions), discussions_user_path, 'discussions'
12
+ end
13
+
14
+ def user_menu_link(label, path, active_on)
15
+ link_klass = 'active' if action_name == active_on
16
+ link_to label, path, { class: link_klass }.compact
17
+ end
18
+ end
@@ -2,26 +2,27 @@
2
2
  <%= breadcrumbs @chapter %>
3
3
  <% end %>
4
4
 
5
- <div class="chapter-description">
6
- <h1 class="pull-left">
7
- <span class="hidden-xs pull-left"><%= t(:chapter_number, number: @chapter.number) %>:&nbsp;</span>
8
- <span class="pull-left"><%= @chapter.name %></span>
5
+ <div class="row">
6
+ <div class="mu-inline-block-left">
7
+ <h1 class="hidden-xs"><%= full_title_for @chapter %></h1>
8
+ <h1 class="visible-xs"><%= short_title_for @chapter %></h1>
9
+
9
10
  <% if @chapter.monolesson? %>
10
- <div class="mu-monolesson pull-left">
11
- <%= render partial: 'layouts/guide_title_icons' %>
12
- </div>
11
+ <%= render partial: 'guides/guide_title_icons' %>
13
12
  <% end %>
14
- </h1>
15
-
16
- <%= @chapter.description_html %>
17
-
13
+ </div>
14
+ </div>
15
+ <div class="row">
16
+ <div class="col-md-12">
17
+ <div class="text-box mu-chapter-description">
18
+ <%= @chapter.description_html %>
19
+ </div>
20
+ </div>
18
21
  </div>
19
22
 
20
23
  <% if @chapter.lessons.present? %>
21
24
  <% if @chapter.monolesson? %>
22
- <div class="mu-monolesson">
23
- <%= render partial: 'layouts/guide', locals: { subject: @monolesson } %>
24
- </div>
25
+ <div> <%= render partial: 'guides/guide', locals: { subject: @monolesson } %> </div>
25
26
  <% else %>
26
27
  <div>
27
28
  <h3><%= t(:lessons) %></h3>
@@ -1 +1 @@
1
- <%= render partial: "layouts/guide_container", locals: { subject: @complement }%>
1
+ <%= render partial: "guides/guide_container", locals: { subject: @complement }%>
@@ -1 +1 @@
1
- <%= render partial: "layouts/guide_container", locals: { subject: @exam }%>
1
+ <%= render partial: "guides/guide_container", locals: { subject: @exam }%>
@@ -0,0 +1,4 @@
1
+ <div class="mu-content-title-icons">
2
+ <%= teacher_info_button @exercise %>
3
+ <%= link_to_bibliotheca_exercise @exercise %>
4
+ </div>
@@ -18,12 +18,9 @@
18
18
  <h1><%= language_icon @exercise.language %></h1>
19
19
  </div>
20
20
  <div class="mu-inline-block-left">
21
- <h1>
22
- <span class="hidden-xs"><%= t(:exercise_number, number: @exercise.number) %>:&nbsp;</span>
23
- <span><%= @exercise.name %></span>
24
- <%= teacher_info_button @exercise %>
25
- <%= link_to_bibliotheca_exercise @exercise %>
26
- </h1>
21
+ <h1 class="hidden-xs"><%= full_title_for @exercise %></h1>
22
+ <h1 class="visible-xs"><%= short_title_for @exercise %></h1>
23
+ <%= render partial: 'exercises/exercise_title_icons' %>
27
24
  </div>
28
25
  </div>
29
26
  <% end %>
@@ -58,7 +55,7 @@
58
55
 
59
56
  <%= content_for :no_container do %>
60
57
  <% if @assignment.skipped? %>
61
- <%= render partial: 'layouts/exercise_skipped' %>
58
+ <%= render partial: 'exercises/exercise_skipped' %>
62
59
  <% end %>
63
60
 
64
61
  <% if in_gamified_context? %>
File without changes