mumuki-laboratory 8.6.1 → 9.0.4
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/certificate.js +17 -0
- data/app/assets/javascripts/mumuki_laboratory/application/faqs.js +90 -0
- data/app/assets/javascripts/mumuki_laboratory/application/organization.js +32 -0
- data/app/assets/javascripts/mumuki_laboratory/application/submissions-store.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/user.js +49 -5
- data/app/assets/stylesheets/mumuki_laboratory/application/_layout.scss +3 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/_modules.scss +3 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_certificate.scss +33 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_content_show.scss +15 -2
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_faqs.scss +84 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_medal.scss +1 -1
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_menu.scss +63 -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/certificates_controller.rb +28 -0
- data/app/controllers/concerns/with_authorization.rb +1 -16
- data/app/controllers/concerns/with_certificate_render.rb +25 -0
- data/app/controllers/concerns/with_user_params.rb +4 -0
- data/app/controllers/discussions_messages_controller.rb +0 -1
- data/app/controllers/faqs_controller.rb +6 -0
- data/app/controllers/users_controller.rb +12 -5
- data/app/helpers/breadcrumbs_helper.rb +4 -0
- data/app/helpers/certificate_helper.rb +13 -0
- data/app/helpers/content_view_helper.rb +19 -0
- data/app/helpers/links_helper.rb +11 -3
- data/app/helpers/menu_bar_helper.rb +15 -11
- data/app/helpers/user_menu_helper.rb +36 -0
- data/app/mailers/application_mailer.rb +0 -1
- data/app/mailers/user_mailer.rb +9 -0
- data/app/views/certificates/_certificate.html.erb +44 -0
- data/app/views/certificates/_download.html.erb +20 -0
- data/app/views/certificates/verify.html.erb +40 -0
- data/app/views/chapters/show.html.erb +15 -14
- data/app/views/complements/show.html.erb +1 -1
- 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 +4 -7
- data/app/views/faqs/index.html.erb +20 -0
- data/app/views/{layouts → guides}/_guide.html.erb +0 -0
- 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/_main.html.erb +4 -0
- data/app/views/layouts/_progress_listing.html.erb +1 -1
- data/app/views/layouts/_user_menu.html.erb +17 -0
- data/app/views/layouts/application.html.erb +6 -1
- data/app/views/layouts/exercise_inputs/editors/_code.html.erb +2 -1
- data/app/views/lessons/show.html.erb +1 -1
- data/app/views/user_mailer/certificate.html.erb +339 -0
- data/app/views/user_mailer/certificate.text.erb +10 -0
- data/app/views/users/_user_form.html.erb +10 -8
- data/app/views/users/certificates.html.erb +32 -0
- 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 +1 -1
- data/config/routes.rb +9 -0
- data/lib/mumuki/laboratory/locales/en.yml +10 -1
- data/lib/mumuki/laboratory/locales/es-CL.yml +10 -1
- data/lib/mumuki/laboratory/locales/es.yml +10 -1
- data/lib/mumuki/laboratory/locales/pt.yml +10 -1
- data/lib/mumuki/laboratory/version.rb +1 -1
- data/spec/controllers/certificates_controller_spec.rb +15 -0
- data/spec/controllers/organizations_api_controller_spec.rb +16 -9
- data/spec/dummy/db/schema.rb +25 -1
- data/spec/features/certificate_programs_flow_spec.rb +17 -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 +44 -24
- data/spec/features/profile_flow_spec.rb +17 -7
- data/spec/helpers/application_helper_spec.rb +10 -0
- data/spec/helpers/certificate_helper_spec.rb +15 -0
- metadata +81 -10
- 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: c79de66ab1c8248e5715cd1e54ac8e4b1e426fb26bc0a69b35539ba19eb954da
|
4
|
+
data.tar.gz: 39cbfb28e86a6ae64f5a1164731d472ca65be3bec82d9f1ed6f159273512b078
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed9430f79c8f92f7b02264aa84f7dc757a7ff05915fcdd17e93a5fe4b7aaac5cfd0d87fadec66ce0d4ac204cd270f08fafc1550a986bd367314f5e7130c360d4
|
7
|
+
data.tar.gz: 8669d687ca7f70178cab77c25f698eef49a58eb74957ed274c73fe6fdf0c6f9139c5963f5c57b08a92ed874a97c6b648030c1be87cd34b107cb831db156e0113
|
@@ -0,0 +1,17 @@
|
|
1
|
+
mumuki.load(() => {
|
2
|
+
scaleCertificate();
|
3
|
+
mumuki.resize(scaleCertificate);
|
4
|
+
|
5
|
+
function scaleCertificate() {
|
6
|
+
const $certPreview = $('.certificate-preview');
|
7
|
+
const $muCertificate = $('.mu-certificate-box');
|
8
|
+
$muCertificate.css('transform', 'scale(1)');
|
9
|
+
|
10
|
+
const scaleWidth = $muCertificate.width() / $certPreview.width();
|
11
|
+
$muCertificate.css({
|
12
|
+
'transform': `scale(${1 / scaleWidth})`,
|
13
|
+
'transform-origin': `0 0`,
|
14
|
+
});
|
15
|
+
$certPreview.height($muCertificate.height());
|
16
|
+
}
|
17
|
+
});
|
@@ -0,0 +1,90 @@
|
|
1
|
+
mumuki.faqs = class {
|
2
|
+
|
3
|
+
constructor() {
|
4
|
+
this.faqs = $('.mu-faqs');
|
5
|
+
this.topHierarchyElem = "H2";
|
6
|
+
}
|
7
|
+
|
8
|
+
// ================
|
9
|
+
// == Public API ==
|
10
|
+
// ================
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Actually setup the faqs page
|
14
|
+
*/
|
15
|
+
load() {
|
16
|
+
if(!this.faqs) return;
|
17
|
+
this._createFaqsGroups();
|
18
|
+
this._createNavbar();
|
19
|
+
}
|
20
|
+
|
21
|
+
// =================
|
22
|
+
// == Private API ==
|
23
|
+
// =================
|
24
|
+
|
25
|
+
_createNavbar() {
|
26
|
+
const $faqsNavbar = $(".mu-faqs-navbar nav ul");
|
27
|
+
$('.mu-faqs-group').each((_index, faqGroup) => {
|
28
|
+
const $navItem = this._createNavbarItem($faqsNavbar, faqGroup)
|
29
|
+
const $faqGroup = $(faqGroup);
|
30
|
+
this._configureClickFor($navItem, $faqGroup, $faqsNavbar)
|
31
|
+
});
|
32
|
+
}
|
33
|
+
|
34
|
+
_createNavbarItem($faqsNavbar, faqGroup) {
|
35
|
+
const $navItem = $(`<li><a href="#${faqGroup.id}">`)
|
36
|
+
.html(`${faqGroup.querySelector('h2').textContent}`);
|
37
|
+
$faqsNavbar.append($navItem);
|
38
|
+
return $navItem;
|
39
|
+
}
|
40
|
+
|
41
|
+
_configureClickFor($navItem, $faqGroup, $faqsNavbar) {
|
42
|
+
$navItem.click(function(e){
|
43
|
+
e.preventDefault();
|
44
|
+
$faqsNavbar.find('li').removeClass('active');
|
45
|
+
$navItem.addClass('active');
|
46
|
+
$('html, body').animate({scrollTop: $faqGroup.offset().top}, 1000);
|
47
|
+
});
|
48
|
+
}
|
49
|
+
|
50
|
+
_createFaqsGroups() {
|
51
|
+
const elemsGroups = this._buildFaqsGroups();
|
52
|
+
elemsGroups.forEach((group, index) => {
|
53
|
+
$(group).wrapAll(`<div class='mu-faqs-group' id='mu-faqs-group-${index}'>`);
|
54
|
+
});
|
55
|
+
this._createFaqsIcons();
|
56
|
+
}
|
57
|
+
|
58
|
+
_createFaqsIcons() {
|
59
|
+
const $faqIcon = $('<i class="mu-faqs-group-icon fa fa-plus">');
|
60
|
+
$faqIcon.click(function(e){
|
61
|
+
const $elem = $(this);
|
62
|
+
$elem.toggleClass('fa-plus fa-minus');
|
63
|
+
$elem.closest('.mu-faqs-group').toggleClass('active');
|
64
|
+
})
|
65
|
+
$('.mu-faqs-group').prepend($faqIcon);
|
66
|
+
}
|
67
|
+
|
68
|
+
_buildFaqsGroups() {
|
69
|
+
let newGroup = [];
|
70
|
+
let elemsGroups = [];
|
71
|
+
let previousNodeName;
|
72
|
+
$(".mu-faqs-content").children().each((index, elem) => {
|
73
|
+
if(elem.nodeName === this.topHierarchyElem && newGroup.length) {
|
74
|
+
elemsGroups.push(newGroup);
|
75
|
+
newGroup = [];
|
76
|
+
}
|
77
|
+
newGroup.push(elem);
|
78
|
+
previousNodeName = elem.nodeName
|
79
|
+
});
|
80
|
+
|
81
|
+
elemsGroups.push(newGroup);
|
82
|
+
|
83
|
+
return elemsGroups;
|
84
|
+
}
|
85
|
+
|
86
|
+
};
|
87
|
+
|
88
|
+
mumuki.load(() => {
|
89
|
+
new mumuki.faqs().load();
|
90
|
+
});
|
@@ -0,0 +1,32 @@
|
|
1
|
+
mumuki.organization = {
|
2
|
+
|
3
|
+
/**
|
4
|
+
* The current organization's id
|
5
|
+
*
|
6
|
+
* @type {number?}
|
7
|
+
* */
|
8
|
+
_id: null,
|
9
|
+
|
10
|
+
/**
|
11
|
+
* The current organization's id
|
12
|
+
*
|
13
|
+
* @type {number?}
|
14
|
+
* */
|
15
|
+
get id() {
|
16
|
+
return this._id;
|
17
|
+
},
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Set global current organization information
|
21
|
+
*/
|
22
|
+
load() {
|
23
|
+
const $muOrganizationId = $('#mu-organization-id');
|
24
|
+
if ($muOrganizationId.length) {
|
25
|
+
this._id = $muOrganizationId.val();
|
26
|
+
} else {
|
27
|
+
this._id = null;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
};
|
31
|
+
|
32
|
+
mumuki.load(() => mumuki.organization.load());
|
@@ -1,9 +1,53 @@
|
|
1
|
+
mumuki.user = {
|
2
|
+
|
3
|
+
/**
|
4
|
+
* The current user's id
|
5
|
+
*
|
6
|
+
* @type {number?}
|
7
|
+
* */
|
8
|
+
_id: null,
|
9
|
+
|
10
|
+
/**
|
11
|
+
* The current user's id
|
12
|
+
*
|
13
|
+
* @type {number?}
|
14
|
+
* */
|
15
|
+
get id() {
|
16
|
+
return this._id;
|
17
|
+
},
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Set global current user information
|
21
|
+
*/
|
22
|
+
load() {
|
23
|
+
const $muUserId = $('#mu-user-id');
|
24
|
+
if ($muUserId.length) {
|
25
|
+
this._id = $muUserId.val();
|
26
|
+
} else {
|
27
|
+
this._id = null;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
};
|
31
|
+
|
1
32
|
mumuki.load(() => {
|
2
|
-
|
3
|
-
|
4
|
-
|
33
|
+
const $userMenuHeader = $('.mu-user-menu-header');
|
34
|
+
let onUserProfile = document.querySelector('.mu-profile-info') !== null;
|
35
|
+
|
36
|
+
$userMenuHeader.click(() => {
|
37
|
+
$('.mu-user-menu-items').toggleClass('hidden-sm-screen');
|
38
|
+
$('#mu-user-menu-header-icon').toggleClass('fa-chevron-up fa-chevron-down');
|
39
|
+
});
|
40
|
+
|
41
|
+
if (onUserProfile) {
|
42
|
+
$userMenuHeader.click();
|
5
43
|
}
|
6
|
-
|
7
|
-
|
44
|
+
|
45
|
+
$('.mu-user-menu-item .active').click((e) => {
|
46
|
+
if (onUserProfile) {
|
47
|
+
e.preventDefault();
|
48
|
+
$userMenuHeader.click();
|
49
|
+
}
|
8
50
|
});
|
51
|
+
|
52
|
+
mumuki.user.load()
|
9
53
|
});
|
@@ -1,6 +1,7 @@
|
|
1
1
|
@import "modules/avatar";
|
2
2
|
@import "modules/book_header";
|
3
3
|
@import "modules/breadcrumb";
|
4
|
+
@import "modules/certificate";
|
4
5
|
@import "modules/checkboxes";
|
5
6
|
@import "modules/console";
|
6
7
|
@import "modules/content_show";
|
@@ -10,6 +11,7 @@
|
|
10
11
|
@import "modules/editor";
|
11
12
|
@import "modules/exercise_assignment";
|
12
13
|
@import "modules/exercise_results";
|
14
|
+
@import "modules/faqs";
|
13
15
|
@import "modules/flash";
|
14
16
|
@import "modules/gs-board";
|
15
17
|
@import "modules/guide_corollary";
|
@@ -27,4 +29,5 @@
|
|
27
29
|
@import "modules/terms";
|
28
30
|
@import "modules/timer";
|
29
31
|
@import "modules/upload";
|
32
|
+
@import "modules/user_menu";
|
30
33
|
@import "modules/user_profile";
|
@@ -0,0 +1,33 @@
|
|
1
|
+
.mu-certificate {
|
2
|
+
border: 1px solid $mu-color-dark-separator;
|
3
|
+
}
|
4
|
+
|
5
|
+
.mu-certificate-name {
|
6
|
+
margin-top: 0;
|
7
|
+
margin-bottom: 1em;
|
8
|
+
}
|
9
|
+
|
10
|
+
.mu-certificate-data {
|
11
|
+
margin-top: 30px;
|
12
|
+
}
|
13
|
+
|
14
|
+
.mu-certificate-buttons {
|
15
|
+
margin-bottom: 30px;
|
16
|
+
}
|
17
|
+
|
18
|
+
.mu-certificate-download-btn {
|
19
|
+
height: 35px;
|
20
|
+
padding: 0;
|
21
|
+
width: 157px;
|
22
|
+
border: none;
|
23
|
+
}
|
24
|
+
.mu-certificate-download-btn-icon {
|
25
|
+
border-right: 1px solid darken($mu-color-complementary, 10%);
|
26
|
+
padding: 8px 6px 9px 6px;
|
27
|
+
width: 35px;
|
28
|
+
}
|
29
|
+
.mu-certificate-download-btn-text {
|
30
|
+
display: inline-block;
|
31
|
+
width: 115px;
|
32
|
+
text-align: center;
|
33
|
+
}
|
@@ -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
|
}
|
@@ -0,0 +1,84 @@
|
|
1
|
+
.mu-faqs-container {
|
2
|
+
position: relative;
|
3
|
+
display: table;
|
4
|
+
width: 100%;
|
5
|
+
|
6
|
+
.mu-faqs-content {
|
7
|
+
padding-top: 50px;
|
8
|
+
|
9
|
+
width: 100%;
|
10
|
+
|
11
|
+
@media (min-width: 768px) {
|
12
|
+
width: 75%;
|
13
|
+
float: right;
|
14
|
+
}
|
15
|
+
|
16
|
+
.mu-faqs-group {
|
17
|
+
padding: 32px;
|
18
|
+
box-shadow: 0 0.375em 2.8125em 0 #d2d5d9;
|
19
|
+
margin-bottom: 32px;
|
20
|
+
|
21
|
+
@media (max-width: 767px) {
|
22
|
+
&:not(.active) {
|
23
|
+
h3, p {
|
24
|
+
display: none
|
25
|
+
}
|
26
|
+
h2 {
|
27
|
+
margin-bottom: 0px;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
h2 {
|
33
|
+
margin-top: 0;
|
34
|
+
margin-bottom: 20px;
|
35
|
+
}
|
36
|
+
|
37
|
+
h3 {
|
38
|
+
color: #1A94A3; // should be $brand-secondary
|
39
|
+
margin-top: 40px;
|
40
|
+
}
|
41
|
+
|
42
|
+
.mu-faqs-group-icon {
|
43
|
+
float: right;
|
44
|
+
margin-top: 10px;
|
45
|
+
cursor: pointer;
|
46
|
+
display: none;
|
47
|
+
@media (max-width: 767px) {
|
48
|
+
display: unset;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
.mu-faqs-navbar {
|
55
|
+
top: 0;
|
56
|
+
position: sticky;
|
57
|
+
width: 25%;
|
58
|
+
padding-top: 50px;
|
59
|
+
|
60
|
+
ul {
|
61
|
+
border-left: 1px solid $mu-color-disabled;
|
62
|
+
list-style: none;
|
63
|
+
padding-left: 0px;
|
64
|
+
li {
|
65
|
+
padding: 8px 10px 8px 15px;
|
66
|
+
cursor: pointer;
|
67
|
+
&.active {
|
68
|
+
border-left: 3px solid transparent;
|
69
|
+
border-color: darken($brand-primary, 5%);
|
70
|
+
margin-left: -3px;
|
71
|
+
}
|
72
|
+
a {
|
73
|
+
color: $brand-primary;
|
74
|
+
&:hover {
|
75
|
+
text-decoration: none;
|
76
|
+
}
|
77
|
+
@media (min-width: $container-lg) {
|
78
|
+
font-size: 1.1em;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
@@ -0,0 +1,63 @@
|
|
1
|
+
.mu-user-menu {
|
2
|
+
display: flex;
|
3
|
+
margin-top: 25px;
|
4
|
+
}
|
5
|
+
|
6
|
+
.mu-user-menu-content {
|
7
|
+
flex-grow: 1;
|
8
|
+
}
|
9
|
+
|
10
|
+
.mu-user-menu-header {
|
11
|
+
font-size: 15px;
|
12
|
+
color: $mu-color-disabled;
|
13
|
+
text-transform: uppercase;
|
14
|
+
padding-left: 2px;
|
15
|
+
cursor: pointer;
|
16
|
+
|
17
|
+
@media only screen and (min-width: $screen-md-min) {
|
18
|
+
padding-left: 15px;
|
19
|
+
cursor: auto;
|
20
|
+
|
21
|
+
i {
|
22
|
+
display: none;
|
23
|
+
}
|
24
|
+
|
25
|
+
span {
|
26
|
+
padding-left: 0px;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
.mu-user-menu-items {
|
32
|
+
margin-top: 30px;
|
33
|
+
|
34
|
+
&.hidden-sm-screen {
|
35
|
+
@media only screen and (max-width: $screen-sm-max) {
|
36
|
+
display: none;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
.mu-user-menu-item {
|
42
|
+
font-size: 17px;
|
43
|
+
margin-bottom: 5px;
|
44
|
+
|
45
|
+
a {
|
46
|
+
color: $brand-primary;
|
47
|
+
&.active {
|
48
|
+
font-weight: bold;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
.mu-user-menu-divider {
|
54
|
+
&.vertical {
|
55
|
+
border-left: 2px solid $mu-color-separator;
|
56
|
+
}
|
57
|
+
|
58
|
+
&.horizontal {
|
59
|
+
border-top: 2px solid $mu-color-separator;
|
60
|
+
|
61
|
+
margin: 25px 0;
|
62
|
+
}
|
63
|
+
}
|