Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration of CA pre/post-program surveys #240

Merged
merged 12 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion cms/djangoapps/contentstore/views/course.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locator import BlockUsageLocator
from organizations.api import add_organization_course, ensure_organization
from organizations.api import (
add_organization_course,
ensure_organization,
get_course_organization,
get_organization_institutions
)
from organizations.exceptions import InvalidOrganizationException
from rest_framework.exceptions import ValidationError

Expand Down Expand Up @@ -1184,6 +1189,14 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
'upgrade_deadline': upgrade_deadline,
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
}

course_org = get_course_organization(course_key)
if course_org:
institutions = get_organization_institutions(course_org)
settings_context.update({'possible_organization_institutions': list(institutions)})
else:
settings_context.update({'possible_organization_institutions': []})

if is_prerequisite_courses_enabled():
courses, in_process_course_actions = get_courses_accessible_to_user(request)
# exclude current course from the list of available courses
Expand Down
1 change: 1 addition & 0 deletions cms/static/js/models/settings/course_details.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js
learning_info: [],
instructor_info: {},
self_paced: null,
course_institution: '',
revision_number: ''
},

Expand Down
14 changes: 14 additions & 0 deletions cms/static/js/spec/views/settings/main_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ define([
instructors: [{name: '', title: '', organization: '', image: '', bio: ''}]
},
self_paced: false,
course_institution: '',
revision_number: ''
},

Expand Down Expand Up @@ -199,6 +200,19 @@ define([
);
});

it('should save institution as part of course details', function() {
var requests = AjaxHelpers.requests(this);
var expectedJson = $.extend(true, {}, modelData, {
course_institution: ''
});
$('#course-institution').val('').trigger('change');
expect(this.model.get('course_institution')).toEqual('');
this.view.saveView();
AjaxHelpers.expectJsonRequest(
requests, 'POST', urlRoot, expectedJson
);
});

