Refactor discussion tab UI code into parts to be reusable for inline discussions

TNL-5669
This commit is contained in:
alisan617
2016-10-20 21:47:31 -04:00
parent 8ffc9197e8
commit e80d9b5792
22 changed files with 664 additions and 704 deletions

View File

@@ -5,38 +5,50 @@
[
'jquery',
'backbone',
'common/js/discussion/content',
'common/js/discussion/discussion',
'common/js/discussion/utils',
'common/js/discussion/models/discussion_course_settings',
'common/js/discussion/models/discussion_user',
'common/js/discussion/views/new_post_view',
'discussion/js/discussion_router',
'discussion/js/views/discussion_fake_breadcrumbs',
'discussion/js/views/discussion_search_view',
'common/js/discussion/views/new_post_view'
'discussion/js/views/discussion_board_view'
],
function($, Backbone, DiscussionRouter, DiscussionFakeBreadcrumbs, DiscussionSearchView, NewPostView) {
function($, Backbone, Content, Discussion, DiscussionUtil, DiscussionCourseSettings, DiscussionUser,
NewPostView, DiscussionRouter, DiscussionBoardView) {
return function(options) {
var userInfo = options.user_info,
sortPreference = options.sort_preference,
threads = options.threads,
threadPages = options.thread_pages,
contentInfo = options.content_info,
user = new window.DiscussionUser(userInfo),
user = new DiscussionUser(userInfo),
discussion,
courseSettings,
newPostView,
discussionBoardView,
router,
breadcrumbs,
BreadcrumbsModel,
searchBox,
routerEvents;
// TODO: Perhaps eliminate usage of global variables when possible
window.DiscussionUtil.loadRoles(options.roles);
// TODO: eliminate usage of global variables when possible
DiscussionUtil.loadRoles(options.roles);
window.$$course_id = options.courseId;
window.courseName = options.course_name;
window.DiscussionUtil.setUser(user);
DiscussionUtil.setUser(user);
window.user = user;
window.Content.loadContentInfos(contentInfo);
Content.loadContentInfos(contentInfo);
discussion = new window.Discussion(threads, {pages: threadPages, sort: sortPreference});
courseSettings = new window.DiscussionCourseSettings(options.course_settings);
// Create a discussion model
discussion = new Discussion(threads, {pages: threadPages, sort: sortPreference});
courseSettings = new DiscussionCourseSettings(options.course_settings);
// Create the discussion board view
discussionBoardView = new DiscussionBoardView({
el: $('.discussion-board'),
discussion: discussion,
courseSettings: courseSettings
});
discussionBoardView.render();
// Create the new post view
newPostView = new NewPostView({
@@ -47,59 +59,27 @@
});
newPostView.render();
// Set up the router to manage the page's history
// Set up a router to manage the page's history
router = new DiscussionRouter({
courseId: options.courseId,
discussion: discussion,
courseSettings: courseSettings,
discussionBoardView: discussionBoardView,
newPostView: newPostView
});
router.start();
// Initialize and render search box
searchBox = new DiscussionSearchView({
el: $('.forum-search'),
threadListView: router.nav
}).render();
// Initialize and render breadcrumbs
BreadcrumbsModel = Backbone.Model.extend({
defaults: {
contents: []
}
});
breadcrumbs = new DiscussionFakeBreadcrumbs({
el: $('.has-breadcrumbs'),
model: new BreadcrumbsModel(),
events: {
'click .all-topics': function(event) {
event.preventDefault();
searchBox.clearSearch();
this.model.set('contents', []);
router.navigate('', {trigger: true});
router.nav.toggleBrowseMenu(event);
}
}
}).render();
routerEvents = {
// Add new breadcrumbs and clear search box when the user selects topics
'topic:selected': function(topic) {
breadcrumbs.model.set('contents', topic);
router.discussionBoardView.breadcrumbs.model.set('contents', topic);
},
// Clear search box when a thread is selected
'thread:selected': function() {
searchBox.clearSearch();
},
// Add 'Search Results' to breadcrumbs when user searches
'search:initiated': function() {
breadcrumbs.model.set('contents', ['Search Results']);
router.discussionBoardView.searchView.clearSearch();
}
};
Object.keys(routerEvents).forEach(function(key) {
router.nav.on(key, routerEvents[key]);
router.discussionBoardView.on(key, routerEvents[key]);
});
};
});

