From 630607d34554aef03f4e74adbdf26f0dd3b01496 Mon Sep 17 00:00:00 2001 From: ichuang Date: Tue, 5 Feb 2013 00:21:04 +0000 Subject: [PATCH 001/299] fix forum management commands (assign_default_role moved); add reload_forum_users --- .../commands/assign_roles_for_course.py | 3 +- .../commands/create_roles_for_existing.py | 3 +- .../management/commands/reload_forum_users.py | 29 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 lms/djangoapps/django_comment_client/management/commands/reload_forum_users.py diff --git a/lms/djangoapps/django_comment_client/management/commands/assign_roles_for_course.py b/lms/djangoapps/django_comment_client/management/commands/assign_roles_for_course.py index 82f2290bc7..64378108b6 100644 --- a/lms/djangoapps/django_comment_client/management/commands/assign_roles_for_course.py +++ b/lms/djangoapps/django_comment_client/management/commands/assign_roles_for_course.py @@ -6,7 +6,8 @@ Enrollments. """ from django.core.management.base import BaseCommand, CommandError -from student.models import CourseEnrollment, assign_default_role +from student.models import CourseEnrollment +from django_comment_client.models import assign_default_role class Command(BaseCommand): args = 'course_id' diff --git a/lms/djangoapps/django_comment_client/management/commands/create_roles_for_existing.py b/lms/djangoapps/django_comment_client/management/commands/create_roles_for_existing.py index d1244a6690..3ec2d0646e 100644 --- a/lms/djangoapps/django_comment_client/management/commands/create_roles_for_existing.py +++ b/lms/djangoapps/django_comment_client/management/commands/create_roles_for_existing.py @@ -6,7 +6,8 @@ Enrollments. """ from django.core.management.base import BaseCommand, CommandError -from student.models import CourseEnrollment, assign_default_role +from student.models import CourseEnrollment +from django_comment_client.models import assign_default_role class Command(BaseCommand): args = 'course_id' diff --git a/lms/djangoapps/django_comment_client/management/commands/reload_forum_users.py b/lms/djangoapps/django_comment_client/management/commands/reload_forum_users.py new file mode 100644 index 0000000000..5e7e268270 --- /dev/null +++ b/lms/djangoapps/django_comment_client/management/commands/reload_forum_users.py @@ -0,0 +1,29 @@ +""" +Reload forum (comment client) users from existing users. +""" +from django.core.management.base import BaseCommand, CommandError + +from django.contrib.auth.models import User +import comment_client as cc + +class Command(BaseCommand): + help = 'Reload forum (comment client) users from existing users' + + def adduser(self,user): + print user + try: + cc_user = cc.User.from_django_user(user) + cc_user.save() + except Exception as err: + print "update user info to discussion failed for user with id: %s" % user + + def handle(self, *args, **options): + if len(args) != 0: + uset = [User.objects.get(username=x) for x in args] + else: + uset = User.objects.all() + + for user in uset: + self.adduser(user) + + \ No newline at end of file From 22639adc639470da940b7ed7720a9d0bb1668f38 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Thu, 21 Feb 2013 14:31:24 -0500 Subject: [PATCH 002/299] studio - alerts WIP --- cms/static/sass/_alerts.scss | 323 ++++++++++++++++++++++++++------ cms/static/sass/_header.scss | 2 +- cms/static/sass/_variables.scss | 44 ++++- cms/templates/unit.html | 28 ++- 4 files changed, 338 insertions(+), 59 deletions(-) diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index 11d2e4fe3a..4a20980a57 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -1,65 +1,280 @@ -.alert { - padding: 15px 20px; - margin-bottom: 30px; - border-radius: 3px; - border: 1px solid #edbd3c; - border-radius: 3px; - background: #fbf6e1; - // background: #edbd3c; - font-size: 14px; - @include clearfix; +// studio alerts and notifications +// ==================== - .alert-message { - float: left; - margin-top: 4px; - } +// notifications +.wrapper-notification { + @include clearfix(); + @include box-sizing(border-box); + @include transition (bottom 2.0s ease-in-out 5s, opacity 2.0s ease-in-out 5s); + @include box-shadow(0 -1px 2px rgba(0,0,0,0.1)); + position: fixed; + bottom: -100px; + z-index: 1000; + width: 100%; + overflow: hidden; + opacity: 0; + border-top: 1px solid $gray-d1; + padding: $baseline ($baseline*2); + background: $white; - strong { - font-weight: 700; - } + &.is-shown { + bottom: 0; + opacity: 1.0; + } - .alert-action { - float: right; + &.wrapper-notification-warning { + border-color: shade($yellow, 25%); + background: tint($yellow, 25%); + } - &.secondary { - @include orange-button; - } - } + &.wrapper-notification-error { + border-color: shade($red, 50%); + background: tint($red, 20%); + color: $white; + } + + &.wrapper-notification-confirm { + border-color: shade($green, 30%); + background: tint($green, 40%); + color: shade($green, 30%); + } } -body.error { - background: $darkGrey; - color: #3c3c3c; +.notification { + @include box-sizing(border-box); + margin: 0 auto; + width: flex-grid(12); + max-width: $fg-max-width; + min-width: $fg-min-width; - .primary-header { - display: none; - } + .copy { + float: left; + width: flex-grid(9, 12); + margin-right: flex-gutter(); + margin-top: 5px; + font-size: 14px; - .error-prompt { - width: 700px; - margin: 150px auto; - padding: 60px 50px 90px; - border-radius: 3px; - background: #fff; - text-align: center; - } + .icon { + display: inline-block; + vertical-align: top; + margin-right: 5px; + font-size: 20px; + } - h1 { - float: none; - margin: 0; - font-size: 60px; - font-weight: 300; - color: #3c3c3c; - } + p { + width: flex-grid(8, 9); + display: inline-block; + vertical-align: top; + } + } - .description { - margin-bottom: 50px; - font-size: 21px; - } + .actions { + float: right; + width: flex-grid(3, 12); + margin-top: ($baseline/2); + text-align: right; - .back-button { - @include blue-button; - padding: 14px 40px 18px; - font-size: 18px; - } -} \ No newline at end of file + li { + display: inline-block; + vertical-align: middle; + margin-right: 10px; + + &:last-child { + margin-right: 0; + } + } + + .save-button { + @include blue-button; + } + + .cancel-button { + @include white-button; + } + } + + strong { + font-weight: 700; + } +} + +// ==================== + +// alerts +.wrapper-alert { + @include clearfix(); + @include box-sizing(border-box); + @include transition (opacity 2.0s ease-in-out 5s); + @include box-shadow(0 1px 2px rgba(0,0,0,0.2)); + position: relative; + top: -($baseline*1.5); + z-index: 100; + overflow: hidden; + width: 100%; + opacity: 0; + border-bottom: 2px solid $blue-d2; + padding: $baseline ($baseline*2); + background: $blue; + + &.is-shown { + bottom: 0; + opacity: 1.0; + } + + &.wrapper-alert-warning { + background: $orange-s1; + border-color: $orange-d1; + } + + &.wrapper-alert-error { + border-color: shade($red, 50%); + color: $white; + } + + &.wrapper-alert-confirm { + border-color: shade($green, 30%); + } + + &.wrapper-alert-inform { + border-color: $blue-d1; + } +} + +.alert { + @include font-size(14); + @include box-sizing(border-box); + margin: 0 auto; + width: flex-grid(12); + max-width: $fg-max-width; + min-width: $fg-min-width; + color: $white; + + strong { + font-weight: 700; + } + + .copy { + @include font-size(14); + + .icon { + @include font-size(24); + @include border-radius(50px); + display: inline-block; + vertical-align: top; + margin-right: ($baseline/2); + padding: ($baseline/4) ($baseline/2) ($baseline/10) ($baseline/2); + } + + p { + width: flex-grid(8, 9); + display: inline-block; + vertical-align: top; + } + } + + &.has-actions { + + .copy { + float: left; + width: flex-grid(8, 12); + margin-right: flex-gutter(); + } + + .actions { + float: right; + width: flex-grid(4, 12); + margin-top: ($baseline/2); + text-align: right; + + li { + display: inline-block; + vertical-align: middle; + margin-right: ($baseline/2); + + &:last-child { + margin-right: 0; + } + } + } + } + + // alert types + &.warning { + color: $gray-d2; + + .copy { + + .icon { + background: $gray-d2; + color: $orange-s1; + } + } + } +} + +// artifact styles +// .alert { +// padding: 15px 20px; +// margin-bottom: 30px; +// border-radius: 3px; +// border: 1px solid #edbd3c; +// border-radius: 3px; +// background: #fbf6e1; +// // background: #edbd3c; +// font-size: 14px; +// @include clearfix; + +// .alert-message { +// float: left; +// margin-top: 4px; +// } + +// strong { +// font-weight: 700; +// } + +// .alert-action { +// float: right; + +// &.secondary { +// @include orange-button; +// } +// } +// } + +// body.error { +// background: $darkGrey; +// color: #3c3c3c; + +// .primary-header { +// display: none; +// } + +// .error-prompt { +// width: 700px; +// margin: 150px auto; +// padding: 60px 50px 90px; +// border-radius: 3px; +// background: #fff; +// text-align: center; +// } + +// h1 { +// float: none; +// margin: 0; +// font-size: 60px; +// font-weight: 300; +// color: #3c3c3c; +// } + +// .description { +// margin-bottom: 50px; +// font-size: 21px; +// } + +// .back-button { +// @include blue-button; +// padding: 14px 40px 18px; +// font-size: 18px; +// } +// } \ No newline at end of file diff --git a/cms/static/sass/_header.scss b/cms/static/sass/_header.scss index ca1092f44b..3115711506 100644 --- a/cms/static/sass/_header.scss +++ b/cms/static/sass/_header.scss @@ -10,7 +10,7 @@ height: 76px; position: relative; width: 100%; - z-index: 10; + z-index: 1000; a { color: $baseFontColor; diff --git a/cms/static/sass/_variables.scss b/cms/static/sass/_variables.scss index 4d8e26b2f9..eb2bd29ebd 100644 --- a/cms/static/sass/_variables.scss +++ b/cms/static/sass/_variables.scss @@ -39,6 +39,12 @@ $blue-d1: shade($blue,20%); $blue-d2: shade($blue,40%); $blue-d3: shade($blue,60%); $blue-d4: shade($blue,80%); +$blue-s1: saturate($blue,15%); +$blue-s2: saturate($blue,30%); +$blue-s3: saturate($blue,45%); +$blue-u1: desaturate($blue,15%); +$blue-u2: desaturate($blue,30%); +$blue-u3: desaturate($blue,45%); $pink: rgb(183, 37, 103); $pink-l1: tint($pink,20%); @@ -50,6 +56,12 @@ $pink-d1: shade($pink,20%); $pink-d2: shade($pink,40%); $pink-d3: shade($pink,60%); $pink-d4: shade($pink,80%); +$pink-s1: saturate($pink,15%); +$pink-s2: saturate($pink,30%); +$pink-s3: saturate($pink,45%); +$pink-u1: desaturate($pink,15%); +$pink-u2: desaturate($pink,30%); +$pink-u3: desaturate($pink,45%); $green: rgb(37, 184, 90); $green-l1: tint($green,20%); @@ -61,8 +73,14 @@ $green-d1: shade($green,20%); $green-d2: shade($green,40%); $green-d3: shade($green,60%); $green-d4: shade($green,80%); +$green-s1: saturate($green,15%); +$green-s2: saturate($green,30%); +$green-s3: saturate($green,45%); +$green-u1: desaturate($green,15%); +$green-u2: desaturate($green,30%); +$green-u3: desaturate($green,45%); -$yellow: rgb(231, 214, 143); +$yellow: rgb(237, 189, 60); $yellow-l1: tint($yellow,20%); $yellow-l2: tint($yellow,40%); $yellow-l3: tint($yellow,60%); @@ -72,9 +90,33 @@ $yellow-d1: shade($yellow,20%); $yellow-d2: shade($yellow,40%); $yellow-d3: shade($yellow,60%); $yellow-d4: shade($yellow,80%); +$yellow-s1: saturate($yellow,15%); +$yellow-s2: saturate($yellow,30%); +$yellow-s3: saturate($yellow,45%); +$yellow-u1: desaturate($yellow,15%); +$yellow-u2: desaturate($yellow,30%); +$yellow-u3: desaturate($yellow,45%); + +$orange: rgb(237, 189, 60); +$orange-l1: tint($orange,20%); +$orange-l2: tint($orange,40%); +$orange-l3: tint($orange,60%); +$orange-l4: tint($orange,80%); +$orange-l5: tint($orange,90%); +$orange-d1: shade($orange,20%); +$orange-d2: shade($orange,40%); +$orange-d3: shade($orange,60%); +$orange-d4: shade($orange,80%); +$orange-s1: saturate($orange,15%); +$orange-s2: saturate($orange,30%); +$orange-s3: saturate($orange,45%); +$orange-u1: desaturate($orange,15%); +$orange-u2: desaturate($orange,30%); +$orange-u3: desaturate($orange,45%); $shadow: rgba(0,0,0,0.2); $shadow-l1: rgba(0,0,0,0.1); +$shadow-l2: rgba(0,0,0,0.05); $shadow-d1: rgba(0,0,0,0.4); // colors - inherited diff --git a/cms/templates/unit.html b/cms/templates/unit.html index c529f5863a..53be470a50 100644 --- a/cms/templates/unit.html +++ b/cms/templates/unit.html @@ -16,7 +16,6 @@ }); $(document).ready(function() { - $('body').addClass('js'); // tabs $('.tab-group').tabs(); @@ -32,9 +31,32 @@ <%block name="content"> + + +
+
+
+ +

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + +
+
+
-
+

You are editing a draft. % if published_date: This unit was originally published on ${published_date}. @@ -144,7 +166,7 @@

-
+

This unit has been published. To make changes, you must edit a draft.

This is a draft of the published unit. To update the live version, you must replace it with this draft.

From d7bbfbc707299ec1f5db960ee892075b5bc29269 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Fri, 22 Feb 2013 13:52:24 -0500 Subject: [PATCH 003/299] studio - alerts: basic layout and general alert styling WIP --- cms/static/sass/_alerts.scss | 161 ++++++++++++++++++++++++-------- cms/static/sass/_base.scss | 45 +++++++++ cms/static/sass/_header.scss | 2 +- cms/static/sass/_variables.scss | 18 +++- cms/templates/overview.html | 129 +++++++++++++++++++++++++ cms/templates/unit.html | 23 ----- 6 files changed, 314 insertions(+), 64 deletions(-) diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index 4a20980a57..c1e64fb889 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -102,19 +102,19 @@ // alerts .wrapper-alert { - @include clearfix(); @include box-sizing(border-box); - @include transition (opacity 2.0s ease-in-out 5s); - @include box-shadow(0 1px 2px rgba(0,0,0,0.2)); + @include transition (opacity 2.0s ease-in-out 5s, border 0.5s ease-in-out); + @include box-shadow(0 1px 1px $white, inset 0 2px 5px $shadow-d1); position: relative; top: -($baseline*1.5); z-index: 100; overflow: hidden; width: 100%; opacity: 0; - border-bottom: 2px solid $blue-d2; + border-bottom: 4px solid $gray-l1; + border-top: 1px solid $black; padding: $baseline ($baseline*2); - background: $blue; + background: $gray-d3; &.is-shown { bottom: 0; @@ -122,27 +122,95 @@ } &.wrapper-alert-warning { - background: $orange-s1; - border-color: $orange-d1; + border-bottom-color: $orange; + + .icon-warning { + color: $orange; + } + + + &:hover { + border-bottom-color: $orange-s2; + + .icon-warning { + color: $orange-s2; + } + } } &.wrapper-alert-error { - border-color: shade($red, 50%); - color: $white; + border-bottom-color: $red; + + .icon-error { + color: $red; + } + + + &:hover { + border-bottom-color: $red-s2; + + .icon-error { + color: $red-s2; + } + } } - &.wrapper-alert-confirm { - border-color: shade($green, 30%); + &.wrapper-alert-confirmation { + border-bottom-color: $green; + + .icon-confirmation { + color: $green; + } + + + &:hover { + border-bottom-color: $green-s2; + + .icon-confirmation { + color: $green-s2; + } + } } - &.wrapper-alert-inform { - border-color: $blue-d1; + &.wrapper-alert-announcement { + border-bottom-color: $blue; + + .icon-announcement { + color: $blue; + } + + + &:hover { + border-bottom-color: $blue-s2; + + .icon-announcement { + color: $blue-s2; + } + } + } + + &.wrapper-alert-step-required { + border-bottom-color: $pink; + + .icon-step-required { + color: $pink; + } + + + &:hover { + border-bottom-color: $pink-s2; + + .icon-announcement { + color: $pink-s2; + } + } } } .alert { @include font-size(14); @include box-sizing(border-box); + @include clearfix(); margin: 0 auto; width: flex-grid(12); max-width: $fg-max-width; @@ -153,40 +221,47 @@ font-weight: 700; } + .icon, .copy { + float: left; + } + + .icon { + @include transition (color 0.5s ease-in-out); + @include font-size(28); + width: flex-grid(1, 12); + margin-right: flex-gutter(); + text-align: right; + } + .copy { @include font-size(14); + width: flex-grid(10, 12); + color: $gray-l2; - .icon { - @include font-size(24); - @include border-radius(50px); - display: inline-block; - vertical-align: top; - margin-right: ($baseline/2); - padding: ($baseline/4) ($baseline/2) ($baseline/10) ($baseline/2); - } - - p { - width: flex-grid(8, 9); - display: inline-block; - vertical-align: top; + .title { + margin-bottom: 0; + color: $white; } } &.has-actions { + .icon { + width: flex-grid(1, 12); + } + .copy { - float: left; width: flex-grid(8, 12); margin-right: flex-gutter(); } - .actions { - float: right; - width: flex-grid(4, 12); - margin-top: ($baseline/2); + .nav-actions { + width: flex-grid(3, 12); + float: right; + margin-top: ($baseline/2); text-align: right; - li { + .nav-item { display: inline-block; vertical-align: middle; margin-right: ($baseline/2); @@ -200,15 +275,23 @@ // alert types &.warning { - color: $gray-d2; + + } - .copy { + &.error { + + } + + &.confirmation { + + } + + &.announcement { + + } + + &.step-required { - .icon { - background: $gray-d2; - color: $orange-s1; - } - } } } diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index 5d4bc7c773..62f72e8d63 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -50,6 +50,51 @@ h1 { // ==================== +// typography - basic +.title-1, .title-2, .title-3, .title-4, .title-5, .title-6 { + font-weight: 600; + color: $gray-d3; + margin: 0; + padding: 0; +} + +.title-1 { + @include font-size(32); + margin-bottom: ($baseline*1.5); +} + +.title-2 { + @include font-size(24); + margin-bottom: $baseline; +} + +.title-3 { + @include font-size(16); + margin-bottom: ($baseline/2); +} + +.title-4 { + @include font-size(14); + margin-bottom: $baseline; + font-weight: 500 +} + +.title-5 { + @include font-size(14); + color: $gray-l1; + margin-bottom: $baseline; + font-weight: 500 +} + +.title-6 { + @include font-size(14); + color: $gray-l2; + margin-bottom: $baseline; + font-weight: 500 +} + +// ==================== + // layout - basic page header .wrapper-mast { margin: 0; diff --git a/cms/static/sass/_header.scss b/cms/static/sass/_header.scss index 3115711506..53edbd3e9e 100644 --- a/cms/static/sass/_header.scss +++ b/cms/static/sass/_header.scss @@ -5,7 +5,7 @@ margin: 0 0 ($baseline*1.5) 0; padding: $baseline; border-bottom: 1px solid $gray; - @include box-shadow(0 1px 5px 0 rgba(0,0,0, 0.1)); + @include box-shadow(0 1px 5px 0 rgba(0,0,0, 0.2)); background: $white; height: 76px; position: relative; diff --git a/cms/static/sass/_variables.scss b/cms/static/sass/_variables.scss index eb2bd29ebd..907d5cbdb2 100644 --- a/cms/static/sass/_variables.scss +++ b/cms/static/sass/_variables.scss @@ -63,6 +63,23 @@ $pink-u1: desaturate($pink,15%); $pink-u2: desaturate($pink,30%); $pink-u3: desaturate($pink,45%); +$red: rgb(178, 6, 16); +$red-l1: tint($red,20%); +$red-l2: tint($red,40%); +$red-l3: tint($red,60%); +$red-l4: tint($red,80%); +$red-l5: tint($red,90%); +$red-d1: shade($red,20%); +$red-d2: shade($red,40%); +$red-d3: shade($red,60%); +$red-d4: shade($red,80%); +$red-s1: saturate($red,15%); +$red-s2: saturate($red,30%); +$red-s3: saturate($red,45%); +$red-u1: desaturate($red,15%); +$red-u2: desaturate($red,30%); +$red-u3: desaturate($red,45%); + $green: rgb(37, 184, 90); $green-l1: tint($green,20%); $green-l2: tint($green,40%); @@ -123,7 +140,6 @@ $shadow-d1: rgba(0,0,0,0.4); $baseFontColor: #3c3c3c; $offBlack: #3c3c3c; $orange: #edbd3c; -$red: #b20610; $green: #108614; $lightGrey: #edf1f5; $mediumGrey: #b0b6c2; diff --git a/cms/templates/overview.html b/cms/templates/overview.html index 91a1107726..292246676b 100644 --- a/cms/templates/overview.html +++ b/cms/templates/overview.html @@ -106,6 +106,135 @@ <%block name="content"> + +
+
+ + +
+

You are editing a draft

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + +
+
+ + +
+
+ + +
+

Your changes have been saved

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

+
+
+
+ + +
+
+ + +
+

X Has been removed

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+
+
+ + +
+
+ + +
+

We're Sorry, there was a error with Studio

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+
+
+ + +
+
+ + +
+

There was an error in your submission

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

+
+ + +
+
+ + +
+
+ 📢 + +
+

Studio will be unavailable this weekend

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + +
+
+ + +
+
+ 📢 + +
+

Studio will be unavailable this weekend

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+
+
+ + +
+
+ + +
+

Your Studio account has been created, but needs to be activated

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+
+
+

Section Release Date

diff --git a/cms/templates/unit.html b/cms/templates/unit.html index 53be470a50..a95061233b 100644 --- a/cms/templates/unit.html +++ b/cms/templates/unit.html @@ -31,29 +31,6 @@ <%block name="content"> - - -
-
-
- -

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
- - -
-
-
From bb24a079a19939bfbf77202c3ae6d37055b4098c Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Fri, 22 Feb 2013 14:28:13 -0500 Subject: [PATCH 004/299] studio - alerts: initial pass at alert styling and markup complete --- cms/static/sass/_alerts.scss | 92 ++++++++++++-- cms/static/sass/_cms_mixins.scss | 204 ++++++++++++++++++------------- cms/templates/overview.html | 56 +++++++-- common/static/sass/_mixins.scss | 34 ++++++ 4 files changed, 283 insertions(+), 103 deletions(-) diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index c1e64fb889..393539e90d 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -128,7 +128,6 @@ color: $orange; } - &:hover { border-bottom-color: $orange-s2; @@ -139,18 +138,17 @@ } &.wrapper-alert-error { - border-bottom-color: $red; + border-bottom-color: $red-l1; .icon-error { - color: $red; + color: $red-l1; } - &:hover { - border-bottom-color: $red-s2; + border-bottom-color: $red; .icon-error { - color: $red-s2; + color: $red; } } } @@ -162,7 +160,6 @@ color: $green; } - &:hover { border-bottom-color: $green-s2; @@ -179,7 +176,6 @@ color: $blue; } - &:hover { border-bottom-color: $blue-s2; @@ -196,7 +192,6 @@ color: $pink; } - &:hover { border-bottom-color: $pink-s2; @@ -251,12 +246,12 @@ } .copy { - width: flex-grid(8, 12); + width: flex-grid(7, 12); margin-right: flex-gutter(); } .nav-actions { - width: flex-grid(3, 12); + width: flex-grid(4, 12); float: right; margin-top: ($baseline/2); text-align: right; @@ -269,6 +264,21 @@ &:last-child { margin-right: 0; } + + .action-primary { + @include transition (opacity 0.25s ease-in-out); + @include font-size(13); + font-weight: 600; + opacity: 0.90; + + &:hover { + opacity: 1.0; + } + } + + .action-secondary { + @include font-size(13); + } } } } @@ -276,22 +286,82 @@ // alert types &.warning { + .action-primary { + @include orange-button; + border-color: $orange-d2; + } + + a { + color: $orange; + + &:hover { + color: $orange-s2; + } + } } &.error { + .action-primary { + @include red-button; + border-color: $red-d2; + } + + a { + color: $red-l1; + + &:hover { + color: $red; + } + } } &.confirmation { + .action-primary { + @include green-button; + border-color: $green-d2; + } + + a { + color: $green; + + &:hover { + color: $green-s2; + } + } } &.announcement { + .action-primary { + @include blue-button; + border-color: $blue-d2; + } + + a { + color: $blue; + + &:hover { + color: $blue-s2; + } + } } &.step-required { + .action-primary { + border-color: $pink-d2; + @include pink-button; + } + + a { + color: $pink; + + &:hover { + color: $pink-s1; + } + } } } diff --git a/cms/static/sass/_cms_mixins.scss b/cms/static/sass/_cms_mixins.scss index b8d9a8ae2e..bd28702895 100644 --- a/cms/static/sass/_cms_mixins.scss +++ b/cms/static/sass/_cms_mixins.scss @@ -1,26 +1,20 @@ -@mixin clearfix { - &:after { - content: ''; - display: block; - height: 0; - visibility: hidden; - clear: both; - } -} +// studio specific mixins +// ==================== +// buttons @mixin button { display: inline-block; - padding: 4px 20px 6px; - font-size: 14px; + padding: ($baseline/5) $baseline ($baseline/4); + @include font-size(14); font-weight: 700; @include box-shadow(0 1px 0 rgba(255, 255, 255, .3) inset, 0 0 0 rgba(0, 0, 0, 0)); @include transition(background-color .15s, box-shadow .15s); &.disabled { - border: 1px solid $lightGrey !important; + border: 1px solid $gray-l1 !important; border-radius: 3px !important; - background: $lightGrey !important; - color: $darkGrey !important; + background: $gray-l1 !important; + color: $gray-d1 !important; pointer-events: none; cursor: none; &:hover { @@ -33,34 +27,119 @@ } } -@mixin blue-button { +// button - green +@mixin green-button { @include button; - border: 1px solid #437fbf; + border: 1px solid $green-d1; border-radius: 3px; @include linear-gradient(top, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0)); - background-color: $blue; - color: #fff; + background-color: $green; + @include box-shadow(0 1px 0 rgba(255, 255, 255, .3) inset); + color: $white; - &:hover, &.active { - background-color: #62aaf5; - color: #fff; + &:hover { + background-color: $green-s1; + color: $white; + } + + &.disabled { + border: 1px solid $green-l3 !important; + background: $green-l3 !important; + color: $white !important; + @include box-shadow(none); } } -@mixin green-button { - @include button; - border: 1px solid #0d7011; - border-radius: 3px; - @include linear-gradient(top, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0)); - background-color: $green; - color: #fff; +// button - blue +@mixin blue-button { + @include button; + border: 1px solid $blue-d1; + border-radius: 3px; + @include linear-gradient(top, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0)); + background-color: $blue; + color: $white; - &:hover { - background-color: #129416; - color: #fff; - } + &:hover, &.active { + background-color: $blue-s2; + color: $white; + } + + &.disabled { + border: 1px solid $blue-l3 !important; + background: $blue-l3 !important; + color: $white !important; + @include box-shadow(none); + } } +// button - red +@mixin red-button { + @include button; + border: 1px solid $red-d1; + border-radius: 3px; + @include linear-gradient(top, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0)); + background-color: $red; + color: $white; + + &:hover, &.active { + background-color: $red-s1; + color: $white; + } + + &.disabled { + border: 1px solid $red-l3 !important; + background: $red-l3 !important; + color: $white !important; + @include box-shadow(none); + } +} + +// button - pink +@mixin pink-button { + @include button; + border: 1px solid $pink-d1; + border-radius: 3px; + @include linear-gradient(top, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0)); + background-color: $pink; + color: $white; + + &:hover, &.active { + background-color: $pink-s1; + color: $white; + } + + &.disabled { + border: 1px solid $pink-l3 !important; + background: $pink-l3 !important; + color: $white !important; + @include box-shadow(none); + } +} + +// button - orange +@mixin orange-button { + @include button; + border: 1px solid $orange-d1; + border-radius: 3px; + @include linear-gradient(top, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0) 60%); + background-color: $orange; + @include box-shadow(0 1px 0 rgba(255, 255, 255, .3) inset); + color: $gray-d2; + + &:hover { + background-color: $orange-s2; + color: $gray-d2; + } + + &.disabled { + border: 1px solid $orange-l3 !important; + background: $orange-l2 !important; + color: $gray-l1 !important; + @include box-shadow(none); + } +} + +// button - white @mixin white-button { @include button; border: 1px solid $mediumGrey; @@ -77,24 +156,10 @@ } } -@mixin orange-button { - @include button; - border: 1px solid #bda046; - border-radius: 3px; - @include linear-gradient(top, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0) 60%); - background-color: #edbd3c; - @include box-shadow(0 1px 0 rgba(255, 255, 255, .3) inset); - color: #3c3c3c; - - &:hover { - background-color: #ffcd46; - color: #3c3c3c; - } -} - +// button - grey @mixin grey-button { @include button; - border: 1px solid $darkGrey; + border: 1px solid $gray-d2; border-radius: 3px; @include linear-gradient(top, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0)); background-color: #d1dae3; @@ -107,42 +172,25 @@ } } -@mixin green-button { - @include button; - border: 1px solid $darkGreen; - border-radius: 3px; - @include linear-gradient(top, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0)); - background-color: $green; - @include box-shadow(0 1px 0 rgba(255, 255, 255, .3) inset); - color: #fff; - - &:hover { - background-color: $brightGreen; - color: #fff; - } - - &.disabled { - border: 1px solid $disabledGreen !important; - background: $disabledGreen !important; - color: #fff !important; - @include box-shadow(none); - } -} - +// button - grey dark @mixin dark-grey-button { @include button; border: 1px solid #1c1e20; border-radius: 3px; background: -webkit-linear-gradient(top, rgba(255, 255, 255, .2), rgba(255, 255, 255, 0)) $extraDarkGrey; box-shadow: 0 1px 0 rgba(255, 255, 255, .2) inset; - color: #fff; + color: $white; &:hover { background-color: #595f64; - color: #fff; + color: $white; } } + +// ==================== + +// UI @mixin edit-box { padding: 15px 20px; border-radius: 3px; @@ -276,17 +324,9 @@ } } -@mixin sr-text { - border: 0; - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; -} +// ==================== +// sunsetted mixins @mixin active { @include linear-gradient(top, rgba(255, 255, 255, .4), rgba(255, 255, 255, 0)); background-color: rgba(255, 255, 255, .3); diff --git a/cms/templates/overview.html b/cms/templates/overview.html index 292246676b..c3a5a1d743 100644 --- a/cms/templates/overview.html +++ b/cms/templates/overview.html @@ -120,10 +120,34 @@

