ECOM-4904 Move the program editor backbone app to Studio (#12962)
This commit is contained in:
21
cms/static/js/programs/utils/api_config.js
Normal file
21
cms/static/js/programs/utils/api_config.js
Normal file
@@ -0,0 +1,21 @@
|
||||
define([
|
||||
'js/programs/models/api_config_model'
|
||||
],
|
||||
function( ApiConfigModel ) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* This js module implements the Singleton pattern for an instance
|
||||
* of the ApiConfigModel Backbone model. It returns the same shared
|
||||
* instance of that model anywhere it is required.
|
||||
*/
|
||||
var instance;
|
||||
|
||||
if (instance === undefined) {
|
||||
instance = new ApiConfigModel();
|
||||
}
|
||||
|
||||
return instance;
|
||||
|
||||
}
|
||||
);
|
||||
89
cms/static/js/programs/utils/auth_utils.js
Normal file
89
cms/static/js/programs/utils/auth_utils.js
Normal file
@@ -0,0 +1,89 @@
|
||||
define([
|
||||
'jquery',
|
||||
'underscore',
|
||||
'js/programs/utils/api_config'
|
||||
],
|
||||
function( $, _, apiConfig ) {
|
||||
'use strict';
|
||||
|
||||
var auth = {
|
||||
autoSync: {
|
||||
/**
|
||||
* Override Backbone.sync to seamlessly attempt (re-)authentication when necessary.
|
||||
*
|
||||
* If a 401 error response is encountered while making a request to the Programs,
|
||||
* API, this wrapper will attempt to request an id token from a custom endpoint
|
||||
* via AJAX. Then the original request will be retried once more.
|
||||
*
|
||||
* Any other response than 401 on the original API request, or any error occurring
|
||||
* on the retried API request (including 401), will be handled by the base sync
|
||||
* implementation.
|
||||
*
|
||||
*/
|
||||
sync: function( method, model, options ) {
|
||||
|
||||
var oldError = options.error;
|
||||
|
||||
this._setHeaders( options );
|
||||
|
||||
options.notifyOnError = false; // suppress Studio error pop-up that will happen if we get a 401
|
||||
|
||||
options.error = function(xhr, textStatus, errorThrown) {
|
||||
if (xhr && xhr.status === 401) {
|
||||
// attempt auth and retry
|
||||
this._updateToken(function() {
|
||||
// restore the original error handler
|
||||
options.error = oldError;
|
||||
options.notifyOnError = true; // if it fails again, let Studio notify.
|
||||
delete options.xhr; // remove the failed (401) xhr from the last try.
|
||||
|
||||
// update authorization header
|
||||
this._setHeaders( options );
|
||||
|
||||
Backbone.sync.call(this, method, model, options);
|
||||
}.bind(this));
|
||||
} else if (oldError) {
|
||||
// fall back to the original error handler
|
||||
oldError.call(this, xhr, textStatus, errorThrown);
|
||||
}
|
||||
}.bind(this);
|
||||
return Backbone.sync.call(this, method, model, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fix up headers on an imminent AJAX sync, ensuring that the JWT token is enclosed
|
||||
* and that credentials are included when the request is being made cross-domain.
|
||||
*/
|
||||
_setHeaders: function( ajaxOptions ) {
|
||||
ajaxOptions.headers = _.extend ( ajaxOptions.headers || {}, {
|
||||
Authorization: 'JWT ' + apiConfig.get( 'idToken' )
|
||||
});
|
||||
ajaxOptions.xhrFields = _.extend( ajaxOptions.xhrFields || {}, {
|
||||
withCredentials: true
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch a new id token from the configured endpoint, update the api config,
|
||||
* and invoke the specified callback.
|
||||
*/
|
||||
_updateToken: function( success ) {
|
||||
|
||||
$.ajax({
|
||||
url: apiConfig.get('authUrl'),
|
||||
xhrFields: {
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
|
||||
withCredentials: true
|
||||
},
|
||||
crossDomain: true
|
||||
}).done(function ( data ) {
|
||||
// save the newly-retrieved id token
|
||||
apiConfig.set( 'idToken', data.id_token );
|
||||
}).done( success );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return auth;
|
||||
}
|
||||
);
|
||||
16
cms/static/js/programs/utils/constants.js
Normal file
16
cms/static/js/programs/utils/constants.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Reusable constants
|
||||
*/
|
||||
define([], function() {
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
keyCodes: {
|
||||
tab: 9,
|
||||
enter: 13,
|
||||
esc: 27,
|
||||
up: 38,
|
||||
down: 40
|
||||
}
|
||||
};
|
||||
});
|
||||
70
cms/static/js/programs/utils/validation_config.js
Normal file
70
cms/static/js/programs/utils/validation_config.js
Normal file
@@ -0,0 +1,70 @@
|
||||
define([
|
||||
'backbone',
|
||||
'backbone.validation',
|
||||
'underscore',
|
||||
'gettext'
|
||||
],
|
||||
function( Backbone, BackboneValidation, _ ) {
|
||||
'use strict';
|
||||
|
||||
var errorClass = 'has-error',
|
||||
messageEl = '.field-message',
|
||||
messageContent = '.field-message-content';
|
||||
|
||||
// These are the same messages provided by Backbone.Validation,
|
||||
// marked for translation.
|
||||
// See: http://thedersen.com/projects/backbone-validation/#overriding-the-default-error-messages.
|
||||
_.extend( Backbone.Validation.messages, {
|
||||
required: gettext( '{0} is required' ),
|
||||
acceptance: gettext( '{0} must be accepted' ),
|
||||
min: gettext( '{0} must be greater than or equal to {1}' ),
|
||||
max: gettext( '{0} must be less than or equal to {1}' ),
|
||||
range: gettext( '{0} must be between {1} and {2}' ),
|
||||
length: gettext( '{0} must be {1} characters' ),
|
||||
minLength: gettext( '{0} must be at least {1} characters' ),
|
||||
maxLength: gettext( '{0} must be at most {1} characters' ),
|
||||
rangeLength: gettext( '{0} must be between {1} and {2} characters' ),
|
||||
oneOf: gettext( '{0} must be one of: gettext( {1}' ),
|
||||
equalTo: gettext( '{0} must be the same as {1}' ),
|
||||
digits: gettext( '{0} must only contain digits' ),
|
||||
number: gettext( '{0} must be a number' ),
|
||||
email: gettext( '{0} must be a valid email' ),
|
||||
url: gettext( '{0} must be a valid url' ),
|
||||
inlinePattern: gettext( '{0} is invalid' )
|
||||
});
|
||||
|
||||
_.extend( Backbone.Validation.callbacks, {
|
||||
// Gets called when a previously invalid field in the
|
||||
// view becomes valid. Removes any error message.
|
||||
valid: function( view, attr, selector ) {
|
||||
var $input = view.$( '[' + selector + '~="' + attr + '"]' ),
|
||||
$message = $input.siblings( messageEl );
|
||||
|
||||
$input.removeClass( errorClass )
|
||||
.removeAttr( 'data-error' );
|
||||
|
||||
$message.removeClass( errorClass )
|
||||
.find( messageContent )
|
||||
.text( '' );
|
||||
},
|
||||
|
||||
// Gets called when a field in the view becomes invalid.
|
||||
// Adds a error message.
|
||||
invalid: function( view, attr, error, selector ) {
|
||||
var $input = view.$( '[' + selector + '~="' + attr + '"]' ),
|
||||
$message = $input.siblings( messageEl );
|
||||
|
||||
$input.addClass( errorClass )
|
||||
.attr( 'data-error', error );
|
||||
|
||||
$message.addClass( errorClass )
|
||||
.find( messageContent )
|
||||
.text( $input.data('error') );
|
||||
}
|
||||
});
|
||||
|
||||
Backbone.Validation.configure({
|
||||
labelFormatter: 'label'
|
||||
});
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user