mumuki-laboratory 9.1.1 → 9.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/mumuki_laboratory/application/faqs.js +6 -6
  3. data/app/assets/javascripts/mumuki_laboratory/application/profile.js +7 -15
  4. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_breadcrumb.scss +4 -28
  5. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_discussion.scss +0 -25
  6. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_faqs.scss +4 -3
  7. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids.scss +0 -1
  8. data/app/controllers/concerns/organizations_controller_template.rb +1 -0
  9. data/app/controllers/exam_authorization_requests_controller.rb +1 -5
  10. data/app/controllers/users_controller.rb +4 -0
  11. data/app/helpers/discussions_helper.rb +10 -2
  12. data/app/helpers/profile_helper.rb +1 -1
  13. data/app/helpers/user_menu_helper.rb +4 -0
  14. data/app/views/discussions/_description_message.html.erb +1 -1
  15. data/app/views/discussions/_message.html.erb +1 -1
  16. data/app/views/discussions/_new_message.html.erb +1 -1
  17. data/app/views/discussions/new.html.erb +1 -1
  18. data/app/views/exam_authorization_requests/_approved.html.erb +1 -0
  19. data/app/views/exam_authorization_requests/_pending.html.erb +4 -0
  20. data/app/views/exam_authorization_requests/_rejected.html.erb +1 -0
  21. data/app/views/exam_registrations/show.html.erb +1 -1
  22. data/app/views/exercises/_read_only.html.erb +3 -3
  23. data/app/views/faqs/index.html.erb +1 -1
  24. data/app/views/layouts/_kids.html.erb +2 -2
  25. data/app/views/layouts/_test_results.html.erb +1 -1
  26. data/app/views/layouts/_user_menu.html.erb +1 -0
  27. data/app/views/layouts/application.html.erb +1 -1
  28. data/app/views/notifications/_exam_authorization_request.html.erb +1 -1
  29. data/app/views/users/activity.html.erb +8 -6
  30. data/app/views/users/exam_authorizations.html.erb +42 -0
  31. data/config/routes.rb +2 -1
  32. data/lib/mumuki/laboratory/locales/en.yml +6 -4
  33. data/lib/mumuki/laboratory/locales/es-CL.yml +6 -4
  34. data/lib/mumuki/laboratory/locales/es.yml +6 -4
  35. data/lib/mumuki/laboratory/locales/pt.yml +6 -4
  36. data/lib/mumuki/laboratory/version.rb +1 -1
  37. data/spec/controllers/exam_authorization_requests_controller_spec.rb +1 -18
  38. data/spec/controllers/organizations_api_controller_spec.rb +3 -1
  39. data/spec/controllers/users_controller_spec.rb +1 -0
  40. data/spec/features/notifications_flow_spec.rb +2 -3
  41. data/spec/features/profile_flow_spec.rb +2 -9
  42. data/spec/features/user_activity_flow_spec.rb +30 -10
  43. data/spec/helpers/with_navigation_spec.rb +37 -0
  44. metadata +122 -119
  45. data/app/views/exam_authorization_requests/show.html.erb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22e07e5d159d6e1e49fd972414dc27da7a622885670bd3d4a60695682bd9cdc4
4
- data.tar.gz: de76a5fe5a591b7aa2783f83ae0a50e15796ae5ba7cf1852a7bd5896c2f7950f
3
+ metadata.gz: 72cf517c032d4c5173d14f33d52060ad7f2ee504beeed5425ebb91a4e3591359
4
+ data.tar.gz: b74980c8331ac7dd02f6e56ba249cb1e7c8a788eecb2e7a88c7b263451069d8c
5
5
  SHA512:
