Skip to content
Snippets Groups Projects
Commit ed2e6dc8 authored by Harry Rein's avatar Harry Rein Committed by GitHub
Browse files

Merge pull request #16306 from edx/HarryRein/responsive-dashboard

Harry rein/responsive dashboard
parents 0084b3b4 889e9880
No related branches found
No related tags found
No related merge requests found
Showing
with 906 additions and 1084 deletions
......@@ -53,12 +53,12 @@ def i_visit_the_homepage(step):
@step(u'I (?:visit|access|open) the dashboard$')
def i_visit_the_dashboard(step):
world.visit('/dashboard')
assert world.is_css_present('.container.dashboard')
assert world.is_css_present('.dashboard')
@step('I should be on the dashboard page$')
def i_should_be_on_the_dashboard(step):
assert world.is_css_present('.container.dashboard')
assert world.is_css_present('.dashboard')
assert 'Dashboard' in world.browser.title
......@@ -166,7 +166,7 @@ def i_am_logged_in(step):
world.create_user('robot', 'test')
world.log_in(username='robot', password='test')
world.browser.visit(lettuce.django.django_url('/'))
dash_css = '.container.dashboard'
dash_css = '.dashboard'
assert world.is_css_present(dash_css)
......
......@@ -11,7 +11,7 @@ def i_register_for_the_course(_step, course):
url = django_url('courses/%s/about' % world.scenario_dict['COURSE'].id.to_deprecated_string())
world.browser.visit(url)
world.css_click('.intro a.register')
assert world.is_css_present('.container.dashboard')
assert world.is_css_present('.dashboard')
@step('I register to audit the course$')
......@@ -27,7 +27,7 @@ def i_register_to_audit_the_course(_step):
ignored_exceptions=AttributeError
)
time.sleep(1)
assert world.is_css_present('.container.dashboard')
assert world.is_css_present('.dashboard')
@step(u'I should see an empty dashboard message')
......
......@@ -20,14 +20,14 @@
a {
@include float(left);
@include margin($baseline/2, 0, 0, $baseline);
@include margin($baseline*0.75, 0, 0, $baseline*2);
display: block;
.logo {
@include float(left);
width: $header-logo-width;
height: $header-logo-height;
}
@include media-breakpoint-down(sm) {
......@@ -90,7 +90,7 @@
a {
color: theme-color("secondary");
padding: $baseline*0.35 $baseline*1.25 $baseline*0.75;
padding: $baseline*0.35 $baseline*1.25 $baseline;
font-weight: $font-weight-normal;
display: inline-block;
margin-bottom: -1*$baseline/2;
......@@ -112,8 +112,7 @@
.secondary {
@include float(right);
margin: $baseline*0.6 $baseline 0 0;
@include margin($baseline*0.75, $baseline*2, 0, 0);
// All navigation items
.nav-item {
......@@ -230,7 +229,7 @@
.hamburger-menu {
@include left(22px);
position: absolute;
top: $baseline;
top: $baseline*1.25;
width: 30px;
height: 20px;
-webkit-transform: rotate(0deg);
......
......@@ -23,8 +23,6 @@
}
.search-results-item {
@include padding-right(140px);
position: relative;
border-top: 1px solid $border-color;
padding: $baseline ($baseline/2);
......@@ -52,10 +50,9 @@
}
.result-link {
@include right($baseline/2);
@include float(right);
@include padding-left($baseline/4);
position: absolute;
top: $baseline;
line-height: 1.6em;
}
......
......@@ -273,6 +273,11 @@
border: none;
box-shadow: none;
padding: 0;
@media (max-width: $learner-profile-container-flex) { // Switch to map-get($grid-breakpoints,md) for bootstrap
max-width: calc(100% - 40px);
min-width: auto;
}
}
.u-field-title {
......
This diff is collapsed.
......@@ -81,8 +81,6 @@
}
.search-results-item {
@include padding-right(140px);
position: relative;
border-bottom: 1px solid $gray-l4;
padding: $baseline ($baseline/2);
......@@ -119,12 +117,10 @@
}
.result-link {
@include right($baseline/2);
@include float(right);
@include padding-left($baseline/4);
position: absolute;
top: $baseline;
line-height: 1.6em;
text-transform: uppercase;
}
.search-results-ellipsis {
......@@ -155,12 +151,8 @@
.dashboard-search-bar {
@include float(right);
@include margin-left(flex-gutter());
margin-bottom: $baseline;
padding: 0;
width: flex-grid(3);
margin: 0 0 $baseline;
display: block;
label {
@extend %t-regular;
......@@ -181,12 +173,8 @@
}
.dashboard-search-results {
@include float(left);
margin: 0;
margin: 0 0 $baseline;
padding: 0;
width: flex-grid(9);
min-height: 300px;
.search-info {
padding-bottom: lh(1.75);
......
......@@ -102,115 +102,116 @@ from openedx.core.djangolib.markup import HTML, Text
</div>
<main id="main" aria-label="Content" tabindex="-1">
<div class="container dashboard" id="dashboard-main">
<div class="my-courses" id="my-courses">
<%include file="learner_dashboard/_dashboard_navigation_courses.html"/>
<div class="dashboard" id="dashboard-main">
% if len(course_enrollments) > 0:
<ul class="listing-courses">
<%
share_settings = configuration_helpers.get_value(
'SOCIAL_SHARING_SETTINGS',
getattr(settings, 'SOCIAL_SHARING_SETTINGS', {})
)
%>
% for dashboard_index, enrollment in enumerate(course_enrollments):
<% show_courseware_link = (enrollment.course_id in show_courseware_links_for) %>
<% cert_status = cert_statuses.get(enrollment.course_id) %>
<% can_unenroll = (not cert_status) or cert_status.get('can_unenroll') %>
<% credit_status = credit_statuses.get(enrollment.course_id) %>
<% show_email_settings = (enrollment.course_id in show_email_settings_for) %>
<% course_mode_info = all_course_modes.get(enrollment.course_id) %>
<% is_paid_course = (enrollment.course_id in enrolled_courses_either_paid) %>
<% is_course_blocked = (enrollment.course_id in block_courses) %>
<% course_verification_status = verification_status_by_course.get(enrollment.course_id, {}) %>
<% course_requirements = courses_requirements_not_met.get(enrollment.course_id) %>
<% related_programs = inverted_programs.get(unicode(enrollment.course_id)) %>
<%include file='dashboard/_dashboard_course_listing.html' args='course_overview=enrollment.course_overview, enrollment=enrollment, show_courseware_link=show_courseware_link, cert_status=cert_status, can_unenroll=can_unenroll, credit_status=credit_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, is_paid_course=is_paid_course, is_course_blocked=is_course_blocked, verification_status=course_verification_status, course_requirements=course_requirements, dashboard_index=dashboard_index, share_settings=share_settings, user=user, related_programs=related_programs, display_course_modes_on_dashboard=display_course_modes_on_dashboard' />
% endfor
<div class="main-container">
<div class="my-courses" id="my-courses">
<%include file="learner_dashboard/_dashboard_navigation_courses.html"/>
</ul>
% else:
<div class="empty-dashboard-message">
<p>${_("You are not enrolled in any courses yet.")}</p>
% if len(course_enrollments) > 0:
<ul class="listing-courses">
<%
share_settings = configuration_helpers.get_value(
'SOCIAL_SHARING_SETTINGS',
getattr(settings, 'SOCIAL_SHARING_SETTINGS', {})
)
%>
% for dashboard_index, enrollment in enumerate(course_enrollments):
<% show_courseware_link = (enrollment.course_id in show_courseware_links_for) %>
<% cert_status = cert_statuses.get(enrollment.course_id) %>
<% can_unenroll = (not cert_status) or cert_status.get('can_unenroll') %>
<% credit_status = credit_statuses.get(enrollment.course_id) %>
<% show_email_settings = (enrollment.course_id in show_email_settings_for) %>
<% course_mode_info = all_course_modes.get(enrollment.course_id) %>
<% is_paid_course = (enrollment.course_id in enrolled_courses_either_paid) %>
<% is_course_blocked = (enrollment.course_id in block_courses) %>
<% course_verification_status = verification_status_by_course.get(enrollment.course_id, {}) %>
<% course_requirements = courses_requirements_not_met.get(enrollment.course_id) %>
<% related_programs = inverted_programs.get(unicode(enrollment.course_id)) %>
<%include file='dashboard/_dashboard_course_listing.html' args='course_overview=enrollment.course_overview, enrollment=enrollment, show_courseware_link=show_courseware_link, cert_status=cert_status, can_unenroll=can_unenroll, credit_status=credit_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, is_paid_course=is_paid_course, is_course_blocked=is_course_blocked, verification_status=course_verification_status, course_requirements=course_requirements, dashboard_index=dashboard_index, share_settings=share_settings, user=user, related_programs=related_programs, display_course_modes_on_dashboard=display_course_modes_on_dashboard' />
% endfor
% if settings.FEATURES.get('COURSES_ARE_BROWSABLE'):
<a href="${marketing_link('COURSES')}">
${_("Explore courses")}
</a>
%endif
</div>
% endif
</ul>
% else:
<div class="empty-dashboard-message">
<p>${_("You are not enrolled in any courses yet.")}</p>
% if staff_access and len(errored_courses) > 0:
<div id="course-errors">
<h2>${_("Course-loading errors")}</h2>
% if settings.FEATURES.get('COURSES_ARE_BROWSABLE'):
<a href="${marketing_link('COURSES')}">
${_("Explore courses")}
</a>
% for course_dir, errors in errored_courses.items():
<h3>${course_dir}</h3>
<ul>
% for (msg, err) in errors:
<li>${msg}
<ul><li><pre>${err}</pre></li></ul>
</li>
% endfor
</ul>
% endfor
%endif
</div>
% endif
</div>
% endif
%if sidebar_account_activation_message:
<div class="sidebar-notification">
${sidebar_account_activation_message | n, decode.utf8}
</div>
%endif
% if staff_access and len(errored_courses) > 0:
<div id="course-errors">
<h2>${_("Course-loading errors")}</h2>
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
<div id="dashboard-search-bar" class="search-bar dashboard-search-bar" role="search" aria-label="Dashboard">
<form class="search-form">
<label for="dashboard-search-input">${_('Search Your Courses')}</label>
<div class="search-field-wrapper">
<input id="dashboard-search-input" type="text" class="search-field"/>
<button type="submit" class="search-button" title="${_('Search')}">
<span class="icon fa fa-search" aria-hidden="true"></span>
</button>
<button type="button" class="cancel-button" title="${_('Clear search')}">
<span class="icon fa fa-remove" aria-hidden="true"></span>
</button>
% for course_dir, errors in errored_courses.items():
<h3>${course_dir}</h3>
<ul>
% for (msg, err) in errors:
<li>${msg}
<ul><li><pre>${err}</pre></li></ul>
</li>
% endfor
</ul>
% endfor
</div>
</form>
% endif
</div>
% endif
</div>
<div class="side-container">
%if sidebar_account_activation_message:
<div class="sidebar-notification">
${sidebar_account_activation_message | n, decode.utf8}
</div>
%endif
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
<div id="dashboard-search-results" class="search-results dashboard-search-results"></div>
% endif
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
<div id="dashboard-search-bar" class="search-bar dashboard-search-bar" role="search" aria-label="Dashboard">
<form class="search-form">
<label for="dashboard-search-input">${_('Search Your Courses')}</label>
<div class="search-field-wrapper">
<input id="dashboard-search-input" type="text" class="search-field"/>
<button type="submit" class="search-button" title="${_('Search')}">
<span class="icon fa fa-search" aria-hidden="true"></span>
</button>
<button type="button" class="cancel-button" title="${_('Clear search')}">
<span class="icon fa fa-remove" aria-hidden="true"></span>
</button>
</div>
</form>
</div>
<div id="dashboard-search-results" class="search-results dashboard-search-results"></div>
% endif
% if display_sidebar_on_dashboard:
<div class="profile-sidebar" id="profile-sidebar" role="region" aria-label="Account Status Info">
<header class="profile">
<h2 class="account-status-title sr">${_("Account Status Info")}: </h2>
</header>
<div class="user-info">
<ul>
% if display_sidebar_on_dashboard:
<div class="profile-sidebar" id="profile-sidebar" role="region" aria-label="Account Status Info">
<header class="profile">
<h2 class="account-status-title sr">${_("Account Status Info")}: </h2>
</header>
<div class="user-info">
<ul>
% if len(order_history_list):
<li class="order-history">
<span class="title">${_("Order History")}</span>
% for order_history_item in order_history_list:
<span><a href="${order_history_item['receipt_url']}" target="_blank" class="edit-name">${order_history_item['order_date']}</a></span>
% endfor
</li>
% endif
% if len(order_history_list):
<li class="order-history">
<span class="title">${_("Order History")}</span>
% for order_history_item in order_history_list:
<span><a href="${order_history_item['receipt_url']}" target="_blank" class="edit-name">${order_history_item['order_date']}</a></span>
% endfor
</li>
% endif
<%include file="${static.get_template_path('dashboard/_dashboard_status_verification.html')}" />
<%include file="${static.get_template_path('dashboard/_dashboard_status_verification.html')}" />
</ul>
</ul>
</div>
</div>
</div>
% endif
% endif
</div>
</div>
</main>
......
......@@ -351,23 +351,18 @@ define([
describe('SearchResultsView', function() {
function showsLoadingMessage() {
this.resultsView.showLoadingMessage();
expect(this.resultsView.$contentElement).toBeHidden();
expect(this.resultsView.$el).toBeVisible();
expect(this.resultsView.$el).not.toBeEmpty();
}
function showsErrorMessage() {
this.resultsView.showErrorMessage();
expect(this.resultsView.$contentElement).toBeHidden();
expect(this.resultsView.$el).toBeVisible();
expect(this.resultsView.$el).not.toBeEmpty();
}
function returnsToContent() {
this.resultsView.clear();
expect(this.resultsView.$contentElement).toHaveCss({
display: this.contentElementDisplayValue
});
expect(this.resultsView.$el).toBeHidden();
expect(this.resultsView.$el).toBeEmpty();
}
......@@ -484,16 +479,6 @@ define([
it('shows a link to load more results', showsMoreResultsLink);
it('triggers an event for next page', triggersNextPageEvent);
it('shows a spinner when loading more results', showsLoadMoreSpinner);
it('returns back to courses', function() {
var onReset = jasmine.createSpy('onReset');
this.resultsView.on('reset', onReset);
this.resultsView.render();
expect(this.resultsView.$el.find('a.search-back-to-courses')).toExist();
this.resultsView.$el.find('.search-back-to-courses').click();
expect(onReset).toHaveBeenCalled();
expect(this.resultsView.$contentElement).toBeVisible();
expect(this.resultsView.$el).toBeHidden();
});
});
});
......@@ -502,9 +487,6 @@ define([
function showsLoadingMessage() {
$('.search-field').val('search string');
$('.search-button').trigger('click');
if (this.$contentElement) {
expect(this.$contentElement).toBeHidden();
}
expect(this.$searchResults).toBeVisible();
expect(this.$searchResults).not.toBeEmpty();
}
......@@ -556,13 +538,11 @@ define([
$('.cancel-button').trigger('click');
AjaxHelpers.skipResetRequest(requests);
// there should be no results
expect(this.$contentElement).toHaveCss({display: this.contentElementDisplayValue});
expect(this.$searchResults).toBeHidden();
}
function clearsResults() {
$('.cancel-button').trigger('click');
expect(this.$contentElement).toHaveCss({display: this.contentElementDisplayValue});
expect(this.$searchResults).toBeHidden();
}
......@@ -636,7 +616,6 @@ define([
DashboardSearchFactory();
spyOn(Backbone.history, 'navigate');
this.$contentElement = $('#my-courses');
this.contentElementDisplayValue = 'block';
this.$searchResults = $('.search-results');
});
......@@ -670,9 +649,7 @@ define([
}
}]
});
expect($('.search-back-to-courses')).toExist();
$('.search-back-to-courses').trigger('click');
expect(this.$contentElement).toBeVisible();
$('.search-form .cancel-button').trigger('click');
expect(this.$searchResults).toBeHidden();
expect(this.$searchResults).toBeEmpty();
});
......
......@@ -12,12 +12,10 @@
) {
return SearchResultsView.extend({
el: '.search-results',
contentElement: '#my-courses, #profile-sidebar',
resultsTemplate: dashboardSearchResultsTemplate,
itemTemplate: dashboardSearchItemTemplate,
events: {
'click .search-load-next': 'loadNext',
'click .search-back-to-courses': 'backToCourses'
},
backToCourses: function() {
......
<header class="search-info">
<a class="search-back-to-courses" href="#"><%- gettext("Back to Dashboard") %></a>
<h2><%- gettext("Search Results") %></h2>
<div class="search-count"><%- totalCountMsg %></div>
</header>
......
......@@ -102,8 +102,8 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers
</div>
<section class="container dashboard" id="dashboard-main">
<main id="main" aria-label="Content" tabindex="-1">
<section class="dashboard" id="dashboard-main">
<main class="main-container" id="main" aria-label="Content" tabindex="-1">
<section class="my-courses" id="my-courses">
<header class="wrapper-header-courses">
<h2 class="header-courses">${_("My Courses")}</h2>
......@@ -159,7 +159,7 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers
% endif
</section>
</main>
<div class="side-container">
%if sidebar_account_activation_message:
<div class="sidebar-notification">
${sidebar_account_activation_message | n, decode.utf8}
......@@ -181,9 +181,6 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers
</div>
</form>
</div>
% endif
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
<section id="dashboard-search-results" class="search-results dashboard-search-results"></section>
% endif
......@@ -226,6 +223,7 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers
</section>
</section>
% endif
</div>
</section>
<section id="email-settings-modal" class="modal" aria-hidden="true">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment