/** * CourseVideoSettingsView shows a sidebar containing course wide video settings which we show on Video Uploads page. */ define([ 'jquery', 'backbone', 'underscore', 'gettext', 'moment', 'common/js/components/utils/view_utils', 'edx-ui-toolkit/js/utils/html-utils', 'edx-ui-toolkit/js/utils/string-utils', 'text!templates/course-video-settings.underscore', 'text!templates/course-video-transcript-preferences.underscore', 'text!templates/course-video-transcript-provider-empty.underscore', 'text!templates/course-video-transcript-provider-selected.underscore', 'text!templates/transcript-organization-credentials.underscore', 'text!templates/course-video-settings-update-settings-footer.underscore', 'text!templates/course-video-settings-update-org-credentials-footer.underscore' ], function($, Backbone, _, gettext, moment, ViewUtils, HtmlUtils, StringUtils, TranscriptSettingsTemplate, TranscriptPreferencesTemplate, TranscriptProviderEmptyStateTemplate, TranscriptProviderSelectedStateTemplate, OrganizationCredentialsTemplate, UpdateSettingsFooterTemplate, OrganizationCredentialsFooterTemplate) { 'use strict'; var CourseVideoSettingsView, CIELO24 = 'Cielo24', THREE_PLAY_MEDIA = '3PlayMedia', INTERNAL_SERVER_ERROR_MESSAGE = gettext('An error has occurred. Wait a few minutes, and then try again.'); CourseVideoSettingsView = Backbone.View.extend({ el: 'div.video-transcript-settings-wrapper', events: { 'change .transcript-provider-group input': 'providerSelected', 'change #transcript-turnaround': 'turnaroundSelected', 'change #transcript-fidelity': 'fidelitySelected', 'change #video-source-language': 'videoSourceLanguageSelected', 'click .action-add-language': 'languageSelected', 'click .action-remove-language': 'languageRemoved', 'click .action-change-provider': 'renderOrganizationCredentials', 'click .action-update-org-credentials': 'updateOrganizationCredentials', 'click .action-update-course-video-settings': 'updateCourseVideoSettings', 'click .action-cancel-course-video-settings': 'discardChanges', 'click .action-close-course-video-settings': 'closeCourseVideoSettings' }, initialize: function(options) { var videoTranscriptSettings = options.videoTranscriptSettings; this.activeTranscriptionPlan = options.activeTranscriptPreferences; this.transcriptOrganizationCredentials = _.extend({}, options.transcriptOrganizationCredentials); this.availableTranscriptionPlans = videoTranscriptSettings.transcription_plans; this.transcriptHandlerUrl = videoTranscriptSettings.transcript_preferences_handler_url; this.transcriptCredentialsHandlerUrl = videoTranscriptSettings.transcript_credentials_handler_url; this.template = HtmlUtils.template(TranscriptSettingsTemplate); this.transcriptPreferencesTemplate = HtmlUtils.template(TranscriptPreferencesTemplate); this.organizationCredentialsTemplate = HtmlUtils.template(OrganizationCredentialsTemplate); this.organizationCredentialsFooterTemplate = HtmlUtils.template(OrganizationCredentialsFooterTemplate); this.updateSettingsFooterTemplate = HtmlUtils.template(UpdateSettingsFooterTemplate); this.transcriptProviderEmptyStateTemplate = HtmlUtils.template(TranscriptProviderEmptyStateTemplate); this.transcriptProviderSelectedStateTemplate = HtmlUtils.template(TranscriptProviderSelectedStateTemplate); this.setActiveTranscriptPlanData(); this.selectedLanguages = []; }, registerCloseClickHandler: function() { var self = this; // Preventing any parent handlers from being notified of the event. This is to stop from firing the document // level click handler to execute on course video settings pane click. self.$el.click(function(event) { event.stopPropagation(); }); // Click anywhere outside the course video settings pane would close the pane. $(document).click(function(event) { // If the target of the click isn't the container nor a descendant of the contain if (!self.$el.is(event.target) && self.$el.has(event.target).length === 0) { self.closeCourseVideoSettings(); } }); }, resetPlanData: function() { this.selectedProvider = ''; this.selectedTurnaroundPlan = ''; this.selectedFidelityPlan = ''; this.activeLanguages = []; this.selectedVideoSourceLanguage = ''; this.selectedLanguages = []; }, setActiveTranscriptPlanData: function() { if (this.activeTranscriptionPlan) { this.selectedProvider = this.activeTranscriptionPlan.provider; this.selectedFidelityPlan = this.activeTranscriptionPlan.cielo24_fidelity; this.selectedTurnaroundPlan = this.selectedProvider === CIELO24 ? this.activeTranscriptionPlan.cielo24_turnaround : this.activeTranscriptionPlan.three_play_turnaround; this.activeLanguages = this.activeTranscriptionPlan.preferred_languages; this.selectedVideoSourceLanguage = this.activeTranscriptionPlan.video_source_language; } else { this.resetPlanData(); } }, getTurnaroundPlan: function() { var turnaroundPlan = null; if (this.selectedProvider) { turnaroundPlan = this.availableTranscriptionPlans[this.selectedProvider].turnaround; } return turnaroundPlan; }, getFidelityPlan: function() { var fidelityPlan = null; if (this.selectedProvider === CIELO24) { fidelityPlan = this.availableTranscriptionPlans[this.selectedProvider].fidelity; } return fidelityPlan; }, getTargetLanguages: function() { var availableLanguages, selectedPlan = this.selectedProvider ? this.availableTranscriptionPlans[this.selectedProvider] : null; if (selectedPlan) { if (this.selectedProvider === CIELO24 && this.selectedFidelityPlan) { availableLanguages = selectedPlan.fidelity[this.selectedFidelityPlan].languages; // If fidelity is mechanical then target language would be same as source language. if (this.selectedFidelityPlan === 'MECHANICAL' && this.selectedVideoSourceLanguage) { availableLanguages = _.pick( availableLanguages, this.selectedVideoSourceLanguage ); } } else if (this.selectedProvider === THREE_PLAY_MEDIA) { availableLanguages = selectedPlan.languages; } } return availableLanguages; }, getSourceLanguages: function() { var sourceLanguages = []; if (this.selectedProvider === THREE_PLAY_MEDIA) { sourceLanguages = this.availableTranscriptionPlans[this.selectedProvider].translations; } else { sourceLanguages = this.getTargetLanguages(); } return sourceLanguages; }, fidelitySelected: function(event) { var $fidelityContainer = this.$el.find('.transcript-fidelity-wrapper'); this.selectedFidelityPlan = event.target.value; // Remove any error if present already. this.clearPreferenceErrorState($fidelityContainer); // Clear active and selected languages. this.selectedLanguages = this.activeLanguages = []; // Also clear selected language. this.selectedVideoSourceLanguage = ''; this.renderSourceLanguages(); this.renderTargetLanguages(); }, videoSourceLanguageSelected: function(event) { var $videoSourceLanguageContainer = this.$el.find('.video-source-language-wrapper'); this.selectedVideoSourceLanguage = event.target.value; // Remove any error if present already. this.clearPreferenceErrorState($videoSourceLanguageContainer); // Clear active and selected languages. this.selectedLanguages = this.activeLanguages = []; this.renderTargetLanguages(); }, turnaroundSelected: function(event) { var $turnaroundContainer = this.$el.find('.transcript-turnaround-wrapper'); this.selectedTurnaroundPlan = event.target.value; // Remove any error if present already. this.clearPreferenceErrorState($turnaroundContainer); }, providerSelected: function(event) { this.resetPlanData(); this.selectedProvider = event.target.value; // Re-render view this.reRenderView(); }, reRenderView: function() { var $courseVideoSettingsContentEl = this.$el.find('.course-video-settings-content'), dateModified = this.activeTranscriptionPlan ? moment.utc(this.activeTranscriptionPlan.modified).format('ll') : ''; if (!this.selectedProvider) { // Hide organization credentials and transcript preferences views $courseVideoSettingsContentEl.hide(); // Render footer HtmlUtils.setHtml( this.$el.find('.course-video-settings-footer'), this.updateSettingsFooterTemplate({ dateModified: dateModified }) ); return; } $courseVideoSettingsContentEl.show(); // If org provider specific credentials are present if (this.transcriptOrganizationCredentials[this.selectedProvider]) { this.renderTranscriptPreferences(); } else { this.renderOrganizationCredentials(); } }, languageSelected: function(event) { var $parentEl = $(event.target.parentElement).parent(), $languagesEl = this.$el.find('.transcript-languages-wrapper'), selectedLanguage = $parentEl.find('select').val(); // Remove any error if present already. this.clearPreferenceErrorState($languagesEl); // Only add if not in the list already. if (selectedLanguage && _.indexOf(this.selectedLanguages, selectedLanguage) === -1) { this.selectedLanguages.push(selectedLanguage); this.addLanguage(selectedLanguage); // Populate language menu with latest data. this.populateLanguageMenu(); } else { this.addErrorState($languagesEl); } }, languageRemoved: function(event) { var selectedLanguage = $(event.target).data('language-code'); $(event.target.parentElement).parent().remove(); // Remove language from selected languages. this.selectedLanguages = this.activeLanguages = _.without(this.selectedLanguages, selectedLanguage); // Populate menu again to reflect latest changes. this.populateLanguageMenu(); }, renderProviders: function(state) { var $transcriptProviderWrapperEl = this.$el.find('.transcript-provider-wrapper'); if (!state) { state = this.selectedProvider ? 'selected' : 'empty'; // eslint-disable-line no-param-reassign } // If no transcription plans are sentm return. if (!this.availableTranscriptionPlans) { return; } if (state === 'empty') { HtmlUtils.setHtml( $transcriptProviderWrapperEl, this.transcriptProviderEmptyStateTemplate({ providers: [ { key: 'none', value: '', name: gettext('None'), checked: this.selectedProvider === '' ? 'checked' : '' }, { key: CIELO24, value: CIELO24, name: this.availableTranscriptionPlans[CIELO24].display_name, checked: this.selectedProvider === CIELO24 ? 'checked' : '' }, { key: THREE_PLAY_MEDIA, value: THREE_PLAY_MEDIA, name: this.availableTranscriptionPlans[THREE_PLAY_MEDIA].display_name, checked: this.selectedProvider === THREE_PLAY_MEDIA ? 'checked' : '' } ] }) ); } else { HtmlUtils.setHtml( $transcriptProviderWrapperEl, this.transcriptProviderSelectedStateTemplate({ selectedProvider: this.availableTranscriptionPlans[this.selectedProvider].display_name }) ); this.renderTranscriptPreferences(); } }, renderTurnaround: function() { var self = this, turnaroundPlan = self.getTurnaroundPlan(), $turnaroundContainer = self.$el.find('.transcript-turnaround-wrapper'), $turnaround = self.$el.find('#transcript-turnaround'); // Clear error state if present any. this.clearPreferenceErrorState($turnaroundContainer); if (turnaroundPlan) { HtmlUtils.setHtml( $turnaround, HtmlUtils.HTML(new Option(gettext('Select turnaround'), '')) ); _.each(turnaroundPlan, function(value, key) { var option = new Option(value, key); if (self.selectedTurnaroundPlan === key) { option.selected = true; } HtmlUtils.append($turnaround, HtmlUtils.HTML(option)); }); $turnaroundContainer.show(); } else { $turnaroundContainer.hide(); } }, renderFidelity: function() { var self = this, fidelityPlan = self.getFidelityPlan(), $fidelityContainer = self.$el.find('.transcript-fidelity-wrapper'), $fidelity = self.$el.find('#transcript-fidelity'); // Clear error state if present any. this.clearPreferenceErrorState($fidelityContainer); // Fidelity dropdown if (fidelityPlan) { HtmlUtils.setHtml( $fidelity, HtmlUtils.HTML(new Option(gettext('Select fidelity'), '')) ); _.each(fidelityPlan, function(fidelityObject, key) { var option = new Option(fidelityObject.display_name, key); if (self.selectedFidelityPlan === key) { option.selected = true; } HtmlUtils.append($fidelity, HtmlUtils.HTML(option)); }); $fidelityContainer.show(); } else { $fidelityContainer.hide(); } }, renderTargetLanguages: function() { var self = this, // Merge active and selected languages, this handles the case when active languages are present and // user also has selected some languages but not saved, user changes organization credentials, // both active and selected languages should be rendered. selectedLanguages = _.union(self.activeLanguages, self.selectedLanguages), $languagesPreferenceContainer = self.$el.find('.transcript-languages-wrapper'), $languagesContainer = self.$el.find('.languages-container'); // Clear error state if present any. self.clearPreferenceErrorState($languagesPreferenceContainer); $languagesContainer.empty(); // Show language container if source language is selected. if (self.selectedVideoSourceLanguage) { _.each(selectedLanguages, function(language) { // Only add if not in the list already. if (_.indexOf(self.selectedLanguages, language) === -1) { self.selectedLanguages.push(language); } // Show active/ add language language container self.addLanguage(language); }); $languagesPreferenceContainer.show(); self.populateLanguageMenu(); } else { $languagesPreferenceContainer.hide(); } }, renderSourceLanguages: function() { var self = this, availableLanguages = self.getTargetLanguages(), availableTranslations = self.getSourceLanguages(), $videoSourceLanguageContainer = self.$el.find('.video-source-language-wrapper'), $languageMenuEl = self.$el.find('.video-source-language'), selectOptionEl = new Option(gettext('Select language'), ''); // Clear error state if present any. self.clearPreferenceErrorState($videoSourceLanguageContainer); if (!_.isEmpty(availableTranslations)) { $videoSourceLanguageContainer.show(); // We need to set id due to a11y aria-labelledby selectOptionEl.id = 'video-source-language-none'; HtmlUtils.setHtml( $languageMenuEl, HtmlUtils.HTML(selectOptionEl) ); _.each(availableTranslations, function(translatableLanguage, key) { var option = new Option(availableLanguages[key], key); if (self.selectedVideoSourceLanguage === key) { option.selected = true; } HtmlUtils.append( $languageMenuEl, HtmlUtils.HTML(option) ); }); } else { $videoSourceLanguageContainer.hide(); } }, populateLanguageMenu: function() { var availableLanguages = this.getTargetLanguages(), availableTranslations = this.availableTranscriptionPlans[THREE_PLAY_MEDIA].translations, $languageMenuEl = this.$el.find('.transcript-language-menu'), $languageMenuContainerEl = this.$el.find('.transcript-language-menu-container'), selectOptionEl = new Option(gettext('Select language'), ''); if (this.selectedProvider === THREE_PLAY_MEDIA) { // Pick out only those languages from plan laguages that also come from video source language. availableLanguages = _.pick( availableLanguages, availableTranslations[this.selectedVideoSourceLanguage] ); } // Omit out selected languages from selecting again. availableLanguages = _.omit(availableLanguages, this.selectedLanguages); // If no available language is left, then don't even show add language box. if (_.keys(availableLanguages).length) { $languageMenuContainerEl.show(); // We need to set id due to a11y aria-labelledby selectOptionEl.id = 'transcript-language-none'; HtmlUtils.setHtml( $languageMenuEl, HtmlUtils.HTML(selectOptionEl) ); _.each(availableLanguages, function(value, key) { HtmlUtils.append( $languageMenuEl, HtmlUtils.HTML(new Option(value, key)) ); }); } else { $languageMenuContainerEl.hide(); } }, addLanguage: function(language) { var $languagesContainer = this.$el.find('.languages-container'); HtmlUtils.append( $languagesContainer, HtmlUtils.joinHtml( HtmlUtils.HTML('
'), HtmlUtils.interpolateHtml( HtmlUtils.HTML('{languageDisplayName}'), { languageDisplayName: this.getTargetLanguages()[language] } ), HtmlUtils.interpolateHtml( HtmlUtils.HTML('
'), // eslint-disable-line max-len { languageCode: language, text: gettext('Remove'), srText: gettext('Press Remove to remove language') } ), HtmlUtils.HTML('
') ) ); }, updateSuccessResponseStatus: function(data, successMessage) { var dateModified = data ? moment.utc(data.modified).format('ll') : ''; successMessage = successMessage ? successMessage : gettext('Settings updated'); // eslint-disable-line no-param-reassign, no-unneeded-ternary, max-len // Update last modified date if (dateModified) { HtmlUtils.setHtml( this.$el.find('.last-updated-text'), HtmlUtils.interpolateHtml( HtmlUtils.HTML('{lastUpdateText} {dateModified}'), { lastUpdateText: gettext('Last updated'), dateModified: dateModified } ) ); } // Now re-render providers state. this.renderProviders(); this.renderResponseStatus(successMessage, 'success'); // Sync ActiveUploadListView with latest active plan. this.activeTranscriptionPlan = data; Backbone.trigger('coursevideosettings:syncActiveTranscriptPreferences', this.activeTranscriptionPlan); }, updateFailResponseStatus: function(data) { var errorMessage; // Enclose inside try-catch so that if we get erroneous data, we could still // show some error to user try { errorMessage = $.parseJSON(data).error; } catch (e) {} // eslint-disable-line no-empty this.renderResponseStatus(errorMessage || INTERNAL_SERVER_ERROR_MESSAGE, 'error'); }, renderResponseStatus: function(responseText, type) { var addClass = type === 'error' ? 'error' : 'success', removeClass = type === 'error' ? 'success' : 'error', iconClass = type === 'error' ? 'fa-info-circle' : 'fa-check-circle', $messageWrapperEl = this.$el.find('.course-video-settings-message-wrapper'); $messageWrapperEl.removeClass(removeClass); $messageWrapperEl.addClass(addClass); HtmlUtils.setHtml( $messageWrapperEl, HtmlUtils.interpolateHtml( HtmlUtils.HTML('
{text}
'), // eslint-disable-line max-len { text: responseText, iconClass: iconClass } ) ); }, clearResponseStatus: function() { // Remove parent level state. var $messageWrapperEl = this.$el.find('.course-video-settings-message-wrapper'); $messageWrapperEl.empty(); $messageWrapperEl.removeClass('error'); $messageWrapperEl.removeClass('success'); }, clearPreferenceErrorState: function($PreferenceContainer) { $PreferenceContainer.removeClass('error'); $PreferenceContainer.find('.error-icon').empty(); $PreferenceContainer.find('.error-info').empty(); // Also clear response status if present already this.clearResponseStatus(); }, addErrorState: function($PreferenceContainer) { var requiredText = gettext('Required'), infoIconHtml = HtmlUtils.HTML(''); $PreferenceContainer.addClass('error'); HtmlUtils.setHtml( $PreferenceContainer.find('.error-icon'), infoIconHtml ); HtmlUtils.setHtml( $PreferenceContainer.find('.error-info'), requiredText ); }, validateCourseVideoSettings: function() { var isValid = true, $turnaroundEl = this.$el.find('.transcript-turnaround-wrapper'), $fidelityEl = this.$el.find('.transcript-fidelity-wrapper'), $languagesEl = this.$el.find('.transcript-languages-wrapper'), $videoSourcelanguageEl = this.$el.find('.video-source-language-wrapper'); // Explicit None selected case. if (this.selectedProvider === '') { return true; } if (!this.selectedTurnaroundPlan) { isValid = false; this.addErrorState($turnaroundEl); } else { this.clearPreferenceErrorState($turnaroundEl); } if (this.selectedProvider === CIELO24 && !this.selectedFidelityPlan) { isValid = false; this.addErrorState($fidelityEl); } else { this.clearPreferenceErrorState($fidelityEl); } if (this.selectedProvider === THREE_PLAY_MEDIA && !this.selectedVideoSourceLanguage) { isValid = false; this.addErrorState($videoSourcelanguageEl); } else { this.clearPreferenceErrorState($videoSourcelanguageEl); } if (this.selectedLanguages.length === 0) { isValid = false; this.addErrorState($languagesEl); } else { this.clearPreferenceErrorState($languagesEl); } return isValid; }, validateOrganizationCredentials: function() { var $OrganizationApiSecretWrapperEl, $OrganizationUsernameWrapperEl, isValid = true, $OrganizationApiKeyWrapperEl = this.$el.find('.' + this.selectedProvider + '-api-key-wrapper'); // Explicit None selected case. if (this.selectedProvider === '') { return false; } if ($OrganizationApiKeyWrapperEl.find('input').val() === '') { isValid = false; this.addErrorState($OrganizationApiKeyWrapperEl); } else { this.clearPreferenceErrorState($OrganizationApiKeyWrapperEl); } if (this.selectedProvider === THREE_PLAY_MEDIA) { $OrganizationApiSecretWrapperEl = this.$el.find('.' + this.selectedProvider + '-api-secret-wrapper'); if ($OrganizationApiSecretWrapperEl.find('input').val() === '') { isValid = false; this.addErrorState($OrganizationApiSecretWrapperEl); } else { this.clearPreferenceErrorState($OrganizationApiSecretWrapperEl); } } else { $OrganizationUsernameWrapperEl = this.$el.find('.' + this.selectedProvider + '-username-wrapper'); if ($OrganizationUsernameWrapperEl.find('input').val() === '') { isValid = false; this.addErrorState($OrganizationUsernameWrapperEl); } else { this.clearPreferenceErrorState($OrganizationUsernameWrapperEl); } } return isValid; }, saveTranscriptPreferences: function() { var self = this, responseTranscriptPreferences; // First clear response status if present already this.clearResponseStatus(); if (self.selectedProvider) { $.postJSON(self.transcriptHandlerUrl, { provider: self.selectedProvider, cielo24_fidelity: self.selectedFidelityPlan, cielo24_turnaround: self.selectedProvider === CIELO24 ? self.selectedTurnaroundPlan : '', three_play_turnaround: self.selectedProvider === THREE_PLAY_MEDIA ? self.selectedTurnaroundPlan : '', // eslint-disable-line max-len preferred_languages: self.selectedLanguages, video_source_language: self.selectedVideoSourceLanguage, global: false // Do not trigger global AJAX error handler }, function(data) { responseTranscriptPreferences = data ? data.transcript_preferences : null; self.updateSuccessResponseStatus(responseTranscriptPreferences); }).fail(function(jqXHR) { self.updateFailResponseStatus(jqXHR.responseText); }); } else { $.ajax({ type: 'DELETE', url: self.transcriptHandlerUrl }).done(function() { responseTranscriptPreferences = null; self.updateSuccessResponseStatus( responseTranscriptPreferences, gettext('Automatic transcripts are disabled.') ); }).fail(function(jqXHR) { self.updateFailResponseStatus(jqXHR.responseText); }); } }, saveOrganizationCredentials: function() { var self = this, username, apiSecret, apiKey = this.$el.find('.' + this.selectedProvider + '-api-key').val(); // First clear response status if present already this.clearResponseStatus(); if (this.selectedProvider === THREE_PLAY_MEDIA) { apiSecret = this.$el.find('.' + this.selectedProvider + '-api-secret').val(); } else { username = this.$el.find('.' + this.selectedProvider + '-username').val(); } $.postJSON(self.transcriptCredentialsHandlerUrl, { provider: self.selectedProvider, api_key: apiKey, api_secret_key: apiSecret, username: username, global: false // Do not trigger global AJAX error handler }, function() { self.$el.find('.organization-credentials-wrapper').hide(); // Update org credentials for selected provider self.transcriptOrganizationCredentials[self.selectedProvider] = true; self.updateSuccessResponseStatus( self.activeTranscriptionPlan, gettext('{selectedProvider} credentials saved').replace( '{selectedProvider}', self.availableTranscriptionPlans[self.selectedProvider].display_name ) ); }).fail(function(jqXHR) { self.updateFailResponseStatus(jqXHR.responseText); }); }, updateOrganizationCredentials: function() { if (this.validateOrganizationCredentials()) { this.saveOrganizationCredentials(); } }, updateCourseVideoSettings: function() { var $messageWrapperEl = this.$el.find('.course-video-settings-message-wrapper'); if (this.validateCourseVideoSettings()) { this.saveTranscriptPreferences(); } else { $messageWrapperEl.empty(); } }, discardChanges: function() { this.setActiveTranscriptPlanData(); // Re-render views this.renderProviders(); this.reRenderView(); }, renderOrganizationCredentials: function() { var $courseVideoSettingsContentEl = this.$el.find('.course-video-settings-content'); // Render empty state providers view. this.renderProviders('empty'); HtmlUtils.setHtml( $courseVideoSettingsContentEl, this.organizationCredentialsTemplate({ selectedProvider: { key: this.selectedProvider, name: this.availableTranscriptionPlans[this.selectedProvider].display_name }, organizationCredentialsExists: this.transcriptOrganizationCredentials[this.selectedProvider], CIELO24: CIELO24, THREE_PLAY_MEDIA: THREE_PLAY_MEDIA }) ); // Render footer HtmlUtils.setHtml( this.$el.find('.course-video-settings-footer'), this.organizationCredentialsFooterTemplate({}) ); }, renderTranscriptPreferences: function() { var $courseVideoSettingsContentEl = this.$el.find('.course-video-settings-content'), dateModified = this.activeTranscriptionPlan ? moment.utc(this.activeTranscriptionPlan.modified).format('ll') : ''; HtmlUtils.setHtml( $courseVideoSettingsContentEl, this.transcriptPreferencesTemplate({ selectedProvider: this.selectedProvider, THREE_PLAY_MEDIA: THREE_PLAY_MEDIA }) ); // Render transcript preferences. this.renderTurnaround(); this.renderFidelity(); this.renderSourceLanguages(); this.renderTargetLanguages(); // Render footer HtmlUtils.setHtml( this.$el.find('.course-video-settings-footer'), this.updateSettingsFooterTemplate({ dateModified: dateModified }) ); }, render: function() { var dateModified = this.activeTranscriptionPlan ? moment.utc(this.activeTranscriptionPlan.modified).format('ll') : ''; HtmlUtils.setHtml(this.$el, this.template({})); // Render footer HtmlUtils.setHtml( this.$el.find('.course-video-settings-footer'), this.updateSettingsFooterTemplate({ dateModified: dateModified }) ); this.renderProviders(); this.registerCloseClickHandler(); this.setFixedCourseVideoSettingsPane(); return this; }, setFixedCourseVideoSettingsPane: function() { var $courseVideoSettingsButton = $('.course-video-settings-button'), $courseVideoSettingsContainer = this.$el.find('.course-video-settings-container'), initialPositionTop = $courseVideoSettingsContainer.offset().top, // Button right position = width of window - button left position - button width - paddings - border. $courseVideoSettingsButtonRight = $(window).width() - $courseVideoSettingsButton.offset().left - $courseVideoSettingsButton.width() - $courseVideoSettingsButton.css('padding-left').replace('px', '') - $courseVideoSettingsButton.css('padding-right').replace('px', '') - $courseVideoSettingsButton.css('border-width').replace('px', '') - 5; // Extra pixles for slack; // Set to windows total height $courseVideoSettingsContainer.css('height', $(window).height()); // Start settings pane adjascent to 'course video settings' button. $courseVideoSettingsContainer.css('right', $courseVideoSettingsButtonRight); // Make sticky when scroll reaches top. $(window).scroll(function() { if ($(window).scrollTop() >= initialPositionTop) { $courseVideoSettingsContainer.addClass('fixed-container'); } else { $courseVideoSettingsContainer.removeClass('fixed-container'); } }); }, closeCourseVideoSettings: function() { // TODO: Slide out when closing settings pane. See EDUCATOR-1477 // Trigger destroy transcript event. Backbone.trigger('coursevideosettings:destroyCourseVideoSettingsView'); // Unbind any events associated this.undelegateEvents(); this.stopListening(); // Empty this.$el content from DOM this.$el.empty(); // Reset everything. this.resetPlanData(); } }); return CourseVideoSettingsView; });