mumuki-laboratory 8.4.0 → 9.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/mumuki_laboratory/application/upload.js +69 -14
- data/app/assets/stylesheets/mumuki_laboratory/application/_layout.scss +3 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/_modules.scss +1 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_content_show.scss +15 -2
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_discussion.scss +31 -8
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_medal.scss +1 -1
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_menu.scss +35 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_profile.scss +11 -0
- data/app/controllers/api/base_controller.rb +0 -1
- data/app/controllers/api/courses_controller.rb +1 -1
- data/app/controllers/api/organizations_controller.rb +5 -2
- data/app/controllers/api/roles_controller.rb +4 -0
- data/app/controllers/api/users_controller.rb +6 -1
- data/app/controllers/application_controller.rb +1 -1
- data/app/controllers/concerns/with_authorization.rb +1 -16
- data/app/controllers/concerns/with_user_params.rb +4 -0
- data/app/controllers/discussions_messages_controller.rb +0 -1
- data/app/controllers/exam_authorization_requests_controller.rb +26 -0
- data/app/controllers/exam_registrations_controller.rb +6 -0
- data/app/controllers/users_controller.rb +8 -5
- data/app/helpers/application_helper.rb +4 -0
- data/app/helpers/breadcrumbs_helper.rb +4 -0
- data/app/helpers/content_view_helper.rb +19 -0
- data/app/helpers/exercise_input_helper.rb +8 -17
- data/app/helpers/icons_helper.rb +3 -11
- data/app/helpers/links_helper.rb +3 -3
- data/app/helpers/menu_bar_helper.rb +3 -3
- data/app/helpers/progress_bar_helper.rb +2 -2
- data/app/helpers/user_menu_helper.rb +18 -0
- data/app/views/chapters/show.html.erb +17 -16
- data/app/views/complements/show.html.erb +1 -1
- data/app/views/discussions/_message.html.erb +7 -7
- data/app/views/exam_authorization_requests/show.html.erb +17 -0
- data/app/views/exam_registrations/show.html.erb +37 -0
- data/app/views/exams/show.html.erb +1 -1
- data/app/views/{layouts → exercises}/_exercise_skipped.html.erb +0 -0
- data/app/views/exercises/_exercise_title_icons.html.erb +4 -0
- data/app/views/exercises/show.html.erb +5 -8
- data/app/views/{layouts → guides}/_guide.html.erb +3 -3
- data/app/views/guides/_guide_container.html.erb +24 -0
- data/app/views/{layouts → guides}/_guide_title_icons.html.erb +1 -3
- data/app/views/layouts/_progress_bar.html.erb +9 -7
- data/app/views/layouts/_progress_listing.html.erb +5 -5
- data/app/views/layouts/_user_menu.html.erb +21 -0
- data/app/views/layouts/application.html.erb +1 -6
- data/app/views/layouts/exercise_inputs/editors/_upload.html.erb +11 -2
- data/app/views/lessons/show.html.erb +1 -1
- data/app/views/notifications/_discussion.html.erb +1 -0
- data/app/views/notifications/_dropdown.html.erb +13 -0
- data/app/views/notifications/_exam_authorization_request.html.erb +1 -0
- data/app/views/notifications/_exam_registration.html.erb +1 -0
- data/app/views/notifications/_message.html.erb +1 -0
- data/app/views/users/_user_form.html.erb +10 -8
- data/app/views/users/discussions.html.erb +28 -0
- data/app/views/users/edit.html.erb +1 -1
- data/app/views/users/messages.html.erb +27 -0
- data/app/views/users/show.html.erb +4 -51
- data/app/views/users/terms.html.erb +2 -2
- data/config/routes.rb +6 -0
- data/lib/mumuki/laboratory/controllers/notifications.rb +3 -22
- data/lib/mumuki/laboratory/locales/en.yml +34 -17
- data/lib/mumuki/laboratory/locales/es-CL.yml +25 -8
- data/lib/mumuki/laboratory/locales/es.yml +30 -14
- data/lib/mumuki/laboratory/locales/pt.yml +27 -10
- data/lib/mumuki/laboratory/version.rb +1 -1
- data/spec/controllers/exam_authorization_requests_controller_spec.rb +40 -0
- data/spec/controllers/exam_registrations_controller_spec.rb +19 -0
- data/spec/controllers/organizations_api_controller_spec.rb +16 -9
- data/spec/dummy/db/schema.rb +23 -0
- data/spec/features/exercise_flow_spec.rb +3 -3
- data/spec/features/login_flow_spec.rb +1 -1
- data/spec/features/menu_bar_spec.rb +24 -24
- data/spec/features/notifications_flow_spec.rb +46 -0
- data/spec/features/profile_flow_spec.rb +6 -9
- data/spec/features/terms_flow_spec.rb +30 -0
- data/spec/helpers/application_helper_spec.rb +10 -0
- data/spec/javascripts/bridge-spec.js +2 -2
- data/spec/javascripts/csrf-token-spec.js +2 -2
- data/spec/javascripts/editors-spec.js +7 -9
- data/spec/javascripts/elipsis-spec.js +4 -4
- data/spec/javascripts/events-spec.js +7 -7
- data/spec/javascripts/exercise-spec.js +7 -8
- data/spec/javascripts/global-spec.js +3 -3
- data/spec/javascripts/i18n-spec.js +23 -20
- data/spec/javascripts/kids-button-spec.js +6 -8
- data/spec/javascripts/results-renderers-spec.js +5 -5
- data/spec/javascripts/speech-bubble-renderer-spec.js +2 -3
- data/spec/javascripts/submissions-store-spec.js +14 -14
- data/spec/javascripts/sync-mode-spec.js +3 -3
- data/spec/javascripts/timeout-spec.js +2 -2
- data/spec/javascripts/timer-spec.js +2 -2
- data/spec/javascripts/upload-spec.js +80 -0
- metadata +132 -108
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4fc890303f1598f34b8258b73ca92a3beb1d594cbdb7f00d729401df4e44f89
|
4
|
+
data.tar.gz: 8ad9aba5c0b5d11251a972f2f5354f6f3ee6c6fcb3ef62d72b592e0d6e78b66f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f44cc0d2df94e3b613abea57d4ff8a1c48628a2d3fbc1797cb2a2fdca1d54c1c639c8da8e19ddfb65c581f874927758cb1fbf673cd9cf66ed8c1b9186a5d9ca
|
7
|
+
data.tar.gz: c5e6c4b580ec812c0ff84290558f6439fab546dc2be009da77c032b9059700230da3db4e1fc0765a4560d846d6409d4e6a17f79dbbff830a10199ad4ae25a6ec
|
@@ -1,17 +1,72 @@
|
|
1
|
+
mumuki.upload = (() => {
|
2
|
+
class FileUploader {
|
3
|
+
constructor(file) {
|
4
|
+
this.file = file;
|
5
|
+
}
|
6
|
+
|
7
|
+
uploadFileIfValid() {
|
8
|
+
if (!this.file) return;
|
9
|
+
|
10
|
+
let maxFileSize = $('#mu-upload-input').attr("mu-upload-file-limit");
|
11
|
+
if (this.file.size > maxFileSize) {
|
12
|
+
return mumuki.upload.ui.showFileExceedsMaxSize();
|
13
|
+
}
|
14
|
+
|
15
|
+
mumuki.upload.ui.allowSubmissionFor(this.file.name);
|
16
|
+
|
17
|
+
const reader = new FileReader();
|
18
|
+
reader.onload = function (e) {
|
19
|
+
const contents = e.target.result;
|
20
|
+
$('#solution_content').html(contents);
|
21
|
+
};
|
22
|
+
reader.readAsText(this.file);
|
23
|
+
|
24
|
+
return reader;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
class UI {
|
29
|
+
constructor() {
|
30
|
+
this.$uploadFileLimitExceeded = $('#mu-upload-file-limit-exceeded');
|
31
|
+
this.$uploadLabel = $('#mu-upload-label span');
|
32
|
+
this.$uploadLabelText = this.$uploadLabel.text();
|
33
|
+
this.$uploadIcon = $('#mu-upload-icon');
|
34
|
+
this.$btnSubmit = $('.btn-submit');
|
35
|
+
}
|
36
|
+
|
37
|
+
showFileExceedsMaxSize() {
|
38
|
+
this.$uploadFileLimitExceeded.removeClass('hidden');
|
39
|
+
this.$uploadLabel.text(this.$uploadLabelText);
|
40
|
+
this.$uploadIcon.addClass('fa-upload').removeClass('fa-file-alt');
|
41
|
+
this.$btnSubmit.addClass('disabled');
|
42
|
+
}
|
43
|
+
|
44
|
+
allowSubmissionFor(filename) {
|
45
|
+
this.$uploadFileLimitExceeded.addClass('hidden');
|
46
|
+
this.$uploadLabel.text(filename);
|
47
|
+
this.$uploadIcon.removeClass('fa-upload').addClass('fa-file-alt');
|
48
|
+
this.$btnSubmit.removeClass('disabled');
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
function _setUI() {
|
53
|
+
mumuki.upload.ui = new UI();
|
54
|
+
}
|
55
|
+
|
56
|
+
return {
|
57
|
+
FileUploader,
|
58
|
+
UI,
|
59
|
+
|
60
|
+
_setUI,
|
61
|
+
|
62
|
+
/** @type {UI} */
|
63
|
+
ui: null
|
64
|
+
};
|
65
|
+
})();
|
66
|
+
|
1
67
|
mumuki.load(() => {
|
2
|
-
$('#upload-input').change(function (evt) {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
var reader = new FileReader();
|
7
|
-
reader.onload = function (e) {
|
8
|
-
var contents = e.target.result;
|
9
|
-
$('#solution_content').html(contents);
|
10
|
-
$(evt.target).val("");
|
11
|
-
$('form.new_solution').submit();
|
12
|
-
};
|
13
|
-
reader.readAsText(file);
|
14
|
-
return false;
|
68
|
+
$('#mu-upload-input').change(function (evt) {
|
69
|
+
if (!mumuki.upload.ui) mumuki.upload._setUI();
|
70
|
+
return new mumuki.upload.FileUploader(evt.target.files[0]).uploadFileIfValid();
|
15
71
|
});
|
16
72
|
});
|
17
|
-
|
@@ -1,3 +1,16 @@
|
|
1
|
-
.chapter-description p {
|
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
|
}
|
@@ -5,7 +5,7 @@ $discussion-toolbar-color: #f6f6fa;
|
|
5
5
|
$message-divider-color: #ecf0f1;
|
6
6
|
$discussion-button-color: #fafafa;
|
7
7
|
$toolbar-filter-color: #808080;
|
8
|
-
$moderator-
|
8
|
+
$moderator-badge-color: #dd9900;
|
9
9
|
|
10
10
|
.discussions-list {
|
11
11
|
margin: 30px 0;
|
@@ -177,8 +177,17 @@ $moderator-star-color: #dd9900;
|
|
177
177
|
width: 100%;
|
178
178
|
}
|
179
179
|
|
180
|
-
.moderator-
|
181
|
-
|
180
|
+
.moderator-badge {
|
181
|
+
position: relative;
|
182
|
+
top: -2px;
|
183
|
+
margin: 2px;
|
184
|
+
font-size: 12px;
|
185
|
+
text-transform: uppercase;
|
186
|
+
color: white;
|
187
|
+
background-color: $moderator-badge-color;
|
188
|
+
border: solid $moderator-badge-color 1px;
|
189
|
+
border-radius: 5px;
|
190
|
+
padding-inline: 5px;
|
182
191
|
}
|
183
192
|
|
184
193
|
.discussion-user-menu {
|
@@ -326,12 +335,15 @@ summary.discussion-summary {
|
|
326
335
|
.actions {
|
327
336
|
float: right;
|
328
337
|
a {
|
329
|
-
margin-left:
|
338
|
+
margin-left: 20px;
|
330
339
|
cursor: pointer;
|
331
340
|
}
|
332
341
|
.discussion-message-approved {
|
333
342
|
text-decoration: none;
|
334
|
-
|
343
|
+
i {
|
344
|
+
transition: color 0.3s;
|
345
|
+
}
|
346
|
+
&:hover, &.selected {
|
335
347
|
i {
|
336
348
|
color: $brand-success;
|
337
349
|
}
|
@@ -341,17 +353,20 @@ summary.discussion-summary {
|
|
341
353
|
text-decoration: none;
|
342
354
|
i {
|
343
355
|
position: relative;
|
356
|
+
transition: color 0.3s;
|
344
357
|
&:after {
|
345
358
|
position: absolute;
|
346
|
-
left:
|
359
|
+
left: 10px;
|
360
|
+
top: -6px;
|
347
361
|
content: ' ';
|
348
|
-
height:
|
362
|
+
height: 30px;
|
349
363
|
width: 2px;
|
350
364
|
transform: rotate(-45deg);
|
351
365
|
background-color: #aaaaaa;
|
366
|
+
transition: background-color 0.3s;
|
352
367
|
}
|
353
368
|
}
|
354
|
-
&.selected {
|
369
|
+
&:hover, &.selected {
|
355
370
|
i {
|
356
371
|
color: $brand-primary;
|
357
372
|
&:after {
|
@@ -360,6 +375,14 @@ summary.discussion-summary {
|
|
360
375
|
}
|
361
376
|
}
|
362
377
|
}
|
378
|
+
.discussion-delete-message {
|
379
|
+
i {
|
380
|
+
transition: color 0.3s;
|
381
|
+
&:hover {
|
382
|
+
color: black;
|
383
|
+
}
|
384
|
+
}
|
385
|
+
}
|
363
386
|
i {
|
364
387
|
color: #aaaaaa
|
365
388
|
}
|
@@ -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 {
|
@@ -2,8 +2,7 @@ module Api
|
|
2
2
|
class OrganizationsController < BaseController
|
3
3
|
include OrganizationsControllerTemplate
|
4
4
|
|
5
|
-
before_action :
|
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
|
@@ -9,8 +9,13 @@ module Api
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def update
|
12
|
-
@user.
|
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
|
@@ -34,8 +34,8 @@ class ApplicationController < ActionController::Base
|
|
34
34
|
helper_method :current_workspace,
|
35
35
|
:login_button,
|
36
36
|
:notifications_count,
|
37
|
-
:user_notifications_path,
|
38
37
|
:has_notifications?,
|
38
|
+
:notifications,
|
39
39
|
:subject,
|
40
40
|
:should_choose_organization?,
|
41
41
|
:current_immersive_organizations,
|
@@ -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
|
@@ -0,0 +1,26 @@
|
|
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
|
+
def create
|
8
|
+
authorization_request = ExamAuthorizationRequest.create! authorization_request_params
|
9
|
+
current_user.read_notification! authorization_request.exam_registration
|
10
|
+
flash.notice = I18n.t :exam_authorization_request_created
|
11
|
+
end
|
12
|
+
|
13
|
+
def update
|
14
|
+
ExamAuthorizationRequest.update params[:id], authorization_request_params
|
15
|
+
flash.notice = I18n.t :exam_authorization_request_saved
|
16
|
+
redirect_to root_path
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def authorization_request_params
|
22
|
+
params
|
23
|
+
.require(:exam_authorization_request).permit(:exam_id, :exam_registration_id)
|
24
|
+
.merge(user: current_user, organization: Organization.current)
|
25
|
+
end
|
26
|
+
end
|