6
- metadata.gz: 0e00878630e1bb812eafc6ca76e67b71e09a246d379de4c3f8ceca39b3d9cdaf216bc322859a0c90ae313a554dbe54c706742296e9d6a04421534485bced4604
7
- data.tar.gz: e529d54a82cba3b40e6642a7f3d4fd4f4bbf211fcceab823b6b255a793df5258389901966319fda2506b28787507d61c4904f556f4ec0f8316bc77bade066eee
6
+ metadata.gz: a92eb701dfaf5fc7666c9e5193908c979018825e9d8a6926eb453ece500dc6431ad149eb43b1eae942e862e6eb8904e57052d3d235b5fb53d54ef0d3c0fe7c77
7
+ data.tar.gz: 023e52805e6213623bda1e6b9bc2e954b032880f7df6ece9c54e8a007c71740aeb5952b0e58365367405e0821d4739480518ac24267bd4839a32b9bb418d8af3
@@ -25,9 +25,9 @@ mumuki.faqs = class {
25
25
  _createNavbar() {
26
26
  const $faqsNavbar = $(".mu-faqs-navbar nav ul");
27
27
  $('.mu-faqs-group').each((_index, faqGroup) => {
28
- const $navItem = this._createNavbarItem($faqsNavbar, faqGroup)
28
+ const $navItem = this._createNavbarItem($faqsNavbar, faqGroup);
29
29
  const $faqGroup = $(faqGroup);
30
- this._configureClickFor($navItem, $faqGroup, $faqsNavbar)
30
+ this._configureClickFor($navItem, $faqGroup, $faqsNavbar);
31
31
  });
32
32
  }
33
33
 
@@ -56,12 +56,12 @@ mumuki.faqs = class {
56
56
  }
57
57
 
58
58
  _createFaqsIcons() {
59
- const $faqIcon = $('<i class="mu-faqs-group-icon fa fa-plus">');
59
+ const $faqIcon = $('<i class="mu-faqs-group-icon fas fa-chevron-down">');
60
60
  $faqIcon.click(function(e){
61
61
  const $elem = $(this);
62
- $elem.toggleClass('fa-plus fa-minus');
62
+ $elem.toggleClass('fa-chevron-down fa-chevron-up');
63
63
  $elem.closest('.mu-faqs-group').toggleClass('active');
64
- })
64
+ });
65
65
  $('.mu-faqs-group').prepend($faqIcon);
66
66
  }
67
67
 
@@ -75,7 +75,7 @@ mumuki.faqs = class {
75
75
  newGroup = [];
76
76
  }
77
77
  newGroup.push(elem);
78
- previousNodeName = elem.nodeName
78
+ previousNodeName = elem.nodeName;
79
79
  });
80
80
 
81
81
  elemsGroups.push(newGroup);