it('should not error if about_page_editable is False', function() {
var requests = AjaxHelpers.requests(this);
// if about_page_editable is false, there is no section.course_details
Expand Down
4 changes: 4 additions & 0 deletions cms/static/js/views/settings/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ define(['js/views/validation', 'codemirror', 'underscore', 'jquery', 'jquery.ui'
pre_requisite_courses = pre_requisite_courses.length > 0 ? pre_requisite_courses : '';
this.$el.find('#' + this.fieldToSelectorMap.pre_requisite_courses).val(pre_requisite_courses);

this.$el.find('#' + this.fieldToSelectorMap.course_institution).val(this.model.get('course_institution'));

if (this.model.get('entrance_exam_enabled') == 'true') {
this.$('#' + this.fieldToSelectorMap.entrance_exam_enabled).attr('checked', this.model.get('entrance_exam_enabled'));
this.$('.div-grade-requirements').show();
Expand Down Expand Up @@ -185,6 +187,7 @@ define(['js/views/validation', 'codemirror', 'underscore', 'jquery', 'jquery.ui'
banner_image_asset_path: 'banner-image-url',
video_thumbnail_image_asset_path: 'video-thumbnail-image-url',
pre_requisite_courses: 'pre-requisite-course',
course_institution: 'course-institution',
entrance_exam_enabled: 'entrance-exam-enabled',
entrance_exam_minimum_score_pct: 'entrance-exam-minimum-score-pct',
course_settings_learning_fields: 'course-settings-learning-fields',
Expand Down Expand Up @@ -318,6 +321,7 @@ define(['js/views/validation', 'codemirror', 'underscore', 'jquery', 'jquery.ui'
case 'course-version':
case 'course-revision-number':
case 'course-title':
case 'course-institution':
case 'course-subtitle':
case 'course-duration':
case 'course-description':
Expand Down
11 changes: 11 additions & 0 deletions cms/templates/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,17 @@ <h2 class="title-2">${_('Course Details')}</h2>
<input id="course-revision-number" type="text" placeholder="YYYY.MM">
<span class="tip tip-stacked">${_("Identify the course revision number here. This is used to assist with identifying what changes have been made for a course. Placeholder indicates a date format (YYYY.MM), however, we don't have to explicity tie this to a date for the number identification.")}</span>
</li>
<li class="field field-select" id="field-course-institution">
<label for="course-institution">${_("Institution Name")}</label>
<select class="input" id="course-institution">
<option value="">${_("None")}</option>
% for institution in sorted(possible_organization_institutions, key=lambda s: s['name'].lower() if s['name'] is not None else ''):
<option value="${institution['short_name']}">${institution['name']}</option>
% endfor
</select>
<span class="tip tip-inline">${_("Institution that is hosting this course run")}</span>
<button type="submit" class="sr" name="submit" value="submit">${_("set course institution")}</button>
</li>
</ol>
</div>
% endif
Expand Down
69 changes: 69 additions & 0 deletions lms/static/sass/multicourse/_dashboard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,75 @@
}
}

.program-survey {
box-shadow: 3px 3px 10px -3px grey;

border: 1px solid theme-color("secondary");
border-radius: 3px;
padding: 30px;
margin-bottom: 30px;

.program-survey-header {
@extend %t-title4;

@include padding-right($baseline/2);
}

.program-details {
color: $gray;
margin-bottom: lh();
line-height: 1.3em;
}

.survey-details-wrapper {
margin-top: 30px;
column-count: 2;
column-width: auto;

.survey-wrapper {

margin-right: 50px;

hr {
@extend .faded-hr-divider-medium;
}

.survey-title {
@extend %t-title5;

font-weight: 600;
@include padding-right($baseline/2);
}

.survey-instructions {
font: -apple-system-short-subheadline !important;
color: $gray-d1;
font-weight: 600;

@extend %t-title7;

display: inline-block;
}

.survey-details {
@extend %t-title7;

color: $gray-d1;
margin-bottom: lh();
line-height: 1.3em;
}

.provide-feedback-btn {
font: -apple-system-short-subheadline !important;

@extend %btn-primary-blue;

margin-top: $baseline;
}
}
}
}

// Responsive behavior
@include media-breakpoint-down(md) {
padding: $baseline;
Expand Down
3 changes: 3 additions & 0 deletions lms/templates/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@
<main id="main" aria-label="Content" tabindex="-1">
<div class="dashboard" id="dashboard-main">
<div class="main-container">
<%include file='dashboard/_dashboard_program_surveys.html'
args='user=user, course_enrollments=course_enrollments'/>

<div class="my-courses" id="my-courses">
% if display_dashboard_courses:
<%include file="learner_dashboard/_dashboard_navigation_courses.html"/>
Expand Down
92 changes: 92 additions & 0 deletions lms/templates/dashboard/_dashboard_program_surveys.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<%page expression_filter="h"/>
<%page args='user, course_enrollments'/>
<%!
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from organizations.models import OrganizationInstitution
from common.djangoapps.student.models import AnonymousUserId
from custom_reg_form.models import ExtraInfo
%>

<%namespace name='static' file='../static_content.html'/>

<!-- Ensure that program surveys are only shown to learners who are enrolled in courses from CA organization -->
<%
show_program_survey = False
course_institution = ''

for enrollment in course_enrollments:
course_overview = CourseOverview.get_from_id(enrollment.course_id)
if course_overview.org == "CA":
show_program_survey = True

if course_overview.course_institution:
course_institution = course_overview.course_institution
break
%>

<!-- If program surveys are being shown to learner, start building strings to pass organization and institution information to qualtrics -->
% if show_program_survey:
<%
course_institution = OrganizationInstitution.get_by_shortname(short_name=course_overview.course_institution)

if user.is_anonymous:
anonymous_user_id = user.id
else:
anonymous_user_id = AnonymousUserId.objects.filter(user=user, course_id=None).order_by('-id')
anonymous_user_id = anonymous_user_id[0].anonymous_user_id

platform_anonymous_user_id_string = "platform_anonymous_user_id=" + (anonymous_user_id or "")
username_string = "platform_username=" + (user.username or "")
platform_fullname = "platform_fullname=" + (user.profile.name or "")
user_email_string = "platform_email=" + (user.email or "")

org_institution_name_string = "org_institution_name="
org_institution_shortname_string = "org_institution_short_name="
org_institution_city_string = "org_institution_city="
org_institution_state_string = "org_institution_state="
org_institution_zipcode_string = "org_institution_zipcode="
if course_institution is not None:
org_institution_name_string += (course_institution.name or "")
org_institution_shortname_string += (course_institution.short_name or "")
org_institution_city_string += (course_institution.city or "")
org_institution_state_string += (course_institution.state or "")
org_institution_zipcode_string += (course_institution.zipcode or "")

try:
demographic_zipcode = "demographic_zipcode=" + (ExtraInfo.objects.get(user_id=user.id).zipcode or "")
except:
demographic_zipcode = "demographic_zipcode="

demographic_country = "demographic_country=" + (str(user.profile.country) or "")
program_name = "program_name=" + "Aviation Mechanic General"
%>

<div class="program-survey">
<h2 class="program-survey-header">
Aviation Mechanic General Surveys
</h2>
<div class="program-details">
<p>This program of courses equips learners for entry into the FAA mechanic pathway. Upon completion, they gain foundational knowledge in mathematics, aircraft drawings, weight and balance, aircraft materials, processes and tools, physics, electricity, inspection, ground operations, and FAA regulations governing maintenance technician certification and work.</p>
</div>

<div class="survey-details-wrapper">
<div class="survey-wrapper">
<h2 class="survey-title">Pre-Program</h2>
<hr>
<p class="survey-instructions">New Learner: Take this survey upon program entry.</p>
<p class="survey-details">This will help us understand your career awareness and interest, gauge where you are with FAA General maintenance knowledge and skill confidence, career plans, and demographic information.</p>
<a class="provide-feedback-btn" href="https://clemson.qualtrics.com/jfe/form/SV_3C2RY5TuB0uIZ70?${username_string}&${platform_fullname}&${user_email_string}&${platform_anonymous_user_id_string}&${org_institution_name_string}&${org_institution_shortname_string}&${org_institution_city_string}&${org_institution_state_string}&${org_institution_zipcode_string}&${demographic_zipcode}&${demographic_country}&${program_name}" target="_blank">
Provide Input</a>
</div>

<div class="survey-wrapper">
<h2 class="survey-title">Post-Program</h2>
<hr>
<p class="survey-instructions">Continuing Learner: Take this survey upon program exit.</p>
<p class="survey-details">This will help us understand your completion of FAA General maintenance program, career awareness and interest, knowledge and skill confidence, and demographic information.</p>
<a class="provide-feedback-btn" href="https://clemson.qualtrics.com/jfe/form/SV_1Al5SpJgWVv6bFI?${username_string}&${platform_fullname}&${user_email_string}&${platform_anonymous_user_id_string}&${org_institution_name_string}&${org_institution_shortname_string}&${org_institution_city_string}&${org_institution_state_string}&${org_institution_zipcode_string}&${demographic_zipcode}&${demographic_country}&${program_name}" target="_blank">
Provide Feedback</a>
</div>
</div>
</div>
% endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.13 on 2024-09-09 15:23

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('course_overviews', '0026_auto_20230525_1917'),
]

operations = [
migrations.AddField(
model_name='courseoverview',
name='course_institution',
field=models.TextField(null=True),
),
migrations.AddField(
model_name='historicalcourseoverview',
name='course_institution',
field=models.TextField(null=True),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Generated by Django 3.2.16 on 2024-12-10 18:37

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('course_overviews', '0027_auto_20240909_1523'),
('course_overviews', '0027_merge_20240123_1603'),
]

operations = [
]
2 changes: 2 additions & 0 deletions openedx/core/djangoapps/content/course_overviews/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class Meta:
display_name = models.TextField(null=True)
display_number_with_default = models.TextField()
display_org_with_default = models.TextField()
course_institution = models.TextField(null=True)

start = models.DateTimeField(null=True)
end = models.DateTimeField(null=True)
Expand Down Expand Up @@ -206,6 +207,7 @@ def _create_or_update(cls, course): # lint-amnesty, pylint: disable=too-many-st
course_overview.display_name = display_name
course_overview.display_number_with_default = course.display_number_with_default
course_overview.display_org_with_default = course.display_org_with_default
course_overview.course_institution = CourseDetails.fetch_about_attribute(course.id, 'course_institution')

course_overview.start = start
course_overview.end = end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def test_malformed_grading_policy(self):
course_overview = CourseOverview._create_or_update(course) # pylint: disable=protected-access
assert course_overview.lowest_passing_grade is None

@ddt.data((ModuleStoreEnum.Type.mongo, 5, 5), (ModuleStoreEnum.Type.split, 2, 2))
@ddt.data((ModuleStoreEnum.Type.mongo, 6, 6), (ModuleStoreEnum.Type.split, 2, 2))
@ddt.unpack
def test_versioning(self, modulestore_type, min_mongo_calls, max_mongo_calls):
"""
Expand Down
2 changes: 2 additions & 0 deletions openedx/core/djangoapps/models/course_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
'entrance_exam_id',
'entrance_exam_minimum_score_pct',
'about_sidebar_html',
'course_institution',
'revision_number',
]

Expand Down Expand Up @@ -71,6 +72,7 @@ def __init__(self, org, course_id, run):
self.video_thumbnail_image_name = ""
self.video_thumbnail_image_asset_path = ""
self.pre_requisite_courses = [] # pre-requisite courses
self.course_institution = "" # course institution
self.entrance_exam_enabled = "" # is entrance exam enabled
self.entrance_exam_id = "" # the content location for the entrance exam
self.entrance_exam_minimum_score_pct = settings.FEATURES.get(
Expand Down
2 changes: 1 addition & 1 deletion requirements/edx/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,7 @@ zipp==3.8.0
# via -r ./requirements/edx/private.txt
-e git+https://github.com/CUCWD/[email protected]#egg=edx-organizations==6.11.1
# via -r ./requirements/edx/private.txt
-e git+https://github.com/CUCWD/[email protected].1#egg=social-auth-backend-bigcommerce==0.1.0
-e git+https://github.com/CUCWD/[email protected].3#egg=social-auth-backend-bigcommerce==0.1.0
# via -r ./requirements/edx/private.txt
# -e git+https://github.com/CUCWD/[email protected]#egg=ora2==4.1.2
-e git+https://github.com/CUCWD/[email protected]#egg=custom-form-app==0.1
Expand Down
2 changes: 1 addition & 1 deletion requirements/edx/development.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1654,7 +1654,7 @@ zipp==3.8.0
# via -r ./requirements/edx/private.txt
-e git+https://github.com/CUCWD/[email protected]#egg=edx-organizations==6.11.1
# via -r ./requirements/edx/private.txt
-e git+https://github.com/CUCWD/[email protected].1#egg=social-auth-backend-bigcommerce==0.1.0
-e git+https://github.com/CUCWD/[email protected].3#egg=social-auth-backend-bigcommerce==0.1.0
# via -r ./requirements/edx/private.txt
-e git+https://github.com/CUCWD/[email protected]#egg=ora2==4.1.2
# via -r ./requirements/edx/private.txt
Expand Down
4 changes: 2 additions & 2 deletions requirements/edx/private.in
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# BigCommerce
-e git+https://github.com/CUCWD/[email protected]maple.3#egg=bigcommerce==0.22.2
-e git+https://github.com/CUCWD/[email protected]nutmeg#egg=bigcommerce==0.22.2
-e git+https://github.com/CUCWD/[email protected]#egg=social-auth-backend-bigcommerce==0.1.0

# Analytics
-e git+https://github.com/CUCWD/[email protected]#egg=Figures==0.4.dev17

# Organizations (reworked for Figures)
-e git+https://github.com/CUCWD/edx-organizations.git@6.10.0-maple.3-cucwd#egg=edx-organizations==6.10.0
-e git+https://github.com/CUCWD/edx-organizations.git@6.11.1.2-cucwd-nutmeg#egg=edx-organizations==6.11.1

# XBlocks
-e git+https://github.com/CUCWD/xblock-qualtrics-survey.git@release/v.2.1.0-maple.3-cucwd#egg=xblock_qualtrics_survey==2.1.0
Expand Down
Loading
Loading