Alert Actions

+ +
+
+ + +
+
+ + +
+

A Newer Version of This Exists

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + @@ -160,7 +184,7 @@
-

We're Sorry, there was a error with Studio

+

We're sorry, there was a error with Studio

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

@@ -180,10 +204,7 @@

Alert Actions

@@ -204,7 +225,10 @@

Alert Actions

@@ -225,13 +249,25 @@
-
+

Your Studio account has been created, but needs to be activated

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+

Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Curabitur blandit tempus porttitor.

+ +
diff --git a/common/static/sass/_mixins.scss b/common/static/sass/_mixins.scss index 76d52ed930..0c3eee602e 100644 --- a/common/static/sass/_mixins.scss +++ b/common/static/sass/_mixins.scss @@ -8,11 +8,16 @@ font-size: ($sizeValue/10) + rem; } + +// ==================== + // line-height @function lh($amount: 1) { @return $body-line-height * $amount; } +// ==================== + // image-replacement hidden text @mixin text-hide() { text-indent: 100%; @@ -32,6 +37,8 @@ width: 1px; } +// ==================== + // vertical and horizontal centering @mixin vertically-and-horizontally-centered ($height, $width) { left: 50%; @@ -43,6 +50,8 @@ top: 150px; } +// ==================== + // sizing @mixin size($width: $baseline, $height: $baseline) { height: $height; @@ -53,6 +62,8 @@ @include size($size); } +// ==================== + // placeholder styling @mixin placeholder($color) { :-moz-placeholder { @@ -64,4 +75,27 @@ :-ms-input-placeholder { color: $color; } +} + +// utility +@mixin clearfix { + &:after { + content: ''; + display: block; + height: 0; + visibility: hidden; + clear: both; + } +} + +// sunsetted mixins +@mixin sr-text { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } \ No newline at end of file From 60f803f3694e6effdc45c7eb128c8a176f3015e8 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Fri, 22 Feb 2013 14:29:19 -0500 Subject: [PATCH 005/299] studio - alerts: initial pass at alert styling and markup complete --- cms/templates/overview.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/templates/overview.html b/cms/templates/overview.html index c3a5a1d743..bfab97d3a0 100644 --- a/cms/templates/overview.html +++ b/cms/templates/overview.html @@ -384,4 +384,4 @@
- + \ No newline at end of file From b1f5d67a9619b8c3af5db3cd16b867ff1f81585e Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Fri, 22 Feb 2013 14:39:49 -0500 Subject: [PATCH 006/299] studio - alerts: initial pass at alert styling and markup complete --- cms/static/sass/_alerts.scss | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index 393539e90d..9774a5e4ba 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -266,14 +266,8 @@ } .action-primary { - @include transition (opacity 0.25s ease-in-out); @include font-size(13); font-weight: 600; - opacity: 0.90; - - &:hover { - opacity: 1.0; - } } .action-secondary { From 8179b9fadc12e75610b64d9ce40d953755e9f5e9 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Mon, 25 Feb 2013 14:19:22 -0500 Subject: [PATCH 007/299] studio - alerts: initial pass at alert styling and markup complete --- cms/static/js/base.js | 19 + cms/static/sass/_alerts.scss | 297 ++++++++++--- cms/static/sass/_base.scss | 21 +- cms/static/sass/_keyframes.scss | 32 +- cms/static/sass/base-style.scss | 2 +- cms/templates/overview.html | 753 ++++++++++++++++++-------------- 6 files changed, 738 insertions(+), 386 deletions(-) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index d8b32cb0e8..c2080c87f9 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -43,6 +43,25 @@ $(document).ready(function () { $('body').addClass('js'); + // notifications + $('.testing .test-notification').click(function(e) { + (e).preventDefault(); + manageNotification(e); + }); + + function manageNotification(e) { + var $notificationRibbon = $('.wrapper-notification'); + + // showing + $notificationRibbon.toggleClass('is-shown'); + + // controls for closing notification + $notificationRibbon.find('.action-notification-close').click(function(e) { + (e).preventDefault(); + $notificationRibbon.toggleClass('is-shown'); + }); + } + // lean/simple modal $('a[rel*=modal]').leanModal({overlay : 0.80, closeButton: '.action-modal-close' }); $('a.action-modal-close').click(function(e){ diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index 9774a5e4ba..de025e1be2 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -5,17 +5,19 @@ .wrapper-notification { @include clearfix(); @include box-sizing(border-box); - @include transition (bottom 2.0s ease-in-out 5s, opacity 2.0s ease-in-out 5s); - @include box-shadow(0 -1px 2px rgba(0,0,0,0.1)); + // @include transition (bottom 1.5s ease-in-out 0.25s); + transition: bottom 1.5s ease-in-out 0.25s; + -webkit-transition: bottom 1.5s ease-in-out 0.25s; + @include box-shadow(0 -1px 3px $shadow); position: fixed; - bottom: -100px; + bottom: -1000px; z-index: 1000; width: 100%; overflow: hidden; opacity: 0; - border-top: 1px solid $gray-d1; - padding: $baseline ($baseline*2); - background: $white; + border-top: 4px solid $gray-l1; + padding: ($baseline*0.75) ($baseline*2); + background: $gray-d3; &.is-shown { bottom: 0; @@ -23,78 +25,263 @@ } &.wrapper-notification-warning { - border-color: shade($yellow, 25%); - background: tint($yellow, 25%); + border-top-color: $orange; + + .icon-warning { + color: $orange; + } + + &:hover { + border-top-color: $orange-s2; + + .icon-warning { + color: $orange-s2; + } + } } &.wrapper-notification-error { - border-color: shade($red, 50%); - background: tint($red, 20%); - color: $white; + border-top-color: $red-l1; + + .icon-error { + color: $red-l1; + } + + &:hover { + border-top-color: $red; + + .icon-error { + color: $red; + } + } } - &.wrapper-notification-confirm { - border-color: shade($green, 30%); - background: tint($green, 40%); - color: shade($green, 30%); + &.wrapper-notification-confirmation { + border-top-color: $green; + + .icon-error { + color: $green; + } + + &:hover { + border-top-color: $green-s1; + + .icon-error { + color: $green-s1; + } + } + } + + // shorter/status notifications + &.wrapper-notification-status { + width: ($baseline*10); + right: ($baseline); + padding: ($baseline/2) $baseline; + + .notification { + background: red; + @include box-sizing(border-box); + @include clearfix(); + width: 100%; + max-width: none; + min-width: none; + + .icon { + width: auto; + } + + .copy { + width: auto; + } + } } } .notification { @include box-sizing(border-box); + @include clearfix(); margin: 0 auto; width: flex-grid(12); max-width: $fg-max-width; min-width: $fg-min-width; - .copy { + strong { + font-weight: 700; + } + + .icon, .copy { float: left; - width: flex-grid(9, 12); + } + + .icon { + @include transition (color 0.5s ease-in-out); + @include font-size(28); + width: flex-grid(1, 12); margin-right: flex-gutter(); - margin-top: 5px; - font-size: 14px; + text-align: right; + color: $white; + } - .icon { - display: inline-block; - vertical-align: top; - margin-right: 5px; - font-size: 20px; - } + .copy { + @include font-size(13); + width: flex-grid(10, 12); + color: $gray-l2; - p { - width: flex-grid(8, 9); - display: inline-block; - vertical-align: top; + .title { + @include font-size(14); + margin-bottom: 0; + color: $white; } } - .actions { - float: right; - width: flex-grid(3, 12); - margin-top: ($baseline/2); - text-align: right; + // with cancel + .action-notification-close { + @include transition(top .25s ease-in-out); + @include border-bottom-radius(3px); + position: absolute; + top: -($baseline/4); + left: ($baseline/2); + padding: ($baseline/4) ($baseline/2) 0 ($baseline/2); + background: $gray-d2; + text-align: center; - li { - display: inline-block; - vertical-align: middle; - margin-right: 10px; + .label { + @include text-sr(); + } - &:last-child { - margin-right: 0; + .ss-icon { + @include font-size(14); + color: $white; + } + + &:hover { + background: $blue; + top: 0; + } + } + + // with actions + &.has-actions { + + .icon { + width: flex-grid(1, 12); + } + + .copy { + width: flex-grid(7, 12); + margin-right: flex-gutter(); + } + + .nav-actions { + width: flex-grid(4, 12); + float: right; + margin-top: ($baseline/2); + text-align: right; + + .nav-item { + display: inline-block; + vertical-align: middle; + margin-right: ($baseline/2); + + &:last-child { + margin-right: 0; + } + + .action-primary { + @include font-size(13); + font-weight: 600; + } + + .action-secondary { + @include font-size(13); + } + } + } + } + + // notification types + &.warning { + + .action-notification-close { + + &:hover { + background: $orange; } } - .save-button { - @include blue-button; + .action-primary { + @include orange-button; + border-color: $orange-d2; } - .cancel-button { - @include white-button; + a { + color: $orange; + + &:hover { + color: $orange-s2; + } } } - strong { - font-weight: 700; + &.error { + + .action-notification-close { + + &:hover { + background: $red-l1; + } + } + + .action-primary { + @include red-button; + border-color: $red-d2; + } + + a { + color: $red-l1; + + &:hover { + color: $red; + } + } + } + + &.confirmation { + + .action-notification-close { + + &:hover { + background: $green; + } + } + + .action-primary { + @include green-button; + border-color: $green-d2; + } + + a { + color: $green; + + &:hover { + color: $green-s2; + } + } + } + + &.announcement { + + .action-notification-close { + + &:hover { + background: $blue; + } + } + + .action-primary { + @include blue-button; + border-color: $blue-d2; + } } } @@ -103,10 +290,9 @@ // alerts .wrapper-alert { @include box-sizing(border-box); - @include transition (opacity 2.0s ease-in-out 5s, border 0.5s ease-in-out); - @include box-shadow(0 1px 1px $white, inset 0 2px 5px $shadow-d1); + @include box-shadow(0 1px 1px $white, inset 0 2px 2px $shadow-d1); position: relative; - top: -($baseline*1.5); + top: -($baseline*20); z-index: 100; overflow: hidden; width: 100%; @@ -117,7 +303,6 @@ background: $gray-d3; &.is-shown { - bottom: 0; opacity: 1.0; } @@ -222,14 +407,14 @@ .icon { @include transition (color 0.5s ease-in-out); - @include font-size(28); + @include font-size(22); width: flex-grid(1, 12); margin-right: flex-gutter(); text-align: right; } .copy { - @include font-size(14); + @include font-size(13); width: flex-grid(10, 12); color: $gray-l2; @@ -332,14 +517,6 @@ @include blue-button; border-color: $blue-d2; } - - a { - color: $blue; - - &:hover { - color: $blue-s2; - } - } } &.step-required { diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index 62f72e8d63..d2cdda443f 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -25,7 +25,7 @@ a { @include transition(color .15s); &:hover { - color: #cb9c40; + color: $orange-d1; } } @@ -885,7 +885,7 @@ body.js { // ==================== -// works in progress +// works in progress & testing body.hide-wip { .wip-box { @@ -893,6 +893,23 @@ body.hide-wip { } } +.wrapper-testing { + background: $black; + width: 100%; + height: auto; + + .testing { + @include font-size(14); + position: relative; + max-width: $fg-max-width; + min-width: $fg-min-width; + width: flex-grid(12); + margin: 0 auto $baseline auto; + padding: $baseline; + color: $white; + } +} + // ==================== // needed fudges for now diff --git a/cms/static/sass/_keyframes.scss b/cms/static/sass/_keyframes.scss index 7661f18980..394548a2e7 100644 --- a/cms/static/sass/_keyframes.scss +++ b/cms/static/sass/_keyframes.scss @@ -1,3 +1,33 @@ +// studio animations & keyframes +// ==================== + +// rotate clockwise +@mixin rotateClockwise { + 0% { + @include transform(rotate(0deg)); + } + + 25% { + @include transform(rotate(90deg)); + } + + 50% { + @include transform(rotate(180deg)); + } + + 100% { + @include transform(rotate(360deg)); + } +} + +@-moz-keyframes rotateClockwise { @include rotateClockwise(); } +@-webkit-keyframes rotateClockwise { @include rotateClockwise(); } +@-o-keyframes rotateClockwise { @include rotateClockwise(); } +@keyframes rotateClockwise { @include rotateClockwise();} + +// ==================== + +// bounce in @mixin bounce-in { 0% { opacity: 0; @@ -24,4 +54,4 @@ @include animation-duration($duration); @include animation-timing-function($timing); @include animation-fill-mode(both); -} +} \ No newline at end of file diff --git a/cms/static/sass/base-style.scss b/cms/static/sass/base-style.scss index dceac4233d..075e0e87a5 100644 --- a/cms/static/sass/base-style.scss +++ b/cms/static/sass/base-style.scss @@ -1,5 +1,6 @@ @import 'bourbon/bourbon'; @import 'bourbon/addons/button'; +@import "variables"; @import 'vendor/normalize'; @import 'keyframes'; @@ -7,7 +8,6 @@ @import 'mixins'; @import "fonts"; -@import "variables"; @import "cms_mixins"; @import "extends"; @import "base"; diff --git a/cms/templates/overview.html b/cms/templates/overview.html index bfab97d3a0..2950280702 100644 --- a/cms/templates/overview.html +++ b/cms/templates/overview.html @@ -13,375 +13,484 @@ <%namespace name="units" file="widgets/units.html" /> <%block name="jsextra"> - - - - - - - - + + + + + + + + - + $(".gradable-status").each(function(index, ele) { + var gradeView = new CMS.Views.OverviewAssignmentGrader({ + el : ele, + graders : window.graderTypes + }); + }); +}); + + <%block name="header_extras"> - - - - - + + + + + + + <%block name="content"> - -
-
- + +
+
+ -
+

You are editing a draft

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
- - +

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+ +
+
- -
-
- + +
+
+ -
+

A Newer Version of This Exists

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
- + +
+
+ + +
+
+ + +
+

Your changes have been saved

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

+
- -
-
- + +
+
+ -
-

Your changes have been saved

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

-
+
+

X Has been removed

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
- -
-
- + +
+
+ -
-

X Has been removed

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
+
+

We're sorry, there was a error with Studio

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
- -
-
- + +
+
+ -
-

We're sorry, there was a error with Studio

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
+
+

There was an error in your submission

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

+
+ + +
+
+ + +
+
+ 📢 + +
+

Studio will be unavailable this weekend

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + +
+
+ + +
+
+ 📢 + +
+

Studio will be unavailable this weekend

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
- -
-
- + +
+
+ -
-

There was an error in your submission

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

-
- - +
+

Your Studio account has been created, but needs to be activated

+

Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Curabitur blandit tempus porttitor.

+ +
+
- -
-
- 📢 - -
-

Studio will be unavailable this weekend

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
- - -
-
- - -
-
- 📢 - -
-

Studio will be unavailable this weekend

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+
+

Section Release Date

+
+ + +
+

On the date set above, this section – – will be released to students. Any units marked private will only be visible to admins.

+ SaveCancel
+
- -
-
- +
+ +
-
-

Your Studio account has been created, but needs to be activated

-

Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Curabitur blandit tempus porttitor.

-
- - +
+
+
+ Course Content +

Course Outline

-
-
-
-

Section Release Date

-
- - -
-

On the date set above, this section – – will be released to students. Any units marked private will only be visible to admins.

-
-
- SaveCancel -
-
+ + +
-
-
-
- Course Content -

Course Outline

-
+
+
+
- -
-
-
- % for section in sections: -
-
- - -
-

- ${section.display_name} - -

- -
- -
- - -
-
-
- -
    - % for subsection in section.get_children(): - - % endfor -
+
+

+ ${section.display_name} + +

+
-
- % endfor -
+ +
+ + +
+
+
+ +
    + % for subsection in section.get_children(): + + % endfor +
+
+ + % endfor + +
+
+
+ + +
+
+ 📝 + +
+

You've Made Some Changes

+

Note: Your changes will not take effect until you save your progress.

+
+ + +
+
+ + +
+
+ + +
+

A Newer Version of This Exists

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + + + + + close notification + +
+
+ + +
+
+ + +
+

Are You Sure You Want to Edit That?

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + +
+
+ + +
+
+ + +
+

Saving

+

Hamster wheels are turning pretty fast right now. Hang on! Saving will be done soon.

-
+
+ + +
+
+ + +
+

Fun Fact:

+

Using the checkmark will allow you make a subsection gradable as an assignment, which counts towards a student's total grade

+
+
+
\ No newline at end of file From d809df913daf3f5d83753922d8f157c94ff217d8 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Mon, 25 Feb 2013 14:45:27 -0500 Subject: [PATCH 008/299] studio - alerts: moved all states and documentation into new /alerts view --- cms/djangoapps/contentstore/views.py | 3 + cms/static/sass/_alerts.scss | 18 +- cms/static/sass/_base.scss | 27 +++ cms/templates/alerts.html | 326 +++++++++++++++++++++++++++ cms/templates/overview.html | 273 ---------------------- cms/urls.py | 1 + 6 files changed, 374 insertions(+), 274 deletions(-) create mode 100644 cms/templates/alerts.html diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 6d5905afe7..2e30751d30 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -106,6 +106,9 @@ def howitworks(request): else: return render_to_response('howitworks.html', {}) +def alerts(request): + return render_to_response('alerts.html', {}) + # ==== Views for any logged-in user ================================== @login_required diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index de025e1be2..d211d0d2ed 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -292,7 +292,7 @@ @include box-sizing(border-box); @include box-shadow(0 1px 1px $white, inset 0 2px 2px $shadow-d1); position: relative; - top: -($baseline*20); + top: -($baseline*1.5); z-index: 100; overflow: hidden; width: 100%; @@ -536,6 +536,22 @@ } } +// temporary +body.uxdesign.alerts { + + .content-primary, .content-supplementary { + @include box-sizing(border-box); + float: left; + } + + .content-primary { + @extend .window; + width: flex-grid(12, 12); + margin-right: flex-gutter(); + padding: $baseline ($baseline*1.5); + } +} + // artifact styles // .alert { // padding: 15px 20px; diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index d2cdda443f..0d01a0b24b 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -339,11 +339,38 @@ h1 { .title-5 { } + + > section { + margin: 0 0 $baseline 0; + + header { + @include clearfix(); + + .title-2 { + width: flex-grid(5, 12); + margin: 0 flex-gutter() 0 0; + float: left; + } + + .tip { + @include font-size(13); + width: flex-grid(7, 12); + float: right; + margin-top: ($baseline/2); + text-align: right; + color: $gray-l2; + } + } + } } // layout - supplemental content .content-supplementary { + > section { + margin: 0 0 $baseline 0; + } + .bit { @include font-size(13); margin: 0 0 $baseline 0; diff --git a/cms/templates/alerts.html b/cms/templates/alerts.html new file mode 100644 index 0000000000..efdac8e761 --- /dev/null +++ b/cms/templates/alerts.html @@ -0,0 +1,326 @@ +<%inherit file="base.html" /> +<%block name="title">Studio Alerts +<%block name="bodyclass">is-signedin course uxdesign alerts + +<%block name="content"> + +
+
+ + +
+

You are editing a draft

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + +
+
+ + +
+
+ + +
+

A Newer Version of This Exists

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + +
+
+ + +
+
+ + +
+

Your changes have been saved

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

+
+
+
+ + +
+
+ + +
+

X Has been removed

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+
+
+ + +
+
+ + +
+

We're sorry, there was a error with Studio

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+
+
+ + +
+
+ + +
+

There was an error in your submission

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

+
+ + +
+
+ + +
+
+ 📢 + +
+

Studio will be unavailable this weekend

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + +
+
+ + +
+
+ 📢 + +
+

Studio will be unavailable this weekend

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+
+
+ + +
+
+ + +
+

Your Studio account has been created, but needs to be activated

+

Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Curabitur blandit tempus porttitor.

+
+ + +
+
+ +
+
+

Section Release Date

+
+ + +
+

On the date set above, this section – – will be released to students. Any units marked private will only be visible to admins.

+
+
+ SaveCancel +
+
+ +
+ +
+ +
+
+
+ UX Design +

Alerts & Notifications

+
+
+
+ +
+
+
+
+
+

Alerts

+ persistant, static messages to the user +
+ +

In Studio, alerts are 1) general warnings/notes (e.g. drafts, published content, next steps) about the current view a user is interacting with or 2) notes about the status (e.g. saved confirmations, errors, next system steps) of any previous state that need to communicated to the user when arriving at the current view.

+
+ +
+
+

Notifications

+ contextual, feedback-based, and temporal messages to the user +
+ +

In Studio, notifications are meant to inform the user of 1) any system status (e.g. saving, processing/validating) occurring based on any action they have taken or 2) any decisions (e.g. saving/discarding) a user must make to confirm.

+
+
+
+
+ + +
+
+ 📝 + +
+

You've Made Some Changes

+

Note: Your changes will not take effect until you save your progress.

+
+ + +
+
+ + +
+
+ + +
+

A Newer Version of This Exists

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + + + + + close notification + +
+
+ + +
+
+ + +
+

Are You Sure You Want to Edit That?

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

+
+ + +
+
+ + +
+
+ + +
+

Saving

+

Hamster wheels are turning pretty fast right now. Hang on! Saving will be done soon.

+
+
+
+ + +
+
+ + +
+

Fun Fact:

+

Using the checkmark will allow you make a subsection gradable as an assignment, which counts towards a student's total grade

+
+
+
+ \ No newline at end of file diff --git a/cms/templates/overview.html b/cms/templates/overview.html index 2950280702..1792cbc844 100644 --- a/cms/templates/overview.html +++ b/cms/templates/overview.html @@ -106,171 +106,6 @@ $(document).ready(function(){ <%block name="content"> - -
-
- - -
-

You are editing a draft

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
- - -
-
- - -
-
- - -
-

A Newer Version of This Exists

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
- - -
-
- - -
-
- - -
-

Your changes have been saved

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

-
-
-
- - -
-
- - -
-

X Has been removed

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
-
-
- - -
-
- - -
-

We're sorry, there was a error with Studio

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
-
-
- - -
-
- - -
-

There was an error in your submission

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

-
- - -
-
- - -
-
- 📢 - -
-

Studio will be unavailable this weekend

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
- - -
-
- - -
-
- 📢 - -
-

Studio will be unavailable this weekend

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
-
-
- - -
-
- - -
-

Your Studio account has been created, but needs to be activated

-

Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Curabitur blandit tempus porttitor.

-
- - -
-
-

Section Release Date

@@ -285,14 +120,6 @@ $(document).ready(function(){
-
- -
-
@@ -393,104 +220,4 @@ $(document).ready(function(){
- -
-
- 📝 - -
-

You've Made Some Changes

-

Note: Your changes will not take effect until you save your progress.

-
- - -
-
- - -
-
- - -
-

A Newer Version of This Exists

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
- - - - - - close notification - -
-
- - -
-
- - -
-

Are You Sure You Want to Edit That?

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

-
- - -
-
- - -
-
- - -
-

Saving

-

Hamster wheels are turning pretty fast right now. Hang on! Saving will be done soon.

-
-
-
- - -
-
- - -
-

Fun Fact:

-

Using the checkmark will allow you make a subsection gradable as an assignment, which counts towards a student's total grade

-
-
-
\ No newline at end of file diff --git a/cms/urls.py b/cms/urls.py index 35b2707241..5c8bd42b10 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -78,6 +78,7 @@ urlpatterns = ('', # User creation and updating views urlpatterns += ( + url(r'^alerts$', 'contentstore.views.alerts', name='alerts'), url(r'^howitworks$', 'contentstore.views.howitworks', name='howitworks'), url(r'^signup$', 'contentstore.views.signup', name='signup'), From 95ea01689f2a0ed955a173192191da8f8040f973 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Mon, 25 Feb 2013 16:30:36 -0500 Subject: [PATCH 009/299] studio - alerts: firmed up status-based notifications --- cms/static/sass/_alerts.scss | 62 +++++++++++++++++++++++---------- cms/static/sass/_base.scss | 40 ++++++++------------- cms/static/sass/_keyframes.scss | 8 ----- cms/templates/alerts.html | 57 ++++++++++++++++++------------ 4 files changed, 93 insertions(+), 74 deletions(-) diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index d211d0d2ed..8e5401112b 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -10,20 +10,12 @@ -webkit-transition: bottom 1.5s ease-in-out 0.25s; @include box-shadow(0 -1px 3px $shadow); position: fixed; - bottom: -1000px; z-index: 1000; width: 100%; - overflow: hidden; - opacity: 0; border-top: 4px solid $gray-l1; padding: ($baseline*0.75) ($baseline*2); background: $gray-d3; - &.is-shown { - bottom: 0; - opacity: 1.0; - } - &.wrapper-notification-warning { border-top-color: $orange; @@ -74,12 +66,11 @@ // shorter/status notifications &.wrapper-notification-status { - width: ($baseline*10); + width: ($baseline*12.5); right: ($baseline); padding: ($baseline/2) $baseline; .notification { - background: red; @include box-sizing(border-box); @include clearfix(); width: 100%; @@ -87,11 +78,19 @@ min-width: none; .icon { - width: auto; + width: $baseline; + margin-right: ($baseline*0.75); } .copy { - width: auto; + width: ($baseline*9); + + p { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + width: 100%; + } } } } @@ -115,7 +114,7 @@ .icon { @include transition (color 0.5s ease-in-out); - @include font-size(28); + @include font-size(22); width: flex-grid(1, 12); margin-right: flex-gutter(); text-align: right; @@ -283,6 +282,16 @@ border-color: $blue-d2; } } + + &.saving { + + .icon-saving { + @include animation(rotateClockwise 3.0s forwards linear infinite); + width: 22px; + height: 25px; + line-height: 3rem !important; + } + } } // ==================== @@ -296,16 +305,11 @@ z-index: 100; overflow: hidden; width: 100%; - opacity: 0; border-bottom: 4px solid $gray-l1; border-top: 1px solid $black; padding: $baseline ($baseline*2); background: $gray-d3; - &.is-shown { - opacity: 1.0; - } - &.wrapper-alert-warning { border-bottom-color: $orange; @@ -536,6 +540,28 @@ } } +// js enabled +.js { + + .wrapper-alert { + display: none; + + &.is-shown { + display: block; + } + } + + .wrapper-notification { + bottom: -1000px; + opacity: 0; + + &.is-shown { + bottom: 0; + opacity: 1.0; + } + } +} + // temporary body.uxdesign.alerts { diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index 0d01a0b24b..d5a8adc6cb 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -69,7 +69,7 @@ h1 { } .title-3 { - @include font-size(16); + @include font-size(18); margin-bottom: ($baseline/2); } @@ -93,6 +93,14 @@ h1 { font-weight: 500 } +p, ul, ol, dl { + margin-bottom: ($baseline/2); + + &:last-child { + margin-bottom: 0; + } +} + // ==================== // layout - basic page header @@ -316,32 +324,12 @@ h1 { color: $gray-d3; } - .title-1 { - - } - - .title-2 { - @include font-size(24); - margin: 0 0 ($baseline/2) 0; - font-weight: 600; - } - - .title-3 { - @include font-size(16); - margin: 0 0 ($baseline/4) 0; - font-weight: 500; - } - - .title-4 { - - } - - .title-5 { - - } - > section { - margin: 0 0 $baseline 0; + margin: 0 0 ($baseline*2) 0; + + &:last-child { + margin-bottom: 0; + } header { @include clearfix(); diff --git a/cms/static/sass/_keyframes.scss b/cms/static/sass/_keyframes.scss index 394548a2e7..0ae1d78ffe 100644 --- a/cms/static/sass/_keyframes.scss +++ b/cms/static/sass/_keyframes.scss @@ -7,14 +7,6 @@ @include transform(rotate(0deg)); } - 25% { - @include transform(rotate(90deg)); - } - - 50% { - @include transform(rotate(180deg)); - } - 100% { @include transform(rotate(360deg)); } diff --git a/cms/templates/alerts.html b/cms/templates/alerts.html index efdac8e761..869bad7260 100644 --- a/cms/templates/alerts.html +++ b/cms/templates/alerts.html @@ -4,7 +4,7 @@ <%block name="content"> -
+
@@ -28,7 +28,7 @@
-
+
@@ -52,7 +52,7 @@
-
+
@@ -64,7 +64,7 @@
-
+
@@ -76,7 +76,7 @@
-
+
@@ -88,7 +88,7 @@
-
+
@@ -109,7 +109,7 @@
-
+
📢 @@ -133,7 +133,7 @@
-
+
📢 @@ -145,7 +145,7 @@
-
+
@@ -182,14 +182,6 @@
-
- -
-
@@ -209,6 +201,17 @@

In Studio, alerts are 1) general warnings/notes (e.g. drafts, published content, next steps) about the current view a user is interacting with or 2) notes about the status (e.g. saved confirmations, errors, next system steps) of any previous state that need to communicated to the user when arriving at the current view.

+ +

Different Static Examples of Alerts

+

Note: alerts will probably never been shown based on click or page action and will primarily be loaded along with a pageload and initial display

+ +
@@ -218,13 +221,23 @@

In Studio, notifications are meant to inform the user of 1) any system status (e.g. saving, processing/validating) occurring based on any action they have taken or 2) any decisions (e.g. saving/discarding) a user must make to confirm.

+ +

Different Static Examples of Notifications

+ +
-
+
📝 @@ -248,7 +261,7 @@
-
+
@@ -277,7 +290,7 @@
-
+
@@ -301,7 +314,7 @@
-
+
@@ -313,7 +326,7 @@
-
+
From 0926395445cf20e15edfd4b0f80e1359994e1ac8 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Tue, 26 Feb 2013 12:32:20 -0500 Subject: [PATCH 010/299] studio - alerts: added in close buttons and basic JS to control them/moved demo JS to alerts.html page --- cms/static/js/base.js | 35 ++++----- cms/static/sass/_alerts.scss | 137 +++++++++++++++++++++++++---------- cms/templates/alerts.html | 79 ++++++++++++++++---- 3 files changed, 179 insertions(+), 72 deletions(-) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index c2080c87f9..21571a8f4a 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -43,31 +43,28 @@ $(document).ready(function () { $('body').addClass('js'); - // notifications - $('.testing .test-notification').click(function(e) { - (e).preventDefault(); - manageNotification(e); - }); - - function manageNotification(e) { - var $notificationRibbon = $('.wrapper-notification'); - - // showing - $notificationRibbon.toggleClass('is-shown'); - - // controls for closing notification - $notificationRibbon.find('.action-notification-close').click(function(e) { - (e).preventDefault(); - $notificationRibbon.toggleClass('is-shown'); - }); - } - // lean/simple modal $('a[rel*=modal]').leanModal({overlay : 0.80, closeButton: '.action-modal-close' }); $('a.action-modal-close').click(function(e){ (e).preventDefault(); }); + // alert and notifications - manual close + $('.action-alert-close').click(function(e) { + (e).preventDefault(); + console.log('closing alert'); + $(this).closest('.wrapper-alert').removeClass('is-shown'); + }); + + // alert and notifications - manual close + $('.action-notification-close').click(function(e) { + (e).preventDefault(); + $(this).closest('.wrapper-notification').removeClass('is-shown'); + }); + + + + // nav - dropdown related $body.click(function (e) { $('.nav-dropdown .nav-item .wrapper-nav-sub').removeClass('is-shown'); diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index 8e5401112b..5b9a08b0ea 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -5,9 +5,8 @@ .wrapper-notification { @include clearfix(); @include box-sizing(border-box); - // @include transition (bottom 1.5s ease-in-out 0.25s); - transition: bottom 1.5s ease-in-out 0.25s; - -webkit-transition: bottom 1.5s ease-in-out 0.25s; + transition: bottom 1.0s ease-in-out 0.125s; + -webkit-transition: bottom 1.0s ease-in-out 0.125s; @include box-shadow(0 -1px 3px $shadow); position: fixed; z-index: 1000; @@ -66,8 +65,9 @@ // shorter/status notifications &.wrapper-notification-status { - width: ($baseline*12.5); + width: ($baseline*6); right: ($baseline); + border-top-color: $pink; padding: ($baseline/2) $baseline; .notification { @@ -94,6 +94,30 @@ } } } + + // shorter/status notifications + &.wrapper-notification-help { + width: ($baseline*14); + right: ($baseline); + padding: ($baseline/2) $baseline; + + .notification { + @include box-sizing(border-box); + @include clearfix(); + width: 100%; + max-width: none; + min-width: none; + + .icon-help { + width: $baseline; + margin-right: ($baseline*0.75); + } + + .copy { + width: ($baseline*11); + } + } + } } .notification { @@ -135,27 +159,24 @@ // with cancel .action-notification-close { - @include transition(top .25s ease-in-out); - @include border-bottom-radius(3px); + @include border-top-radius(3px); position: absolute; - top: -($baseline/4); - left: ($baseline/2); + top: -31px; + right: $baseline; padding: ($baseline/4) ($baseline/2) 0 ($baseline/2); - background: $gray-d2; + background: $gray-l1; text-align: center; .label { @include text-sr(); } - .ss-icon { + .icon { @include font-size(14); color: $white; - } - - &:hover { - background: $blue; - top: 0; + width: auto; + margin: 0; + padding: 2px; } } @@ -185,31 +206,35 @@ &:last-child { margin-right: 0; } - - .action-primary { - @include font-size(13); - font-weight: 600; - } - - .action-secondary { - @include font-size(13); - } } } + + .action-primary { + @include blue-button(); + @include font-size(13); + border-color: $blue-d2; + font-weight: 600; + } + + .action-secondary { + @include font-size(13); + } } // notification types &.warning { .action-notification-close { + background: $orange; &:hover { - background: $orange; + background: $orange-s2; } } .action-primary { - @include orange-button; + @include orange-button(); + @include font-size(13); border-color: $orange-d2; } @@ -225,14 +250,16 @@ &.error { .action-notification-close { + background: $red-l1; &:hover { - background: $red-l1; + background: $red; } } .action-primary { - @include red-button; + @include red-button(); + @include font-size(13); border-color: $red-d2; } @@ -248,14 +275,16 @@ &.confirmation { .action-notification-close { + background: $green; &:hover { - background: $green; + background: $green-s2; } } .action-primary { - @include green-button; + @include green-button(); + @include font-size(13); border-color: $green-d2; } @@ -271,14 +300,16 @@ &.announcement { .action-notification-close { + background: $blue; &:hover { - background: $blue; + background: $blue-s1; } } .action-primary { - @include blue-button; + @include blue-button(); + @include font-size(13); border-color: $blue-d2; } } @@ -291,6 +322,10 @@ height: 25px; line-height: 3rem !important; } + + .copy p { + @include text-sr(); + } } } @@ -428,6 +463,7 @@ } } + // with actions &.has-actions { .icon { @@ -466,11 +502,38 @@ } } + // with cancel + .action-alert-close { + @include border-bottom-radius(3px); + position: absolute; + top: -($baseline/10); + right: $baseline; + padding: ($baseline/4) ($baseline/2) 0 ($baseline/2); + background: $gray-d1; + text-align: center; + + .label { + @include text-sr(); + } + + .icon { + @include font-size(14); + color: $white; + width: auto; + margin: 0; + padding: 2px; + } + + &:hover { + background: $gray-l1; + } + } + // alert types &.warning { .action-primary { - @include orange-button; + @include orange-button(); border-color: $orange-d2; } @@ -486,7 +549,7 @@ &.error { .action-primary { - @include red-button; + @include red-button(); border-color: $red-d2; } @@ -502,7 +565,7 @@ &.confirmation { .action-primary { - @include green-button; + @include green-button(); border-color: $green-d2; } @@ -518,7 +581,7 @@ &.announcement { .action-primary { - @include blue-button; + @include blue-button(); border-color: $blue-d2; } } @@ -527,7 +590,7 @@ .action-primary { border-color: $pink-d2; - @include pink-button; + @include pink-button(); } a { diff --git a/cms/templates/alerts.html b/cms/templates/alerts.html index 869bad7260..a783a6f2fe 100644 --- a/cms/templates/alerts.html +++ b/cms/templates/alerts.html @@ -2,6 +2,26 @@ <%block name="title">Studio Alerts <%block name="bodyclass">is-signedin course uxdesign alerts +<%block name="jsextra"> + + + <%block name="content">
@@ -63,6 +83,23 @@
+ +
+
+ + +
+

Your changes have been saved

+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Please see below

+
+ + + + close alert + +
+
+
@@ -206,11 +243,16 @@

Note: alerts will probably never been shown based on click or page action and will primarily be loaded along with a pageload and initial display

@@ -225,11 +267,11 @@

Different Static Examples of Notifications

@@ -243,7 +285,7 @@

You've Made Some Changes

-

Note: Your changes will not take effect until you save your progress.

+

Your changes will not take effect until you save your progress.

-
+
@@ -325,15 +367,20 @@
- -
-
- + +
+
+

Fun Fact:

Using the checkmark will allow you make a subsection gradable as an assignment, which counts towards a student's total grade

+ + + + close notification +
\ No newline at end of file From d09927e8ddf9be8640fcae31541f0e761e737db7 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Tue, 26 Feb 2013 12:38:46 -0500 Subject: [PATCH 011/299] studio - alerts: small styling tweaks for the close button on help notifications --- cms/static/sass/_alerts.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index 5b9a08b0ea..5364e637d7 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -113,8 +113,12 @@ margin-right: ($baseline*0.75); } + .action-notification-close { + right: 0; + } + .copy { - width: ($baseline*11); + width: ($baseline*10); } } } From cb456ad22875b8eac9e9b7e552158e40e702ad97 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Wed, 27 Feb 2013 12:45:44 -0500 Subject: [PATCH 012/299] studio - alerts: converted transition-based animation to keyframe/css animation and added in a demo for a fleeting notification --- cms/static/js/base.js | 9 ++--- cms/static/sass/_alerts.scss | 62 ++++++++++++++++++++------------- cms/static/sass/_keyframes.scss | 44 +++++++++++++++++++++++ cms/static/sass/_variables.scss | 4 +++ cms/templates/alerts.html | 21 ++++++++--- 5 files changed, 105 insertions(+), 35 deletions(-) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index 21571a8f4a..0bb0ae10f1 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -50,21 +50,18 @@ $(document).ready(function () { }); // alert and notifications - manual close - $('.action-alert-close').click(function(e) { + $('.action-alert-close, .alert.has-actions .nav-actions a').click(function(e) { (e).preventDefault(); console.log('closing alert'); $(this).closest('.wrapper-alert').removeClass('is-shown'); }); - // alert and notifications - manual close - $('.action-notification-close').click(function(e) { + // alert and notifications - manual & action-based close + $('.action-notification-close, .notification.has-actions .nav-actions a').click(function(e) { (e).preventDefault(); $(this).closest('.wrapper-notification').removeClass('is-shown'); }); - - - // nav - dropdown related $body.click(function (e) { $('.nav-dropdown .nav-item .wrapper-nav-sub').removeClass('is-shown'); diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index 5364e637d7..a582c5cfcf 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -5,10 +5,9 @@ .wrapper-notification { @include clearfix(); @include box-sizing(border-box); - transition: bottom 1.0s ease-in-out 0.125s; - -webkit-transition: bottom 1.0s ease-in-out 0.125s; @include box-shadow(0 -1px 3px $shadow); position: fixed; + bottom: 0; z-index: 1000; width: 100%; border-top: 4px solid $gray-l1; @@ -31,7 +30,7 @@ } } - &.wrapper-notification-error { + &.wrapper-cation-error { border-top-color: $red-l1; .icon-error { @@ -50,24 +49,31 @@ &.wrapper-notification-confirmation { border-top-color: $green; - .icon-error { + .icon-confirmation { color: $green; } &:hover { border-top-color: $green-s1; - .icon-error { + .icon-confirmation { color: $green-s1; } } } + &.wrapper-notification-saving { + border-top-color: $pink; + + &:hover { + border-top-color: $pink-s1; + } + } + // shorter/status notifications &.wrapper-notification-status { - width: ($baseline*6); + width: ($baseline*8); right: ($baseline); - border-top-color: $pink; padding: ($baseline/2) $baseline; .notification { @@ -77,25 +83,26 @@ max-width: none; min-width: none; + .icon, .copy { + float: none; + display: inline-block; + vertical-align: middle; + } + .icon { width: $baseline; + height: ($baseline*1.25); margin-right: ($baseline*0.75); + line-height: 3rem; } .copy { - width: ($baseline*9); - p { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - width: 100%; - } } - } + } } - // shorter/status notifications + // help notifications &.wrapper-notification-help { width: ($baseline*14); right: ($baseline); @@ -138,12 +145,15 @@ .icon, .copy { float: left; + display: inline-block; + vertical-align: middle; } .icon { @include transition (color 0.5s ease-in-out); @include font-size(22); width: flex-grid(1, 12); + height: ($baseline*1.25); margin-right: flex-gutter(); text-align: right; color: $white; @@ -165,9 +175,9 @@ .action-notification-close { @include border-top-radius(3px); position: absolute; - top: -31px; + top: -34px; right: $baseline; - padding: ($baseline/4) ($baseline/2) 0 ($baseline/2); + padding: ($baseline/5) ($baseline/2.5) 0 ($baseline/2.5); background: $gray-l1; text-align: center; @@ -278,6 +288,10 @@ &.confirmation { + .copy { + margin-top: ($baseline/5); + } + .action-notification-close { background: $green; @@ -323,8 +337,6 @@ .icon-saving { @include animation(rotateClockwise 3.0s forwards linear infinite); width: 22px; - height: 25px; - line-height: 3rem !important; } .copy p { @@ -619,12 +631,14 @@ } .wrapper-notification { - bottom: -1000px; - opacity: 0; + bottom: -($notification-height); &.is-shown { - bottom: 0; - opacity: 1.0; + @include animation(notificationsSlideUp 2s forwards ease-in-out 1); + } + + &.is-fleeting.is-shown { + @include animation(notificationsSlideUpDown 6s forwards ease-in-out 1); } } } diff --git a/cms/static/sass/_keyframes.scss b/cms/static/sass/_keyframes.scss index 0ae1d78ffe..a13891160a 100644 --- a/cms/static/sass/_keyframes.scss +++ b/cms/static/sass/_keyframes.scss @@ -19,6 +19,50 @@ // ==================== +// notifications slide up +@mixin notificationsSlideUp { + 0% { + @include transform(translateY(0)); + } + + 90% { + @include transform(translateY(-($notification-height))); + } + + 100% { + @include transform(translateY(-($notification-height*0.99))); + } +} + +@-moz-keyframes notificationsSlideUp { @include notificationsSlideUp(); } +@-webkit-keyframes notificationsSlideUp { @include notificationsSlideUp(); } +@-o-keyframes notificationsSlideUp { @include notificationsSlideUp(); } +@keyframes notificationsSlideUp { @include notificationsSlideUp();} + +// ==================== + +// notifications slide up +@mixin notificationsSlideUpDown { + 0%, 100% { + @include transform(translateY(0)); + } + + 15%, 85% { + @include transform(translateY(-($notification-height))); + } + + 20%, 80% { + @include transform(translateY(-($notification-height*0.99))); + } +} + +@-moz-keyframes notificationsSlideUpDown { @include notificationsSlideUpDown(); } +@-webkit-keyframes notificationsSlideUpDown { @include notificationsSlideUpDown(); } +@-o-keyframes notificationsSlideUpDown { @include notificationsSlideUpDown(); } +@keyframes notificationsSlideUpDown { @include notificationsSlideUpDown();} + +// ==================== + // bounce in @mixin bounce-in { 0% { diff --git a/cms/static/sass/_variables.scss b/cms/static/sass/_variables.scss index 907d5cbdb2..b89fa7cc18 100644 --- a/cms/static/sass/_variables.scss +++ b/cms/static/sass/_variables.scss @@ -136,6 +136,10 @@ $shadow-l1: rgba(0,0,0,0.1); $shadow-l2: rgba(0,0,0,0.05); $shadow-d1: rgba(0,0,0,0.4); + +// specific UI +$notification-height: ($baseline*10); + // colors - inherited $baseFontColor: #3c3c3c; $offBlack: #3c3c3c; diff --git a/cms/templates/alerts.html b/cms/templates/alerts.html index a783a6f2fe..3682cb3200 100644 --- a/cms/templates/alerts.html +++ b/cms/templates/alerts.html @@ -250,8 +250,8 @@
  • Toggle Previous View/Action Removed Alert
  • Toggle System Error Alert
  • Toggle User Error Alert
  • -
  • Toggle Announcement Alert
  • -
  • Toggle Announcement with Actions Alert
  • +
  • Toggle Announcement Alert
  • +
  • Toggle Announcement with Actions Alert
  • Toggle Activiation Alert
  • @@ -270,6 +270,7 @@
  • Toggle Change Warning Notification
  • Toggle New Version Warning Notification
  • Toggle Editing Warning Notification
  • +
  • Toggle Confirmation Notification
  • Toggle Saving Notification
  • Toggle Help Notification
  • @@ -356,13 +357,23 @@
    -
    +
    -

    Saving

    -

    Hamster wheels are turning pretty fast right now. Hang on! Saving will be done soon.

    +

    Saving …

    +
    +
    +
    + + +
    +
    + + +
    +

    Your Section Has Been Created

    From ad70581b80635999ebb610c26abbb2371c738888 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Fri, 1 Mar 2013 15:43:07 -0500 Subject: [PATCH 013/299] studio - alerts: more progress including prompts --- cms/static/js/base.js | 8 +- cms/static/sass/_alerts.scss | 82 +++++++++++++++++++- cms/static/sass/_keyframes.scss | 24 +++++- cms/static/sass/_variables.scss | 6 ++ cms/templates/alerts.html | 129 ++++++++++++++++++++++++++------ 5 files changed, 222 insertions(+), 27 deletions(-) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index 0bb0ae10f1..9af785045f 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -59,7 +59,13 @@ $(document).ready(function () { // alert and notifications - manual & action-based close $('.action-notification-close, .notification.has-actions .nav-actions a').click(function(e) { (e).preventDefault(); - $(this).closest('.wrapper-notification').removeClass('is-shown'); + $(this).closest('.wrapper-notification').removeClass('is-shown').addClass('is-hiding'); + }); + + // prompt close + $('.prompt .action-cancel').click(function(e) { + (e).preventDefault(); + $(this).closest('.wrapper-prompt').removeClass('is-shown').addClass('is-hiding'); }); // nav - dropdown related diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index a582c5cfcf..fc8b25ea2c 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -1,6 +1,43 @@ // studio alerts and notifications // ==================== +// prompts +.wrapper-prompt { + position: fixed; + top: 0; + background: $black-t1; + width: 100%; + height: 100%; + text-align: center; + z-index: 100; + + &:before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; + margin-right: -0.25em; /* Adjusts for spacing */ + } + + .prompt { + @include border-radius(3px); + @include box-sizing(border-box); + @include box-shadow(0 0 4px $shadow-d1); + display: inline-block; + vertical-align: middle; + width: $baseline*15; + padding: $baseline; + background: $white; + + .nav-actions { + + .nav-item { + + } + } + } +} + // notifications .wrapper-notification { @include clearfix(); @@ -622,6 +659,17 @@ // js enabled .js { + .wrapper-prompt { + @include transition (opacity 0.25s ease-in-out); + display: none; + opacity: 0; + + &.is-shown { + display: block; + opacity: 1.0; + } + } + .wrapper-alert { display: none; @@ -633,12 +681,17 @@ .wrapper-notification { bottom: -($notification-height); + // varying animations &.is-shown { - @include animation(notificationsSlideUp 2s forwards ease-in-out 1); + @include animation(notificationsSlideUp 1s forwards ease-in-out 1); } - &.is-fleeting.is-shown { - @include animation(notificationsSlideUpDown 6s forwards ease-in-out 1); + &.is-hiding { + @include animation(notificationsSlideDown 1s forwards ease-in-out 1); + } + + &.is-fleeting { + @include animation(notificationsSlideUpDown 2s forwards ease-in-out 1); } } } @@ -656,6 +709,29 @@ body.uxdesign.alerts { width: flex-grid(12, 12); margin-right: flex-gutter(); padding: $baseline ($baseline*1.5); + + ul { + + li { + @include clearfix(); + width: flex-grid(12, 12); + margin-bottom: ($baseline/4); + border-bottom: 1px solid $gray-l4; + padding-bottom: ($baseline/4); + + &:last-child { + margin-bottom: 0; + border-bottom: none; + padding-bottom: 0; + } + + a { + float: left; + width: flex-grid(5, 12); + margin-right: flex-gutter(); + } + } + } } } diff --git a/cms/static/sass/_keyframes.scss b/cms/static/sass/_keyframes.scss index a13891160a..372fb9e0ca 100644 --- a/cms/static/sass/_keyframes.scss +++ b/cms/static/sass/_keyframes.scss @@ -41,7 +41,29 @@ // ==================== -// notifications slide up +// notifications slide down +@mixin notificationsSlideDown { + 0% { + @include transform(translateY(-($notification-height*0.99))); + } + + 10% { + @include transform(translateY(-($notification-height))); + } + + 100% { + @include transform(translateY(0)); + } +} + +@-moz-keyframes notificationsSlideDown { @include notificationsSlideDown(); } +@-webkit-keyframes notificationsSlideDown { @include notificationsSlideDown(); } +@-o-keyframes notificationsSlideDown { @include notificationsSlideDown(); } +@keyframes notificationsSlideDown { @include notificationsSlideDown();} + +// ==================== + +// notifications slide up then down @mixin notificationsSlideUpDown { 0%, 100% { @include transform(translateY(0)); diff --git a/cms/static/sass/_variables.scss b/cms/static/sass/_variables.scss index b89fa7cc18..35f39fcd3a 100644 --- a/cms/static/sass/_variables.scss +++ b/cms/static/sass/_variables.scss @@ -16,7 +16,13 @@ $error-red: rgb(253, 87, 87); // colors - new for re-org $black: rgb(0,0,0); +$black-t1: rgba(0,0,0,0.25); +$black-t2: rgba(0,0,0,0.50); +$black-t3: rgba(0,0,0,0.75); $white: rgb(255,255,255); +$white-t1: rgba(255,255,255,0.25); +$white-t2: rgba(255,255,255,0.50); +$white-t3: rgba(255,255,255,0.75); $gray: rgb(127,127,127); $gray-l1: tint($gray,20%); diff --git a/cms/templates/alerts.html b/cms/templates/alerts.html index 3682cb3200..9b5ba70411 100644 --- a/cms/templates/alerts.html +++ b/cms/templates/alerts.html @@ -7,16 +7,46 @@ // notifications - demo $(document).ready(function() { - $('.test-notification').click(function(e) { + $('.hide-notification').click(function(e) { (e).preventDefault(); - $('.wrapper-notification').removeClass('is-shown'); - $(this.hash).toggleClass('is-shown'); + $('.wrapper-notification').removeClass('is-hiding is-shown'); + $(this.hash).addClass('is-hiding'); }); - $('.test-alert').click(function(e) { + $('.show-notification').click(function(e) { + (e).preventDefault(); + $('.wrapper-notification').removeClass('is-shown is-hiding'); + $(this.hash).addClass('is-shown'); + }); + + $('.show-notification-fleeting').click(function(e) { + (e).preventDefault(); + $('.wrapper-notification').removeClass('is-fleeting'); + $(this.hash).addClass('is-fleeting'); + }); + + $('.hide-alert').click(function(e) { + (e).preventDefault(); + $('.wrapper-alert').removeClass('is-hiding'); + $(this.hash).addClass('is-hiding'); + }); + + $('.show-alert').click(function(e) { (e).preventDefault(); $('.wrapper-alert').removeClass('is-shown'); - $(this.hash).toggleClass('is-shown'); + $(this.hash).addClass('is-shown'); + }); + + $('.hide-prompt').click(function(e) { + (e).preventDefault(); + $('.wrapper-prompt').removeClass('is-hiding is-shown'); + $(this.hash).addClass('is-hiding'); + }); + + $('.show-prompt').click(function(e) { + (e).preventDefault(); + $('.wrapper-prompt').removeClass('is-shown is-hiding'); + $(this.hash).addClass('is-shown'); }); }); @@ -243,16 +273,16 @@

    Note: alerts will probably never been shown based on click or page action and will primarily be loaded along with a pageload and initial display

    @@ -267,12 +297,46 @@

    Different Static Examples of Notifications

    + + +
    +
    +

    Prompts

    + presents a user with a choice, based on their previous interaction, that must be decided before they can proceed +
    + +

    In Studio, prompts are dialogs that are presented above all other page components and present a user with a choice, based on their previous interaction, that must be decided before they can proceed (or return to the previous interaction step).

    + +

    Different Static Examples of Notifications

    + +
    @@ -368,7 +432,7 @@
    -
    +
    @@ -394,4 +458,25 @@
    + + +
    +
    +
    +

    Are You Sure You Want to Do That?

    +
    + + +
    +
    \ No newline at end of file From 2ce4ecbc8481964e18d4cba475ba37b84f05a9db Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Fri, 1 Mar 2013 15:48:15 -0500 Subject: [PATCH 014/299] local merge with master - finished --- cms/templates/overview.html | 288 ++++++++++++++++-------------------- 1 file changed, 128 insertions(+), 160 deletions(-) diff --git a/cms/templates/overview.html b/cms/templates/overview.html index ec35e4864f..27fd208e0d 100644 --- a/cms/templates/overview.html +++ b/cms/templates/overview.html @@ -13,144 +13,145 @@ <%namespace name="units" file="widgets/units.html" /> <%block name="jsextra"> - - - - - - - - + + + + + + + + - + + <%block name="header_extras"> - + + + + - - - - +
      +
    1. + + New Unit + +
    2. +
    + + <%block name="content"> -
    -
    -

    Section Release Date

    -
    - - -
    -

    On the date set above, this section – – will be released to students. Any units marked private will only be visible to admins.

    +
    +
    +

    Section Release Date

    +
    + + +
    +

    On the date set above, this section – – will be released to students. Any units marked private will only be visible to admins.

    +
    + SaveCancel
    - SaveCancel
    -
    -
    -
    -
    - Course Content -

    Course Outline

    -
    +
    +
    +
    + Course Content +

    Course Outline

    +
    - -
    -
    + +
    +
    + +
    +
    +
    + % for section in sections: +
    +
    + -
    -
    -
    - % for section in sections: -
    -
    -

    ${section.display_name} @@ -211,44 +212,11 @@ $(document).ready(function(){ % endfor -

    -
    -
    - -
      - % for subsection in section.get_children(): - - % endfor -
    -
    -
    - % endfor -
    +
    + % endfor +
    +
    -
    -
    - +
    From bc0b1b09580a6b154ecc48ae1ba852cf0b41ff7e Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Sat, 2 Mar 2013 22:06:55 -0500 Subject: [PATCH 015/299] studio - alerts: cleaned up animation standards and made mixins to reference as well as got prompt UI pattern behavior working --- cms/static/sass/_alerts.scss | 30 ++++++++--- cms/static/sass/_keyframes.scss | 95 ++++++++++++++++++++++++++++++--- 2 files changed, 109 insertions(+), 16 deletions(-) diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index 9a2ebf1854..a152db636a 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -9,7 +9,7 @@ width: 100%; height: 100%; text-align: center; - z-index: 100; + z-index: 10000; &:before { content: ''; @@ -372,7 +372,8 @@ &.saving { .icon-saving { - @include animation(rotateClockwise 3.0s forwards linear infinite); + @include anim-rotateClockwise(3s, linear, infinite); + width: 22px; } @@ -661,13 +662,26 @@ .js { .wrapper-prompt { - @include transition (opacity 0.25s ease-in-out); display: none; - opacity: 0; + + .prompt { + @include anim-bounceIn(0.5s); + opacity: 0.1; + } &.is-shown { display: block; - opacity: 1.0; + + .prompt { + opacity: 1.0; + } + } + + &.is-hiding { + + .prompt { + @include anim-bounceOut(0.5s); + } } } @@ -684,15 +698,15 @@ // varying animations &.is-shown { - @include animation(notificationsSlideUp 1s forwards ease-in-out 1); + @include anim-notificationsSlideUp(1s); } &.is-hiding { - @include animation(notificationsSlideDown 1s forwards ease-in-out 1); + @include anim-notificationsSlideDown(1s); } &.is-fleeting { - @include animation(notificationsSlideUpDown 2s forwards ease-in-out 1); + @include anim-notificationsSlideUpDown(2s); } } } diff --git a/cms/static/sass/_keyframes.scss b/cms/static/sass/_keyframes.scss index 372fb9e0ca..817dc27132 100644 --- a/cms/static/sass/_keyframes.scss +++ b/cms/static/sass/_keyframes.scss @@ -17,6 +17,14 @@ @-o-keyframes rotateClockwise { @include rotateClockwise(); } @keyframes rotateClockwise { @include rotateClockwise();} +@mixin anim-rotateClockwise($duration, $timing: ease-in-out, $count: 1) { + @include animation-name(rotateClockwise); + @include animation-duration($duration); + @include animation-timing-function($timing); + @include animation-fill-mode(both); + @include animation-iteration-count($count); +} + // ==================== // notifications slide up @@ -39,6 +47,14 @@ @-o-keyframes notificationsSlideUp { @include notificationsSlideUp(); } @keyframes notificationsSlideUp { @include notificationsSlideUp();} +@mixin anim-notificationsSlideUp($duration, $timing: ease-in-out, $count: 1) { + @include animation-name(notificationsSlideUp); + @include animation-duration($duration); + @include animation-timing-function($timing); + @include animation-fill-mode(both); + @include animation-iteration-count($count); +} + // ==================== // notifications slide down @@ -61,6 +77,14 @@ @-o-keyframes notificationsSlideDown { @include notificationsSlideDown(); } @keyframes notificationsSlideDown { @include notificationsSlideDown();} +@mixin anim-notificationsSlideDown($duration, $timing: ease-in-out, $count: 1) { + @include animation-name(notificationsSlideDown); + @include animation-duration($duration); + @include animation-timing-function($timing); + @include animation-fill-mode(both); + @include animation-iteration-count($count); +} + // ==================== // notifications slide up then down @@ -83,13 +107,21 @@ @-o-keyframes notificationsSlideUpDown { @include notificationsSlideUpDown(); } @keyframes notificationsSlideUpDown { @include notificationsSlideUpDown();} +@mixin anim-notificationsSlideUpDown($duration, $timing: ease-in-out, $count: 1) { + @include animation-name(notificationsSlideUpDown); + @include animation-duration($duration); + @include animation-timing-function($timing); + @include animation-fill-mode(both); + @include animation-iteration-count($count); +} + // ==================== // bounce in -@mixin bounce-in { +@mixin bounceIn { 0% { opacity: 0; - @include transform(scale(.3)); + @include transform(scale(0.3)); } 50% { @@ -102,14 +134,61 @@ } } -@-moz-keyframes bounce-in { @include bounce-in(); } -@-webkit-keyframes bounce-in { @include bounce-in(); } -@-o-keyframes bounce-in { @include bounce-in(); } -@keyframes bounce-in { @include bounce-in();} +@-moz-keyframes bounceIn { @include bounceIn(); } +@-webkit-keyframes bounceIn { @include bounceIn(); } +@-o-keyframes bounceIn { @include bounceIn(); } +@keyframes bounceIn { @include bounceIn();} -@mixin bounce-in-animation($duration, $timing: ease-in-out) { - @include animation-name(bounce-in); +@mixin anim-bounceIn($duration, $timing: ease-in-out, $count: 1) { + @include animation-name(bounceIn); @include animation-duration($duration); @include animation-timing-function($timing); @include animation-fill-mode(both); + @include animation-iteration-count($count); +} + +// ==================== + +// bounce in +@mixin bounceOut { + 0% { + opacity: 0; + @include transform(scale(0.3)); + } + + 50% { + opacity: 1; + @include transform(scale(1.05)); + } + + 100% { + @include transform(scale(1)); + } + + 0% { + @include transform(scale(1)); + } + + 50% { + opacity: 1; + @include transform(scale(1.05)); + } + + 100% { + opacity: 0; + @include transform(scale(0.3)); + } +} + +@-moz-keyframes bounceOut { @include bounceOut(); } +@-webkit-keyframes bounceOut { @include bounceOut(); } +@-o-keyframes bounceOut { @include bounceOut(); } +@keyframes bounceOut { @include bounceOut();} + +@mixin anim-bounceOut($duration, $timing: ease-in-out, $count: 1) { + @include animation-name(bounceOut); + @include animation-duration($duration); + @include animation-timing-function($timing); + @include animation-fill-mode(both); + @include animation-iteration-count($count); } \ No newline at end of file From 72c58cd454e65f282d0b7d93f0b454f73fdafdc8 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Sun, 3 Mar 2013 20:44:48 -0500 Subject: [PATCH 016/299] studio - alerts: refactored styles for common content types across UI, got prompts set up and styled, and refactored base template for future prompt/notification/alert use --- cms/static/js/base.js | 12 +- cms/static/sass/_alerts.scss | 296 +++++++++++++++----------------- cms/static/sass/_base.scss | 7 + cms/static/sass/_keyframes.scss | 32 ++-- cms/static/sass/_variables.scss | 2 + cms/templates/alerts.html | 295 ++++++++++++++++++------------- cms/templates/base.html | 39 +++-- 7 files changed, 375 insertions(+), 308 deletions(-) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index 9af785045f..a6e8190e17 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -62,10 +62,16 @@ $(document).ready(function () { $(this).closest('.wrapper-notification').removeClass('is-shown').addClass('is-hiding'); }); - // prompt close - $('.prompt .action-cancel').click(function(e) { + // prompt pop + $('.action-prompt').click(function(e){ (e).preventDefault(); - $(this).closest('.wrapper-prompt').removeClass('is-shown').addClass('is-hiding'); + $body.toggleClass('prompt-is-shown'); + }); + + // prompt close + $('.prompt .action-cancel, .prompt .action-proceed').click(function(e) { + (e).preventDefault(); + $body.removeClass('prompt-is-shown'); }); // nav - dropdown related diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index a152db636a..c507034284 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -1,11 +1,35 @@ // studio alerts and notifications // ==================== +// shared +.wrapper-notification, .wrapper-alert, .prompt { + @include box-sizing(border-box); + background: $gray-d3; + border-top: 4px solid $gray-d4; + + .copy { + @include font-size(13); + color: $gray-l2; + + .title { + color: $white; + } + + .nav-actions { + + .action-primary { + color: $gray-d4; + } + } + } +} + // prompts .wrapper-prompt { + @include transition(all 0.05s ease-in-out); position: fixed; top: 0; - background: $black-t1; + background: $black-t0; width: 100%; height: 100%; text-align: center; @@ -20,20 +44,80 @@ } .prompt { - @include border-radius(3px); - @include box-sizing(border-box); - @include box-shadow(0 0 4px $shadow-d1); + @include border-radius(($baseline/5)); + @include box-shadow(0 0 3px $shadow-d1); display: inline-block; vertical-align: middle; - width: $baseline*15; - padding: $baseline; - background: $white; + width: $baseline*17.5; + border: 4px solid $black; + text-align: left; + + .copy { + border-top: 4px solid $blue; + padding: $baseline; + } .nav-actions { + @include box-shadow(inset 0 1px 2px $shadow-d1); + border-top: 1px solid $black-t1; + padding: ($baseline*0.75) $baseline; + background: $gray-d4; .nav-item { + display: inline-block; + margin-right: ($baseline*0.75); + &:last-child { + margin-right: 0; + } } + + .action-primary { + @include blue-button(); + @include font-size(13); + border-color: $blue-d2; + font-weight: 600; + } + + .action-secondary { + @include font-size(13); + } + } + } + + // types of prompts - error + .prompt.error { + + .icon-error { + color: $red-l1; + } + + .copy { + border-top-color: $red-l1; + } + } + + // types of prompts - confirmation + .prompt.confirmation { + + .icon-error { + color: $green; + } + + .copy { + border-top-color: $green; + } + } + + // types of prompts - error + .prompt.warning { + + .icon-warning { + color: $orange; + } + + .copy { + border-top-color: $orange; } } } @@ -41,15 +125,12 @@ // notifications .wrapper-notification { @include clearfix(); - @include box-sizing(border-box); @include box-shadow(0 -1px 3px $shadow); position: fixed; bottom: 0; z-index: 1000; width: 100%; - border-top: 4px solid $gray-l1; padding: ($baseline*0.75) ($baseline*2); - background: $gray-d3; &.wrapper-notification-warning { border-top-color: $orange; @@ -67,7 +148,7 @@ } } - &.wrapper-cation-error { + &.wrapper-notification-error { border-top-color: $red-l1; .icon-error { @@ -208,29 +289,6 @@ } } - // with cancel - .action-notification-close { - @include border-top-radius(3px); - position: absolute; - top: -34px; - right: $baseline; - padding: ($baseline/5) ($baseline/2.5) 0 ($baseline/2.5); - background: $gray-l1; - text-align: center; - - .label { - @include text-sr(); - } - - .icon { - @include font-size(14); - color: $white; - width: auto; - margin: 0; - padding: 2px; - } - } - // with actions &.has-actions { @@ -272,108 +330,17 @@ } } - // notification types - &.warning { - - .action-notification-close { - background: $orange; - - &:hover { - background: $orange-s2; - } - } - - .action-primary { - @include orange-button(); - @include font-size(13); - border-color: $orange-d2; - } - - a { - color: $orange; - - &:hover { - color: $orange-s2; - } - } - } - - &.error { - - .action-notification-close { - background: $red-l1; - - &:hover { - background: $red; - } - } - - .action-primary { - @include red-button(); - @include font-size(13); - border-color: $red-d2; - } - - a { - color: $red-l1; - - &:hover { - color: $red; - } - } - } - &.confirmation { .copy { margin-top: ($baseline/5); } - - .action-notification-close { - background: $green; - - &:hover { - background: $green-s2; - } - } - - .action-primary { - @include green-button(); - @include font-size(13); - border-color: $green-d2; - } - - a { - color: $green; - - &:hover { - color: $green-s2; - } - } - } - - &.announcement { - - .action-notification-close { - background: $blue; - - &:hover { - background: $blue-s1; - } - } - - .action-primary { - @include blue-button(); - @include font-size(13); - border-color: $blue-d2; - } } &.saving { .icon-saving { @include anim-rotateClockwise(3s, linear, infinite); - width: 22px; } @@ -559,12 +526,12 @@ // with cancel .action-alert-close { - @include border-bottom-radius(3px); + @include border-bottom-radius(($baseline/5)); position: absolute; top: -($baseline/10); right: $baseline; padding: ($baseline/4) ($baseline/2) 0 ($baseline/2); - background: $gray-d1; + background: $gray-d4; text-align: center; .label { @@ -580,16 +547,20 @@ } &:hover { - background: $gray-l1; + background: $gray-d1; } } +} - // alert types +.alert, .notification, .prompt { + + // types - warning &.warning { - - .action-primary { + + .nav-actions .action-primary { @include orange-button(); border-color: $orange-d2; + color: $gray-d4; } a { @@ -601,9 +572,10 @@ } } + // types - error &.error { - .action-primary { + .nav-actions .action-primary { @include red-button(); border-color: $red-d2; } @@ -617,9 +589,27 @@ } } + // types - announcement + &.announcement { + + .nav-actions .action-primary { + @include blue-button(); + border-color: $blue-d2; + } + + a { + color: $blue; + + &:hover { + color: $blue-s2; + } + } + } + + // types - confirmation &.confirmation { - .action-primary { + .nav-actions .action-primary { @include green-button(); border-color: $green-d2; } @@ -633,17 +623,10 @@ } } - &.announcement { - - .action-primary { - @include blue-button(); - border-color: $blue-d2; - } - } - + // types - step required &.step-required { - .action-primary { + .nav-actions .action-primary { border-color: $pink-d2; @include pink-button(); } @@ -661,28 +644,33 @@ // js enabled .js { + // prompt set-up .wrapper-prompt { - display: none; + visibility: hidden; + pointer-events: none; .prompt { - @include anim-bounceIn(0.5s); - opacity: 0.1; + opacity: 0; + } + } + + // prompt showing + &.prompt-is-shown { + + .wrapper-view { + -webkit-filter: blur(2px) grayscale(25%); + filter: blur(2px) grayscale(25%); } - &.is-shown { - display: block; + .wrapper-prompt.is-shown { + visibility: visible; + pointer-events: auto; .prompt { + @include anim-bounceIn(0.5s); opacity: 1.0; } } - - &.is-hiding { - - .prompt { - @include anim-bounceOut(0.5s); - } - } } .wrapper-alert { diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index d5a8adc6cb..5fd05d27a6 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -103,6 +103,13 @@ p, ul, ol, dl { // ==================== +// layout - basic +.wrapper-view { + +} + +// ==================== + // layout - basic page header .wrapper-mast { margin: 0; diff --git a/cms/static/sass/_keyframes.scss b/cms/static/sass/_keyframes.scss index 817dc27132..a756f66b2e 100644 --- a/cms/static/sass/_keyframes.scss +++ b/cms/static/sass/_keyframes.scss @@ -17,12 +17,14 @@ @-o-keyframes rotateClockwise { @include rotateClockwise(); } @keyframes rotateClockwise { @include rotateClockwise();} -@mixin anim-rotateClockwise($duration, $timing: ease-in-out, $count: 1) { +@mixin anim-rotateClockwise($duration, $timing: ease-in-out, $count: 1, $delay: 0) { @include animation-name(rotateClockwise); @include animation-duration($duration); + @include animation-delay($delay); @include animation-timing-function($timing); - @include animation-fill-mode(both); @include animation-iteration-count($count); + @include animation-fill-mode(both); + } // ==================== @@ -47,12 +49,14 @@ @-o-keyframes notificationsSlideUp { @include notificationsSlideUp(); } @keyframes notificationsSlideUp { @include notificationsSlideUp();} -@mixin anim-notificationsSlideUp($duration, $timing: ease-in-out, $count: 1) { +@mixin anim-notificationsSlideUp($duration, $timing: ease-in-out, $count: 1, $delay: 0) { @include animation-name(notificationsSlideUp); @include animation-duration($duration); + @include animation-delay($delay); @include animation-timing-function($timing); - @include animation-fill-mode(both); @include animation-iteration-count($count); + @include animation-fill-mode(both); + } // ==================== @@ -77,12 +81,13 @@ @-o-keyframes notificationsSlideDown { @include notificationsSlideDown(); } @keyframes notificationsSlideDown { @include notificationsSlideDown();} -@mixin anim-notificationsSlideDown($duration, $timing: ease-in-out, $count: 1) { +@mixin anim-notificationsSlideDown($duration, $timing: ease-in-out, $count: 1, $delay: 0) { @include animation-name(notificationsSlideDown); @include animation-duration($duration); + @include animation-delay($delay); @include animation-timing-function($timing); - @include animation-fill-mode(both); @include animation-iteration-count($count); + @include animation-fill-mode(both); } // ==================== @@ -107,12 +112,13 @@ @-o-keyframes notificationsSlideUpDown { @include notificationsSlideUpDown(); } @keyframes notificationsSlideUpDown { @include notificationsSlideUpDown();} -@mixin anim-notificationsSlideUpDown($duration, $timing: ease-in-out, $count: 1) { +@mixin anim-notificationsSlideUpDown($duration, $timing: ease-in-out, $count: 1, $delay: 0) { @include animation-name(notificationsSlideUpDown); @include animation-duration($duration); + @include animation-delay($delay); @include animation-timing-function($timing); - @include animation-fill-mode(both); @include animation-iteration-count($count); + @include animation-fill-mode(both); } // ==================== @@ -139,12 +145,13 @@ @-o-keyframes bounceIn { @include bounceIn(); } @keyframes bounceIn { @include bounceIn();} -@mixin anim-bounceIn($duration, $timing: ease-in-out, $count: 1) { +@mixin anim-bounceIn($duration, $timing: ease-in-out, $count: 1, $delay: 0) { @include animation-name(bounceIn); @include animation-duration($duration); + @include animation-delay($delay); @include animation-timing-function($timing); - @include animation-fill-mode(both); @include animation-iteration-count($count); + @include animation-fill-mode(both); } // ==================== @@ -185,10 +192,11 @@ @-o-keyframes bounceOut { @include bounceOut(); } @keyframes bounceOut { @include bounceOut();} -@mixin anim-bounceOut($duration, $timing: ease-in-out, $count: 1) { +@mixin anim-bounceOut($duration, $timing: ease-in-out, $count: 1, $delay: 0) { @include animation-name(bounceOut); @include animation-duration($duration); + @include animation-delay($delay); @include animation-timing-function($timing); - @include animation-fill-mode(both); @include animation-iteration-count($count); + @include animation-fill-mode(both); } \ No newline at end of file diff --git a/cms/static/sass/_variables.scss b/cms/static/sass/_variables.scss index 35f39fcd3a..7998d0b199 100644 --- a/cms/static/sass/_variables.scss +++ b/cms/static/sass/_variables.scss @@ -16,10 +16,12 @@ $error-red: rgb(253, 87, 87); // colors - new for re-org $black: rgb(0,0,0); +$black-t0: rgba(0,0,0,0.125); $black-t1: rgba(0,0,0,0.25); $black-t2: rgba(0,0,0,0.50); $black-t3: rgba(0,0,0,0.75); $white: rgb(255,255,255); +$white-t0: rgba(255,255,255,0.125); $white-t1: rgba(255,255,255,0.25); $white-t2: rgba(255,255,255,0.50); $white-t3: rgba(255,255,255,0.75); diff --git a/cms/templates/alerts.html b/cms/templates/alerts.html index 9b5ba70411..12c605d863 100644 --- a/cms/templates/alerts.html +++ b/cms/templates/alerts.html @@ -37,15 +37,15 @@ $(this.hash).addClass('is-shown'); }); - $('.hide-prompt').click(function(e) { - (e).preventDefault(); - $('.wrapper-prompt').removeClass('is-hiding is-shown'); - $(this.hash).addClass('is-hiding'); + $('.hide-prompt').click(function(e){ + (e).preventDefault(); + $body.removeClass('prompt-is-shown'); }); $('.show-prompt').click(function(e) { - (e).preventDefault(); - $('.wrapper-prompt').removeClass('is-shown is-hiding'); + (e).preventDefault(); + $body.toggleClass('prompt-is-shown'); + $('.wrapper-prompt').removeClass('is-shown'); $(this.hash).addClass('is-shown'); }); }); @@ -53,6 +53,122 @@ <%block name="content"> +
    +
    +

    Section Release Date

    +
    + + +
    +

    On the date set above, this section – – will be released to students. Any units marked private will only be visible to admins.

    +
    +
    + SaveCancel +
    +
    + +
    +
    +
    + UX Design +

    Alerts & Notifications

    +
    +
    +
    + +
    +
    +
    +
    +
    +

    Alerts

    + persistant, static messages to the user +
    + +

    In Studio, alerts are 1) general warnings/notes (e.g. drafts, published content, next steps) about the current view a user is interacting with or 2) notes about the status (e.g. saved confirmations, errors, next system steps) of any previous state that need to communicated to the user when arriving at the current view.

    + +

    Different Static Examples of Alerts

    +

    Note: alerts will probably never been shown based on click or page action and will primarily be loaded along with a pageload and initial display

    + + +
    + +
    +
    +

    Notifications

    + contextual, feedback-based, and temporal messages to the user +
    + +

    In Studio, notifications are meant to inform the user of 1) any system status (e.g. saving, processing/validating) occurring based on any action they have taken or 2) any decisions (e.g. saving/discarding) a user must make to confirm.

    + +

    Different Static Examples of Notifications

    + + +
    + +
    +
    +

    Prompts

    + presents a user with a choice, based on their previous interaction, that must be decided before they can proceed +
    + +

    In Studio, prompts are dialogs that are presented above all other page components and present a user with a choice, based on their previous interaction, that must be decided before they can proceed (or return to the previous interaction step).

    + +

    Different Static Examples of Prompts

    + + +
    +
    +
    +
    + + +<%block name="view_alerts">
    @@ -234,115 +350,9 @@
    + -
    -
    -

    Section Release Date

    -
    - - -
    -

    On the date set above, this section – – will be released to students. Any units marked private will only be visible to admins.

    -
    -
    - SaveCancel -
    -
    - -
    -
    -
    - UX Design -

    Alerts & Notifications

    -
    -
    -
    - -
    -
    -
    -
    -
    -

    Alerts

    - persistant, static messages to the user -
    - -

    In Studio, alerts are 1) general warnings/notes (e.g. drafts, published content, next steps) about the current view a user is interacting with or 2) notes about the status (e.g. saved confirmations, errors, next system steps) of any previous state that need to communicated to the user when arriving at the current view.

    - -

    Different Static Examples of Alerts

    -

    Note: alerts will probably never been shown based on click or page action and will primarily be loaded along with a pageload and initial display

    - - -
    - -
    -
    -

    Notifications

    - contextual, feedback-based, and temporal messages to the user -
    - -

    In Studio, notifications are meant to inform the user of 1) any system status (e.g. saving, processing/validating) occurring based on any action they have taken or 2) any decisions (e.g. saving/discarding) a user must make to confirm.

    - -

    Different Static Examples of Notifications

    - - -
    - -
    -
    -

    Prompts

    - presents a user with a choice, based on their previous interaction, that must be decided before they can proceed -
    - -

    In Studio, prompts are dialogs that are presented above all other page components and present a user with a choice, based on their previous interaction, that must be decided before they can proceed (or return to the previous interaction step).

    - -

    Different Static Examples of Notifications

    - - -
    -
    -
    -
    - +<%block name="view_notifications">
    @@ -388,11 +398,6 @@ - - - - close notification -
    @@ -458,22 +463,66 @@
    + - +<%block name="view_prompts"> +
    -

    Are You Sure You Want to Do That?

    +

    Delete "Introduction & Overview"?

    +

    Deleting a section cannot be undone and its contents cannot be recovered.

    +
    +
    + + +
    +
    +
    +

    Use Advanced Problem Editor?

    +

    If you proceed, you cannot edit this problem using the simple problem editor.

    +
    + + +
    +
    + + +
    +
    +
    +

    There Were Errors in Your Submission

    +

    Please correct the errors noted on the page and try again.

    +
    + + diff --git a/cms/templates/base.html b/cms/templates/base.html index 498897bd11..387b45a0d1 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -6,12 +6,12 @@ - <%block name="title"></%block> | - % if context_course: - <% ctx_loc = context_course.location %> - ${context_course.display_name} | - % endif - edX Studio + <%block name="title"></%block> | + % if context_course: + <% ctx_loc = context_course.location %> + ${context_course.display_name} | + % endif + edX Studio @@ -22,14 +22,13 @@ - + <%block name="header_extras"> - <%include file="widgets/header.html" /> - <%include file="courseware_vendor_js.html"/> + <%include file="courseware_vendor_js.html"/> @@ -48,15 +47,23 @@ - <%block name="content"> - <%include file="widgets/footer.html" /> + +
    + <%include file="widgets/header.html" /> + + <%block name="view_alerts"> + + <%block name="content"> + <%include file="widgets/footer.html" /> + <%block name="view_notifications"> +
    + + <%block name="view_prompts"> <%block name="jsextra"> - - - + \ No newline at end of file From eb1658730a6d258286e3d2134941015de91d8e2f Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Mon, 4 Mar 2013 12:30:04 -0500 Subject: [PATCH 017/299] studio - alerts: revised border styling on all elements and button/color inheritance --- cms/static/sass/_alerts.scss | 300 +++++++++++++++-------------------- 1 file changed, 126 insertions(+), 174 deletions(-) diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index c507034284..a6ce1f9830 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -24,6 +24,112 @@ } } +.alert, .notification, .prompt { + + // types - confirm + &.confirm { + + .nav-actions .action-primary { + @include blue-button(); + border-color: $blue-d2; + } + + a { + color: $blue; + + &:hover { + color: $blue-s2; + } + } + } + + // types - warning + &.warning { + + .nav-actions .action-primary { + @include orange-button(); + border-color: $orange-d2; + color: $gray-d4; + } + + a { + color: $orange; + + &:hover { + color: $orange-s2; + } + } + } + + // types - error + &.error { + + .nav-actions .action-primary { + @include red-button(); + border-color: $red-d2; + } + + a { + color: $red-l1; + + &:hover { + color: $red; + } + } + } + + // types - announcement + &.announcement { + + .nav-actions .action-primary { + @include blue-button(); + border-color: $blue-d2; + } + + a { + color: $blue; + + &:hover { + color: $blue-s2; + } + } + } + + // types - confirmation + &.confirmation { + + .nav-actions .action-primary { + @include green-button(); + border-color: $green-d2; + } + + a { + color: $green; + + &:hover { + color: $green-s2; + } + } + } + + // types - step required + &.step-required { + + .nav-actions .action-primary { + border-color: $pink-d2; + @include pink-button(); + } + + a { + color: $pink; + + &:hover { + color: $pink-s1; + } + } + } +} + // prompts .wrapper-prompt { @include transition(all 0.05s ease-in-out); @@ -73,9 +179,7 @@ } .action-primary { - @include blue-button(); @include font-size(13); - border-color: $blue-d2; font-weight: 600; } @@ -125,73 +229,48 @@ // notifications .wrapper-notification { @include clearfix(); - @include box-shadow(0 -1px 3px $shadow); + @include box-shadow(0 -1px 3px $shadow, inset 0 3px 1px $blue); position: fixed; bottom: 0; z-index: 1000; width: 100%; - padding: ($baseline*0.75) ($baseline*2); + border-top: 4px solid $black; + padding: $baseline ($baseline*2); &.wrapper-notification-warning { - border-top-color: $orange; + @include box-shadow(0 -1px 3px $shadow, inset 0 3px 1px $orange); .icon-warning { color: $orange; } - - &:hover { - border-top-color: $orange-s2; - - .icon-warning { - color: $orange-s2; - } - } } &.wrapper-notification-error { - border-top-color: $red-l1; + @include box-shadow(0 -1px 3px $shadow, inset 0 3px 1px $red-l1); .icon-error { color: $red-l1; } - - &:hover { - border-top-color: $red; - - .icon-error { - color: $red; - } - } } &.wrapper-notification-confirmation { - border-top-color: $green; + @include box-shadow(0 -1px 3px $shadow, inset 0 3px 1px $green); .icon-confirmation { color: $green; } - - &:hover { - border-top-color: $green-s1; - - .icon-confirmation { - color: $green-s1; - } - } } &.wrapper-notification-saving { - border-top-color: $pink; - - &:hover { - border-top-color: $pink-s1; - } + @include box-shadow(0 -1px 3px $shadow, inset 0 3px 1px $pink); } // shorter/status notifications &.wrapper-notification-status { + @include border-top-radius(3px); width: ($baseline*8); right: ($baseline); + border: 4px solid $black; padding: ($baseline/2) $baseline; .notification { @@ -222,8 +301,10 @@ // help notifications &.wrapper-notification-help { + @include border-top-radius(3px); width: ($baseline*14); right: ($baseline); + border: 4px solid $black; padding: ($baseline/2) $baseline; .notification { @@ -304,7 +385,7 @@ .nav-actions { width: flex-grid(4, 12); float: right; - margin-top: ($baseline/2); + margin-top: ($baseline/4); text-align: right; .nav-item { @@ -355,95 +436,55 @@ // alerts .wrapper-alert { @include box-sizing(border-box); - @include box-shadow(0 1px 1px $white, inset 0 2px 2px $shadow-d1); + @include box-shadow(0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $blue); position: relative; top: -($baseline*1.5); z-index: 100; overflow: hidden; width: 100%; - border-bottom: 4px solid $gray-l1; + border-bottom: 2px solid $black; border-top: 1px solid $black; - padding: $baseline ($baseline*2); + padding: $baseline ($baseline*2) ($baseline*1.5) ($baseline*2); background: $gray-d3; &.wrapper-alert-warning { - border-bottom-color: $orange; + @include box-shadow(0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $orange); .icon-warning { color: $orange; } - - &:hover { - border-bottom-color: $orange-s2; - - .icon-warning { - color: $orange-s2; - } - } } &.wrapper-alert-error { - border-bottom-color: $red-l1; + @include box-shadow(0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $red-l1); .icon-error { color: $red-l1; } - - &:hover { - border-bottom-color: $red; - - .icon-error { - color: $red; - } - } } &.wrapper-alert-confirmation { - border-bottom-color: $green; + @include box-shadow(0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $green); .icon-confirmation { color: $green; } - - &:hover { - border-bottom-color: $green-s2; - - .icon-confirmation { - color: $green-s2; - } - } } &.wrapper-alert-announcement { - border-bottom-color: $blue; + @include box-shadow(0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $blue); .icon-announcement { color: $blue; } - - &:hover { - border-bottom-color: $blue-s2; - - .icon-announcement { - color: $blue-s2; - } - } } &.wrapper-alert-step-required { - border-bottom-color: $pink; + @include box-shadow(0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $pink); .icon-step-required { color: $pink; } - - &:hover { - border-bottom-color: $pink-s2; - - .icon-announcement { - color: $pink-s2; - } - } } } @@ -552,95 +593,6 @@ } } -.alert, .notification, .prompt { - - // types - warning - &.warning { - - .nav-actions .action-primary { - @include orange-button(); - border-color: $orange-d2; - color: $gray-d4; - } - - a { - color: $orange; - - &:hover { - color: $orange-s2; - } - } - } - - // types - error - &.error { - - .nav-actions .action-primary { - @include red-button(); - border-color: $red-d2; - } - - a { - color: $red-l1; - - &:hover { - color: $red; - } - } - } - - // types - announcement - &.announcement { - - .nav-actions .action-primary { - @include blue-button(); - border-color: $blue-d2; - } - - a { - color: $blue; - - &:hover { - color: $blue-s2; - } - } - } - - // types - confirmation - &.confirmation { - - .nav-actions .action-primary { - @include green-button(); - border-color: $green-d2; - } - - a { - color: $green; - - &:hover { - color: $green-s2; - } - } - } - - // types - step required - &.step-required { - - .nav-actions .action-primary { - border-color: $pink-d2; - @include pink-button(); - } - - a { - color: $pink; - - &:hover { - color: $pink-s1; - } - } - } -} - // js enabled .js { From ec90d349e20ed76b2b53e4281aeb5e7ad70727fc Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Mon, 4 Mar 2013 12:47:07 -0500 Subject: [PATCH 018/299] studio - alerts: revisited advanced editor notification UI to marry new styles/behavior - WIP --- cms/static/js/base.js | 2 +- cms/static/js/views/settings/advanced_view.js | 4 ++-- cms/templates/settings_advanced.html | 23 +++++++++++-------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index a6e8190e17..3cb1829ffb 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -57,7 +57,7 @@ $(document).ready(function () { }); // alert and notifications - manual & action-based close - $('.action-notification-close, .notification.has-actions .nav-actions a').click(function(e) { + $('.action-notification-close').click(function(e) { (e).preventDefault(); $(this).closest('.wrapper-notification').removeClass('is-shown').addClass('is-hiding'); }); diff --git a/cms/static/js/views/settings/advanced_view.js b/cms/static/js/views/settings/advanced_view.js index d20a21f7e7..dc9adb30ed 100644 --- a/cms/static/js/views/settings/advanced_view.js +++ b/cms/static/js/views/settings/advanced_view.js @@ -141,13 +141,13 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({ event.keyCode === 8 || event.keyCode === 46)) return; } this.$el.find(".message-status").removeClass("is-shown"); - $('.wrapper-notification').addClass('is-shown'); + $('.wrapper-notification').removeClass('is-hiding').addClass('is-shown'); this.buttonsVisible = true; } }, hideSaveCancelButtons: function() { - $('.wrapper-notification').removeClass('is-shown'); + $('.wrapper-notification').removeClass('is-shown').addClass('is-hiding'); this.buttonsVisible = false; }, diff --git a/cms/templates/settings_advanced.html b/cms/templates/settings_advanced.html index ceee406398..f04015a4a9 100644 --- a/cms/templates/settings_advanced.html +++ b/cms/templates/settings_advanced.html @@ -105,20 +105,25 @@ editor.render();
    -
    +
    + +
    - - -

    Note: Your changes will not take effect until you save your - progress. Take care with key and value formatting, as validation is not implemented.

    +

    You've Made Some Changes

    +

    Your changes will not take effect until you save your progress. Take care with key and value formatting, as validation is not implemented.

    -
    +
    +
    \ No newline at end of file From cbdf9ea25bc9ffd43ffd6213a0e20cdfb6670364 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Tue, 5 Mar 2013 09:57:14 -0500 Subject: [PATCH 019/299] studio - alerts: proofing older, but still needed in page alerts (unit drafts) styling --- cms/static/sass/_alerts.scss | 117 +++++++++++++++++++---------------- cms/templates/unit.html | 4 +- 2 files changed, 64 insertions(+), 57 deletions(-) diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index a6ce1f9830..395519f867 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -271,6 +271,7 @@ width: ($baseline*8); right: ($baseline); border: 4px solid $black; + border-bottom: none; padding: ($baseline/2) $baseline; .notification { @@ -305,6 +306,7 @@ width: ($baseline*14); right: ($baseline); border: 4px solid $black; + border-bottom: none; padding: ($baseline/2) $baseline; .notification { @@ -690,69 +692,74 @@ body.uxdesign.alerts { } } +// ==================== + // artifact styles -// .alert { -// padding: 15px 20px; -// margin-bottom: 30px; -// border-radius: 3px; -// border: 1px solid #edbd3c; -// border-radius: 3px; -// background: #fbf6e1; -// // background: #edbd3c; -// font-size: 14px; -// @include clearfix; +.main-wrapper { + .alert { + padding: 15px 20px; + margin-bottom: 30px; + border-radius: 3px; + border: 1px solid #edbd3c; + border-radius: 3px; + background: #fbf6e1; + // background: #edbd3c; + font-size: 14px; + @include clearfix; -// .alert-message { -// float: left; -// margin-top: 4px; -// } + .alert-message { + float: left; + margin: 4px 0 0 0; + color: $gray-d3; + } -// strong { -// font-weight: 700; -// } + strong { + font-weight: 700; + } -// .alert-action { -// float: right; + .alert-action { + float: right; -// &.secondary { -// @include orange-button; -// } -// } -// } + &.secondary { + @include orange-button; + } + } + } +} -// body.error { -// background: $darkGrey; -// color: #3c3c3c; +body.error { + background: $gray-d4; + color: $gray-d3; -// .primary-header { -// display: none; -// } + .primary-header { + display: none; + } -// .error-prompt { -// width: 700px; -// margin: 150px auto; -// padding: 60px 50px 90px; -// border-radius: 3px; -// background: #fff; -// text-align: center; -// } + .error-prompt { + width: 700px; + margin: 150px auto; + padding: 60px 50px 90px; + border-radius: 3px; + background: $white; + text-align: center; + } -// h1 { -// float: none; -// margin: 0; -// font-size: 60px; -// font-weight: 300; -// color: #3c3c3c; -// } + h1 { + float: none; + margin: 0; + font-size: 60px; + font-weight: 300; + color: $gray-d3; + } -// .description { -// margin-bottom: 50px; -// font-size: 21px; -// } + .description { + margin-bottom: 50px; + font-size: 21px; + } -// .back-button { -// @include blue-button; -// padding: 14px 40px 18px; -// font-size: 18px; -// } -// } + .back-button { + @include blue-button; + padding: 14px 40px 18px; + font-size: 18px; + } +} diff --git a/cms/templates/unit.html b/cms/templates/unit.html index fa4b5dc20b..63d04a837f 100644 --- a/cms/templates/unit.html +++ b/cms/templates/unit.html @@ -33,7 +33,7 @@ <%block name="content">
    -
    +

    You are editing a draft. % if published_date: This unit was originally published on ${published_date}. @@ -143,7 +143,7 @@

    -
    +

    This unit has been published. To make changes, you must edit a draft.

    This is a draft of the published unit. To update the live version, you must replace it with this draft.

    From 62514d85a37fdfa5e60fa676902554e9c8eb1b19 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Wed, 6 Mar 2013 15:36:38 -0500 Subject: [PATCH 020/299] studio - alerts: loosely wired advanced settings with new notification and alert messages --- cms/static/js/views/settings/advanced_view.js | 6 ++-- cms/static/sass/_alerts.scss | 2 +- cms/templates/settings_advanced.html | 33 +++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/cms/static/js/views/settings/advanced_view.js b/cms/static/js/views/settings/advanced_view.js index dc9adb30ed..1aaa7d0c1e 100644 --- a/cms/static/js/views/settings/advanced_view.js +++ b/cms/static/js/views/settings/advanced_view.js @@ -114,13 +114,13 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({ }, showMessage: function (type) { - this.$el.find(".message-status").removeClass("is-shown"); + $(".wrapper-alert").removeClass("is-shown"); if (type) { if (type === this.error_saving) { - this.$el.find(".message-status.error").addClass("is-shown"); + $(".wrapper-alert-error").addClass("is-shown"); } else if (type === this.successful_changes) { - this.$el.find(".message-status.confirm").addClass("is-shown"); + $(".wrapper-alert-confirmation").addClass("is-shown"); this.hideSaveCancelButtons(); } } diff --git a/cms/static/sass/_alerts.scss b/cms/static/sass/_alerts.scss index 395519f867..07ac1e7913 100644 --- a/cms/static/sass/_alerts.scss +++ b/cms/static/sass/_alerts.scss @@ -234,7 +234,7 @@ bottom: 0; z-index: 1000; width: 100%; - border-top: 4px solid $black; + border-width: 2px; padding: $baseline ($baseline*2); &.wrapper-notification-warning { diff --git a/cms/templates/settings_advanced.html b/cms/templates/settings_advanced.html index f04015a4a9..00325f01b4 100644 --- a/cms/templates/settings_advanced.html +++ b/cms/templates/settings_advanced.html @@ -102,7 +102,9 @@ editor.render();
    + +<%block name="view_notifications">
    @@ -126,4 +128,35 @@ editor.render();
    + + +<%block name="view_alerts"> + +
    +
    + + +
    +

    Your policy changes have been saved.

    +

    Please note that validation of your policy key and value pairs is not currently in place yet. If you are having difficulties, please review your policy pairs.

    +
    + + + + close alert + +
    +
    + + +
    +
    + + +
    +

    There was an error saving your information

    +

    Please see the error below and correct it to ensure there are no problems in rendering your course.

    +
    +
    +
    \ No newline at end of file From 559a311acbc093ded0a7da9d0d57e90a2b0687d3 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Thu, 7 Mar 2013 11:37:15 -0500 Subject: [PATCH 021/299] studio - alerts: refactored static alerts demo view to have a different template/view/url name to help with user facing views vs. documentation views --- cms/djangoapps/contentstore/views.py | 4 ++-- cms/templates/{alerts.html => ux-alerts.html} | 0 cms/urls.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename cms/templates/{alerts.html => ux-alerts.html} (100%) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index df40a1972d..464342f3e1 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -110,8 +110,8 @@ def howitworks(request): else: return render_to_response('howitworks.html', {}) -def alerts(request): - return render_to_response('alerts.html', {}) +def ux_alerts(request): + return render_to_response('ux-alerts.html', {}) # ==== Views for any logged-in user ================================== diff --git a/cms/templates/alerts.html b/cms/templates/ux-alerts.html similarity index 100% rename from cms/templates/alerts.html rename to cms/templates/ux-alerts.html diff --git a/cms/urls.py b/cms/urls.py index b2c5670913..7a384b3f20 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -82,7 +82,7 @@ urlpatterns = ('', # User creation and updating views urlpatterns += ( - url(r'^alerts$', 'contentstore.views.alerts', name='alerts'), + url(r'^ux-alerts$', 'contentstore.views.ux_alerts', name='ux-alerts'), url(r'^howitworks$', 'contentstore.views.howitworks', name='howitworks'), url(r'^signup$', 'contentstore.views.signup', name='signup'), From 4d136f8d3bc1d247941b68f0af8b2caac4e947b0 Mon Sep 17 00:00:00 2001 From: Arthur Barrett Date: Thu, 7 Mar 2013 11:51:45 -0500 Subject: [PATCH 022/299] fixed annotation tooltip styling issue in studio --- common/lib/xmodule/xmodule/css/annotatable/display.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/common/lib/xmodule/xmodule/css/annotatable/display.scss b/common/lib/xmodule/xmodule/css/annotatable/display.scss index 308b379ec1..c462d4806e 100644 --- a/common/lib/xmodule/xmodule/css/annotatable/display.scss +++ b/common/lib/xmodule/xmodule/css/annotatable/display.scss @@ -127,6 +127,7 @@ $body-font-size: em(14); font-weight: 400; padding: 0 10px 10px 10px; background-color: transparent; + border-color: transparent; } p { color: inherit; From f5c3775b5dcbb8b16e6a0fcd27fd8b835516a56e Mon Sep 17 00:00:00 2001 From: Arthur Barrett Date: Thu, 7 Mar 2013 12:21:47 -0500 Subject: [PATCH 023/299] fixed the annotation tooltip line height so it is the same in studio and the lms. --- common/lib/xmodule/xmodule/css/annotatable/display.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/common/lib/xmodule/xmodule/css/annotatable/display.scss b/common/lib/xmodule/xmodule/css/annotatable/display.scss index c462d4806e..b5739b28fc 100644 --- a/common/lib/xmodule/xmodule/css/annotatable/display.scss +++ b/common/lib/xmodule/xmodule/css/annotatable/display.scss @@ -144,6 +144,7 @@ $body-font-size: em(14); margin: 0px 0px 10px 0; max-height: 225px; overflow: auto; + line-height: normal; } .annotatable-reply { display: block; From 60b060263c15bb90fc658349224c50158609e31d Mon Sep 17 00:00:00 2001 From: Arthur Barrett Date: Thu, 7 Mar 2013 16:02:22 -0500 Subject: [PATCH 024/299] refactor highlight css to prevent issues with cascade --- common/lib/xmodule/xmodule/css/annotatable/display.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/lib/xmodule/xmodule/css/annotatable/display.scss b/common/lib/xmodule/xmodule/css/annotatable/display.scss index b5739b28fc..f8ae779b8c 100644 --- a/common/lib/xmodule/xmodule/css/annotatable/display.scss +++ b/common/lib/xmodule/xmodule/css/annotatable/display.scss @@ -55,6 +55,7 @@ $body-font-size: em(14); display: inline; cursor: pointer; + $highlight_index: 0; @each $highlight in ( (yellow rgba(255,255,10,0.3) rgba(255,255,10,0.9)), (red rgba(178,19,16,0.3) rgba(178,19,16,0.9)), @@ -62,12 +63,13 @@ $body-font-size: em(14); (green rgba(25,255,132,0.3) rgba(25,255,132,0.9)), (blue rgba(35,163,255,0.3) rgba(35,163,255,0.9)), (purple rgba(115,9,178,0.3) rgba(115,9,178,0.9))) { - + + $highlight_index: $highlight_index + 1; $marker: nth($highlight,1); $color: nth($highlight,2); $selected_color: nth($highlight,3); - @if $marker == yellow { + @if $highlight_index == 1 { &.highlight { background-color: $color; &.selected { background-color: $selected_color; } @@ -167,5 +169,3 @@ $body-font-size: em(14); border-top-color: rgba(0, 0, 0, .85); } } - - From 094458dd6f0e4437a71dcbcd990d31286725dc16 Mon Sep 17 00:00:00 2001 From: Arthur Barrett Date: Mon, 11 Mar 2013 16:19:36 -0400 Subject: [PATCH 025/299] Modified tooltip positioning on non-overlapping annotation spans. --- .../xmodule/js/src/annotatable/display.coffee | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee b/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee index 2ad49ae6d7..523b0e99cf 100644 --- a/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee @@ -75,6 +75,7 @@ class @Annotatable classes: 'ui-tooltip-annotatable' events: show: @onShowTip + move: @onMoveTip onClickToggleAnnotations: (e) => @toggleAnnotations() @@ -87,6 +88,40 @@ class @Annotatable onShowTip: (event, api) => event.preventDefault() if @annotationsHidden + onMoveTip: (event, api, position) => + ### + This method handles an edge case in which a tooltip is displayed above + a non-overlapping span like this: + + (( TOOLTIP )) + \/ + text text text ... text text text ...... + + + The problem is that the tooltip looks disconnected from both spans, so + we should re-position the tooltip to appear above the span. + ### + + tip = api.elements.tooltip + adjust_y = api.options.position?.adjust?.y || 0 + target = api.elements.target + rects = $(target).get(0).getClientRects() + is_non_overlapping = (rects?.length == 2 and rects[0].left > rects[1].right) + + if is_non_overlapping + focus_rect = rects[0] + rect_center = focus_rect.left + (focus_rect.width / 2) + rect_top = focus_rect.top + tip_width = $(tip).width() + tip_height = $(tip).height() + tip_left = rect_center - (tip_width / 2) + tip_top = window.pageYOffset + rect_top - tip_height + adjust_y + win_width = $(window).width() + if tip_left + tip_width > win_width + tip_left = win_width - tip_width + position.left = tip_left + position.top = tip_top + getSpanForProblemReturn: (el) -> problem_id = $(@problemReturnSelector).index(el) @$(@spanSelector).filter("[data-problem-id='#{problem_id}']") From fcf82ba2bc44cb701c020d0494e2537139635f27 Mon Sep 17 00:00:00 2001 From: Arthur Barrett Date: Mon, 11 Mar 2013 18:02:22 -0400 Subject: [PATCH 026/299] fixed pep8 violations for annotation module --- common/lib/xmodule/xmodule/annotatable_module.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/common/lib/xmodule/xmodule/annotatable_module.py b/common/lib/xmodule/xmodule/annotatable_module.py index f093b76f52..1385296ddf 100644 --- a/common/lib/xmodule/xmodule/annotatable_module.py +++ b/common/lib/xmodule/xmodule/annotatable_module.py @@ -11,13 +11,13 @@ from xmodule.contentstore.content import StaticContent log = logging.getLogger(__name__) + class AnnotatableModule(XModule): js = {'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee'), resource_string(__name__, 'js/src/collapsible.coffee'), resource_string(__name__, 'js/src/html/display.coffee'), resource_string(__name__, 'js/src/annotatable/display.coffee')], - 'js': [] - } + 'js': []} js_module_name = "Annotatable" css = {'scss': [resource_string(__name__, 'css/annotatable/display.scss')]} icon_class = 'annotatable' @@ -34,11 +34,11 @@ class AnnotatableModule(XModule): if color is not None: if color in self.highlight_colors: - cls.append('highlight-'+color) + cls.append('highlight-' + color) attr['_delete'] = highlight_key attr['value'] = ' '.join(cls) - return { 'class' : attr } + return {'class': attr} def _get_annotation_data_attr(self, index, el): """ Returns a dict in which the keys are the HTML data attributes @@ -58,7 +58,7 @@ class AnnotatableModule(XModule): if xml_key in el.attrib: value = el.get(xml_key, '') html_key = attrs_map[xml_key] - data_attrs[html_key] = { 'value': value, '_delete': xml_key } + data_attrs[html_key] = {'value': value, '_delete': xml_key} return data_attrs @@ -76,7 +76,6 @@ class AnnotatableModule(XModule): delete_key = attr[key]['_delete'] del el.attrib[delete_key] - def _render_content(self): """ Renders annotatable content with annotation spans and returns HTML. """ xmltree = etree.fromstring(self.content) @@ -123,9 +122,9 @@ class AnnotatableModule(XModule): self.element_id = self.location.html_id() self.highlight_colors = ['yellow', 'orange', 'purple', 'blue', 'green'] + class AnnotatableDescriptor(RawDescriptor): module_class = AnnotatableModule stores_state = True template_dir_name = "annotatable" mako_template = "widgets/raw-edit.html" - From d860b167d6838443d05b5b67805047a7e032f6a3 Mon Sep 17 00:00:00 2001 From: Arthur Barrett Date: Tue, 12 Mar 2013 14:09:56 -0400 Subject: [PATCH 027/299] fixed tooltip positioning for non-overlapping spans in studio --- .../xmodule/css/annotatable/display.scss | 4 +++ .../xmodule/js/src/annotatable/display.coffee | 34 ++++++++++++++----- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/common/lib/xmodule/xmodule/css/annotatable/display.scss b/common/lib/xmodule/xmodule/css/annotatable/display.scss index f8ae779b8c..6e1a38ee31 100644 --- a/common/lib/xmodule/xmodule/css/annotatable/display.scss +++ b/common/lib/xmodule/xmodule/css/annotatable/display.scss @@ -1,6 +1,10 @@ $border-color: #C8C8C8; $body-font-size: em(14); +.annotatable-wrapper { + position: relative; +} + .annotatable-header { margin-bottom: .5em; .annotatable-title { diff --git a/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee b/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee index 523b0e99cf..e38e48eeda 100644 --- a/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee @@ -1,7 +1,8 @@ class @Annotatable _debug: false - # selectors for the annotatable xmodule + # selectors for the annotatable xmodule + wrapperSelector: '.annotatable-wrapper' toggleAnnotationsSelector: '.annotatable-toggle-annotations' toggleInstructionsSelector: '.annotatable-toggle-instructions' instructionsSelector: '.annotatable-instructions' @@ -61,7 +62,7 @@ class @Annotatable my: 'bottom center' # of tooltip at: 'top center' # of target target: $(el) # where the tooltip was triggered (i.e. the annotation span) - container: @$el + container: @$(@wrapperSelector) adjust: y: -5 show: @@ -104,23 +105,38 @@ class @Annotatable tip = api.elements.tooltip adjust_y = api.options.position?.adjust?.y || 0 + container = api.options.position?.container || $('body') target = api.elements.target + rects = $(target).get(0).getClientRects() is_non_overlapping = (rects?.length == 2 and rects[0].left > rects[1].right) if is_non_overlapping - focus_rect = rects[0] + # we want to choose the largest of the two non-overlapping spans and display + # the tooltip above the center of it (see api.options.position settings) + focus_rect = (if rects[0].width > rects[1].width then rects[0] else rects[1]) rect_center = focus_rect.left + (focus_rect.width / 2) rect_top = focus_rect.top tip_width = $(tip).width() tip_height = $(tip).height() - tip_left = rect_center - (tip_width / 2) - tip_top = window.pageYOffset + rect_top - tip_height + adjust_y + + # tooltip is positioned relative to its container, so we need to factor in offsets + container_offset = $(container).offset() + offset_left = -container_offset.left + offset_top = $('body').scrollTop() - container_offset.top + + tip_left = offset_left + rect_center - (tip_width / 2) + tip_top = offset_top + rect_top - tip_height + adjust_y + + # make sure the new tip position doesn't clip the edges of the screen win_width = $(window).width() - if tip_left + tip_width > win_width - tip_left = win_width - tip_width - position.left = tip_left - position.top = tip_top + if tip_left < offset_left + tip_left = offset_left + else if tip_left + tip_width > win_width + offset_left + tip_left = win_width + offset_left - tip_width + + # final step: update the position object (used by qtip2 to show the tip after the move event) + $.extend position, 'left': tip_left, 'top': tip_top getSpanForProblemReturn: (el) -> problem_id = $(@problemReturnSelector).index(el) From bf6ca1b0e759252795ca89ad905828d30ceada28 Mon Sep 17 00:00:00 2001 From: Arthur Barrett Date: Tue, 12 Mar 2013 17:32:00 -0400 Subject: [PATCH 028/299] use document to get scrollTop for firefox --- common/lib/xmodule/xmodule/js/src/annotatable/display.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee b/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee index e38e48eeda..8a32c8f51e 100644 --- a/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/annotatable/display.coffee @@ -123,7 +123,7 @@ class @Annotatable # tooltip is positioned relative to its container, so we need to factor in offsets container_offset = $(container).offset() offset_left = -container_offset.left - offset_top = $('body').scrollTop() - container_offset.top + offset_top = $(document).scrollTop() - container_offset.top tip_left = offset_left + rect_center - (tip_width / 2) tip_top = offset_top + rect_top - tip_height + adjust_y From 4c8a45f85ecfb6422bd10de3b79f3a5ef51c70f9 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 14 Mar 2013 13:29:26 -0400 Subject: [PATCH 029/299] Code to add in an open ended tab automatically --- cms/djangoapps/contentstore/utils.py | 12 +++++++- cms/djangoapps/contentstore/views.py | 28 +++++++++++++++++-- .../models/settings/course_metadata.py | 9 ++++-- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index cba30131b5..4113361445 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -2,9 +2,10 @@ from django.conf import settings from xmodule.modulestore import Location from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError +import copy DIRECT_ONLY_CATEGORIES = ['course', 'chapter', 'sequential', 'about', 'static_tab', 'course_info'] - +OPEN_ENDED_PANEL = {"name" : "Open Ended Panel", "type" : "open_ended"} def get_modulestore(location): """ @@ -158,3 +159,12 @@ def update_item(location, value): get_modulestore(location).delete_item(location) else: get_modulestore(location).update_item(location, value) + +def add_open_ended_panel_tab(course): + course_tabs = copy.copy(course.tabs) + changed = False + if OPEN_ENDED_PANEL not in course_tabs: + course_tabs.append(OPEN_ENDED_PANEL) + changed = True + return changed, course_tabs + diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 6566350f8d..b066f476a3 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -47,6 +47,7 @@ from auth.authz import is_user_in_course_group_role, get_users_in_course_group_b from auth.authz import get_user_by_email, add_user_to_course_group, remove_user_from_course_group from auth.authz import INSTRUCTOR_ROLE_NAME, STAFF_ROLE_NAME, create_all_course_groups from .utils import get_course_location_for_item, get_lms_link_for_item, compute_unit_state, get_date_display, UnitState, get_course_for_item +from .utils import add_open_ended_panel_tab from xmodule.modulestore.xml_importer import import_from_xml from contentstore.course_info_model import get_course_updates,\ @@ -68,7 +69,8 @@ log = logging.getLogger(__name__) COMPONENT_TYPES = ['customtag', 'discussion', 'html', 'problem', 'video'] -ADVANCED_COMPONENT_TYPES = ['annotatable','combinedopenended', 'peergrading'] +OPEN_ENDED_COMPONENT_TYPES = ["combinedopenended", "peergrading"] +ADVANCED_COMPONENT_TYPES = ['annotatable'] + OPEN_ENDED_COMPONENT_TYPES ADVANCED_COMPONENT_CATEGORY = 'advanced' ADVANCED_COMPONENT_POLICY_KEY = 'advanced_modules' @@ -295,6 +297,9 @@ def edit_unit(request, location): # in ADVANCED_COMPONENT_TYPES that should be enabled for the course. course_metadata = CourseMetadata.fetch(course.location) course_advanced_keys = course_metadata.get(ADVANCED_COMPONENT_POLICY_KEY, []) + log.debug(course.tabs) + log.debug(type(course.tabs)) + log.debug("LOOK HERE NOW!!!!!") # Set component types according to course policy file component_types = list(COMPONENT_TYPES) @@ -1329,7 +1334,26 @@ def course_advanced_updates(request, org, course, name): return HttpResponse(json.dumps(CourseMetadata.delete_key(location, json.loads(request.body))), mimetype="application/json") elif real_method == 'POST' or real_method == 'PUT': # NOTE: request.POST is messed up because expect_json cloned_request.POST.copy() is creating a defective entry w/ the whole payload as the key - return HttpResponse(json.dumps(CourseMetadata.update_from_json(location, json.loads(request.body))), mimetype="application/json") + request_body = json.loads(request.body) + filter_tabs = True + if ADVANCED_COMPONENT_POLICY_KEY in request_body: + log.debug("Advanced component in.") + for oe_type in OPEN_ENDED_COMPONENT_TYPES: + log.debug(request_body[ADVANCED_COMPONENT_POLICY_KEY]) + if oe_type in request_body[ADVANCED_COMPONENT_POLICY_KEY]: + log.debug("OE type in.") + course_module = modulestore().get_item(location) + changed, new_tabs = add_open_ended_panel_tab(course_module) + log.debug(new_tabs) + if changed: + request_body.update({'tabs' : new_tabs}) + filter_tabs = False + break + log.debug(request_body) + log.debug(filter_tabs) + log.debug("LOOK HERE FOR TAB SAVING!!!!") + response_json = json.dumps(CourseMetadata.update_from_json(location, request_body, filter_tabs=filter_tabs)) + return HttpResponse(response_json, mimetype="application/json") @login_required diff --git a/cms/djangoapps/models/settings/course_metadata.py b/cms/djangoapps/models/settings/course_metadata.py index 24245a39d5..af0923213b 100644 --- a/cms/djangoapps/models/settings/course_metadata.py +++ b/cms/djangoapps/models/settings/course_metadata.py @@ -1,6 +1,7 @@ from xmodule.modulestore import Location from contentstore.utils import get_modulestore from xmodule.x_module import XModuleDescriptor +import copy class CourseMetadata(object): @@ -30,7 +31,7 @@ class CourseMetadata(object): return course @classmethod - def update_from_json(cls, course_location, jsondict): + def update_from_json(cls, course_location, jsondict, filter_tabs=True): """ Decode the json into CourseMetadata and save any changed attrs to the db. @@ -40,9 +41,13 @@ class CourseMetadata(object): dirty = False + filtered_list = copy.copy(cls.FILTERED_LIST) + if not filter_tabs: + filtered_list.remove("tabs") + for k, v in jsondict.iteritems(): # should it be an error if one of the filtered list items is in the payload? - if k not in cls.FILTERED_LIST and (k not in descriptor.metadata or descriptor.metadata[k] != v): + if k not in filtered_list and (k not in descriptor.metadata or descriptor.metadata[k] != v): dirty = True descriptor.metadata[k] = v From a717dffd4886a185ae2d4414f060e295871dbd82 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 14 Mar 2013 13:31:30 -0400 Subject: [PATCH 030/299] Remove debug statements --- cms/djangoapps/contentstore/views.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index b066f476a3..591ec7d7cf 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -297,10 +297,7 @@ def edit_unit(request, location): # in ADVANCED_COMPONENT_TYPES that should be enabled for the course. course_metadata = CourseMetadata.fetch(course.location) course_advanced_keys = course_metadata.get(ADVANCED_COMPONENT_POLICY_KEY, []) - log.debug(course.tabs) - log.debug(type(course.tabs)) - log.debug("LOOK HERE NOW!!!!!") - + # Set component types according to course policy file component_types = list(COMPONENT_TYPES) if isinstance(course_advanced_keys, list): @@ -1337,21 +1334,14 @@ def course_advanced_updates(request, org, course, name): request_body = json.loads(request.body) filter_tabs = True if ADVANCED_COMPONENT_POLICY_KEY in request_body: - log.debug("Advanced component in.") for oe_type in OPEN_ENDED_COMPONENT_TYPES: - log.debug(request_body[ADVANCED_COMPONENT_POLICY_KEY]) if oe_type in request_body[ADVANCED_COMPONENT_POLICY_KEY]: - log.debug("OE type in.") course_module = modulestore().get_item(location) changed, new_tabs = add_open_ended_panel_tab(course_module) - log.debug(new_tabs) if changed: request_body.update({'tabs' : new_tabs}) filter_tabs = False break - log.debug(request_body) - log.debug(filter_tabs) - log.debug("LOOK HERE FOR TAB SAVING!!!!") response_json = json.dumps(CourseMetadata.update_from_json(location, request_body, filter_tabs=filter_tabs)) return HttpResponse(response_json, mimetype="application/json") From 10eb7e45ea58a776113087515c1a00748f954320 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 14 Mar 2013 13:42:41 -0400 Subject: [PATCH 031/299] Add in some docs --- cms/djangoapps/contentstore/utils.py | 8 ++++++++ cms/djangoapps/contentstore/views.py | 14 +++++++++++--- cms/djangoapps/models/settings/course_metadata.py | 2 ++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index 4113361445..7e034d8da8 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -161,9 +161,17 @@ def update_item(location, value): get_modulestore(location).update_item(location, value) def add_open_ended_panel_tab(course): + """ + Used to add the open ended panel tab to a course if it does not exist. + @param course: A course object from the modulestore. + @return: Boolean indicating whether or not a tab was added and a list of tabs for the course. + """ + #Copy course tabs course_tabs = copy.copy(course.tabs) changed = False + #Check to see if open ended panel is defined in the course if OPEN_ENDED_PANEL not in course_tabs: + #Add panel to the tabs if it is not defined course_tabs.append(OPEN_ENDED_PANEL) changed = True return changed, course_tabs diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 591ec7d7cf..b7fcc9988e 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -297,7 +297,7 @@ def edit_unit(request, location): # in ADVANCED_COMPONENT_TYPES that should be enabled for the course. course_metadata = CourseMetadata.fetch(course.location) course_advanced_keys = course_metadata.get(ADVANCED_COMPONENT_POLICY_KEY, []) - + # Set component types according to course policy file component_types = list(COMPONENT_TYPES) if isinstance(course_advanced_keys, list): @@ -310,7 +310,6 @@ def edit_unit(request, location): templates = modulestore().get_items(Location('i4x', 'edx', 'templates')) for template in templates: category = template.location.category - if category in course_advanced_keys: category = ADVANCED_COMPONENT_CATEGORY @@ -1332,15 +1331,24 @@ def course_advanced_updates(request, org, course, name): elif real_method == 'POST' or real_method == 'PUT': # NOTE: request.POST is messed up because expect_json cloned_request.POST.copy() is creating a defective entry w/ the whole payload as the key request_body = json.loads(request.body) + #Whether or not to filter the tabs key out of the settings metadata filter_tabs = True + #Check to see if the user instantiated any advanced components. This is a hack to add the open ended panel tab + #to a course automatically if the user has indicated that they want to edit the combinedopenended or peergrading + #module. if ADVANCED_COMPONENT_POLICY_KEY in request_body: + #Check to see if the user instantiated any open ended components for oe_type in OPEN_ENDED_COMPONENT_TYPES: if oe_type in request_body[ADVANCED_COMPONENT_POLICY_KEY]: + #Get the course so that we can scrape current tabs course_module = modulestore().get_item(location) + #Add an open ended tab to the course if needed changed, new_tabs = add_open_ended_panel_tab(course_module) + #If a tab has been added to the course, then send the metadata along to CourseMetadata.update_from_json if changed: request_body.update({'tabs' : new_tabs}) - filter_tabs = False + #Indicate that tabs should not be filtered out of the metadata + filter_tabs = False break response_json = json.dumps(CourseMetadata.update_from_json(location, request_body, filter_tabs=filter_tabs)) return HttpResponse(response_json, mimetype="application/json") diff --git a/cms/djangoapps/models/settings/course_metadata.py b/cms/djangoapps/models/settings/course_metadata.py index af0923213b..2747cc0751 100644 --- a/cms/djangoapps/models/settings/course_metadata.py +++ b/cms/djangoapps/models/settings/course_metadata.py @@ -41,7 +41,9 @@ class CourseMetadata(object): dirty = False + #Copy the filtered list to avoid permanently changing the class attribute filtered_list = copy.copy(cls.FILTERED_LIST) + #Don't filter on the tab attribute if filter_tabs is False if not filter_tabs: filtered_list.remove("tabs") From 16f9f6ef4f0293aab1e5ff41e8d4d25eb3b24f92 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Mon, 18 Mar 2013 13:15:01 -0400 Subject: [PATCH 032/299] studio - tender widget: added initial reference and behavior --- cms/static/sass/_tender-widget.scss | 20 ++++++++++++++++++++ cms/static/sass/base-style.scss | 1 + cms/templates/base.html | 1 + cms/templates/widgets/footer.html | 7 +++---- cms/templates/widgets/tender.html | 13 +++++++++++++ 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 cms/static/sass/_tender-widget.scss create mode 100644 cms/templates/widgets/tender.html diff --git a/cms/static/sass/_tender-widget.scss b/cms/static/sass/_tender-widget.scss new file mode 100644 index 0000000000..fa406009ee --- /dev/null +++ b/cms/static/sass/_tender-widget.scss @@ -0,0 +1,20 @@ +// tender help/support widget +// ==================== + +// tender help link + + +// ==================== + +// tender modal UI +#tender_window { + +} + +#tender_frame { + +} + +.widget-layout { + font-family: 'Open Sans', sans-serif; +} \ No newline at end of file diff --git a/cms/static/sass/base-style.scss b/cms/static/sass/base-style.scss index dceac4233d..bdfdab2cb3 100644 --- a/cms/static/sass/base-style.scss +++ b/cms/static/sass/base-style.scss @@ -32,6 +32,7 @@ @import "account"; @import "index"; @import 'jquery-ui-calendar'; +@import 'tender-widget'; @import 'content-types'; diff --git a/cms/templates/base.html b/cms/templates/base.html index f7b2c46f61..5e6f4348b0 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -56,6 +56,7 @@ <%include file="widgets/footer.html" /> <%block name="jsextra"> + <%include file="widgets/tender.html" /> diff --git a/cms/templates/widgets/footer.html b/cms/templates/widgets/footer.html index 0f265dfc2c..c38d5dec7f 100644 --- a/cms/templates/widgets/footer.html +++ b/cms/templates/widgets/footer.html @@ -17,13 +17,12 @@ + - - % if user.is_authenticated(): - - % endif diff --git a/cms/templates/widgets/tender.html b/cms/templates/widgets/tender.html new file mode 100644 index 0000000000..e2bba3d2ef --- /dev/null +++ b/cms/templates/widgets/tender.html @@ -0,0 +1,13 @@ +% if user.is_authenticated(): + + +% endif \ No newline at end of file From 7507f91d2274a64c2993717bcbecb078346461a3 Mon Sep 17 00:00:00 2001 From: Arthur Barrett Date: Mon, 18 Mar 2013 15:43:43 -0400 Subject: [PATCH 033/299] Added TODO and explanation for the top-level scss variables. --- common/lib/xmodule/xmodule/css/annotatable/display.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/lib/xmodule/xmodule/css/annotatable/display.scss b/common/lib/xmodule/xmodule/css/annotatable/display.scss index 6e1a38ee31..e2c095de2d 100644 --- a/common/lib/xmodule/xmodule/css/annotatable/display.scss +++ b/common/lib/xmodule/xmodule/css/annotatable/display.scss @@ -1,3 +1,9 @@ +/* TODO: move top-level variables to a common _variables.scss. + * NOTE: These variables were only added here because when this was integrated with the CMS, + * SASS compilation errors were triggered because the CMS didn't have the same variables defined + * that the LMS did, so the quick fix was to localize the LMS variables not shared by the CMS. + * -Abarrett and Vshnayder + */ $border-color: #C8C8C8; $body-font-size: em(14); From c901cecdea15249a63e41e4468fe5467b4b83999 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Mon, 18 Mar 2013 16:23:30 -0400 Subject: [PATCH 034/299] studio - tender widget: added compromise of style given iframe and clunky DOM elements that tender is using. meh. --- cms/static/sass/_tender-widget.scss | 87 ++++++++++++++++++++++++++--- cms/static/sass/_variables.scss | 1 + cms/templates/base.html | 2 +- cms/templates/widgets/footer.html | 2 +- 4 files changed, 82 insertions(+), 10 deletions(-) diff --git a/cms/static/sass/_tender-widget.scss b/cms/static/sass/_tender-widget.scss index fa406009ee..422be36908 100644 --- a/cms/static/sass/_tender-widget.scss +++ b/cms/static/sass/_tender-widget.scss @@ -1,20 +1,91 @@ // tender help/support widget // ==================== -// tender help link - - -// ==================== - -// tender modal UI -#tender_window { - +#tender_frame, #tender_window { + background-image: none !important; } #tender_frame { + @include border-radius(3px); + @include box-shadow(0 2px 3px $shadow); + border: 1px solid $gray; + background: $white; +} +#tender_closer { + color: $blue-l2 !important; + margin-top: 15px; + margin-right: 5px; +} + +// ==================== + +// tender style overrides - not rendered through here, but an archive is needed +#tender_frame iframe html { + font-size: 62.5%; } .widget-layout { font-family: 'Open Sans', sans-serif; +} + +.widget-layout .search, +.widget-layout .tabs, +.widget-layout .header h1 a { + display: none; +} + +.widget-layout .header { + background: rgb(85, 151, 221); + padding: 20px; +} + +.widget-layout h1, .widget-layout h2, .widget-layout h3, .widget-layout h4, .widget-layout h5, .widget-layout h6, .widget-layout label { + font-weight: 600; +} + +.widget-layout .header h1 { + font-weight: 700; + font-size: 24px; + font-size: 2.4rem; +} + +.widget-layout .content { + padding: 20px; +} + +.widget-layout label { + font-size: 14px; + font-size: 1.4rem; + margin-bottom: 5px; + color: rgb(127,127,127) !important; +} + +.widget-layout input[type="text"], .widget-layout textarea { + padding: 10px; + font-size: 16px; + font-size: 1.6rem; + color: rgb(0,0,0) !important; +} + +.widget-layout textarea { + width: 97%; +} + +.widget-layout .form-actions { + border-top: 1px solid #ccc; + margin-top: 10px; + padding-top: 10px; +} + +.widget-layout dl.form { + margin-bottom: 15px; +} + +.widget-layout #brain_buster_captcha { + display: block; + width: 100%; + border-bottom: 1px solid #ccc; + margin-bottom: 10px; + padding-bottom: 10px; } \ No newline at end of file diff --git a/cms/static/sass/_variables.scss b/cms/static/sass/_variables.scss index 4d8e26b2f9..8e588b6234 100644 --- a/cms/static/sass/_variables.scss +++ b/cms/static/sass/_variables.scss @@ -16,6 +16,7 @@ $error-red: rgb(253, 87, 87); // colors - new for re-org $black: rgb(0,0,0); +$black-t0: rgba(0,0,0,0.125); $white: rgb(255,255,255); $gray: rgb(127,127,127); diff --git a/cms/templates/base.html b/cms/templates/base.html index 5e6f4348b0..77323be4d1 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -54,9 +54,9 @@ <%block name="content"> <%include file="widgets/footer.html" /> + <%include file="widgets/tender.html" /> <%block name="jsextra"> - <%include file="widgets/tender.html" /> diff --git a/cms/templates/widgets/footer.html b/cms/templates/widgets/footer.html index c38d5dec7f..e3063dafa7 100644 --- a/cms/templates/widgets/footer.html +++ b/cms/templates/widgets/footer.html @@ -18,7 +18,7 @@ edX Studio Help
    -
    \ No newline at end of file diff --git a/cms/templates/howitworks.html b/cms/templates/howitworks.html index 1cf9b17710..7a819fceba 100644 --- a/cms/templates/howitworks.html +++ b/cms/templates/howitworks.html @@ -151,7 +151,7 @@
    Simple two-level outline to organize your couse. Drag and drop, and see your course at a glance.
    - + close modal @@ -164,7 +164,7 @@
    Quickly create videos, text snippets, inline discussions, and a variety of problem types.
    - + close modal @@ -177,7 +177,7 @@
    Simply set the date of a section or subsection, and Studio will publish it to your students for you.
    - + close modal diff --git a/cms/templates/widgets/footer.html b/cms/templates/widgets/footer.html index a3674cfe20..9ff98fa26b 100644 --- a/cms/templates/widgets/footer.html +++ b/cms/templates/widgets/footer.html @@ -16,13 +16,13 @@ --> diff --git a/cms/templates/widgets/sock.html b/cms/templates/widgets/sock.html new file mode 100644 index 0000000000..ff5f9c9ad4 --- /dev/null +++ b/cms/templates/widgets/sock.html @@ -0,0 +1,8 @@ +<%! from django.core.urlresolvers import reverse %> +% if user.is_authenticated(): +
    +
    +

    Sock!

    +
    +
    +% endif \ No newline at end of file From 25acab497e05ab6d9883726d0cba2ec5146fa6ae Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Wed, 27 Mar 2013 01:33:04 -0400 Subject: [PATCH 064/299] studio - corrected JQ selector for smoothscrolling in-page links --- cms/static/js/base.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index 7135e2780c..211981b05a 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -81,7 +81,7 @@ $(document).ready(function () { }); // general link management - smooth scrolling page links - $('a[rel*="view"][href|="#"]').bind('click', smoothScrollLink); + $('a[rel*="view"][href^="#"]').bind('click', smoothScrollLink); // tender feedback window scrolling $('a.show-tender').bind('click', smoothScrollTop); From 74439746cc804fc2dfe9bc6b679f0a714093aa74 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Wed, 27 Mar 2013 01:38:36 -0400 Subject: [PATCH 065/299] studio - made provide feedback conditional for logged in users --- cms/templates/widgets/footer.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cms/templates/widgets/footer.html b/cms/templates/widgets/footer.html index 9ff98fa26b..18ecf2bc39 100644 --- a/cms/templates/widgets/footer.html +++ b/cms/templates/widgets/footer.html @@ -18,9 +18,11 @@ + % if user.is_authenticated(): + + % endif From e3c646492c1147f74fec0e9df45f58f1c9fe892e Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Wed, 27 Mar 2013 01:39:24 -0400 Subject: [PATCH 066/299] studio - made provide feedback conditional for logged in users --- cms/templates/widgets/footer.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cms/templates/widgets/footer.html b/cms/templates/widgets/footer.html index a3674cfe20..c0cf8f73a6 100644 --- a/cms/templates/widgets/footer.html +++ b/cms/templates/widgets/footer.html @@ -18,9 +18,11 @@ + % if user.is_authenticated(): + + % endif From 285e3ee1edfbb5cbb22f821b05b7a752aab25c73 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 10:49:47 -0400 Subject: [PATCH 067/299] Capa response now displays full stack trace on student input error if the user is a staff member. Otherwise, it displays just the exception message. --- common/lib/capa/capa/responsetypes.py | 7 +++--- common/lib/xmodule/xmodule/capa_module.py | 16 +++++++++++- .../xmodule/xmodule/tests/test_capa_module.py | 25 +++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 2c556211f8..465c212b30 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -17,6 +17,7 @@ import logging import numbers import numpy import os +import sys import random import re import requests @@ -1233,9 +1234,9 @@ def sympy_check2(): log.debug(msg, exc_info=True) log.debug(traceback.format_exc()) - # Notify student - raise StudentInputError( - "Error: Problem could not be evaluated with your input") + # Notify student with a student input error + _, _, traceback_obj = sys.exc_info() + raise StudentInputError, StudentInputError(err.message), traceback_obj #----------------------------------------------------------------------------- diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index da8b5b4f96..203e14fdc1 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -725,9 +725,23 @@ class CapaModule(CapaFields, XModule): try: correct_map = self.lcp.grade_answers(answers) self.set_state_from_lcp() + except StudentInputError as inst: log.exception("StudentInputError in capa_module:problem_check") - return {'success': inst.message} + + # If the user is a staff member, include + # the full exception, including traceback, + # in the response + if self.system.user_is_staff: + msg = traceback.format_exc() + + # Otherwise, display just the error message, + # without a stack trace + else: + msg = inst.message + + return {'success': msg } + except Exception, err: if self.system.DEBUG: msg = "Error checking problem: " + str(err) diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index d2458cb3d0..d769b65914 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -505,6 +505,9 @@ class CapaModuleTest(unittest.TestCase): def test_check_problem_student_input_error(self): module = CapaFactory.create(attempts=1) + # Ensure that the user is NOT staff + module.system.user_is_staff = False + # Simulate a student input exception with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: mock_grade.side_effect = capa.responsetypes.StudentInputError('test error') @@ -515,10 +518,32 @@ class CapaModuleTest(unittest.TestCase): # Expect an AJAX alert message in 'success' self.assertTrue('test error' in result['success']) + # We do NOT include traceback information for + # a non-staff user + self.assertFalse('Traceback' in result['success']) + # Expect that the number of attempts is NOT incremented self.assertEqual(module.attempts, 1) + def test_check_problem_student_input_error_with_staff_user(self): + module = CapaFactory.create(attempts=1) + # Ensure that the user IS staff + module.system.user_is_staff = True + + # Simulate a student input exception + with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: + mock_grade.side_effect = capa.responsetypes.StudentInputError('test error') + + get_request_dict = { CapaFactory.input_key(): '3.14'} + result = module.check_problem(get_request_dict) + + # Expect an AJAX alert message in 'success' + self.assertTrue('test error' in result['success']) + + # We DO include traceback information for staff users + self.assertTrue('Traceback' in result['success']) + def test_reset_problem(self): module = CapaFactory.create(done=True) module.new_lcp = Mock(wraps=module.new_lcp) From 754e30240d7c62c7efd80c38d552c4d168d23262 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Wed, 27 Mar 2013 11:01:25 -0400 Subject: [PATCH 068/299] studio - adjusting tender widget window height based on field removal --- cms/static/sass/elements/_tender-widget.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cms/static/sass/elements/_tender-widget.scss b/cms/static/sass/elements/_tender-widget.scss index 146d5b4111..478489d0e8 100644 --- a/cms/static/sass/elements/_tender-widget.scss +++ b/cms/static/sass/elements/_tender-widget.scss @@ -9,6 +9,7 @@ #tender_window { @include border-radius(3px); @include box-shadow(0 2px 3px $shadow); + height: 650px !important; background: $white !important; border: 1px solid $gray; } @@ -72,7 +73,7 @@ .widget-layout .flash { margin: -10px 0 15px 0; - padding: 5px 10px !important; + padding: 10px 20px !important; background-image: none !important; } From 8252ba15df79f3f2b213d8afed58c3a152f0bb2b Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 11:02:30 -0400 Subject: [PATCH 069/299] Changed error message for StudentInputError for non-staff to a generic message. Otherwise, the default exception messages are cryptic for students (e.g. "cannot convert string to float") --- common/lib/xmodule/xmodule/capa_module.py | 4 ++-- common/lib/xmodule/xmodule/tests/test_capa_module.py | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 203e14fdc1..c3159bb3ee 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -735,10 +735,10 @@ class CapaModule(CapaFields, XModule): if self.system.user_is_staff: msg = traceback.format_exc() - # Otherwise, display just the error message, + # Otherwise, display just an error message, # without a stack trace else: - msg = inst.message + msg = "Error: Problem could not be evaluated with your input" return {'success': msg } diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index d769b65914..b5e1ff311c 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -516,11 +516,8 @@ class CapaModuleTest(unittest.TestCase): result = module.check_problem(get_request_dict) # Expect an AJAX alert message in 'success' - self.assertTrue('test error' in result['success']) - - # We do NOT include traceback information for - # a non-staff user - self.assertFalse('Traceback' in result['success']) + expected_msg = 'Error: Problem could not be evaluated with your input' + self.assertEqual(expected_msg, result['success']) # Expect that the number of attempts is NOT incremented self.assertEqual(module.attempts, 1) From 5bc44e50da28ca31f10bbf447fd112c948717f86 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 11:13:31 -0400 Subject: [PATCH 070/299] Changed error messages to account for NumericalResponse formatting, which is the only other response type to use StudentInputError. --- common/lib/capa/capa/responsetypes.py | 2 +- common/lib/xmodule/xmodule/capa_module.py | 2 +- common/lib/xmodule/xmodule/tests/test_capa_module.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 465c212b30..08cfa8b9d9 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -834,7 +834,7 @@ class NumericalResponse(LoncapaResponse): import sys type, value, traceback = sys.exc_info() - raise StudentInputError, ("Invalid input: could not interpret '%s' as a number" % + raise StudentInputError, ("Could not interpret '%s' as a number" % cgi.escape(student_answer)), traceback if correct: diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index c3159bb3ee..773ae73d59 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -738,7 +738,7 @@ class CapaModule(CapaFields, XModule): # Otherwise, display just an error message, # without a stack trace else: - msg = "Error: Problem could not be evaluated with your input" + msg = "Error: %s" % str(inst.message) return {'success': msg } diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index b5e1ff311c..3617086f85 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -516,7 +516,7 @@ class CapaModuleTest(unittest.TestCase): result = module.check_problem(get_request_dict) # Expect an AJAX alert message in 'success' - expected_msg = 'Error: Problem could not be evaluated with your input' + expected_msg = 'Error: test error' self.assertEqual(expected_msg, result['success']) # Expect that the number of attempts is NOT incremented From 0f5e8c5f3bb8acbe8b4396ab172ca1740b7b89fd Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 11:17:21 -0400 Subject: [PATCH 071/299] pep8 fixes --- common/lib/capa/capa/responsetypes.py | 8 ++--- common/lib/xmodule/xmodule/capa_module.py | 10 +++--- .../xmodule/xmodule/tests/test_capa_module.py | 32 +++++++++---------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 08cfa8b9d9..e79399c5fc 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1141,9 +1141,9 @@ def sympy_check2(): correct = [] messages = [] for input_dict in input_list: - correct.append('correct' + correct.append('correct' if input_dict['ok'] else 'incorrect') - msg = (self.clean_message_html(input_dict['msg']) + msg = (self.clean_message_html(input_dict['msg']) if 'msg' in input_dict else None) messages.append(msg) @@ -1168,7 +1168,7 @@ def sympy_check2(): correct_map.set_overall_message(overall_message) for k in range(len(idset)): - npoints = (self.maxpoints[idset[k]] + npoints = (self.maxpoints[idset[k]] if correct[k] == 'correct' else 0) correct_map.set(idset[k], correct[k], msg=messages[k], npoints=npoints) @@ -2085,7 +2085,7 @@ class AnnotationResponse(LoncapaResponse): option_scoring = dict([(option['id'], { 'correctness': choices.get(option['choice']), 'points': scoring.get(option['choice']) - }) for option in self._find_options(inputfield) ]) + }) for option in self._find_options(inputfield)]) scoring_map[inputfield.get('id')] = option_scoring diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 773ae73d59..af29c4c2fe 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -576,7 +576,7 @@ class CapaModule(CapaFields, XModule): # save any state changes that may occur self.set_state_from_lcp() return response - + def get_answer(self, get): ''' @@ -731,7 +731,7 @@ class CapaModule(CapaFields, XModule): # If the user is a staff member, include # the full exception, including traceback, - # in the response + # in the response if self.system.user_is_staff: msg = traceback.format_exc() @@ -740,7 +740,7 @@ class CapaModule(CapaFields, XModule): else: msg = "Error: %s" % str(inst.message) - return {'success': msg } + return {'success': msg} except Exception, err: if self.system.DEBUG: @@ -792,7 +792,7 @@ class CapaModule(CapaFields, XModule): event_info['answers'] = answers # Too late. Cannot submit - if self.closed() and not self.max_attempts ==0: + if self.closed() and not self.max_attempts == 0: event_info['failure'] = 'closed' self.system.track_function('save_problem_fail', event_info) return {'success': False, @@ -812,7 +812,7 @@ class CapaModule(CapaFields, XModule): self.system.track_function('save_problem_success', event_info) msg = "Your answers have been saved" - if not self.max_attempts ==0: + if not self.max_attempts == 0: msg += " but not graded. Hit 'Check' to grade them." return {'success': True, 'msg': msg} diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index 3617086f85..18d20a2756 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -407,7 +407,7 @@ class CapaModuleTest(unittest.TestCase): mock_html.return_value = "Test HTML" # Check the problem - get_request_dict = { CapaFactory.input_key(): '3.14'} + get_request_dict = {CapaFactory.input_key(): '3.14'} result = module.check_problem(get_request_dict) # Expect that the problem is marked correct @@ -428,7 +428,7 @@ class CapaModuleTest(unittest.TestCase): mock_is_correct.return_value = False # Check the problem - get_request_dict = { CapaFactory.input_key(): '0'} + get_request_dict = {CapaFactory.input_key(): '0'} result = module.check_problem(get_request_dict) # Expect that the problem is marked correct @@ -446,7 +446,7 @@ class CapaModuleTest(unittest.TestCase): with patch('xmodule.capa_module.CapaModule.closed') as mock_closed: mock_closed.return_value = True with self.assertRaises(xmodule.exceptions.NotFoundError): - get_request_dict = { CapaFactory.input_key(): '3.14'} + get_request_dict = {CapaFactory.input_key(): '3.14'} module.check_problem(get_request_dict) # Expect that number of attempts NOT incremented @@ -492,7 +492,7 @@ class CapaModuleTest(unittest.TestCase): mock_is_queued.return_value = True mock_get_queuetime.return_value = datetime.datetime.now() - get_request_dict = { CapaFactory.input_key(): '3.14'} + get_request_dict = {CapaFactory.input_key(): '3.14'} result = module.check_problem(get_request_dict) # Expect an AJAX alert message in 'success' @@ -512,7 +512,7 @@ class CapaModuleTest(unittest.TestCase): with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: mock_grade.side_effect = capa.responsetypes.StudentInputError('test error') - get_request_dict = { CapaFactory.input_key(): '3.14'} + get_request_dict = {CapaFactory.input_key(): '3.14'} result = module.check_problem(get_request_dict) # Expect an AJAX alert message in 'success' @@ -532,7 +532,7 @@ class CapaModuleTest(unittest.TestCase): with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: mock_grade.side_effect = capa.responsetypes.StudentInputError('test error') - get_request_dict = { CapaFactory.input_key(): '3.14'} + get_request_dict = {CapaFactory.input_key(): '3.14'} result = module.check_problem(get_request_dict) # Expect an AJAX alert message in 'success' @@ -540,7 +540,7 @@ class CapaModuleTest(unittest.TestCase): # We DO include traceback information for staff users self.assertTrue('Traceback' in result['success']) - + def test_reset_problem(self): module = CapaFactory.create(done=True) module.new_lcp = Mock(wraps=module.new_lcp) @@ -595,11 +595,11 @@ class CapaModuleTest(unittest.TestCase): module = CapaFactory.create(done=False) # Save the problem - get_request_dict = { CapaFactory.input_key(): '3.14'} + get_request_dict = {CapaFactory.input_key(): '3.14'} result = module.save_problem(get_request_dict) # Expect that answers are saved to the problem - expected_answers = { CapaFactory.answer_key(): '3.14'} + expected_answers = {CapaFactory.answer_key(): '3.14'} self.assertEqual(module.lcp.student_answers, expected_answers) # Expect that the result is success @@ -614,7 +614,7 @@ class CapaModuleTest(unittest.TestCase): mock_closed.return_value = True # Try to save the problem - get_request_dict = { CapaFactory.input_key(): '3.14'} + get_request_dict = {CapaFactory.input_key(): '3.14'} result = module.save_problem(get_request_dict) # Expect that the result is failure @@ -625,7 +625,7 @@ class CapaModuleTest(unittest.TestCase): module = CapaFactory.create(rerandomize='always', done=True) # Try to save - get_request_dict = { CapaFactory.input_key(): '3.14'} + get_request_dict = {CapaFactory.input_key(): '3.14'} result = module.save_problem(get_request_dict) # Expect that we cannot save @@ -636,7 +636,7 @@ class CapaModuleTest(unittest.TestCase): module = CapaFactory.create(rerandomize='never', done=True) # Try to save - get_request_dict = { CapaFactory.input_key(): '3.14'} + get_request_dict = {CapaFactory.input_key(): '3.14'} result = module.save_problem(get_request_dict) # Expect that we succeed @@ -648,7 +648,7 @@ class CapaModuleTest(unittest.TestCase): # Just in case, we also check what happens if we have # more attempts than allowed. attempts = random.randint(1, 10) - module = CapaFactory.create(attempts=attempts -1, max_attempts=attempts) + module = CapaFactory.create(attempts=attempts - 1, max_attempts=attempts) self.assertEqual(module.check_button_name(), "Final Check") module = CapaFactory.create(attempts=attempts, max_attempts=attempts) @@ -658,14 +658,14 @@ class CapaModuleTest(unittest.TestCase): self.assertEqual(module.check_button_name(), "Final Check") # Otherwise, button name is "Check" - module = CapaFactory.create(attempts=attempts -2, max_attempts=attempts) + module = CapaFactory.create(attempts=attempts - 2, max_attempts=attempts) self.assertEqual(module.check_button_name(), "Check") - module = CapaFactory.create(attempts=attempts -3, max_attempts=attempts) + module = CapaFactory.create(attempts=attempts - 3, max_attempts=attempts) self.assertEqual(module.check_button_name(), "Check") # If no limit on attempts, then always show "Check" - module = CapaFactory.create(attempts=attempts -3) + module = CapaFactory.create(attempts=attempts - 3) self.assertEqual(module.check_button_name(), "Check") module = CapaFactory.create(attempts=0) From 6edee96caf528b73f2d9c097800ba8b867942de2 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 11:24:16 -0400 Subject: [PATCH 072/299] Added "Staff Debug Info" prefix to traceback message. --- common/lib/xmodule/xmodule/capa_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index af29c4c2fe..d7346faa67 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -733,7 +733,7 @@ class CapaModule(CapaFields, XModule): # the full exception, including traceback, # in the response if self.system.user_is_staff: - msg = traceback.format_exc() + msg = "Staff debug info: %s" % traceback.format_exc() # Otherwise, display just an error message, # without a stack trace From 3a4bdf19fb6733dae57b557223481601dbbe8efb Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Wed, 27 Mar 2013 12:26:49 -0400 Subject: [PATCH 073/299] studio - tweaking footer navigation for tender widget label --- cms/templates/widgets/footer.html | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cms/templates/widgets/footer.html b/cms/templates/widgets/footer.html index c0cf8f73a6..c5fc81957f 100644 --- a/cms/templates/widgets/footer.html +++ b/cms/templates/widgets/footer.html @@ -20,12 +20,9 @@ % if user.is_authenticated(): - % endif - + % endif From ac86687fa104d8c0c96ce3e73b7ad29f7baf5a91 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 14:33:59 -0400 Subject: [PATCH 074/299] Added exception handling that solves SchematicResponse exceptions causing a 500 error. When XModule raises a ProcessingError during an AJAX request, this module_render now returns a 404 to further reduce number of 500 responses. --- common/lib/capa/capa/responsetypes.py | 22 +++++-- common/lib/xmodule/xmodule/capa_module.py | 16 +++-- common/lib/xmodule/xmodule/exceptions.py | 8 ++- .../xmodule/xmodule/tests/test_capa_module.py | 60 ++++++++++++------- lms/djangoapps/courseware/module_render.py | 11 +++- 5 files changed, 86 insertions(+), 31 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index e79399c5fc..bc8e7ff541 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -53,12 +53,17 @@ class LoncapaProblemError(Exception): class ResponseError(Exception): ''' - Error for failure in processing a response + Error for failure in processing a response, including + exceptions that occur when executing a custom script. ''' pass class StudentInputError(Exception): + ''' + Error for an invalid student input. + For example, submitting a string when the problem expects a number + ''' pass #----------------------------------------------------------------------------- @@ -1151,7 +1156,7 @@ def sympy_check2(): # Raise an exception else: log.error(traceback.format_exc()) - raise LoncapaProblemError( + raise ResponseError( "CustomResponse: check function returned an invalid dict") # The check function can return a boolean value, @@ -1226,7 +1231,7 @@ def sympy_check2(): Handle an exception raised during the execution of custom Python code. - Raises a StudentInputError + Raises a ResponseError ''' # Log the error if we are debugging @@ -1236,7 +1241,7 @@ def sympy_check2(): # Notify student with a student input error _, _, traceback_obj = sys.exc_info() - raise StudentInputError, StudentInputError(err.message), traceback_obj + raise ResponseError, ResponseError(err.message), traceback_obj #----------------------------------------------------------------------------- @@ -1912,7 +1917,14 @@ class SchematicResponse(LoncapaResponse): submission = [json.loads(student_answers[ k]) for k in sorted(self.answer_ids)] self.context.update({'submission': submission}) - exec self.code in global_context, self.context + + try: + exec self.code in global_context, self.context + + except Exception as err: + _, _, traceback_obj = sys.exc_info() + raise ResponseError, ResponseError(err.message), traceback_obj + cmap = CorrectMap() cmap.set_dict(dict(zip(sorted( self.answer_ids), self.context['correct']))) diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index d7346faa67..fd25016ca5 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -12,12 +12,13 @@ from lxml import etree from pkg_resources import resource_string from capa.capa_problem import LoncapaProblem -from capa.responsetypes import StudentInputError +from capa.responsetypes import StudentInputError, \ + ResponseError, LoncapaProblemError from capa.util import convert_files_to_filenames from .progress import Progress from xmodule.x_module import XModule from xmodule.raw_module import RawDescriptor -from xmodule.exceptions import NotFoundError +from xmodule.exceptions import NotFoundError, ProcessingError from xblock.core import Integer, Scope, BlockScope, ModelType, String, Boolean, Object, Float from .fields import Timedelta @@ -454,7 +455,14 @@ class CapaModule(CapaFields, XModule): return 'Error' before = self.get_progress() - d = handlers[dispatch](get) + + try: + d = handlers[dispatch](get) + + except Exception as err: + _, _, traceback_obj = sys.exc_info() + raise ProcessingError, ProcessingError(err.message), traceback_obj + after = self.get_progress() d.update({ 'progress_changed': after != before, @@ -726,7 +734,7 @@ class CapaModule(CapaFields, XModule): correct_map = self.lcp.grade_answers(answers) self.set_state_from_lcp() - except StudentInputError as inst: + except (StudentInputError, ResponseError, LoncapaProblemError) as inst: log.exception("StudentInputError in capa_module:problem_check") # If the user is a staff member, include diff --git a/common/lib/xmodule/xmodule/exceptions.py b/common/lib/xmodule/xmodule/exceptions.py index 3db5ceccde..d38fbb12bb 100644 --- a/common/lib/xmodule/xmodule/exceptions.py +++ b/common/lib/xmodule/xmodule/exceptions.py @@ -1,6 +1,12 @@ class InvalidDefinitionError(Exception): pass - class NotFoundError(Exception): pass + +class ProcessingError(Exception): + ''' + An error occurred while processing a request to the XModule. + For example: if an exception occurs while checking a capa problem. + ''' + pass diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index 18d20a2756..cb7d599413 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -7,6 +7,8 @@ import random import xmodule import capa +from capa.responsetypes import StudentInputError, \ + LoncapaProblemError, ResponseError from xmodule.capa_module import CapaModule from xmodule.modulestore import Location from lxml import etree @@ -502,38 +504,52 @@ class CapaModuleTest(unittest.TestCase): self.assertEqual(module.attempts, 1) - def test_check_problem_student_input_error(self): - module = CapaFactory.create(attempts=1) + def test_check_problem_error(self): - # Ensure that the user is NOT staff - module.system.user_is_staff = False + # Try each exception that capa_module should handle + for exception_class in [StudentInputError, + LoncapaProblemError, + ResponseError]: - # Simulate a student input exception - with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: - mock_grade.side_effect = capa.responsetypes.StudentInputError('test error') + # Create the module + module = CapaFactory.create(attempts=1) - get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.check_problem(get_request_dict) + # Ensure that the user is NOT staff + module.system.user_is_staff = False + + # Simulate answering a problem that raises the exception + with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: + mock_grade.side_effect = exception_class('test error') + + get_request_dict = {CapaFactory.input_key(): '3.14'} + result = module.check_problem(get_request_dict) # Expect an AJAX alert message in 'success' expected_msg = 'Error: test error' self.assertEqual(expected_msg, result['success']) - # Expect that the number of attempts is NOT incremented - self.assertEqual(module.attempts, 1) + # Expect that the number of attempts is NOT incremented + self.assertEqual(module.attempts, 1) - def test_check_problem_student_input_error_with_staff_user(self): - module = CapaFactory.create(attempts=1) + def test_check_problem_error_with_staff_user(self): + + # Try each exception that capa module should handle + for exception_class in [StudentInputError, + LoncapaProblemError, + ResponseError]: - # Ensure that the user IS staff - module.system.user_is_staff = True + # Create the module + module = CapaFactory.create(attempts=1) - # Simulate a student input exception - with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: - mock_grade.side_effect = capa.responsetypes.StudentInputError('test error') + # Ensure that the user IS staff + module.system.user_is_staff = True - get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.check_problem(get_request_dict) + # Simulate answering a problem that raises an exception + with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: + mock_grade.side_effect = exception_class('test error') + + get_request_dict = {CapaFactory.input_key(): '3.14'} + result = module.check_problem(get_request_dict) # Expect an AJAX alert message in 'success' self.assertTrue('test error' in result['success']) @@ -541,6 +557,10 @@ class CapaModuleTest(unittest.TestCase): # We DO include traceback information for staff users self.assertTrue('Traceback' in result['success']) + # Expect that the number of attempts is NOT incremented + self.assertEqual(module.attempts, 1) + + def test_reset_problem(self): module = CapaFactory.create(done=True) module.new_lcp = Mock(wraps=module.new_lcp) diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 973940d784..182c45775d 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -22,7 +22,7 @@ from .models import StudentModule from psychometrics.psychoanalyze import make_psychometrics_data_update_handler from student.models import unique_id_for_user from xmodule.errortracker import exc_info_to_str -from xmodule.exceptions import NotFoundError +from xmodule.exceptions import NotFoundError, ProcessingError from xmodule.modulestore import Location from xmodule.modulestore.django import modulestore from xmodule.x_module import ModuleSystem @@ -443,9 +443,18 @@ def modx_dispatch(request, dispatch, location, course_id): # Let the module handle the AJAX try: ajax_return = instance.handle_ajax(dispatch, p) + + # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 + + # For XModule-specific errors, we respond with 404 + except ProcessingError: + log.exception("Module encountered an error while prcessing AJAX call") + raise Http404 + + # If any other error occurred, re-raise it to trigger a 500 response except: log.exception("error processing ajax call") raise From 99cd3fafdb5f0d2cbe00ad541cb0a07ad83197e5 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 14:48:44 -0400 Subject: [PATCH 075/299] Added error handling of XModule processing errors to CMS Added tests for SchematicResponse error handling --- cms/djangoapps/contentstore/views.py | 8 ++++++- .../lib/capa/capa/tests/test_responsetypes.py | 21 +++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 561708c833..6ff3e41510 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -42,7 +42,7 @@ from xmodule.modulestore.mongo import MongoUsage from mitxmako.shortcuts import render_to_response, render_to_string from xmodule.modulestore.django import modulestore from xmodule_modifiers import replace_static_urls, wrap_xmodule -from xmodule.exceptions import NotFoundError +from xmodule.exceptions import NotFoundError, ProcessingError from functools import partial from xmodule.contentstore.django import contentstore @@ -448,9 +448,15 @@ def preview_dispatch(request, preview_id, location, dispatch=None): # Let the module handle the AJAX try: ajax_return = instance.handle_ajax(dispatch, request.POST) + except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 + + except ProcessingError: + log.exception("Module raised an error while processing AJAX request") + raise Http404 + except: log.exception("error processing ajax call") raise diff --git a/common/lib/capa/capa/tests/test_responsetypes.py b/common/lib/capa/capa/tests/test_responsetypes.py index ac50e6defc..d42e9afcb8 100644 --- a/common/lib/capa/capa/tests/test_responsetypes.py +++ b/common/lib/capa/capa/tests/test_responsetypes.py @@ -13,7 +13,8 @@ import textwrap from . import test_system import capa.capa_problem as lcp -from capa.responsetypes import LoncapaProblemError, StudentInputError +from capa.responsetypes import LoncapaProblemError, \ + StudentInputError, ResponseError from capa.correctmap import CorrectMap from capa.util import convert_files_to_filenames from capa.xqueue_interface import dateformat @@ -865,7 +866,7 @@ class CustomResponseTest(ResponseTest): problem = self.build_problem(script=script, cfn="check_func") # Expect that an exception gets raised when we check the answer - with self.assertRaises(StudentInputError): + with self.assertRaises(ResponseError): problem.grade_answers({'1_2_1': '42'}) def test_script_exception_inline(self): @@ -875,7 +876,7 @@ class CustomResponseTest(ResponseTest): problem = self.build_problem(answer=script) # Expect that an exception gets raised when we check the answer - with self.assertRaises(StudentInputError): + with self.assertRaises(ResponseError): problem.grade_answers({'1_2_1': '42'}) def test_invalid_dict_exception(self): @@ -889,7 +890,7 @@ class CustomResponseTest(ResponseTest): problem = self.build_problem(script=script, cfn="check_func") # Expect that an exception gets raised when we check the answer - with self.assertRaises(LoncapaProblemError): + with self.assertRaises(ResponseError): problem.grade_answers({'1_2_1': '42'}) @@ -922,6 +923,18 @@ class SchematicResponseTest(ResponseTest): # is what we expect) self.assertEqual(correct_map.get_correctness('1_2_1'), 'correct') + def test_script_exception(self): + + # Construct a script that will raise an exception + script = "raise Exception('test')" + problem = self.build_problem(answer=script) + + # Expect that an exception gets raised when we check the answer + with self.assertRaises(ResponseError): + submission_dict = {'test': 'test'} + input_dict = {'1_2_1': json.dumps(submission_dict)} + problem.grade_answers(input_dict) + class AnnotationResponseTest(ResponseTest): from response_xml_factory import AnnotationResponseXMLFactory From df1be877390c6869b766870c7d5e40bbfe258913 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 15:20:40 -0400 Subject: [PATCH 076/299] * Changed 404 errors to 400 errors * Removed duplicate traceback log message * Now provide string, not Exception, as second tuple item to raise --- cms/djangoapps/contentstore/views.py | 2 +- common/lib/capa/capa/responsetypes.py | 3 +-- common/lib/xmodule/xmodule/capa_module.py | 2 +- lms/djangoapps/courseware/module_render.py | 6 +++--- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 6ff3e41510..24f3eae8a4 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -455,7 +455,7 @@ def preview_dispatch(request, preview_id, location, dispatch=None): except ProcessingError: log.exception("Module raised an error while processing AJAX request") - raise Http404 + return HttpResponseBadRequest() except: log.exception("error processing ajax call") diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index bc8e7ff541..3d19fb4cb1 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1237,11 +1237,10 @@ def sympy_check2(): # Log the error if we are debugging msg = 'Error occurred while evaluating CustomResponse' log.debug(msg, exc_info=True) - log.debug(traceback.format_exc()) # Notify student with a student input error _, _, traceback_obj = sys.exc_info() - raise ResponseError, ResponseError(err.message), traceback_obj + raise ResponseError, err.message, traceback_obj #----------------------------------------------------------------------------- diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index fd25016ca5..4975478421 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -461,7 +461,7 @@ class CapaModule(CapaFields, XModule): except Exception as err: _, _, traceback_obj = sys.exc_info() - raise ProcessingError, ProcessingError(err.message), traceback_obj + raise ProcessingError, err.message, traceback_obj after = self.get_progress() d.update({ diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 182c45775d..39d16dbb19 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -10,7 +10,7 @@ from django.conf import settings from django.contrib.auth.models import User from django.core.urlresolvers import reverse from django.http import Http404 -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseBadRequest from django.views.decorators.csrf import csrf_exempt from requests.auth import HTTPBasicAuth @@ -449,10 +449,10 @@ def modx_dispatch(request, dispatch, location, course_id): log.exception("Module indicating to user that request doesn't exist") raise Http404 - # For XModule-specific errors, we respond with 404 + # For XModule-specific errors, we respond with 400 except ProcessingError: log.exception("Module encountered an error while prcessing AJAX call") - raise Http404 + return HttpResponseBadRequest() # If any other error occurred, re-raise it to trigger a 500 response except: From 756f75951dca8311ff0d642af2ef3abddbf2c9b3 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Wed, 27 Mar 2013 16:28:49 -0400 Subject: [PATCH 077/299] studio - in progress work on help UI --- cms/static/client_templates/checklist.html | 2 +- cms/static/sass/_base.scss | 3 +- cms/static/sass/_variables.scss | 2 +- cms/static/sass/base-style.scss | 2 + cms/static/sass/elements/_sock.scss | 95 +++++++++++++++++++++- cms/static/sass/views/_account.scss | 2 +- cms/templates/howitworks.html | 4 +- cms/templates/widgets/footer.html | 5 +- cms/templates/widgets/sock.html | 41 +++++++++- 9 files changed, 143 insertions(+), 13 deletions(-) diff --git a/cms/static/client_templates/checklist.html b/cms/static/client_templates/checklist.html index ec6ff4e892..6884b0e9c9 100644 --- a/cms/static/client_templates/checklist.html +++ b/cms/static/client_templates/checklist.html @@ -44,7 +44,7 @@ <% if (item['action_text'] !== '' && item['action_url'] !== '') { %>
      -
    • +
    • rel="external" title="This link will open in a new browser window/tab" diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index 5901b19306..5ce131288e 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -357,7 +357,8 @@ h1 { // layout - grandfathered .main-wrapper { position: relative; - margin: 40px; + margin: ($baseline*2); + padding-bottom: $footer-primary-height; } .inner-wrapper { diff --git a/cms/static/sass/_variables.scss b/cms/static/sass/_variables.scss index ccbd3ed7b0..ffa99e3fc6 100644 --- a/cms/static/sass/_variables.scss +++ b/cms/static/sass/_variables.scss @@ -155,7 +155,7 @@ $shadow-l1: rgba(0,0,0,0.1); $shadow-d1: rgba(0,0,0,0.4); // colors - inherited -$baseFontColor: #3c3c3c; +$baseFontColor: $gray-d2; $offBlack: #3c3c3c; $green: #108614; $lightGrey: #edf1f5; diff --git a/cms/static/sass/base-style.scss b/cms/static/sass/base-style.scss index bc6638bf14..e1afa45804 100644 --- a/cms/static/sass/base-style.scss +++ b/cms/static/sass/base-style.scss @@ -21,6 +21,8 @@ @import 'base'; // elements +@import 'elements/typography'; +@import 'elements/icons'; @import 'elements/header'; @import 'elements/sock'; @import 'elements/footer'; diff --git a/cms/static/sass/elements/_sock.scss b/cms/static/sass/elements/_sock.scss index e1b147b849..e8fbcc3ef2 100644 --- a/cms/static/sass/elements/_sock.scss +++ b/cms/static/sass/elements/_sock.scss @@ -9,10 +9,101 @@ .sock { @include clearfix(); - @include font-size(13); + @extend .t-copy-sub2; max-width: $fg-max-width; min-width: $fg-min-width; width: flex-grid(12); - margin: 0 auto ($baseline*2) auto; + margin: 0 auto $baseline auto; + + header { + + .title { + @extend .t-title-3; + } + + .ss-icon { + @extend .t-icon-inline; + } + } + + // shared elements + .support, .feedback { + @include box-sizing(border-box); + + .title { + + } + + .copy { + margin: 0 0 $baseline 0; + } + + .list-actions { + @include clearfix(); + + .action-item { + float: left; + margin-right: ($baseline/2); + + &:last-child { + margin-right: 0; + } + + .action { + display: block; + + .ss-icon { + @include transition(color .25s ease-in-out); + @include font-size(15); + @extend .t-icon-inline; + @extend .icon-inline; + margin-right: ($baseline/4); + color: $blue-l2; + } + + &:hover, &:active { + + .ss-icon { + color: $white; + } + } + } + + .tip { + @extend .sr; + } + } + + .action-primary { + @include blue-button; + @include transition(all .15s); + @include font-size(13); + font-weight: 500; + padding: ($baseline/4) ($baseline/2); + text-align: center; + } + } + } + + // studio support content + .support { + width: flex-grid(8,12); + float: left; + margin-right: flex-gutter(); + + .action-item { + width: flexgrid(4,8); + } + } + + // studio feedback content + .feedback { + width: flex-grid(4,12); + float: left; + + .action-item { + width: flexgrid(4,4); + } + } } } \ No newline at end of file diff --git a/cms/static/sass/views/_account.scss b/cms/static/sass/views/_account.scss index 1206db5e76..2be94a81ea 100644 --- a/cms/static/sass/views/_account.scss +++ b/cms/static/sass/views/_account.scss @@ -71,7 +71,7 @@ body.signup, body.signin { @include blue-button; @include transition(all .15s); @include font-size(15); - display:block; + display: block; width: 100%; padding: ($baseline*0.75) ($baseline/2); font-weight: 600; diff --git a/cms/templates/howitworks.html b/cms/templates/howitworks.html index 7a819fceba..6c0029c425 100644 --- a/cms/templates/howitworks.html +++ b/cms/templates/howitworks.html @@ -134,10 +134,10 @@ diff --git a/cms/templates/widgets/footer.html b/cms/templates/widgets/footer.html index 18ecf2bc39..c00bf0187a 100644 --- a/cms/templates/widgets/footer.html +++ b/cms/templates/widgets/footer.html @@ -20,12 +20,9 @@
    • % if user.is_authenticated(): % endif - diff --git a/cms/templates/widgets/sock.html b/cms/templates/widgets/sock.html index ff5f9c9ad4..d8d191a773 100644 --- a/cms/templates/widgets/sock.html +++ b/cms/templates/widgets/sock.html @@ -2,7 +2,46 @@ % if user.is_authenticated():
      -

      Sock!

      +
      +

      Studio Support

      +
      + +
      +

      Studio Support

      + +
      +

      Need help getting started with Studio? Want to know how to manage a particular part of your course using Studio? Take advantage of our documentation, help forums, as well as our edX101 introduction course for course authors.

      +
      + + +
      + +
      % endif \ No newline at end of file From 6564cc57e6f7a2bddfab8a9dabbcc012687135a1 Mon Sep 17 00:00:00 2001 From: Jay Zoldak Date: Wed, 27 Mar 2013 16:29:55 -0400 Subject: [PATCH 078/299] Fix typo with hyphen in cms lettuce feature files --- .../contentstore/features/advanced-settings.feature | 6 +++--- .../features/studio-overview-togglesection.feature | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cms/djangoapps/contentstore/features/advanced-settings.feature b/cms/djangoapps/contentstore/features/advanced-settings.feature index 66039e19b1..db7294c14c 100644 --- a/cms/djangoapps/contentstore/features/advanced-settings.feature +++ b/cms/djangoapps/contentstore/features/advanced-settings.feature @@ -27,16 +27,16 @@ Feature: Advanced (manual) course policy And I reload the page Then the policy key value is changed - Scenario: Test how multi -line input appears + Scenario: Test how multi-line input appears Given I am on the Advanced Course Settings page in Studio When I create a JSON object as a value Then it is displayed as formatted And I reload the page Then it is displayed as formatted - Scenario: Test automatic quoting of non -JSON values + Scenario: Test automatic quoting of non-JSON values Given I am on the Advanced Course Settings page in Studio - When I create a non -JSON value not in quotes + When I create a non-JSON value not in quotes Then it is displayed as a string And I reload the page Then it is displayed as a string diff --git a/cms/djangoapps/contentstore/features/studio-overview-togglesection.feature b/cms/djangoapps/contentstore/features/studio-overview-togglesection.feature index 88492d55e3..762dea6838 100644 --- a/cms/djangoapps/contentstore/features/studio-overview-togglesection.feature +++ b/cms/djangoapps/contentstore/features/studio-overview-togglesection.feature @@ -21,7 +21,7 @@ Feature: Overview Toggle Section Then I see the "Collapse All Sections" link And all sections are expanded - @skip -phantom + @skip-phantom Scenario: Collapse link is not removed after last section of a course is deleted Given I have a course with 1 section And I navigate to the course overview page From f038237ee9f2d7a5dae9c2ebdb6a2ba57db860c8 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 16:34:08 -0400 Subject: [PATCH 079/299] Changed log.exception to log.warning --- cms/djangoapps/contentstore/views.py | 2 +- common/lib/capa/capa/responsetypes.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 24f3eae8a4..bfdfb1742b 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -454,7 +454,7 @@ def preview_dispatch(request, preview_id, location, dispatch=None): raise Http404 except ProcessingError: - log.exception("Module raised an error while processing AJAX request") + log.warning("Module raised an error while processing AJAX request") return HttpResponseBadRequest() except: diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 3d19fb4cb1..bc62654bef 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1236,7 +1236,7 @@ def sympy_check2(): # Log the error if we are debugging msg = 'Error occurred while evaluating CustomResponse' - log.debug(msg, exc_info=True) + log.warning(msg, exc_info=True) # Notify student with a student input error _, _, traceback_obj = sys.exc_info() From 9c671163fdf1be224cf4d3f310380fa9caa75cf8 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 17:11:02 -0400 Subject: [PATCH 080/299] Added exc_info=True to log.warning Changed log.exception to log.warning --- cms/djangoapps/contentstore/views.py | 3 ++- common/lib/xmodule/xmodule/capa_module.py | 3 ++- lms/djangoapps/courseware/module_render.py | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index bfdfb1742b..0d58133763 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -454,7 +454,8 @@ def preview_dispatch(request, preview_id, location, dispatch=None): raise Http404 except ProcessingError: - log.warning("Module raised an error while processing AJAX request") + log.warning("Module raised an error while processing AJAX request", + exc_info=True) return HttpResponseBadRequest() except: diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 4975478421..3e594f9d46 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -735,7 +735,8 @@ class CapaModule(CapaFields, XModule): self.set_state_from_lcp() except (StudentInputError, ResponseError, LoncapaProblemError) as inst: - log.exception("StudentInputError in capa_module:problem_check") + log.warning("StudentInputError in capa_module:problem_check", + exc_info=True) # If the user is a staff member, include # the full exception, including traceback, diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 39d16dbb19..48aab024df 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -451,7 +451,8 @@ def modx_dispatch(request, dispatch, location, course_id): # For XModule-specific errors, we respond with 400 except ProcessingError: - log.exception("Module encountered an error while prcessing AJAX call") + log.warning("Module encountered an error while prcessing AJAX call", + exc_info=True) return HttpResponseBadRequest() # If any other error occurred, re-raise it to trigger a 500 response From c8ab45cc579c675265b0d9223d61eb2c3310614c Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Wed, 27 Mar 2013 17:40:24 -0400 Subject: [PATCH 081/299] studio - footer help ui revamp - animation, structure, styling - WIP --- cms/static/js/base.js | 11 +- cms/static/sass/_base.scss | 8 ++ cms/static/sass/_cms_mixins.scss | 15 +++ cms/static/sass/_variables.scss | 2 +- cms/static/sass/base-style.scss | 1 - cms/static/sass/elements/_footer.scss | 121 ++++++++++++++++++++++ cms/static/sass/elements/_icons.scss | 16 +++ cms/static/sass/elements/_sock.scss | 109 ------------------- cms/static/sass/elements/_typography.scss | 82 +++++++++++++++ cms/templates/base.html | 5 +- cms/templates/widgets/footer.html | 45 +++++++- cms/templates/widgets/sock.html | 47 --------- 12 files changed, 299 insertions(+), 163 deletions(-) create mode 100644 cms/static/sass/elements/_icons.scss delete mode 100644 cms/static/sass/elements/_sock.scss create mode 100644 cms/static/sass/elements/_typography.scss delete mode 100644 cms/templates/widgets/sock.html diff --git a/cms/static/js/base.js b/cms/static/js/base.js index 211981b05a..d93d2fd8d4 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -34,11 +34,11 @@ $(document).ready(function () { $(this).select(); }); + $('body').addClass('js'); + $('.unit .item-actions .delete-button').bind('click', deleteUnit); $('.new-unit-item').bind('click', createNewUnit); - $('body').addClass('js'); - // lean/simple modal $('a[rel*=modal]').leanModal({overlay : 0.80, closeButton: '.action-modal-close' }); $('a.action-modal-close').click(function(e){ @@ -86,6 +86,8 @@ $(document).ready(function () { // tender feedback window scrolling $('a.show-tender').bind('click', smoothScrollTop); + // toggling footer additional support + $('.show-support').bind('click', toggleSupport); // toggling overview section details $(function () { @@ -456,6 +458,11 @@ function onKeyUp(e) { } } +function toggleSupport(e) { + e.preventDefault(); + $body.toggleClass('footer-is-expanded'); +} + function toggleSubmodules(e) { e.preventDefault(); $(this).toggleClass('expand').toggleClass('collapse'); diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index 5ce131288e..328c7e99c3 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -56,6 +56,14 @@ h1 { min-height: 100%; } +.wrapper-main { + padding-bottom: $footer-primary-height; +} + +.js.footer-is-expanded .wrapper-main { + padding-bottom: ($footer-primary-height*4); +} + // layout - basic page header .wrapper-mast { margin: 0; diff --git a/cms/static/sass/_cms_mixins.scss b/cms/static/sass/_cms_mixins.scss index 015a94b762..d837000a24 100644 --- a/cms/static/sass/_cms_mixins.scss +++ b/cms/static/sass/_cms_mixins.scss @@ -110,6 +110,21 @@ } } +@mixin gray-button { + @include button; + border: 1px solid $gray-d1; + border-radius: 3px; + @include linear-gradient(top, $white-t1, rgba(255, 255, 255, 0)); + background-color: $gray-d2; + @include box-shadow(0 1px 0 $white-t1 inset); + color: $gray-l3; + + &:hover { + background-color: $gray-d3; + color: $white; + } +} + @mixin green-button { @include button; border: 1px solid $darkGreen; diff --git a/cms/static/sass/_variables.scss b/cms/static/sass/_variables.scss index ffa99e3fc6..806fbc8c57 100644 --- a/cms/static/sass/_variables.scss +++ b/cms/static/sass/_variables.scss @@ -13,7 +13,7 @@ $fg-max-width: 1280px; $fg-min-width: 900px; // elements -$footer-primary-height: ($baseline*3); +$footer-primary-height: (60px); // type $sans-serif: 'Open Sans', $verdana; diff --git a/cms/static/sass/base-style.scss b/cms/static/sass/base-style.scss index e1afa45804..3015c3592d 100644 --- a/cms/static/sass/base-style.scss +++ b/cms/static/sass/base-style.scss @@ -24,7 +24,6 @@ @import 'elements/typography'; @import 'elements/icons'; @import 'elements/header'; -@import 'elements/sock'; @import 'elements/footer'; @import 'elements/navigation'; @import 'elements/forms'; diff --git a/cms/static/sass/elements/_footer.scss b/cms/static/sass/elements/_footer.scss index dfebc6d44c..f2941e11be 100644 --- a/cms/static/sass/elements/_footer.scss +++ b/cms/static/sass/elements/_footer.scss @@ -75,4 +75,125 @@ } } } + + // sock - additional help + .sock { + @include clearfix(); + @extend .t-copy-sub2; + max-width: $fg-max-width; + min-width: $fg-min-width; + width: flex-grid(12); + margin: 0 auto $baseline auto; + border-bottom: 1px solid $gray-l2; + padding-bottom: $baseline; + + header { + + .title { + @extend .t-title-3; + } + + .ss-icon { + @extend .t-icon; + @extend .icon-inline; + } + } + + // shared elements + .support, .feedback { + @include box-sizing(border-box); + + .title { + + } + + .copy { + margin: 0 0 $baseline 0; + } + + .list-actions { + @include clearfix(); + + .action-item { + float: left; + margin-right: ($baseline/2); + + &:last-child { + margin-right: 0; + } + + .action { + display: block; + + .ss-icon { + @include font-size(15); + @extend .t-icon; + @extend .icon-inline; + } + + &:hover, &:active { + + .ss-icon { + } + } + } + + .tip { + @extend .sr; + } + } + + .action-primary { + @include gray-button; + @include transition(all .15s); + @include font-size(13); + font-weight: 500; + padding: ($baseline/4) ($baseline/2); + text-align: center; + } + } + } + + // studio support content + .support { + width: flex-grid(8,12); + float: left; + margin-right: flex-gutter(); + + .action-item { + width: flexgrid(4,8); + } + } + + // studio feedback content + .feedback { + width: flex-grid(4,12); + float: left; + + .action-item { + width: flexgrid(4,4); + } + } + } +} + + +// js-enabled styling +.js .wrapper-footer { + @include transition(height 2s ease-in-out); + height: $footer-primary-height; + overflow: hidden; + + .sock { + display: none; + } +} + + // expanded view +.js.footer-is-expanded .wrapper-footer { + height: ($footer-primary-height*4); + + .sock { + display: block; + } } \ No newline at end of file diff --git a/cms/static/sass/elements/_icons.scss b/cms/static/sass/elements/_icons.scss new file mode 100644 index 0000000000..2bc73d8b8d --- /dev/null +++ b/cms/static/sass/elements/_icons.scss @@ -0,0 +1,16 @@ +// studio - elements - icons +// ==================== + +.icon { + +} + +.ss-icon { + +} + +.icon-inline { + display: inline-block; + vertical-align: middle; + margin-right: ($baseline/4); +} \ No newline at end of file diff --git a/cms/static/sass/elements/_sock.scss b/cms/static/sass/elements/_sock.scss deleted file mode 100644 index e8fbcc3ef2..0000000000 --- a/cms/static/sass/elements/_sock.scss +++ /dev/null @@ -1,109 +0,0 @@ -// studio - elements - sock -// ==================== - -.wrapper-sock { - margin: 0; - padding: $baseline $baseline $footer-primary-height $baseline; - position: relative; - width: 100%; - - .sock { - @include clearfix(); - @extend .t-copy-sub2; - max-width: $fg-max-width; - min-width: $fg-min-width; - width: flex-grid(12); - margin: 0 auto $baseline auto; - - header { - - .title { - @extend .t-title-3; - } - - .ss-icon { - @extend .t-icon-inline; - } - } - - // shared elements - .support, .feedback { - @include box-sizing(border-box); - - .title { - - } - - .copy { - margin: 0 0 $baseline 0; - } - - .list-actions { - @include clearfix(); - - .action-item { - float: left; - margin-right: ($baseline/2); - - &:last-child { - margin-right: 0; - } - - .action { - display: block; - - .ss-icon { - @include transition(color .25s ease-in-out); - @include font-size(15); - @extend .t-icon-inline; - @extend .icon-inline; - margin-right: ($baseline/4); - color: $blue-l2; - } - - &:hover, &:active { - - .ss-icon { - color: $white; - } - } - } - - .tip { - @extend .sr; - } - } - - .action-primary { - @include blue-button; - @include transition(all .15s); - @include font-size(13); - font-weight: 500; - padding: ($baseline/4) ($baseline/2); - text-align: center; - } - } - } - - // studio support content - .support { - width: flex-grid(8,12); - float: left; - margin-right: flex-gutter(); - - .action-item { - width: flexgrid(4,8); - } - } - - // studio feedback content - .feedback { - width: flex-grid(4,12); - float: left; - - .action-item { - width: flexgrid(4,4); - } - } - } -} \ No newline at end of file diff --git a/cms/static/sass/elements/_typography.scss b/cms/static/sass/elements/_typography.scss new file mode 100644 index 0000000000..a9b3d362ee --- /dev/null +++ b/cms/static/sass/elements/_typography.scss @@ -0,0 +1,82 @@ +// studio - elements - typography +// ==================== + +// headings/titles +.t-title-1, .t-title-2, .t-title-3, .t-title-4, .t-title-5, .t-title-5 { + color: $gray-d3; +} + +.t-title-1 { + @include font-size(32); +} + +.t-title-2 { + @include font-size(24); + margin: 0 0 ($baseline/2) 0; + font-weight: 600; +} + +.t-title-3 { + @include font-size(16); + margin: 0 0 ($baseline/2) 0; + font-weight: 600; +} + +.t-title-4 { + +} + +.t-title-5 { + +} + +// ==================== + +// copy +.t-copy-base { + @include font-size(16); +} + +.t-copy-lead1 { + @include font-size(18); +} + +.t-copy-lead2 { + @include font-size(20); +} + +.t-copy-sub1 { + @include font-size(14); +} + +.t-copy-sub2 { + @include font-size(13); +} + +.t-copy-sub3 { + @include font-size(12); +} + +// ==================== + +// actions/labels +.t-action { + @include font-size(14); + font-weight: 600; +} + +.t-action-primary { + @include font-size(14); + font-weight: 600; +} + +.t-action-primary-s { + @include font-size(13); +} + +// ==================== + +// misc +.t-icon { + line-height: 0; +} \ No newline at end of file diff --git a/cms/templates/base.html b/cms/templates/base.html index 44847c1da4..e587619bae 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -53,8 +53,9 @@
      <%include file="widgets/header.html" /> - <%block name="content"> - <%include file="widgets/sock.html" /> +
      + <%block name="content"> +
      <%include file="widgets/footer.html" />
      diff --git a/cms/templates/widgets/footer.html b/cms/templates/widgets/footer.html index c00bf0187a..b6a3b84272 100644 --- a/cms/templates/widgets/footer.html +++ b/cms/templates/widgets/footer.html @@ -1,6 +1,49 @@ <%! from django.core.urlresolvers import reverse %>
    +
    %endif @@ -202,6 +203,8 @@ function goto( mode) %if instructor_access:

    You may also delete the entire state of a student for a problem:

    +

    To delete the state of other XBlocks specify modulename/urlname, eg + combinedopenended/Humanities_SA_Peer

    %endif %endif From 57e5eb683bbb745c911d6988a3f08ac3a7e08bc2 Mon Sep 17 00:00:00 2001 From: Brian Talbot Date: Mon, 1 Apr 2013 16:54:56 -0400 Subject: [PATCH 171/299] studio - basic design, interaction, and content for static in-page help --- cms/static/js/base.js | 14 +- cms/static/sass/_base.scss | 27 ++-- cms/static/sass/_cms_mixins.scss | 103 +++++++++++++-- cms/static/sass/_variables.scss | 4 +- cms/static/sass/base-style.scss | 4 +- cms/static/sass/elements/_controls.scss | 143 ++++++++++++++++++++ cms/static/sass/elements/_footer.scss | 133 +------------------ cms/static/sass/elements/_header.scss | 2 +- cms/static/sass/elements/_sock.scss | 152 ++++++++++++++++++++++ cms/static/sass/elements/_typography.scss | 23 ++-- cms/static/sass/views/_index.scss | 3 +- cms/templates/base.html | 11 +- cms/templates/widgets/footer.html | 52 +------- cms/templates/widgets/sock.html | 52 ++++++++ 14 files changed, 499 insertions(+), 224 deletions(-) create mode 100644 cms/static/sass/elements/_controls.scss create mode 100644 cms/static/sass/elements/_sock.scss create mode 100644 cms/templates/widgets/sock.html diff --git a/cms/static/js/base.js b/cms/static/js/base.js index d93d2fd8d4..7bea860531 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -87,7 +87,7 @@ $(document).ready(function () { $('a.show-tender').bind('click', smoothScrollTop); // toggling footer additional support - $('.show-support').bind('click', toggleSupport); + $('.cta-show-sock').bind('click', toggleSock); // toggling overview section details $(function () { @@ -458,9 +458,17 @@ function onKeyUp(e) { } } -function toggleSupport(e) { +function toggleSock(e) { e.preventDefault(); - $body.toggleClass('footer-is-expanded'); + $body.toggleClass('sock-is-shown'); + + $.smoothScroll({ + offset: -200, + easing: 'swing', + speed: 1000, + scrollElement: null, + scrollTarget: $('.wrapper-sock') + }); } function toggleSubmodules(e) { diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index 328c7e99c3..10c046d22a 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -22,7 +22,7 @@ body, input { a { text-decoration: none; color: $blue; - @include transition(color .15s); + @include transition(color 0.25s ease-in-out); &:hover { color: #cb9c40; @@ -50,18 +50,22 @@ h1 { // ==================== -// layout - view +// layout - overall view .wrapper-view { - position: relative; min-height: 100%; + position: relative; } .wrapper-main { - padding-bottom: $footer-primary-height; + background: $gray-l5; + margin: ($baseline*1.5) 0 0 0; + padding-bottom: $bottom-height; } -.js.footer-is-expanded .wrapper-main { - padding-bottom: ($footer-primary-height*4); +.wrapper-bottom { + position: absolute; + bottom: 0; + height: $bottom-height; } // layout - basic page header @@ -286,19 +290,17 @@ h1 { } .title-1 { - + @extend .t-title-1; } .title-2 { - @include font-size(24); + @extend .t-title-2; margin: 0 0 ($baseline/2) 0; - font-weight: 600; } .title-3 { - @include font-size(16); + @extend .t-title-3; margin: 0 0 ($baseline/2) 0; - font-weight: 600; } .title-4 { @@ -365,8 +367,7 @@ h1 { // layout - grandfathered .main-wrapper { position: relative; - margin: ($baseline*2); - padding-bottom: $footer-primary-height; + margin: 0 ($baseline*2); } .inner-wrapper { diff --git a/cms/static/sass/_cms_mixins.scss b/cms/static/sass/_cms_mixins.scss index d837000a24..a25a07cb73 100644 --- a/cms/static/sass/_cms_mixins.scss +++ b/cms/static/sass/_cms_mixins.scss @@ -1,6 +1,7 @@ // studio - utilities - mixins and extends // ==================== +// mixins - utility @mixin clearfix { &:after { content: ''; @@ -11,6 +12,7 @@ } } +// mixins - grandfathered @mixin button { display: inline-block; padding: 4px 20px 6px; @@ -294,20 +296,97 @@ } } -@mixin sr-text { - border: 0; - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; -} - @mixin active { @include linear-gradient(top, rgba(255, 255, 255, .4), rgba(255, 255, 255, 0)); background-color: rgba(255, 255, 255, .3); @include box-shadow(0 -1px 0 rgba(0, 0, 0, .2) inset, 0 1px 0 #fff inset); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -} \ No newline at end of file +} + +// ==================== + +// extends - buttons +.btn { + @include box-sizing(border-box); + @include transition(color 0.25s ease-in-out, border-color 0.25s ease-in-out, background 0.25s ease-in-out, box-shadow 0.25s ease-in-out); + display: inline-block; + cursor: pointer; + + &:hover, &:active { + + } + + &.disabled, &[disabled] { + cursor: default; + pointer-events: none; + opacity: 0.5; + } + + .icon-inline { + display: inline-block; + vertical-align: middle; + margin-right: ($baseline/4); + } +} + +// pill button +.btn-pill { + @include border-radius($baseline/5); +} + +.btn-rounded { + @include border-radius($baseline/2); +} + +// primary button +.btn-primary { + @extend .btn; + @extend .btn-pill; + padding:($baseline/2) $baseline; + border-width: 1px; + border-style: solid; + line-height: 1.5em; + text-align: center; + + &:hover, &:active { + @include box-shadow(0 2px 1px $shadow-l1); + } + + &.current, &.active { + @include box-shadow(inset 1px 1px 2px $shadow-d1); + + &:hover, &:active { + @include box-shadow(inset 1px 1px 1px $shadow-d1); + } + } +} + +// secondary button +.btn-secondary { + @extend .btn; + @extend .btn-pill; + border-width: 1px; + border-style: solid; + padding:($baseline/2) $baseline; + background: transparent; + line-height: 1.5em; + text-align: center; + + &:hover, &:active { + + } + + &.current, &.active { + + } +} + +// ==================== + +// extends - depth levels +.depth0 { z-index: 0; } +.depth1 { z-index: 10; } +.depth2 { z-index: 100; } +.depth3 { z-index: 1000; } +.depth4 { z-index: 10000; } +.depth5 { z-index: 100000; } \ No newline at end of file diff --git a/cms/static/sass/_variables.scss b/cms/static/sass/_variables.scss index 806fbc8c57..88143c2365 100644 --- a/cms/static/sass/_variables.scss +++ b/cms/static/sass/_variables.scss @@ -13,7 +13,7 @@ $fg-max-width: 1280px; $fg-min-width: 900px; // elements -$footer-primary-height: (60px); +$bottom-height: ($baseline*3); // type $sans-serif: 'Open Sans', $verdana; @@ -170,4 +170,4 @@ $disabledGreen: rgb(124, 206, 153); $darkGreen: rgb(52, 133, 76); $lightBluishGrey: rgb(197, 207, 223); $lightBluishGrey2: rgb(213, 220, 228); -$error-red: rgb(253, 87, 87); +$error-red: rgb(253, 87, 87); \ No newline at end of file diff --git a/cms/static/sass/base-style.scss b/cms/static/sass/base-style.scss index 3015c3592d..da17441c71 100644 --- a/cms/static/sass/base-style.scss +++ b/cms/static/sass/base-style.scss @@ -23,9 +23,11 @@ // elements @import 'elements/typography'; @import 'elements/icons'; +@import 'elements/controls'; +@import 'elements/navigation'; @import 'elements/header'; @import 'elements/footer'; -@import 'elements/navigation'; +@import 'elements/sock'; @import 'elements/forms'; @import 'elements/modal'; @import 'elements/alerts'; diff --git a/cms/static/sass/elements/_controls.scss b/cms/static/sass/elements/_controls.scss new file mode 100644 index 0000000000..c4e96616a8 --- /dev/null +++ b/cms/static/sass/elements/_controls.scss @@ -0,0 +1,143 @@ +// studio - elements - UI controls +// ==================== + +// gray primary button +.btn-primary-gray { + @extend .btn-primary; + background: $gray-l1; + border-color: $gray-l2; + color: $white; + + &:hover, &:active { + border-color: $gray-l1; + background: $gray; + } + + &.current, &.active { + background: $gray-d1; + color: $gray-l1; + + &:hover, &:active { + background: $gray-d1; + } + } +} + +// blue primary button +.btn-primary-blue { + @extend .btn-primary; + background: $blue; + border-color: $blue-s1; + color: $white; + + &:hover, &:active { + background: $blue-s2; + border-color: $blue-s2; + } + + &.current, &.active { + background: $blue-d1; + color: $blue-l4; + border-color: $blue-d2; + + &:hover, &:active { + background: $blue-d1; + } + } +} + +// green primary button +.btn-primary-green { + @extend .btn-primary; + background: $green; + border-color: $green; + color: $white; + + &:hover, &:active { + background: $green-s1; + border-color: $green-s1; + } + + &.current, &.active { + background: $green-d1; + color: $green-l4; + border-color: $green-d2; + + &:hover, &:active { + background: $green-d1; + } + } +} + +// gray secondary button +.btn-secondary-gray { + @extend .btn-secondary; + border-color: $gray-l3; + color: $gray-l1; + + &:hover, &:active { + background: $gray-l3; + color: $gray-d2; + } + + &.current, &.active { + background: $gray-d2; + color: $gray-l5; + + &:hover, &:active { + background: $gray-d2; + } + } +} + +// blue secondary button +.btn-secondary-blue { + @extend .btn-secondary; + border-color: $blue-l3; + color: $blue; + + &:hover, &:active { + background: $blue-l3; + color: $blue-s2; + } + + &.current, &.active { + border-color: $blue-l3; + background: $blue-l3; + color: $blue-d1; + + &:hover, &:active { + + } + } +} + +// green secondary button +.btn-secondary-green { + @extend .btn-secondary; + border-color: $green-l4; + color: $green-l2; + + &:hover, &:active { + background: $green-l4; + color: $green-s1; + } + + &.current, &.active { + background: $green-s1; + color: $green-l4; + + &:hover, &:active { + background: $green-s1; + } + } +} + +// ==================== + +// layout-based buttons + +// ==================== + +// calls-to-action + diff --git a/cms/static/sass/elements/_footer.scss b/cms/static/sass/elements/_footer.scss index f2941e11be..d0bb9b9dee 100644 --- a/cms/static/sass/elements/_footer.scss +++ b/cms/static/sass/elements/_footer.scss @@ -3,13 +3,10 @@ .wrapper-footer { @include box-shadow(inset 0 1px 2px $shadow-d1); - margin: ($baseline*1.5) 0 0 0; - padding: $baseline; - position: absolute; - bottom: 0; + position: relative; width: 100%; - height: $footer-primary-height; - background: $gray-l3; + padding: $baseline; + background: $gray-l4; footer.primary { @include clearfix(); @@ -55,8 +52,6 @@ .ss-icon { @include transition(top .25s ease-in-out .25s); @include font-size(15); - position: relative; - top: 0; display: inline-block; vertical-align: middle; margin-right: ($baseline/4); @@ -67,133 +62,15 @@ color: $gray-d2; .ss-icon { - top: -($baseline/10); color: $gray-d2; } } - } - } - } - } - // sock - additional help - .sock { - @include clearfix(); - @extend .t-copy-sub2; - max-width: $fg-max-width; - min-width: $fg-min-width; - width: flex-grid(12); - margin: 0 auto $baseline auto; - border-bottom: 1px solid $gray-l2; - padding-bottom: $baseline; - - header { - - .title { - @extend .t-title-3; - } - - .ss-icon { - @extend .t-icon; - @extend .icon-inline; - } - } - - // shared elements - .support, .feedback { - @include box-sizing(border-box); - - .title { - - } - - .copy { - margin: 0 0 $baseline 0; - } - - .list-actions { - @include clearfix(); - - .action-item { - float: left; - margin-right: ($baseline/2); - - &:last-child { - margin-right: 0; - } - - .action { - display: block; - - .ss-icon { - @include font-size(15); - @extend .t-icon; - @extend .icon-inline; - } - - &:hover, &:active { - - .ss-icon { - } - } - } - - .tip { - @extend .sr; + &.is-active { + color: $gray-d2; } } - - .action-primary { - @include gray-button; - @include transition(all .15s); - @include font-size(13); - font-weight: 500; - padding: ($baseline/4) ($baseline/2); - text-align: center; - } } } - - // studio support content - .support { - width: flex-grid(8,12); - float: left; - margin-right: flex-gutter(); - - .action-item { - width: flexgrid(4,8); - } - } - - // studio feedback content - .feedback { - width: flex-grid(4,12); - float: left; - - .action-item { - width: flexgrid(4,4); - } - } - } -} - - -// js-enabled styling -.js .wrapper-footer { - @include transition(height 2s ease-in-out); - height: $footer-primary-height; - overflow: hidden; - - .sock { - display: none; - } -} - - // expanded view -.js.footer-is-expanded .wrapper-footer { - height: ($footer-primary-height*4); - - .sock { - display: block; } } \ No newline at end of file diff --git a/cms/static/sass/elements/_header.scss b/cms/static/sass/elements/_header.scss index e8df37f57f..12c736de7d 100644 --- a/cms/static/sass/elements/_header.scss +++ b/cms/static/sass/elements/_header.scss @@ -2,7 +2,7 @@ // ==================== .wrapper-header { - margin: 0 0 ($baseline*1.5) 0; + margin: 0; padding: $baseline; border-bottom: 1px solid $gray; @include box-shadow(0 1px 5px 0 rgba(0,0,0, 0.1)); diff --git a/cms/static/sass/elements/_sock.scss b/cms/static/sass/elements/_sock.scss new file mode 100644 index 0000000000..27f43935f6 --- /dev/null +++ b/cms/static/sass/elements/_sock.scss @@ -0,0 +1,152 @@ +// studio - elements - support sock +// ==================== + +.wrapper-sock { + @include transition(background 0.25s ease-in-out); + @include clearfix(); + position: relative; + width: 100%; + margin: ($baseline*2.5) 0; + padding: 0 $baseline; + border-top: 1px solid $gray-l4; + + // actions + .list-cta { + position: relative; + top: -($baseline); + margin: 0 auto; + text-align: center; + + .cta-show-sock { + @extend .btn-secondary-gray; + @extend .t-action3; + background: $gray-l5; + padding: ($baseline/2) $baseline; + + .icon { + @include font-size(17); + } + } + } + + // sock - additional help + .sock { + @include clearfix(); + @extend .t-copy-sub2; + display: none; + opacity: 0.0; + pointer-events: none; + max-width: $fg-max-width; + min-width: $fg-min-width; + width: flex-grid(12); + margin: 0 auto; + color: $gray-l3; + + // support body + header { + + .title { + @extend .t-title-3; + margin-bottom: ($baseline/2); + } + + .ss-icon { + @extend .t-icon; + @extend .icon-inline; + } + } + + // shared elements + .support, .feedback { + @include box-sizing(border-box); + + .title { + @extend .t-title-3; + color: $white; + } + + .copy { + margin: 0 0 $baseline 0; + } + + .list-actions { + @include clearfix(); + + .action-item { + float: left; + margin-right: ($baseline/2); + + &:last-child { + margin-right: 0; + } + + .action { + display: block; + + .icon { + @include font-size(18); + } + + &:hover, &:active { + + } + } + + .tip { + @extend .sr; + } + } + + .action-primary { + @extend .btn-primary-blue; + @extend .t-action3; + } + } + } + + // studio support content + .support { + width: flex-grid(8,12); + float: left; + margin-right: flex-gutter(); + + .action-item { + width: flexgrid(4,8); + } + } + + // studio feedback content + .feedback { + width: flex-grid(4,12); + float: left; + + .action-item { + width: flexgrid(4,4); + } + } + } +} + +// case: sock content is shown +.sock-is-shown { + + .wrapper-sock { + @include linear-gradient($gray-d4 0%, $gray-d3 2%, $gray-d3 98%, $gray-d4 100%); + border-bottom: 1px solid $white; + border-top: 1px solid $white; + padding-bottom: ($baseline*2); + padding-top: ($baseline*2); + + .cta-show-sock { + display: none; + opacity: 0.0; + pointer-events: none; + } + + .sock { + display: block; + opacity: 1.0; + pointer-events: auto; + } + } +} \ No newline at end of file diff --git a/cms/static/sass/elements/_typography.scss b/cms/static/sass/elements/_typography.scss index a9b3d362ee..32c4b3928b 100644 --- a/cms/static/sass/elements/_typography.scss +++ b/cms/static/sass/elements/_typography.scss @@ -7,18 +7,16 @@ } .t-title-1 { - @include font-size(32); + @include font-size(36); } .t-title-2 { @include font-size(24); - margin: 0 0 ($baseline/2) 0; font-weight: 600; } .t-title-3 { @include font-size(16); - margin: 0 0 ($baseline/2) 0; font-weight: 600; } @@ -60,18 +58,23 @@ // ==================== // actions/labels -.t-action { +.t-action1 { @include font-size(14); font-weight: 600; } -.t-action-primary { - @include font-size(14); - font-weight: 600; -} - -.t-action-primary-s { +.t-action2 { @include font-size(13); + font-weight: 600; + text-transform: uppercase; +} + +.t-action3 { + @include font-size(13); +} + +.t-action4 { + @include font-size(12); } // ==================== diff --git a/cms/static/sass/views/_index.scss b/cms/static/sass/views/_index.scss index 88beccc82d..7c45530339 100644 --- a/cms/static/sass/views/_index.scss +++ b/cms/static/sass/views/_index.scss @@ -296,8 +296,7 @@ body.index { // call to action content .wrapper-content-cta { position: relative; - padding-bottom: ($footer-primary-height*2); - padding-top: ($baseline*2); + padding: ($baseline*2) 0; background: $white; } diff --git a/cms/templates/base.html b/cms/templates/base.html index e587619bae..46d566116e 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -53,10 +53,17 @@
    <%include file="widgets/header.html" /> +
    - <%block name="content"> + <%block name="content"> + % if user.is_authenticated(): + <%include file="widgets/sock.html" /> + % endif +
    + +
    + <%include file="widgets/footer.html" />
    - <%include file="widgets/footer.html" />
    <%include file="widgets/tender.html" /> diff --git a/cms/templates/widgets/footer.html b/cms/templates/widgets/footer.html index b6a3b84272..eea155ce19 100644 --- a/cms/templates/widgets/footer.html +++ b/cms/templates/widgets/footer.html @@ -1,49 +1,5 @@ <%! from django.core.urlresolvers import reverse %> - - @@ -251,7 +279,7 @@

    We're sorry, there was a error with Studio

    -

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

    +

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.

    @@ -263,7 +291,7 @@
    @@ -320,7 +348,7 @@

    Your Studio account has been created, but needs to be activated

    -

    Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Curabitur blandit tempus porttitor.

    +

    Donec sed odio dui. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Curabitur blandit tempus porttitor.