@@ -9,11 +9,10 @@ mumuki.load(function() {
9
9
  let avatarId = "";
10
10
  let avatarType = "";
11
11
 
12
- let originalData = $userForm.serialize();
13
- let originalProfilePicture = $userAvatar.attr('src');
12
+ toggleEditButtonIfRequiredFieldsNotCompleted();
14
13
 
15
14
  $userForm.on('change keyup', function() {
16
- toggleEditButtonIfThereAreChanges();
15
+ toggleEditButtonIfRequiredFieldsNotCompleted();
17
16
  });
18
17
 
19
18
  $avatarItem.on('keypress click', function(e) {
@@ -25,26 +24,19 @@ mumuki.load(function() {
25
24
  const clickedAvatarType = $(this).attr('type');
26
25
  avatarId = clickedAvatarId || "";
27
26
  avatarType = clickedAvatarType || "";
28
-
29
- toggleEditButtonIfThereAreChanges();
30
27
  });
31
28
  });
32
29
 
33
- function toggleEditButtonIfThereAreChanges() {
34
- let shouldEnable = requiredFieldsAreFilled() && (dataChanged() || avatarChanged());
35
-
36
- $editButton.prop('disabled', !shouldEnable);
30
+ function toggleEditButtonIfRequiredFieldsNotCompleted() {
31
+ $editButton.prop('disabled', !requiredFieldsAreCompleted());
37
32
  }
38
33
 
39
- const requiredFieldsAreFilled = () =>
40
- $userForm.find('select, textarea, input').toArray().every(elem => {
34
+ function requiredFieldsAreCompleted() {
35
+ return $userForm.find('select, textarea, input').toArray().every(elem => {
41
36
  const $elem = $(elem);
42
37
  return !($elem.prop('required')) || !!$elem.val();
43
38
  });
44
-
45
- const dataChanged = () => $userForm.serialize() !== originalData;
46
-
47
- const avatarChanged = () => $userAvatar.attr('src') !== originalProfilePicture;
39
+ }
48
40
 
49
41
  $('#mu-user-image').on('keypress click', function(e){
50
42
  onClickOrSpacebarOrEnter($(this), e, function() {
@@ -22,34 +22,6 @@
22
22
 
23
23
  }
24
24
 
25
- .hamburguer-breadcrumb {
26
- .hamburguer {
27
- font-size: 2.5rem;
28
- cursor: pointer;
29
- }
30
- li {
31
- a {
32
- padding: 15px;
33
- }
34
- &:first-child {
35
- i {
36
- &:before {
37
- font-family: 'dev-awesome', serif;
38
- content: "\f10b";
39
- }
40
- &:after {
41
- font-family: 'Lato', serif;
42
- content: "mumuki";
43
- padding: 5px;
44
- }
45
- }
46
- }
47
- &:last-child {
48
- display: none;
49
- }
50
- }
51
- }
52
-
53
25
  .mu-navbar-avatar {
54
26
  justify-self: flex-end;
55
27
  .rounded-circle {
@@ -61,4 +33,8 @@
61
33
  object-fit: contain;
62
34
  height: 38px;
63
35
  position: relative;
36
+
37
+ @include media-breakpoint-down(lg) {
38
+ max-width: 70vw;
39
+ }
64
40
  }
@@ -394,31 +394,6 @@ $moderator-badge-color: #dd9900;
394
394
  }
395
395
  }
396
396
 
397
- $statuses: (
398
- closed: ($danger white $danger),
399
- opened: (white #333333 #eaeaea),
400
- solved: ($success white $success),
401
- pending_review: ($success white $success)
402
- );
403
-
404
- @each $status, $style in $statuses {
405
- $background-color: nth($style, 1);
406
- $font-color: nth($style, 2);
407
- $border-color: nth($style, 3);
408
-
409
- .btn-discussion-#{$status} {
410
- background-color: $background-color;
411
- color: $font-color;
412
- border-color: $border-color;
413
- margin-left: 5px;
414
- &:hover {
415
- color: $font-color;
416
- border-color: darken($border-color, 3%);
417
- background-color: darken($background-color, 3%);
418
- }
419
- }
420
- }
421
-
422
397
  .discussion-requires-attention {
423
398
  margin-right: 20px;
424
399
  label {
@@ -8,7 +8,7 @@
8
8
 
9
9
  width: 100%;
10
10
 
11
- @media (min-width: 768px) {
11
+ @include media-breakpoint-up(md) {
12
12
  width: 75%;
13
13
  float: right;
14
14
  }
@@ -17,8 +17,9 @@
17
17
  padding: 32px;
18
18
  box-shadow: 0 0.375em 2.8125em 0 #d2d5d9;
19
19
  margin-bottom: 32px;
20
+ word-wrap: anywhere;
20
21
 
21
- @media (max-width: 767px) {
22
+ @include media-breakpoint-down(md) {
22
23
  &:not(.active) {
23
24
  h3, p {
24
25
  display: none
@@ -44,7 +45,7 @@
44
45
  margin-top: 10px;
45
46
  cursor: pointer;
46
47
  display: none;
47
- @media (max-width: 767px) {
48
+ @include media-breakpoint-down(md) {
48
49
  display: unset;
49
50
  }
50
51
  }
@@ -195,7 +195,6 @@ $kids-speech-tabs-width: 40px;
195
195
  .mu-kids-next-speech {
196
196
  position: absolute;
197
197
  right: $kids-speech-tabs-width;
198
- font-size: 90%;
199
198
  color: darken($mu-color-disabled, 25%);
200
199
  &:hover {
201
200
  cursor: pointer;
@@ -26,6 +26,7 @@ module OrganizationsControllerTemplate
26
26
  .require(:organization)
27
27
  .permit(:book,
28
28
  :name,
29
+ :faqs,
29
30
  *Mumuki::Domain::Organization::Profile.attributes,
30
31
  *Mumuki::Domain::Organization::Theme.attributes,
31
32
  *(Mumuki::Domain::Organization::Settings.attributes - [:login_methods]),
@@ -1,13 +1,9 @@
1
1
  class ExamAuthorizationRequestsController < ApplicationController
2
- def show
3
- @authorization_request = ExamAuthorizationRequest.find(params[:id])
4
- current_user.read_notification! @authorization_request
5
- end
6
-
7
2
  def create
8
3
  authorization_request = ExamAuthorizationRequest.create! authorization_request_params
9
4
  current_user.read_notification! authorization_request.exam_registration
10
5
  flash.notice = I18n.t :exam_authorization_request_created
6
+ redirect_to root_path
11
7
  end
12
8
 
13
9
  def update
@@ -38,6 +38,10 @@ class UsersController < ApplicationController
38
38
  @certificates ||= current_user.certificates_in_organization
39
39
  end
40
40
 
41
+ def exam_authorizations
42
+ @exam_authorization_requests ||= ExamAuthorizationRequest.where(user: current_user, organization: Organization.current)
43
+ end
44
+
41
45
  def unsubscribe
42
46
  user_id = User.unsubscription_verifier.verify(params[:id])
43
47
  User.find(user_id).unsubscribe_from_reminders!
@@ -83,10 +83,14 @@ module DiscussionsHelper
83
83
  def discussion_update_status_button(status)
84
84
  button_to t("to_#{status}"),
85
85
  item_discussion_path(@discussion, {status: status}),
86
- class: "btn btn-discussion-#{status}",
86
+ class: "btn btn-#{btn_type_for_discussion_statuses[status.to_sym]}",
87
87
  method: :put
88
88
  end
89
89
 
90
+ def btn_type_for_discussion_statuses
91
+ { closed: 'danger', solved: 'success', opened: 'light' }
92
+ end
93
+
90
94
  def new_discussion_link(teaser_text, link_text)
91
95
  %Q{
92
96
  <h4>
@@ -173,7 +177,7 @@ module DiscussionsHelper
173
177
  end
174
178
 
175
179
  def discussion_info(discussion)
176
- "#{t(:time_since, time: time_ago_in_words(discussion.created_at))} · #{t(:message_count, count: discussion.visible_messages.size)}"
180
+ "#{t(:time_since, time: time_ago_in_words(discussion.created_at))} · #{t(:reply_count, count: discussion.visible_messages.size)}"
177
181
  end
178
182
 
179
183
  def discussion_filter_params_without_page
@@ -188,6 +192,10 @@ module DiscussionsHelper
188
192
  user.abbreviated_name
189
193
  end
190
194
 
195
+ def linked_discussion_user_name(user)
196
+ content_tag :a, discussion_user_name(user)
197
+ end
198
+
191
199
  def subscription_icon
192
200
  fa_icon :bell, text: t(:subscribe)
193
201
  end
@@ -8,6 +8,6 @@ module ProfileHelper
8
8
  end
9
9
 
10
10
  def save_edit_profile_button(form)
11
- form.submit t(:save), disabled: true, class: 'btn btn-complementary mu-edit-profile-btn'
11
+ form.submit t(:save), class: 'btn btn-complementary mu-edit-profile-btn'
12
12
  end
13
13
  end
@@ -27,6 +27,10 @@ module UserMenuHelper
27
27
  user_menu_item t(:certificates), certificates_user_path, 'certificates'
28
28
  end
29
29
 
30
+ def exam_authorizations_user_menu_link
31
+ user_menu_item t(:exams), exam_authorizations_user_path, 'exam_authorizations'
32
+ end
33
+
30
34
  private
31
35
 
32
36
  def user_menu_item(label, path, active_on)
@@ -2,7 +2,7 @@
2
2
  <div class="discussion-message-bubble">
3
3
  <div class="discussion-message-bubble-header">
4
4
  <div class="discussion-message-bubble-title">
5
- <%= discussion_user_name(discussion.initiator) %>
5
+ <%= linked_discussion_user_name(discussion.initiator) %>
6
6
  <span class="message-date">
7
7
  <%= t(:time_since, time: time_ago_in_words(discussion.created_at)) %>
8
8
  </span>
@@ -2,7 +2,7 @@
2
2
  <div class="discussion-message-bubble">
3
3
  <div class="discussion-message-bubble-header">
4
4
  <div class="discussion-message-bubble-title">
5
- <%= discussion_user_name user %>
5
+ <%= linked_discussion_user_name user %>
6
6
  <% if user.moderator_here? %>
7
7
  <span class="moderator-badge"><%= t(:moderation) %></span>
8
8
  <% end %>
@@ -3,7 +3,7 @@
3
3
  <div class="discussion-message-bubble">
4
4
  <div class="discussion-message-bubble-header">
5
5
  <div class="discussion-message-bubble-title">
6
- <%= user.name %>
6
+ <%= discussion_user_name user %>
7
7
  </div>
8
8
  </div>
9
9
  <div class="discussion-message-bubble-content">
@@ -15,7 +15,7 @@
15
15
  <div class="discussion-message-bubble" id="new-discussion-description-container">
16
16
  <div class="discussion-message-bubble-header">
17
17
  <div class="discussion-message-bubble-title">
18
- <%= @discussion.initiator.name %>
18
+ <%= discussion_user_name @discussion.initiator %>
19
19
  </div>
20
20
  </div>
21
21
  <div class="discussion-message-bubble-content">
@@ -0,0 +1 @@
1
+ <%= t :exam_authorization_request_approved_html, date: l(authorization_request.exam.start_time, format: :long) %>
@@ -0,0 +1,4 @@
1
+ <%= t :exam_authorization_pending_explanation_html,
2
+ date: l(authorization_request.exam.start_time, format: :long),
3
+ end_time: l(authorization_request.exam_registration.end_time, format: :long),
4
+ edit_path: url_for(authorization_request.exam_registration) %>
@@ -0,0 +1 @@
1
+ <%= t :exam_authorization_request_rejected %>
@@ -11,7 +11,7 @@
11
11
  </div>
12
12
 
13
13
  <div class="row">
14
- <div class="mu-inline-block-left">
14
+ <div class="col-lg-12">
15
15
  <div class="bs-callout bs-callout-info">
16
16
  <h4 class="text-info">
17
17
  <strong><%= fa_icon :info_circle %> <%= t :important_info %></strong>
@@ -26,15 +26,15 @@
26
26
  <%= label_for_contextualization(@discussion, class: 'd-none d-sm-inline') %> ·
27
27
  <span class="discussion-info">
28
28
  <span class="discussion-initiator-name">
29
- <%= @discussion.initiator.name %>
29
+ <%= discussion_user_name @discussion.initiator %>
30
30
  </span>
31
- <span class="d-none d-sm-inline"><%= discussion_info(@discussion) unless @discussion.new_record? %></span>
31
+ <span><%= discussion_info(@discussion) unless @discussion.new_record? %></span>
32
32
  </span>
33
33
  </div>
34
34
  <% if @discussion.last_moderator_access_visible_for?(current_user) %>
35
35
  <h5 class="my-2 me-3">
36
36
  <span class="badge bg-primary text-wrap">
37
- <%= t :last_seen, name: @discussion.last_moderator_access_by.full_name %>
37
+ <%= t :last_seen, name: discussion_user_name(@discussion.last_moderator_access_by) %>
38
38
  <%= t :time_since, time: time_ago_in_words(@discussion.last_moderator_access_at) %>
39
39
  </span>
40
40
  </h5>
@@ -9,7 +9,7 @@
9
9
  <div class="mu-faqs-content">
10
10
  <%= @faqs %>
11
11
  </div>
12
- <div class="mu-faqs-navbar hidden-xs">
12
+ <div class="mu-faqs-navbar d-none d-md-block">
13
13
  <nav>
14
14
  <ul>
15
15
  </ul>
@@ -12,8 +12,8 @@
12
12
  </ul>
13
13
  <% end %>
14
14
  <div class="mu-kids-character-speech-bubble-normal">
15
- <i class="mu-kids-prev-speech fas fa-fw fa-caret-up"></i>
16
- <i class="mu-kids-next-speech fas fa-fw fa-caret-down"></i>
15
+ <i class="mu-kids-prev-speech fas fa-fw fa-lg fa-caret-up"></i>
16
+ <i class="mu-kids-next-speech fas fa-fw fa-lg fa-caret-down"></i>
17
17
  <div class="description"><%= exercise.description_task %></div>
18
18
  <div class="hint"><%= exercise.hint_html %></div>
19
19
  </div>
@@ -23,7 +23,7 @@
23
23
  </span>
24
24
  <% end %>
25
25
 
26
- <div class="example-result collapse <%= 'in' if contextualization.visible_success_output? %>" id="example-result-<%= index %>">
26
+ <div class="example-result collapse <%= 'show' if contextualization.visible_success_output? %>" id="example-result-<%= index %>">
27
27
  <%= contextualization.test_result_html test_result %>
28
28
  </div>
29
29
  </li>
@@ -10,6 +10,7 @@
10
10
  <%= user_menu_divider %>
11
11
  <%= activity_user_menu_link %>
12
12
  <%= certificates_user_menu_link %>
13
+ <%= exam_authorizations_user_menu_link %>
13
14
  </div>
14
15
  </div>
15
16
  <div class="mu-user-menu-divider vertical d-none d-md-block"></div>
@@ -3,7 +3,7 @@
3
3
  <div class="<%= exercise_container_type %> px-0">
4
4
  <nav class="navbar navbar-light navbar-expand-lg mu-navbar">
5
5
  <div class="container-fluid">
6
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#muNavbar" aria-controls="muNavbar" aria-expanded="false" aria-label="Toggle navigation">
6
+ <button class="navbar-toggler collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#muNavbar" aria-controls="muNavbar" aria-expanded="false" aria-label="Toggle navigation">
7
7
  <span class="navbar-toggler-icon"></span>
8
8
  </button>
9
9
  <div class="mu-navbar-avatar order-lg-2">
@@ -1 +1 @@
1
- <%= menu_item :book_open, :exam_authorization_request_updated, url_for(target), { description: target.exam_registration.description } %>
1
+ <%= menu_item :book_open, :exam_authorization_request_updated, exam_authorizations_user_path, { description: target.exam_registration.description } %>