Merge pull request #9845 from edx/christina/bio-hyperlink
Make HTML for non-editable views on leaner profile page more logical
This commit is contained in:
@@ -143,7 +143,11 @@ class FieldsMixin(object):
|
||||
"""
|
||||
self.wait_for_field(field_id)
|
||||
|
||||
return self.value_for_text_field(field_id)
|
||||
query = self.q(css='.u-field-{} .u-field-value'.format(field_id))
|
||||
if not query.present:
|
||||
return None
|
||||
|
||||
return query.text[0]
|
||||
|
||||
def value_for_text_field(self, field_id, value=None, press_enter=True):
|
||||
"""
|
||||
|
||||
@@ -24,6 +24,16 @@ class AccountSettingsTestMixin(EventsTestMixin, WebAppTest):
|
||||
USER_SETTINGS_CHANGED_EVENT_NAME = 'edx.user.settings.changed'
|
||||
ACCOUNT_SETTINGS_REFERER = u"/account/settings"
|
||||
|
||||
def visit_account_settings_page(self):
|
||||
"""
|
||||
Visit the account settings page for the current user, and store the page instance
|
||||
as self.account_settings_page.
|
||||
"""
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
self.account_settings_page = AccountSettingsPage(self.browser)
|
||||
self.account_settings_page.visit()
|
||||
self.account_settings_page.wait_for_ajax()
|
||||
|
||||
def log_in_as_unique_user(self, email=None):
|
||||
"""
|
||||
Create a unique user and return the account's username and id.
|
||||
@@ -116,14 +126,6 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, WebAppTest):
|
||||
self.username, self.user_id = self.log_in_as_unique_user()
|
||||
self.visit_account_settings_page()
|
||||
|
||||
def visit_account_settings_page(self):
|
||||
"""
|
||||
Visit the account settings page for the current user.
|
||||
"""
|
||||
self.account_settings_page = AccountSettingsPage(self.browser)
|
||||
self.account_settings_page.visit()
|
||||
self.account_settings_page.wait_for_ajax()
|
||||
|
||||
def test_page_view_event(self):
|
||||
"""
|
||||
Scenario: An event should be recorded when the "Account Settings"
|
||||
@@ -444,3 +446,18 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, WebAppTest):
|
||||
for field_id, title, link_title in providers:
|
||||
self.assertEqual(self.account_settings_page.title_for_field(field_id), title)
|
||||
self.assertEqual(self.account_settings_page.link_title_for_link_field(field_id), link_title)
|
||||
|
||||
|
||||
@attr('a11y')
|
||||
class AccountSettingsA11yTest(AccountSettingsTestMixin, WebAppTest):
|
||||
"""
|
||||
Class to test account settings accessibility.
|
||||
"""
|
||||
|
||||
def test_account_settings_a11y(self):
|
||||
"""
|
||||
Test the accessibility of the account settings page.
|
||||
"""
|
||||
self.log_in_as_unique_user()
|
||||
self.visit_account_settings_page()
|
||||
self.account_settings_page.a11y_audit.check_for_accessibility_errors()
|
||||
|
||||
@@ -147,6 +147,26 @@ class LearnerProfileTestMixin(EventsTestMixin):
|
||||
with self.assert_events_match_during(event_filter=event_filter, expected_events=[expected_event]):
|
||||
yield
|
||||
|
||||
def initialize_different_user(self, privacy=None, birth_year=None):
|
||||
"""
|
||||
Initialize the profile page for a different test user
|
||||
"""
|
||||
username, user_id = self.log_in_as_unique_user()
|
||||
|
||||
# Set the privacy for the new user
|
||||
if privacy is None:
|
||||
privacy = self.PRIVACY_PUBLIC
|
||||
self.visit_profile_page(username, privacy=privacy)
|
||||
|
||||
# Set the user's year of birth
|
||||
if birth_year:
|
||||
self.set_birth_year(birth_year)
|
||||
|
||||
# Log the user out
|
||||
LogoutPage(self.browser).visit()
|
||||
|
||||
return username, user_id
|
||||
|
||||
|
||||
@attr('shard_4')
|
||||
class OwnLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
|
||||
@@ -677,7 +697,7 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
|
||||
Then I shouldn't see the profile visibility selector dropdown.
|
||||
Then I see some of the profile fields are shown.
|
||||
"""
|
||||
different_username, different_user_id = self._initialize_different_user(privacy=self.PRIVACY_PRIVATE)
|
||||
different_username, different_user_id = self.initialize_different_user(privacy=self.PRIVACY_PRIVATE)
|
||||
username, __ = self.log_in_as_unique_user()
|
||||
profile_page = self.visit_profile_page(different_username)
|
||||
self.verify_profile_page_is_private(profile_page, is_editable=False)
|
||||
@@ -693,7 +713,7 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
|
||||
Then I see that only the private fields are shown.
|
||||
"""
|
||||
under_age_birth_year = datetime.now().year - 10
|
||||
different_username, different_user_id = self._initialize_different_user(
|
||||
different_username, different_user_id = self.initialize_different_user(
|
||||
privacy=self.PRIVACY_PUBLIC,
|
||||
birth_year=under_age_birth_year
|
||||
)
|
||||
@@ -713,29 +733,52 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
|
||||
Then I shouldn't see the profile visibility selector dropdown.
|
||||
Also `location`, `language` and `about me` fields are not editable.
|
||||
"""
|
||||
different_username, different_user_id = self._initialize_different_user(privacy=self.PRIVACY_PUBLIC)
|
||||
different_username, different_user_id = self.initialize_different_user(privacy=self.PRIVACY_PUBLIC)
|
||||
username, __ = self.log_in_as_unique_user()
|
||||
profile_page = self.visit_profile_page(different_username)
|
||||
profile_page.wait_for_public_fields()
|
||||
self.verify_profile_page_is_public(profile_page, is_editable=False)
|
||||
self.verify_profile_page_view_event(username, different_user_id, visibility=self.PRIVACY_PUBLIC)
|
||||
|
||||
def _initialize_different_user(self, privacy=None, birth_year=None):
|
||||
|
||||
@attr('a11y')
|
||||
class LearnerProfileA11yTest(LearnerProfileTestMixin, WebAppTest):
|
||||
"""
|
||||
Class to test learner profile accessibility.
|
||||
"""
|
||||
|
||||
def test_editable_learner_profile_a11y(self):
|
||||
"""
|
||||
Initialize the profile page for a different test user
|
||||
Test the accessibility of the editable version of the profile page
|
||||
(user viewing her own public profile).
|
||||
"""
|
||||
username, user_id = self.log_in_as_unique_user()
|
||||
username, _ = self.log_in_as_unique_user()
|
||||
profile_page = self.visit_profile_page(username)
|
||||
|
||||
# Set the privacy for the new user
|
||||
if privacy is None:
|
||||
privacy = self.PRIVACY_PUBLIC
|
||||
self.visit_profile_page(username, privacy=privacy)
|
||||
# TODO: There are several existing color contrast errors on this page,
|
||||
# we will ignore this error in the test until we fix them.
|
||||
profile_page.a11y_audit.config.set_rules({
|
||||
"ignore": ['color-contrast'],
|
||||
})
|
||||
|
||||
# Set the user's year of birth
|
||||
if birth_year:
|
||||
self.set_birth_year(birth_year)
|
||||
profile_page.a11y_audit.check_for_accessibility_errors()
|
||||
|
||||
# Log the user out
|
||||
LogoutPage(self.browser).visit()
|
||||
profile_page.make_field_editable('language_proficiencies')
|
||||
profile_page.a11y_audit.check_for_accessibility_errors()
|
||||
|
||||
return username, user_id
|
||||
profile_page.make_field_editable('bio')
|
||||
profile_page.a11y_audit.check_for_accessibility_errors()
|
||||
|
||||
def test_read_only_learner_profile_a11y(self):
|
||||
"""
|
||||
Test the accessibility of the read-only version of a public profile page
|
||||
(user viewing someone else's profile page).
|
||||
"""
|
||||
# initialize_different_user should cause country, language, and bio to be filled out (since
|
||||
# privacy is public). It doesn't appear that this is happening, although the method
|
||||
# works in regular bokchoy tests. Perhaps a problem with phantomjs? So this test is currently
|
||||
# only looking at a read-only profile page with a username.
|
||||
different_username, _ = self.initialize_different_user(privacy=self.PRIVACY_PUBLIC)
|
||||
self.log_in_as_unique_user()
|
||||
profile_page = self.visit_profile_page(different_username)
|
||||
profile_page.a11y_audit.check_for_accessibility_errors()
|
||||
|
||||
@@ -63,6 +63,10 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
expect(view.$('.u-field-title').text().trim()).toContain(expectedTitle);
|
||||
};
|
||||
|
||||
var expectDropdownSrTitleToContain = function(view, expectedTitle) {
|
||||
expect(view.$('.u-field-value .sr').text().trim()).toContain(expectedTitle);
|
||||
};
|
||||
|
||||
var expectMessageContains = function(view, expectedText) {
|
||||
expect(view.$('.u-field-message').html()).toContain(expectedText);
|
||||
};
|
||||
@@ -167,7 +171,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
expectMessageContains(view, view.indicators.canEdit);
|
||||
view.$el.click();
|
||||
} else {
|
||||
expectTitleAndMessageToContain(view, data.title, data.helpMessage, false);
|
||||
expectTitleAndMessageToContain(view, data.title, data.helpMessage);
|
||||
}
|
||||
expect(view.el).toHaveClass('mode-edit');
|
||||
|
||||
@@ -254,6 +258,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
createFieldData: createFieldData,
|
||||
createErrorMessage: createErrorMessage,
|
||||
expectTitleToContain: expectTitleToContain,
|
||||
expectDropdownSrTitleToContain: expectDropdownSrTitleToContain,
|
||||
expectTitleAndMessageToContain: expectTitleAndMessageToContain,
|
||||
expectMessageContains: expectMessageContains,
|
||||
expectAjaxRequestWithData: expectAjaxRequestWithData,
|
||||
|
||||
@@ -10,7 +10,10 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
describe("edx.FieldViews", function () {
|
||||
|
||||
var requests,
|
||||
timerCallback;
|
||||
timerCallback,
|
||||
dropdownSelectClass = '.u-field-value > select',
|
||||
dropdownButtonClass = '.u-field-value > button',
|
||||
textareaLinkClass = '.u-field-value a';
|
||||
|
||||
var fieldViewClasses = [
|
||||
FieldViews.ReadonlyFieldView,
|
||||
@@ -89,11 +92,11 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
});
|
||||
var view = new FieldViews.ReadonlyFieldView(fieldData).render();
|
||||
|
||||
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false);
|
||||
expect(view.$('.u-field-value input').val().trim()).toBe(USERNAME);
|
||||
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
|
||||
expect(view.fieldValue()).toBe(USERNAME);
|
||||
|
||||
view.model.set({'username': 'bookworm'});
|
||||
expect(view.$('.u-field-value input').val().trim()).toBe('bookworm');
|
||||
expect(view.fieldValue()).toBe('bookworm');
|
||||
});
|
||||
|
||||
it("correctly renders, updates and persists changes to TextFieldView when editable == always", function() {
|
||||
@@ -133,13 +136,30 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
|
||||
});
|
||||
var view = new FieldViews.DropdownFieldView(fieldData).render();
|
||||
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false);
|
||||
var readOnlyDisplayClass = '.u-field-value-readonly';
|
||||
|
||||
FieldViewsSpecHelpers.expectDropdownSrTitleToContain(view, fieldData.title);
|
||||
FieldViewsSpecHelpers.expectMessageContains(view, fieldData.helpMessage);
|
||||
expect(view.el).toHaveClass('mode-hidden');
|
||||
// Note that "name" will be retrieved from the model, but the options specified are
|
||||
// the languages options. Therefore initially the placeholder message will be shown because
|
||||
// the model value does not match any of the possible options.
|
||||
expect(view.fieldValue()).toBeNull();
|
||||
expect(view.$(readOnlyDisplayClass).text()).toBe(fieldData.placeholderValue);
|
||||
// Make sure that the select and the button are not in the HTML.
|
||||
expect(view.$(dropdownSelectClass).length).toBe(0);
|
||||
expect(view.$(dropdownButtonClass).length).toBe(0);
|
||||
|
||||
view.model.set({'name': fieldData.options[1][0]});
|
||||
expect(view.el).toHaveClass('mode-display');
|
||||
expect(view.fieldValue()).toBe(fieldData.options[1][0]);
|
||||
expect(view.$(readOnlyDisplayClass).text()).toBe(fieldData.options[1][1]);
|
||||
|
||||
view.$el.click();
|
||||
expect(view.el).toHaveClass('mode-display');
|
||||
// Make sure that the select and the button still are not in the HTML.
|
||||
expect(view.$(dropdownSelectClass).length).toBe(0);
|
||||
expect(view.$(dropdownButtonClass).length).toBe(0);
|
||||
});
|
||||
|
||||
it("correctly renders, updates and persists changes to DropdownFieldView when editable == always", function() {
|
||||
@@ -210,12 +230,16 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
expect(view.modelValueIsSet()).toBe(false);
|
||||
expect(view.displayValue()).toBe('');
|
||||
|
||||
if(editable === 'toggle') { view.showEditMode(true); }
|
||||
view.$('.u-field-value > select').val(FieldViewsSpecHelpers.SELECT_OPTIONS[0]).change();
|
||||
if (editable === 'toggle') {
|
||||
expect(view.$(dropdownButtonClass).length).toBe(1);
|
||||
view.showEditMode(true);
|
||||
}
|
||||
expect(view.$(dropdownSelectClass).length).toBe(1);
|
||||
view.$(dropdownSelectClass).val(FieldViewsSpecHelpers.SELECT_OPTIONS[0]).change();
|
||||
expect(view.fieldValue()).toBe(FieldViewsSpecHelpers.SELECT_OPTIONS[0][0]);
|
||||
|
||||
AjaxHelpers.respondWithNoContent(requests);
|
||||
if(editable === 'toggle') { view.showEditMode(true); }
|
||||
if (editable === 'toggle') { view.showEditMode(true); }
|
||||
// When server returns success, there should no longer be an empty option.
|
||||
expect($(view.$('.u-field-value option')[0]).val()).toBe('si');
|
||||
});
|
||||
@@ -236,16 +260,18 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
// set bio to empty to see the placeholder.
|
||||
fieldData.model.set({bio: ''});
|
||||
var view = new FieldViews.TextareaFieldView(fieldData).render();
|
||||
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false);
|
||||
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
|
||||
expect(view.el).toHaveClass('mode-hidden');
|
||||
expect(view.$('.u-field-value .u-field-value-readonly').text()).toBe(fieldData.placeholderValue);
|
||||
expect(view.fieldValue()).toBe(fieldData.placeholderValue);
|
||||
expect(view.$(textareaLinkClass).length).toBe(0);
|
||||
|
||||
var bio = 'Too much to tell!';
|
||||
view.model.set({'bio': bio});
|
||||
expect(view.el).toHaveClass('mode-display');
|
||||
expect(view.$('.u-field-value .u-field-value-readonly').text()).toBe(bio);
|
||||
expect(view.fieldValue()).toBe(bio);
|
||||
view.$el.click();
|
||||
expect(view.el).toHaveClass('mode-display');
|
||||
expect(view.$(textareaLinkClass).length).toBe(0);
|
||||
});
|
||||
|
||||
it("correctly renders, updates and persists changes to TextAreaFieldView when editable == toggle", function() {
|
||||
@@ -270,23 +296,26 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
FieldViewsSpecHelpers.expectTitleToContain(view, fieldData.title);
|
||||
FieldViewsSpecHelpers.expectMessageContains(view, view.indicators.canEdit);
|
||||
expect(view.el).toHaveClass('mode-placeholder');
|
||||
expect(view.$('.u-field-value .u-field-value-readonly').text()).toBe(fieldData.placeholderValue);
|
||||
expect(view.fieldValue()).toBe(fieldData.placeholderValue);
|
||||
expect(view.$(textareaLinkClass).length).toBe(1);
|
||||
|
||||
view.$('.wrapper-u-field').click();
|
||||
expect(view.el).toHaveClass('mode-edit');
|
||||
view.$(valueInputSelector).val(BIO).focusout();
|
||||
expect(view.fieldValue()).toBe(BIO);
|
||||
expect(view.$(textareaLinkClass).length).toBe(0);
|
||||
AjaxHelpers.expectJsonRequest(
|
||||
requests, 'PATCH', view.model.url, {'bio': BIO}
|
||||
);
|
||||
AjaxHelpers.respondWithNoContent(requests);
|
||||
expect(view.el).toHaveClass('mode-display');
|
||||
expect(view.$(textareaLinkClass).length).toBe(1);
|
||||
|
||||
view.$('.wrapper-u-field').click();
|
||||
view.$(valueInputSelector).val('').focusout();
|
||||
AjaxHelpers.respondWithNoContent(requests);
|
||||
expect(view.el).toHaveClass('mode-placeholder');
|
||||
expect(view.$('.u-field-value .u-field-value-readonly').text()).toBe(fieldData.placeholderValue);
|
||||
expect(view.fieldValue()).toBe(fieldData.placeholderValue);
|
||||
});
|
||||
|
||||
it("correctly renders LinkFieldView", function() {
|
||||
@@ -298,7 +327,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
});
|
||||
var view = new FieldViews.LinkFieldView(fieldData).render();
|
||||
|
||||
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false);
|
||||
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
|
||||
expect(view.$('.u-field-value > a .u-field-link-title-' + view.options.valueAttribute).text().trim()).toBe(fieldData.linkTitle);
|
||||
});
|
||||
|
||||
@@ -311,7 +340,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
|
||||
});
|
||||
var view = new FieldViews.LinkFieldView(fieldData).render();
|
||||
|
||||
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false);
|
||||
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
|
||||
expect(view.$('.u-field-value > a .u-field-link-title-' + view.options.valueAttribute).text().trim()).toBe(fieldData.linkTitle);
|
||||
});
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
},
|
||||
|
||||
finishEditing: function() {
|
||||
if (this.persistChanges === false) {return;}
|
||||
if (this.persistChanges === false || this.mode !== 'edit') {return;}
|
||||
if (this.fieldValue() !== this.modelValue()) {
|
||||
this.saveValue();
|
||||
} else {
|
||||
@@ -271,11 +271,11 @@
|
||||
},
|
||||
|
||||
fieldValue: function () {
|
||||
return this.$('.u-field-value input').val();
|
||||
return this.$('.u-field-value').text();
|
||||
},
|
||||
|
||||
updateValueInField: function () {
|
||||
this.$('.u-field-value input').val(_.escape(this.modelValue()));
|
||||
this.$('.u-field-value ').html(_.escape(this.modelValue()));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -345,9 +345,10 @@
|
||||
this.$el.html(this.template({
|
||||
id: this.options.valueAttribute,
|
||||
mode: this.mode,
|
||||
editable: this.editable,
|
||||
title: this.options.title,
|
||||
screenReaderTitle: this.options.screenReaderTitle || this.options.title,
|
||||
titleVisible: this.options.titleVisible || true,
|
||||
titleVisible: this.options.titleVisible !== undefined ? this.options.titleVisible : true,
|
||||
iconName: this.options.iconName,
|
||||
showBlankOption: (!this.options.required || !this.modelValueIsSet()),
|
||||
selectOptions: this.options.options,
|
||||
@@ -376,7 +377,13 @@
|
||||
},
|
||||
|
||||
fieldValue: function () {
|
||||
var value = this.$('.u-field-value select').val();
|
||||
var value;
|
||||
if (this.editable === 'never') {
|
||||
value = this.modelValueIsSet() ? this.modelValue () : null;
|
||||
}
|
||||
else {
|
||||
value = this.$('.u-field-value select').val();
|
||||
}
|
||||
return value === '' ? null : value;
|
||||
},
|
||||
|
||||
@@ -390,7 +397,9 @@
|
||||
},
|
||||
|
||||
updateValueInField: function () {
|
||||
this.$('.u-field-value select').val(this.modelValue() || '');
|
||||
if (this.editable !== 'never') {
|
||||
this.$('.u-field-value select').val(this.modelValue() || '');
|
||||
}
|
||||
|
||||
var value = this.displayValue(this.modelValue() || '');
|
||||
if (this.modelValueIsSet() === false) {
|
||||
@@ -437,7 +446,9 @@
|
||||
},
|
||||
|
||||
disableField: function(disable) {
|
||||
this.$('.u-field-value select').prop('disabled', disable);
|
||||
if (this.editable !== 'never') {
|
||||
this.$('.u-field-value select').prop('disabled', disable);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -473,6 +484,7 @@
|
||||
id: this.options.valueAttribute,
|
||||
screenReaderTitle: this.options.screenReaderTitle || this.options.title,
|
||||
mode: this.mode,
|
||||
editable: this.editable,
|
||||
value: value,
|
||||
message: this.helpMessage,
|
||||
messagePosition: this.options.messagePosition || 'footer',
|
||||
@@ -504,11 +516,16 @@
|
||||
|
||||
modelValue: function() {
|
||||
var value = this._super();
|
||||
return value ? $.trim(value) : '';
|
||||
return value ? $.trim(value) : '';
|
||||
},
|
||||
|
||||
fieldValue: function () {
|
||||
return this.$('.u-field-value textarea').val();
|
||||
if (this.mode === 'edit') {
|
||||
return this.$('.u-field-value textarea').val();
|
||||
}
|
||||
else {
|
||||
return this.$('.u-field-value .u-field-value-readonly').text();
|
||||
}
|
||||
},
|
||||
|
||||
saveValue: function () {
|
||||
|
||||
@@ -133,6 +133,8 @@
|
||||
padding: 0;
|
||||
box-shadow: none;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
.view-profile {
|
||||
$profile-image-dimension: 120px;
|
||||
|
||||
.window-wrap,
|
||||
.content-wrapper {
|
||||
background-color: $white;
|
||||
}
|
||||
@@ -34,6 +35,7 @@
|
||||
|
||||
.u-field-image {
|
||||
padding-top: 0;
|
||||
padding-bottom: ($baseline/4);
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
@@ -128,10 +130,11 @@
|
||||
.wrapper-profile-field-account-privacy {
|
||||
@include clearfix();
|
||||
@include box-sizing(border-box);
|
||||
margin: 0 auto 0;
|
||||
padding: ($baseline*0.75) 0;
|
||||
width: 100%;
|
||||
background-color: $gray-l3;
|
||||
margin: 0 auto 0;
|
||||
border: 1px solid $gray-l3;
|
||||
background-color: $gray-l4;
|
||||
padding: ($baseline*0.75) 0;
|
||||
|
||||
.u-field-account_privacy {
|
||||
@extend .container;
|
||||
@@ -141,10 +144,11 @@
|
||||
}
|
||||
|
||||
.u-field-title {
|
||||
@extend %t-strong;
|
||||
width: auto;
|
||||
color: $base-font-color;
|
||||
font-weight: $font-bold;
|
||||
cursor: text;
|
||||
text-shadow: none; // override bad lms styles on labels
|
||||
}
|
||||
|
||||
.u-field-value {
|
||||
@@ -157,6 +161,10 @@
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
color: $base-font-color;
|
||||
|
||||
.u-field-message-notification {
|
||||
color: $gray-d2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,22 +178,22 @@
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
margin-top: ($baseline*1.5);
|
||||
@include margin-left($baseline/2);
|
||||
}
|
||||
|
||||
.profile-section-one-fields {
|
||||
@include float(left);
|
||||
width: flex-grid(4, 12);
|
||||
@include margin-left($baseline*1.5);
|
||||
@include margin-left($baseline);
|
||||
|
||||
.u-field {
|
||||
margin-bottom: ($baseline/4);
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
@include padding-left(3px);
|
||||
}
|
||||
|
||||
.u-field-username {
|
||||
margin-bottom: ($baseline/2);
|
||||
|
||||
input[type="text"] {
|
||||
font-weight: 600;
|
||||
@@ -197,12 +205,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
.u-field-icon {
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.u-field-title {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.u-field-value {
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
select {
|
||||
@@ -212,7 +227,13 @@
|
||||
.u-field-message {
|
||||
@include float(right);
|
||||
width: 20px;
|
||||
margin-top: 2px;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
margin-top: 0;
|
||||
|
||||
.icon {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,30 +245,40 @@
|
||||
|
||||
.u-field-textarea {
|
||||
margin-bottom: ($baseline/2);
|
||||
padding: ($baseline/4) ($baseline/2) ($baseline/2);
|
||||
padding: ($baseline/2) ($baseline*.75) ($baseline*.75) ($baseline*.75);
|
||||
|
||||
&.editable-toggle {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.u-field-title {
|
||||
font-size: 1.1em;
|
||||
@extend %t-title5;
|
||||
@extend %t-weight4;
|
||||
display: inline-block;
|
||||
margin-top: 0;
|
||||
margin-bottom: ($baseline/4);
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.u-field-value {
|
||||
@extend %t-copy-base;
|
||||
width: 100%;
|
||||
white-space: pre-line;
|
||||
line-height: 1.5em;
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.u-field-message {
|
||||
@include float(right);
|
||||
width: auto;
|
||||
padding-top: ($baseline/4);
|
||||
}
|
||||
|
||||
.u-field.mode-placeholder {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<% if (title) { %>
|
||||
<label class="u-field-title" for="u-field-select-<%- id %>">
|
||||
<%- title %>
|
||||
</label>
|
||||
<% } %>
|
||||
|
||||
<% if (!titleVisible) { %>
|
||||
<label class="sr" for="u-field-select-<%- id %>">
|
||||
<%- screenReaderTitle %>
|
||||
</label>
|
||||
<% if (editable !== 'never') { %>
|
||||
<% if (title && titleVisible) { %>
|
||||
<label class="u-field-title" for="u-field-select-<%- id %>">
|
||||
<%- title %>
|
||||
</label>
|
||||
<% } else { %>
|
||||
<label class="sr" for="u-field-select-<%- id %>">
|
||||
<%- screenReaderTitle %>
|
||||
</label>
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
<% if (iconName) { %>
|
||||
@@ -15,19 +15,24 @@
|
||||
<% } %>
|
||||
|
||||
<span class="u-field-value">
|
||||
<select name="select" id="u-field-select-<%- id %>" aria-describedby="u-field-message-<%- id %>">
|
||||
<% if (showBlankOption) { %>
|
||||
<option value=""></option>
|
||||
<% } %>
|
||||
<% _.each(selectOptions, function(selectOption) { %>
|
||||
<option value="<%- selectOption[0] %>"><%- selectOption[1] %></option>
|
||||
<% }); %>
|
||||
</select>
|
||||
<button class="u-field-value-display">
|
||||
<% if (editable === 'never') { %>
|
||||
<span class="sr"><%- screenReaderTitle %> </span>
|
||||
<span class="u-field-value-readonly"></span>
|
||||
<span class="sr"> <%- gettext('Click to edit') %></span>
|
||||
</button>
|
||||
<% } else { %>
|
||||
<select name="select" id="u-field-select-<%- id %>" aria-describedby="u-field-message-<%- id %>">
|
||||
<% if (showBlankOption) { %>
|
||||
<option value=""></option>
|
||||
<% } %>
|
||||
<% _.each(selectOptions, function(selectOption) { %>
|
||||
<option value="<%- selectOption[0] %>"><%- selectOption[1] %></option>
|
||||
<% }); %>
|
||||
</select>
|
||||
<button class="u-field-value-display">
|
||||
<span class="sr"><%- screenReaderTitle %> </span>
|
||||
<span class="u-field-value-readonly"></span>
|
||||
<span class="sr"> <%- gettext('Click to edit') %></span>
|
||||
</button>
|
||||
<% } %>
|
||||
</span>
|
||||
|
||||
<span class="u-field-message" id="u-field-message-<%- id %>">
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<label class="u-field-title" aria-hidden="true">
|
||||
<%- title %>
|
||||
</label>
|
||||
<span class="sr" for="u-field-input-<%- id %>"><%- screenReaderTitle %></span>
|
||||
<span class="u-field-value">
|
||||
<input id="u-field-input-<%- id %>" aria-describedby="u-field-message-<%- id %>" type="text" name="input" readonly=true value="<%- value %>">
|
||||
</span>
|
||||
<% if (title) { %>
|
||||
<span class="u-field-title" aria-hidden="true"><%- title %></span>
|
||||
<% } %>
|
||||
<span class="sr" for="u-field-value-<%- id %>"><%- screenReaderTitle %></span>
|
||||
<span class="u-field-value" id="u-field-value-<%- id %>" aria-describedby="u-field-message-<%- id %>"><%- value %></span>
|
||||
<span class="u-field-message" id="u-field-message-<%- id %>">
|
||||
<span class="u-field-message-notification" aria-live="polite"></span>
|
||||
<span class="u-field-message-help" id="u-field-help-message-<%- id %>"> <%- message %></span>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<div class="wrapper-u-field">
|
||||
<div class="u-field-header">
|
||||
<label class="u-field-title" for="u-field-textarea-<%- id %>" id="u-field-title-<%- id %>" aria-describedby="u-field-message-help-<%- id %>"></label>
|
||||
<% if (mode === 'edit') { %>
|
||||
<label class="u-field-title" for="u-field-textarea-<%- id %>" id="u-field-title-<%- id %>"></label>
|
||||
<% } else { %>
|
||||
<span class="u-field-title" id="u-field-title-<%- id %>" aria-hidden="true"></span>
|
||||
<% } %>
|
||||
<% if (messagePosition === 'header') { %>
|
||||
<span class="u-field-message" id="u-field-message-<%- id %>">
|
||||
<span class="u-field-message-notification" aria-live="polite"></span>
|
||||
@@ -9,14 +13,23 @@
|
||||
<% }%>
|
||||
</div>
|
||||
|
||||
<div class="u-field-value" id="u-field-value-<%- id %>" aria-labelledby="u-field-title-<%- id %>"><%
|
||||
var textareaDescribedBy = (message ? 'u-field-message-help-' : 'u-field-placeholder-value-') + id;
|
||||
if (mode === 'edit') {%>
|
||||
<textarea id="u-field-textarea-<%- id %>" rows="4" aria-describedby="<%- textareaDescribedBy %>"><%- value %></textarea>
|
||||
<% } else {
|
||||
%><a href="#"><span class="sr"><%- screenReaderTitle %></span><span class="u-field-value-readonly" aria-hidden="false" aria-describedby="u-field-placeholder-value-<%- id %>"><%- value %></span><span class="sr"><%- gettext('Click to edit') %></span></a><%
|
||||
}
|
||||
%><span class="sr" id="u-field-placeholder-value-<%- id %>"><%- placeholderValue %></span>
|
||||
<div class="u-field-value" id="u-field-value-<%- id %>"
|
||||
<% if (mode === 'edit') { %>
|
||||
aria-labelledby="u-field-title-<%- id %>"><textarea id="u-field-textarea-<%- id %>" rows="4"
|
||||
<% if (message) { %>
|
||||
aria-describedby="u-field-message-help-<%- id %>"
|
||||
<% } %>
|
||||
><%- value %></textarea>
|
||||
<% } else if (editable === 'never') { %>
|
||||
><p class="sr"><%- screenReaderTitle %></p><span class="u-field-value-readonly" aria-hidden="false"
|
||||
<% if (message) { %>
|
||||
aria-describedby="u-field-message-help-<%- id %>"
|
||||
<% } %>
|
||||
><%- value %></span>
|
||||
<% } else { %>
|
||||
><a href="#"><p class="sr"><%- screenReaderTitle %></p><span class="u-field-value-readonly" aria-hidden="false" aria-describedby="u-field-placeholder-value-<%- id %>"><%- value %></span><span class="sr"><%- gettext('Click to edit') %></span></a>
|
||||
<span class="sr" id="u-field-placeholder-value-<%- id %>"><%- placeholderValue %></span>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
<div class="u-field-footer">
|
||||
|
||||
@@ -12,7 +12,7 @@ from microsite_configuration import microsite
|
||||
<%namespace name='static' file='/static_content.html'/>
|
||||
|
||||
<%block name="pagetitle">${_("Account Settings")}</%block>
|
||||
<%block name="nav_skip">#u-field-input-username</%block>
|
||||
<%block name="nav_skip">#content</%block>
|
||||
|
||||
% if duplicate_provider:
|
||||
<section>
|
||||
|
||||
@@ -8,7 +8,7 @@ from openedx.core.lib.json_utils import EscapedEdxJSONEncoder
|
||||
%>
|
||||
|
||||
<%block name="pagetitle">${_("Learner Profile")}</%block>
|
||||
<%block name="nav_skip">#u-field-select-account_privacy</%block>
|
||||
<%block name="nav_skip">#content</%block>
|
||||
|
||||
<%block name="bodyclass">view-profile</%block>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user