View File

@@ -1,8 +1,14 @@
(function(define) {
'use strict';
define(['jquery', 'discussion/js/views/discussion_user_profile_view'],
function($, DiscussionUserProfileView) {
define(
[
'jquery',
'common/js/discussion/utils',
'common/js/discussion/models/discussion_user',
'discussion/js/views/discussion_user_profile_view'
],
function($, DiscussionUtil, DiscussionUser, DiscussionUserProfileView) {
return function(options) {
var $element = options.$el,
threads = options.threads,
@@ -10,13 +16,16 @@
page = options.page,
numPages = options.numPages;
// Roles are not included in user profile page, but they are not used for anything
window.DiscussionUtil.loadRoles({
DiscussionUtil.loadRoles({
Moderator: [],
Administrator: [],
'Community TA': []
});
// TODO: remove global variable usage
window.$$course_id = options.courseId;
window.user = new window.DiscussionUser(userInfo);
window.user = new DiscussionUser(userInfo);
new DiscussionUserProfileView({ // eslint-disable-line no-new
el: $element,
collection: threads,

View File

@@ -6,10 +6,10 @@
'underscore',
'backbone',
'common/js/discussion/utils',
'common/js/discussion/views/discussion_thread_list_view',
'common/js/discussion/models/discussion_course_settings',
'common/js/discussion/views/discussion_thread_view'
],
function(_, Backbone, DiscussionUtil, DiscussionThreadListView, DiscussionThreadView) {
function(_, Backbone, DiscussionUtil, DiscussionCourseSettings, DiscussionThreadView) {
var DiscussionRouter = Backbone.Router.extend({
routes: {
'': 'allThreads',
@@ -21,14 +21,9 @@
_.bindAll(this, 'allThreads', 'showThread');
this.courseId = options.courseId;
this.discussion = options.discussion;
this.course_settings = options.courseSettings;
this.course_settings = new DiscussionCourseSettings(options.course_settings);
this.discussionBoardView = options.discussionBoardView;
this.newPostView = options.newPostView;
this.nav = new DiscussionThreadListView({
collection: this.discussion,
el: $('.forum-nav'),
courseSettings: this.course_settings
});
this.nav.render();
},
start: function() {
@@ -41,10 +36,18 @@
});
// Automatically navigate when the user selects threads
this.nav.on('thread:selected', _.bind(this.navigateToThread, this));
this.nav.on('thread:removed', _.bind(this.navigateToAllThreads, this));
this.nav.on('threads:rendered', _.bind(this.setActiveThread, this));
this.nav.on('thread:created', _.bind(this.navigateToThread, this));
this.discussionBoardView.discussionThreadListView.on(
'thread:selected', _.bind(this.navigateToThread, this)
);
this.discussionBoardView.discussionThreadListView.on(
'thread:removed', _.bind(this.navigateToAllThreads, this)
);
this.discussionBoardView.discussionThreadListView.on(
'threads:rendered', _.bind(this.setActiveThread, this)
);
this.discussionBoardView.discussionThreadListView.on(
'thread:created', _.bind(this.navigateToThread, this)
);
Backbone.history.start({
pushState: true,
@@ -57,15 +60,15 @@
},
allThreads: function() {
this.nav.updateSidebar();
return this.nav.goHome();
this.discussionBoardView.updateSidebar();
return this.discussionBoardView.goHome();
},
setActiveThread: function() {
if (this.thread) {
return this.nav.setActiveThread(this.thread.get('id'));
return this.discussionBoardView.discussionThreadListView.setActiveThread(this.thread.get('id'));
} else {
return this.nav.goHome;
return this.discussionBoardView.goHome;
}
},
@@ -86,8 +89,8 @@
if (!($('.forum-content').is(':visible'))) {
$('.forum-content').fadeIn();
}
if (this.newPostView.$el.is(':visible')) {
this.newPostView.$el.fadeOut();
if ($('.new-post-article').is(':visible')) {
$('.new-post-article').fadeOut();
}
this.main = new DiscussionThreadView({
el: $('.forum-content'),
@@ -97,14 +100,13 @@
});
this.main.render();
this.main.on('thread:responses:rendered', function() {
return self.nav.updateSidebar();
return self.discussionBoardView.updateSidebar();
});
return this.thread.on('thread:thread_type_updated', this.showMain);
},
navigateToThread: function(threadId) {
var thread;
thread = this.discussion.get(threadId);
var thread = this.discussion.get(threadId);
return this.navigate('' + (thread.get('commentable_id')) + '/threads/' + threadId, {
trigger: true
});
@@ -135,6 +137,7 @@
}
});
}
});
return DiscussionRouter;

View File

@@ -4,16 +4,34 @@ define(
'backbone',
'common/js/spec_helpers/page_helpers',
'common/js/spec_helpers/discussion_spec_helper',
'discussion/js/discussion_board_factory'
'discussion/js/discussion_board_factory',
'discussion/js/views/discussion_board_view'
],
function($, Backbone, PageHelpers, DiscussionSpecHelper, DiscussionBoardFactory) {
function($, Backbone, PageHelpers, DiscussionSpecHelper, DiscussionBoardFactory, DiscussionBoardView) {
'use strict';
// TODO: re-enable when this doesn't interact badly with other history tests
xdescribe('Discussion Board Factory', function() {
describe('DiscussionBoardFactory', function() {
var createDiscussionBoardView = function() {
var discussionBoardView,
discussion = DiscussionSpecHelper.createTestDiscussion({}),
courseSettings = DiscussionSpecHelper.createTestCourseSettings();
setFixtures('<div class="discussion-board"><div class="forum-search"></div></div>');
DiscussionSpecHelper.setUnderscoreFixtures();
discussionBoardView = new DiscussionBoardView({
el: $('.discussion-board'),
discussion: discussion,
courseSettings: courseSettings
});
return discussionBoardView;
};
var initializeDiscussionBoardFactory = function() {
DiscussionBoardFactory({
el: $('.discussion-board'),
el: $('#discussion-container'),
courseId: 'test_course_id',
course_name: 'Test Course',
user_info: DiscussionSpecHelper.getTestUserInfo(),
@@ -33,14 +51,11 @@ define(
};
beforeEach(function() {
PageHelpers.preventBackboneChangingUrl();
// Install the fixtures
setFixtures(
'<div class="discussion-board">' +
' <div class="forum-nav"></div>' +
'</div>'
'<div id="discussion-container" class="discussion-board"></div></div>'
);
PageHelpers.preventBackboneChangingUrl();
DiscussionSpecHelper.setUnderscoreFixtures();
});
@@ -48,9 +63,11 @@ define(
Backbone.history.stop();
});
it('can render itself', function() {
xit('can render itself', function() { // this failed Search: navigates to search, and TeamsTab
var discussionView = createDiscussionBoardView();
discussionView.render();
initializeDiscussionBoardFactory();
expect($('.discussion-board').text()).toContain('All Discussions');
expect(discussionView.$el.text()).toContain('Search all posts');
});
});
}

View File

@@ -0,0 +1,58 @@
/* globals Discussion, DiscussionCourseSettings */
(function(define) {
'use strict';
define(
[
'underscore',
'jquery',
'edx-ui-toolkit/js/utils/constants',
'common/js/discussion/discussion',
'common/js/spec_helpers/discussion_spec_helper',
'discussion/js/views/discussion_board_view'
],
function(_, $, constants, Discussion, DiscussionSpecHelper, DiscussionBoardView) {
describe('DiscussionBoardView', function() {
var createDiscussionBoardView;
createDiscussionBoardView = function() {
var discussionBoardView,
discussion = DiscussionSpecHelper.createTestDiscussion({}),
courseSettings = DiscussionSpecHelper.createTestCourseSettings();
setFixtures('<div class="discussion-board"><div class="forum-search"></div></div>');
DiscussionSpecHelper.setUnderscoreFixtures();
discussionBoardView = new DiscussionBoardView({
el: $('.discussion-board'),
discussion: discussion,
courseSettings: courseSettings
});
return discussionBoardView;
};
describe('Search events', function() {
it('perform search when enter pressed inside search textfield', function() {
var discussionBoardView = createDiscussionBoardView(),
threadListView;
discussionBoardView.render();
threadListView = discussionBoardView.discussionThreadListView;
spyOn(threadListView, 'performSearch');
discussionBoardView.$('.search-input').trigger($.Event('keydown', {
which: constants.keyCodes.enter
}));
expect(threadListView.performSearch).toHaveBeenCalled();
});
it('perform search when search icon is clicked', function() {
var discussionBoardView = createDiscussionBoardView(),
threadListView;
discussionBoardView.render();
threadListView = discussionBoardView.discussionThreadListView;
spyOn(threadListView, 'performSearch');
discussionBoardView.$el.find('.search-btn').click();
expect(threadListView.performSearch).toHaveBeenCalled();
});
});
});
});
}).call(this, define || RequireJS.define);

View File

@@ -1,36 +0,0 @@
define([
'jquery',
'edx-ui-toolkit/js/utils/constants',
'discussion/js/views/discussion_search_view'
],
function($, constants, DiscussionSearchView) {
'use strict';
describe('DiscussionSearchView', function() {
var view;
beforeEach(function() {
setFixtures('<div class="search-container"></div>');
view = new DiscussionSearchView({
el: $('.search-container'),
threadListView: {
performSearch: jasmine.createSpy()
}
}).render();
});
describe('Search events', function() {
it('perform search when enter pressed inside search textfield', function() {
view.$el.find('.search-input').trigger($.Event('keydown', {
which: constants.keyCodes.enter
}));
expect(view.threadListView.performSearch).toHaveBeenCalled();
});
it('perform search when search icon is clicked', function() {
view.$el.find('.search-btn').click();
expect(view.threadListView.performSearch).toHaveBeenCalled();
});
});
});
}
);

View File

@@ -0,0 +1,336 @@
/* globals Discussion */
(function(define) {
'use strict';
define([
'underscore',
'backbone',
'edx-ui-toolkit/js/utils/html-utils',
'edx-ui-toolkit/js/utils/constants',
'common/js/discussion/utils',
'common/js/discussion/views/discussion_thread_list_view',
'discussion/js/views/discussion_fake_breadcrumbs',
'discussion/js/views/discussion_search_view',
'text!discussion/templates/discussion-home.underscore'
],
function(_, Backbone, HtmlUtils, Constants, DiscussionUtil,
DiscussionThreadListView, DiscussionFakeBreadcrumbs, DiscussionSearchView, discussionHomeTemplate) {
var DiscussionBoardView = Backbone.View.extend({
events: {
'click .forum-nav-browse-title': 'selectTopicHandler',
'click .all-topics': 'toggleBrowseMenu',
'keypress .forum-nav-browse-filter-input': function(event) {
return DiscussionUtil.ignoreEnterKey(event);
},
'keyup .forum-nav-browse-filter-input': 'filterTopics',
'keydown .forum-nav-browse-filter-input': 'keyboardBinding',
'click .forum-nav-browse-menu-wrapper': 'ignoreClick',
'keydown .search-input': 'performSearch',
'click .search-btn': 'performSearch',
'topic:selected': 'clearSearch'
},
initialize: function(options) {
this.courseSettings = options.courseSettings;
this.sidebar_padding = 10;
this.current_search = '';
this.mode = 'all';
this.discussion = options.discussion;
this.filterInputReset();
this.selectedTopic = $('.forum-nav-browse-menu-item:visible .forum-nav-browse-title.is-focused');
this.listenTo(this.model, 'change', this.render);
},
render: function() {
this.discussionThreadListView = new DiscussionThreadListView({
collection: this.discussion,
el: this.$('.discussion-thread-list-container'),
courseSettings: this.courseSettings
}).render();
this.searchView = new DiscussionSearchView({
el: this.$('.forum-search')
}).render();
this.renderBreadcrumbs();
$(window).bind('load scroll resize', this.updateSidebar);
this.showBrowseMenu(true);
return this;
},
renderBreadcrumbs: function() {
var BreadcrumbsModel = Backbone.Model.extend({
defaults: {
contents: []
}
});
this.breadcrumbs = new DiscussionFakeBreadcrumbs({
el: $('.has-breadcrumbs'),
model: new BreadcrumbsModel(),
events: {
'click .all-topics': function(event) {
event.preventDefault();
}
}
}).render();
},
isBrowseMenuVisible: function() {
return this.$('.forum-nav-browse-menu-wrapper').is(':visible');
},
showBrowseMenu: function(initialLoad) {
if (!this.isBrowseMenuVisible()) {
this.$('.forum-nav-browse-menu-wrapper').show();
this.$('.forum-nav-thread-list-wrapper').hide();
if (!initialLoad) {
$('.forum-nav-browse-filter-input').focus();
this.filterInputReset();
}
this.updateSidebar();
}
},
hideBrowseMenu: function() {
var selectedTopicList = this.$('.forum-nav-browse-title.is-focused');
if (this.isBrowseMenuVisible()) {
selectedTopicList.removeClass('is-focused');
this.$('.forum-nav-browse-menu-wrapper').hide();
this.$('.forum-nav-thread-list-wrapper').show();
if (this.selectedTopicId !== 'undefined') {
this.$('.forum-nav-browse-filter-input').attr('aria-activedescendant', this.selectedTopicId);
}
this.updateSidebar();
}
},
toggleBrowseMenu: function(event) {
var inputText = this.$('.forum-nav-browse-filter-input').val();
event.preventDefault();
event.stopPropagation();
if (this.isBrowseMenuVisible()) {
this.hideBrowseMenu();
} else {
if (inputText !== '') {
this.filterTopics(inputText);
}
this.showBrowseMenu();
}
this.breadcrumbs.model.set('contents', []);
this.clearSearch();
},
performSearch: function(event) {
if (event.which === Constants.keyCodes.enter || event.type === 'click') {
event.preventDefault();
this.hideBrowseMenu();
this.breadcrumbs.model.set('contents', ['Search Results']);
this.discussionThreadListView.performSearch($('.search-input', this.$el));
}
},
clearSearch: function() {
this.$('.search-input').val('');
this.discussionThreadListView.clearSearchAlerts();
},
updateSidebar: function() {
var amount, browseFilterHeight, discussionBottomOffset, discussionsBodyBottom,
discussionsBodyTop, headerHeight, refineBarHeight, scrollTop, sidebarHeight, topOffset,
windowHeight, $discussionBody, $sidebar;
scrollTop = $(window).scrollTop();
windowHeight = $(window).height();
$discussionBody = this.$('.discussion-column');
discussionsBodyTop = $discussionBody[0] ? $discussionBody.offset().top : undefined;
discussionsBodyBottom = discussionsBodyTop + $discussionBody.outerHeight();
$sidebar = this.$('.forum-nav');
if (scrollTop > discussionsBodyTop - this.sidebar_padding) {
$sidebar.css('top', scrollTop - discussionsBodyTop + this.sidebar_padding);
} else {
$sidebar.css('top', '0');
}
sidebarHeight = windowHeight - Math.max(discussionsBodyTop - scrollTop, this.sidebar_padding);
topOffset = scrollTop + windowHeight;
discussionBottomOffset = discussionsBodyBottom + this.sidebar_padding;
amount = Math.max(topOffset - discussionBottomOffset, 0);
sidebarHeight = sidebarHeight - this.sidebar_padding - amount;
sidebarHeight = Math.min(sidebarHeight + 1, $discussionBody.outerHeight());
$sidebar.css('height', sidebarHeight);
headerHeight = this.$('.forum-nav-header').outerHeight();
refineBarHeight = this.$('.forum-nav-refine-bar').outerHeight();
browseFilterHeight = this.$('.forum-nav-browse-filter').outerHeight();
this.$('.forum-nav-thread-list')
.css('height', (sidebarHeight - headerHeight - refineBarHeight - 2) + 'px');
this.$('.forum-nav-browse-menu')
.css('height', (sidebarHeight - headerHeight - browseFilterHeight - 2) + 'px');
},
goHome: function() {
var url = DiscussionUtil.urlFor('notifications_status', window.user.get('id'));
HtmlUtils.append(this.$('.forum-content').empty(), HtmlUtils.template(discussionHomeTemplate)({}));
this.$('.forum-nav-thread-list a').removeClass('is-active').find('.sr')
.remove();
this.$('input.email-setting').bind('click', this.updateEmailNotifications);
DiscussionUtil.safeAjax({
url: url,
type: 'GET',
success: function(response) {
$('input.email-setting').prop('checked', response.status);
}
});
},
filterInputReset: function() {
this.filterEnabled = true;
this.selectedTopicIndex = -1;
this.selectedTopicId = null;
},
selectOption: function(element) {
var activeDescendantId, activeDescendantText;
if (this.selectedTopic.length > 0) {
this.selectedTopic.removeClass('is-focused');
}
if (element) {
element.addClass('is-focused');
activeDescendantId = element.parent().attr('id');
activeDescendantText = element.text();
this.selectedTopic = element;
this.selectedTopicId = activeDescendantId;
this.$('.forum-nav-browse-filter-input')
.attr('aria-activedescendant', activeDescendantId)
.val(activeDescendantText);
}
},
keyboardBinding: function(event) {
var key = event.which,
$inputText = $('.forum-nav-browse-filter-input'),
$filteredMenuItems = $('.forum-nav-browse-menu-item:visible'),
filteredMenuItemsLen = $filteredMenuItems.length,
$curOption = $filteredMenuItems.eq(0).find('.forum-nav-browse-title').eq(0),
$activeOption, $prev, $next;
switch (key) {
case Constants.keyCodes.enter:
$activeOption = $filteredMenuItems.find('.forum-nav-browse-title.is-focused');
if ($inputText.val() !== '') {
$activeOption.trigger('click');
this.filterInputReset();
}
break;
case Constants.keyCodes.esc:
this.toggleBrowseMenu(event);
this.$('.forum-nav-browse-filter-input').val('');
this.filterInputReset();
$('.all-topics').trigger('click');
break;
case Constants.keyCodes.up:
if (this.selectedTopicIndex > 0) {
this.selectedTopicIndex -= 1;
if (this.isBrowseMenuVisible()) {
$prev = $('.forum-nav-browse-menu-item:visible')
.eq(this.selectedTopicIndex).find('.forum-nav-browse-title')
.eq(0);
this.filterEnabled = false;
$curOption.removeClass('is-focused');
$prev.addClass('is-focused');
}
this.selectOption($prev);
}
break;
case Constants.keyCodes.down:
if (this.selectedTopicIndex < filteredMenuItemsLen - 1) {
this.selectedTopicIndex += 1;
if (this.isBrowseMenuVisible()) {
$next = $('.forum-nav-browse-menu-item:visible')
.eq(this.selectedTopicIndex).find('.forum-nav-browse-title')
.eq(0);
this.filterEnabled = false;
$curOption.removeClass('is-focused');
$next.addClass('is-focused');
}
this.selectOption($next);
}
break;
default:
}
},
filterTopics: function() {
var $items, query, filteredItems,
self = this;
query = this.$('.forum-nav-browse-filter-input').val();
$items = this.$('.forum-nav-browse-menu-item');
if (query.length === 0) {
$items.find('.forum-nav-browse-title.is-focused').removeClass('is-focused');
return $items.show();
} else {
if (self.filterEnabled) {
$items.hide();
filteredItems = $items.each(function(i, item) {
var path, pathText,
$item = $(item);
if (!$item.is(':visible')) {
pathText = self.getPathText($item).toLowerCase();
if (query.split(' ').every(function(term) {
return pathText.search(term.toLowerCase()) !== -1;
})) {
path = $item.parents('.forum-nav-browse-menu-item').andSelf();
path.add($item.find('.forum-nav-browse-menu-item')).show();
}
}
});
}
return filteredItems;
}
},
getPathText: function(item) {
var path, pathTitles;
path = item.parents('.forum-nav-browse-menu-item').andSelf();
pathTitles = path.children('.forum-nav-browse-title').map(function(i, elem) {
return $(elem).text();
}).get();
return pathTitles.join(' / ');
},
selectTopicHandler: function(event) {
var $item = $(event.target).closest('.forum-nav-browse-menu-item');
event.preventDefault();
this.hideBrowseMenu();
this.trigger('topic:selected', this.getBreadcrumbText($item));
return this.discussionThreadListView.selectTopic($(event.target));
},
getBreadcrumbText: function($item) {
var $parentSubMenus = $item.parents('.forum-nav-browse-submenu'),
crumbs = [],
subTopic = $('.forum-nav-browse-title', $item)
.first()
.text()
.trim();
$parentSubMenus.each(function(i, el) {
crumbs.push($(el).siblings('.forum-nav-browse-title')
.first()
.text()
.trim()
);
});
if (subTopic !== 'All Discussions') {
crumbs.push(subTopic);
}
return crumbs;
}
});
return DiscussionBoardView;
});
}).call(this, define || RequireJS.define);

View File

@@ -15,33 +15,16 @@
* in order to clean up that file and make it possible to break its logic into files like this one.
*/
var searchView = Backbone.View.extend({
events: {
'keydown .search-input': 'performSearch',
'click .search-btn': 'performSearch',
'topic:selected': 'clearSearch'
},
initialize: function(options) {
_.extend(this, _.pick(options, 'threadListView'));
_.extend(this, _.pick(options, ['discussionBoardView']));
this.template = HtmlUtils.template(searchTemplate);
this.threadListView = options.threadListView;
this.listenTo(this.model, 'change', this.render);
this.render();
},
render: function() {
HtmlUtils.setHtml(this.$el, this.template());
return this;
},
performSearch: function(event) {
if (event.which === constants.keyCodes.enter || event.type === 'click') {
event.preventDefault();
this.threadListView.performSearch($('.search-input', this.$el));
}
},
clearSearch: function() {
this.$('.search-input').val('');
this.threadListView.clearSearchAlerts();
}
});

View File

@@ -0,0 +1,62 @@
<div class="discussion-article view-discussion-home">
<section class="home-header">
<span class="label"><%- gettext("Discussion Home") %></span>
<% if (window.courseName) { %>
<h1 class="home-title"><%- window.courseName %></h1>
<% } %>
</section>
<% if (window.ENABLE_DISCUSSION_HOME_PANEL) { %>
<span class="label label-settings">
<%- interpolate(
gettext("How to use %(platform_name)s discussions"),
{platform_name: window.PLATFORM_NAME}, true
) %>
</span>
<table class="home-helpgrid">
<tr class="helpgrid-row helpgrid-row-navigation">
<th scope="row" class="row-title"><%- gettext("Find discussions") %></td>
<td class="row-item">
<span class="icon fa fa-reorder" aria-hidden="true"></span>
<span class="row-description"><%- gettext("Use the All Topics menu to find specific topics.") %></span>
</td>
<td class="row-item">
<span class="icon fa fa-search" aria-hidden="true"></span>
<span class="row-description"><%- gettext("Search all posts") %></span>
</td>
<td class="row-item">
<span class="icon fa fa-sort" aria-hidden="true"></span>
<span class="row-description"><%- gettext("Filter and sort topics") %></span>
</td>
</tr>
<tr class="helpgrid-row helpgrid-row-participation">
<th scope="row" class="row-title"><%- gettext("Engage with posts") %></td>
<td class="row-item">
<span class="icon fa fa-plus" aria-hidden="true"></span>
<span class="row-description"><%- gettext("Vote for good posts and responses") %></span>
</td>
<td class="row-item">
<span class="icon fa fa-flag" aria-hidden="true"></span>
<span class="row-description"><%- gettext("Report abuse, topics, and responses") %></span>
</td>
<td class="row-item">
<span class="icon fa fa-star" aria-hidden="true"></span>
<span class="row-description"><%- gettext("Follow or unfollow posts") %></span>
</td>
</tr>
<tr class="helpgrid-row helpgrid-row-notification">
<th scope="row" class="row-title"><%- gettext('Receive updates') %></td>
<td class="row-item-full" colspan="3">
<label for="email-setting-checkbox">
<span class="sr"><%- gettext("Toggle Notifications Setting") %></span>
<span class="notification-checkbox">
<input type="checkbox" id="email-setting-checkbox" class="email-setting" name="email-notification"/>
<span class="icon fa fa-envelope" aria-hidden="true"></span>
</span>
</label>
<span class="row-description"><%- gettext("Check this box to receive an email digest once a day notifying you about new, unread activity from posts you are following.") %></span>
</td>
</tr>
</table>
<% } %>
</div>

View File

@@ -77,6 +77,8 @@ DiscussionBoardFactory({
<div class="page-content">
<div class="discussion-body layout layout-1t2t">
<aside class="forum-nav layout-col layout-col-a" role="complementary" aria-label="${_("Discussion thread list")}">
<%include file="_filter_dropdown.html" />
<div class="discussion-thread-list-container"></div>
</aside>
<main id="main" aria-label="Content" tabindex="-1" class="discussion-column layout-col layout-col-b">