Commit 889e9880 by Harry Rein

Responsive dashboard and learner profile.

parent 1b63bd9c
......@@ -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 {
......
// lms - views - user/student dashboard
// ====================
// Table of Contents
// * +Dashboard - Sidebar
// * +Dashboard - Course Listing
// * +Dashboard - Course Item
// * +Misc - Uncategorized
// * +Dashboard - Banner
// +Dashboard - Sidebar
// +Dashboard
// ====================
.dashboard {
@include clearfix();
padding: ($baseline*2) 0 $baseline 0;
.wrapper-find-courses {
@include float(right);
@include margin-left(flex-gutter());
width: flex-grid(3);
.course-advertise {
@include clearfix();
box-sizing: border-box;
padding: $baseline;
border: 1px solid $border-color-l3;
.advertise-message {
@include font-size(12);
color: $gray-d4;
margin-bottom: $baseline;
}
.ad-link {
@include text-align(center);
.btn-neutral {
padding-bottom: 12px;
padding-top: 12px;
}
a {
@include font-size(16);
@include line-height(17);
padding: $baseline * 0.5;
border: 1px solid $blue;
color: $blue;
text-decoration: none;
display: block;
&:hover,
&:focus,
&:active {
color: $white;
background-color: $blue;
}
span {
@include margin-left($baseline*0.25);
}
.icon {
@include margin-right($baseline*0.25);
}
}
}
}
}
.profile-sidebar {
background: transparent;
@include float(right);
@include margin-left(flex-gutter());
width: flex-grid(3);
margin-top: ($baseline*2);
.user-info {
@include clearfix();
> ul {
@include box-sizing(border-box);
@include clearfix();
margin: 0;
padding: 0;
width: flex-grid(12);
li {
@include clearfix();
border-bottom: 1px dotted $border-color-2;
list-style: none;
margin-bottom: ($baseline*0.75);
padding-bottom: 17px;
&:hover, &:focus {
.title .icon {
opacity: 1;
}
}
span {
display: block;
margin-bottom: ($baseline/4);
}
span.title {
@extend %t-title6;
@extend %t-strong;
a {
text-transform: none;
}
}
span.copy {
@extend %t-copy-sub1;
}
span.data {
color: $base-font-color;
font-weight: 600;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
.third-party-auth {
color: inherit;
font-weight: inherit;
}
}
}
li.order-history {
span a {
font-size: 13px;
line-height: 20px;
}
}
.heads-up {
.title {
display: inline;
}
.copy {
@extend %t-copy-sub2;
display: inline;
}
}
}
.reverify-status-list {
padding: 0 0 0 ($baseline/2);
margin: ($baseline/4) 0;
.status-item {
@extend %t-copy-sub2;
margin-bottom: 7px;
border-bottom: 0;
padding: 0;
.icon {
display: inline-block;
vertical-align: top;
margin: ($baseline/10) ($baseline/4) 0 0;
}
&.is-open .icon {
color: $action-primary-bg;
}
&.is-pending .icon {
color: $warning-color;
}
&.is-approved .icon {
color: $success-color;
}
&.is-denied .icon {
color: $alert-color;
}
.label {
@extend %text-sr;
}
.course-name {
@include line-height(12);
display: inline-block;
vertical-align: top;
width: 80%;
color: inherit;
}
}
}
// status
.status {
@include clearfix();
box-sizing: border-box;
padding: $baseline;
border: 1px solid $border-color-l3;
.list--nav {
margin: ($baseline/2) 0 0 0;
padding: 0;
}
.nav__item {
@extend %t-weight4;
@include font-size(13);
margin-left: 26px;
}
}
}
}
}
// CASE: empty dashboard
.empty-dashboard-message {
border: 3px solid $gray-l4;
background: $gray-l6;
padding: ($baseline*2) 0;
text-align: center;
p {
@include font-size(24);
color: $lighter-base-font-color;
margin-bottom: $baseline;
text-shadow: 0 1px rgba(255,255,255, 0.6);
}
a {
background-color: $blue;
border: 1px solid $blue;
box-shadow: 0 1px 8px 0 $shadow-l1;
@include box-sizing(border-box);
display: flex;
flex-direction: row;
width: 100%;
color: $white;
font-family: $sans-serif;
display: inline-block;
letter-spacing: 1px;
margin-top: ($baseline/4);
margin-left: ($baseline/4);
padding: 15px 20px;
// Contains main course card listings
.main-container {
@include padding($baseline*2, $baseline, $baseline, $baseline*2);
&:hover, &:focus {
background: $blue-l2;
text-decoration: none;
}
}
}
flex-grow: 8;
order: 1;
// +Dashboard - Course Listing
// ====================
.dashboard {
.my-courses {
@include float(left);
margin: 0;
margin-bottom: $baseline * 2;
width: flex-grid(9);
&:focus {
outline: none;
}
.wrapper-header-courses {
border-bottom: 4px solid $border-color-l4;
margin-bottom: $baseline;
margin-bottom: $baseline/2;
.header-courses {
@extend %t-title5;
......@@ -301,26 +41,17 @@
padding-bottom: $baseline;
.course-container {
border: 2px solid $border-color-l4;
border: 1px solid theme-color("light");
border-radius: 3px;
}
&:last-child {
&:last-of-type {
margin-bottom: 0;
border-bottom: none;
padding-bottom: 0;
}
}
}
}
}
// +Dashboard - Course
// ====================
.dashboard .my-courses {
&:focus {
outline: none;
}
// UI: individual course item
.course {
......@@ -330,8 +61,6 @@
@extend %ui-depth2;
margin: ($baseline/2);
.details {
@include clearfix();
......@@ -340,18 +69,15 @@
@include margin-right(flex-gutter());
width: flex-grid(3);
max-height: 150px;
overflow: hidden;
.cover {
@include box-sizing(border-box);
@include transition(all 0.15s linear 0s);
@include float(left);
overflow: hidden;
position: relative;
max-height: 120px;
border-radius: ($baseline/5);
border: 1px solid $dashboard-course-cover-border;
border-bottom: 4px solid $dashboard-course-cover-border;
.course-image {
width: 100%;
......@@ -391,6 +117,11 @@
color: white;
}
}
// Responsive behavior
@include media-breakpoint-down(sm) {
display: none;
}
}
.wrapper-course-details {
......@@ -400,7 +131,7 @@
width: flex-grid(9);
padding: 0;
}
margin: $baseline/2 0;
.course-title {
a, span {
......@@ -409,9 +140,11 @@
display: inline-block;
margin-bottom: ($baseline/2);
&:hover, &:focus {
text-decoration: none;
// Responsive behavior
@include media-breakpoint-down(sm) {
@extend %t-title4;
}
}
}
......@@ -421,14 +154,13 @@
@include float(left);
width: flex-grid(4);
padding: 0;
margin-top: ($baseline/2);
[class*="info-"] {
color: $gray-d1;
@extend %t-title6;
@extend %t-title7;
display: inline-block;
}
......@@ -442,13 +174,16 @@
}
.wrapper-course-actions {
display: block;
@include margin-right($baseline);
@include float(right);
margin-top: $baseline/2;
}
width: flex-grid(8);
padding: 0;
margin-top: ($baseline/2);
// Responsive behavior
@include media-breakpoint-down(sm) {
width: 100%;
}
}
.course-actions {
......@@ -634,6 +369,11 @@
@extend %btn-pl-default-base;
}
}
// Responsive behavior
@include media-breakpoint-down(md) {
@include padding-left($baseline/2);
}
}
// ====================
......@@ -645,6 +385,7 @@
.messages-list {
margin: 0;
padding: 0;
background-color: theme-color("lightest");
}
.message {
......@@ -652,7 +393,6 @@
border-radius: 3px;
display: none;
margin: $baseline 0 ($baseline/2) 0;
padding: ($baseline/2) $baseline;
border-top: 1px solid $gray-l4;
color: $base-font-color; // Overrides the normal white color in this one case
......@@ -665,7 +405,7 @@
}
a {
font-family: $sans-serif;
font-family: $font-family-sans-serif;
}
strong {
......@@ -778,7 +518,6 @@
padding: ($baseline/4) 0;
.message-copy {
width: flex-grid(9, 12);
display: inline-block;
.message-copy-bold {
......@@ -894,7 +633,7 @@
@include float(left);
border-radius: 3px;
font: normal 0.8rem/1.2rem $sans-serif;
font: normal 0.8rem/1.2rem $font-family-sans-serif;
letter-spacing: 1px;
padding: 6px 12px;
text-align: center;
......@@ -913,7 +652,7 @@
.btn {
@include float(left);
font: normal 0.8rem/1.2rem $sans-serif;
font: normal 0.8rem/1.2rem $font-family-sans-serif;
letter-spacing: 1px;
padding: 6px 12px;
text-align: center;
......@@ -922,11 +661,11 @@
}
.exam-registration-number {
font-family: $sans-serif;
font-family: $font-family-sans-serif;
font-size: 18px;
a {
font-family: $sans-serif;
font-family: $font-family-sans-serif;
}
}
......@@ -1116,12 +855,16 @@
@include clearfix;
.tip {
font-family: $sans-serif;
font-family: $font-family-sans-serif;
font-size: 1em;
color: $lighter-base-font-color;
margin-top: ($baseline/2);
}
}
@include media-breakpoint-down(md) {
@include padding($baseline/2, $baseline, $baseline/2, $baseline/2);
}
}
}
......@@ -1211,6 +954,123 @@
}
}
}
}
// Responsive behavior
@include media-breakpoint-down(md) {
padding: $baseline;
}
}
// Secondary functionality
.side-container {
@include padding($baseline*2, $baseline*2, $baseline, $baseline);
max-width: $baseline*20;
flex-grow: 1;
order: 2;
.wrapper-find-courses {
.course-advertise {
@include clearfix();
box-sizing: border-box;
padding: $baseline;
border: 1px solid $border-color-l3;
.advertise-message {
@include font-size(12);
color: $gray-d4;
margin-bottom: $baseline;
}
.ad-link {
@include text-align(center);
.btn-neutral {
padding-bottom: 12px;
padding-top: 12px;
}
a {
@include font-size(16);
@include line-height(17);
padding: $baseline * 0.5;
border: 1px solid theme-color('primary');
color: theme-color('primary');
text-decoration: none;
display: block;
&:hover,
&:focus,
&:active {
color: $white;
background-color: theme-color('primary');
}
span {
@include margin-left($baseline*0.25);
}
.icon {
@include margin-right($baseline*0.25);
}
}
}
}
}
// Responsive behavior
@include media-breakpoint-down(md) {
margin: 0 $baseline $baseline*2;
padding: 0;
max-width: 100%;
}
}
// Responsive behavior
@include media-breakpoint-down(md) {
flex-direction: column;
}
}
// CASE: empty dashboard
.empty-dashboard-message {
border: 3px solid $gray-l4;
background: $gray-l6;
padding: ($baseline*2) 0;
text-align: center;
p {
@include font-size(24);
color: $lighter-base-font-color;
margin-bottom: $baseline;
text-shadow: 0 1px rgba(255,255,255, 0.6);
}
a {
background-color: theme-color('primary');
border: 1px solid theme-color('primary');
box-shadow: 0 1px 8px 0 $shadow-l1;
@include box-sizing(border-box);
color: $white;
font-family: $font-family-sans-serif;
display: inline-block;
letter-spacing: 1px;
margin-top: ($baseline/4);
margin-left: ($baseline/4);
padding: $baseline*0.75 $baseline;
&:hover, &:focus {
background: theme-color('primary')-l2;
text-decoration: none;
}
}
}
// +Misc - Uncategorized
......@@ -1417,7 +1277,7 @@ p.course-block {
@include float(left);
display: block;
font: normal 15px/1.6rem $sans-serif;
font: normal 15px/1.6rem $font-family-sans-serif;
letter-spacing: 0;
padding: 6px 32px 7px;
text-align: center;
......@@ -1431,7 +1291,7 @@ p.course-block {
&.archived {
@include button(simple, $button-archive-color);
font: normal 15px/1.6rem $sans-serif;
font: normal 15px/1.6rem $font-family-sans-serif;
padding: 6px 32px 7px;
&:hover, &:focus {
......@@ -1464,7 +1324,7 @@ a.fade-cover {
.msg {
@include clearfix();
font-family: $sans-serif;
font-family: $font-family-sans-serif;
padding-bottom: $baseline;
border-bottom: thin solid $gray;
......
......@@ -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,7 +102,9 @@ 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="dashboard" id="dashboard-main">
<div class="main-container">
<div class="my-courses" id="my-courses">
<%include file="learner_dashboard/_dashboard_navigation_courses.html"/>
......@@ -160,7 +162,8 @@ from openedx.core.djangolib.markup import HTML, Text
</div>
% endif
</div>
</div>
<div class="side-container">
%if sidebar_account_activation_message:
<div class="sidebar-notification">
${sidebar_account_activation_message | n, decode.utf8}
......@@ -182,9 +185,6 @@ from openedx.core.djangolib.markup import HTML, Text
</div>
</form>
</div>
% endif
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
<div id="dashboard-search-results" class="search-results dashboard-search-results"></div>
% endif
......@@ -212,6 +212,7 @@ from openedx.core.djangolib.markup import HTML, Text
</div>
% endif
</div>
</div>
</main>
<div id="email-settings-modal" class="modal" aria-hidden="true">
......
......@@ -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">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment