Source: themes/ess-dive/views/MetadataView.js

/*global define */
define(['jquery',
		'underscore',
		'views/BaseMetadataView',
		'models/DataONEObject'
		],
	function($, _,BaseMetadataView, DataONEObject) {
        'use strict';


        var MetadataView = BaseMetadataView.extend({

			/** EXTEND ancestor
			 * EXTEND NOTES: Don't execute the function if null is passed in for json. We want to do this
			 * because we changed overrode generateJSONLD to not return the JSONLD but to update the model in the
			 * done callback.
			 *
			 *  ------------- Ancestor Doc ---------------
			 * Insert Schema.org-compliant JSONLD for the model bound to the view into
			 * the head tag of the page (at the end).
			 *
			 * @param {object} json - JSON-LD to insert into the page
			 *
			 * Some notes:
			 *
			 * - Checks if the JSONLD already exists from the previous data view
			 * - If not create a new script tag and append otherwise replace the text
			 *   for the script
			 */
			insertJSONLD: function(json){
				if (json) {
					BaseMetadataView.prototype.insertJSONLD.apply(this, [json]);
				}
			},

			/** OVERRIDE Ancestor
			 * OVERRIDE NOTES: This overrides the ancestor function by using the
			 * ESS-DIVE custom json-ld metacat view service. This method is making
			 * and asynchronous call to the json-ld view service and is updating vhew
			 * MetadataView model receiving the response
			 *
			 * ------ Ancestor Doc -----------
			 * Generate Schema.org-compliant JSONLD for the model bound to the view into
			 *  the head tag of the page by `insertJSONLD`.
			 *
			 * Note: `insertJSONLD` should be called to do the actual inserting into the
			 * DOM.
			 */
			generateJSONLD: function () {

				// Reference this so that we can access it in the ajax callback
				var thisView = this;

				// Build the JSONLD view service endpoint.
				var jsonldEndpoint = MetacatUI.appModel.get('baseUrl') +
					 MetacatUI.appModel.get('context') + MetacatUI.appModel.get('d1Service') + '/views/json-ld/'+
					this.model.get("id");

				// Default JSON is empty.
				var json_ld='{}';

				// Call the JSON-LD view service asynchronously
				$.ajax({
					url: jsonldEndpoint,
					type: "GET",
					headers: {
						"Authorization": "Bearer " + MetacatUI.appUserModel.get("token")},
					contentType: "application/json"
				}).done(function( result ) {
					// Update the JSON_LD Model in the Metadata View page
					// This is an asynchronous call and the json result
					// may not be available by the time we hit the
					// end of this method
					thisView.insertJSONLD(JSON.parse(result));
				});

				// The view model is being updated in this function. Otherwise we would
				// have to make the above call synchronously.
				return null
			},

			/**
			 * Shows the confirmation message on successful save
			 *
			 * @param model
			 * @param value
             * @param options
             */
			handleSaveMetadata: function(model, value, options){
				var msg = "Your publication request "
					+ "has been received. An ESS-DIVE admin will check the submission and contact you "
					+ "through the email address in your profile. Note that the publication status will "
					+ "not prevent you from editing your data package. The data package will not be published "
					+ "until you respond to our email and address all issues regarding your submission.";
				this.$el.find("div.alert").remove()
				this.$el.find('.container').prepend(
				this.alertTemplate({
					msg: msg,
					classes: 'alert-success'
				})
				);


			},
			/**
			 * Shows confirmation message that the dataset DOI has already been requested
			 *
			 * @param model
			 * @param value
             * @param options
             */
			handleAlreadyRequested: function(model, value, options){
				var msg = "You have already requested to publish this data package. "
					+"Contact "+MetacatUI.appModel.get("emailContact") + " if you have any questions.";
				this.$el.find("div.alert").remove()
				this.$el.find('.container').prepend(
				this.alertTemplate({
					msg: msg,
					classes: 'alert-warning'
				})
				);


			},
			/***
			 * Handle error on fetch
			 *
			 * @param model
             * @param viewRef
             */
			handleError: function(model, viewRef){
				// show the error message, but stay on the same page
				var msg = "Publish failed: " + $(response.responseText).find("description").text();

				viewRef.hideLoading();
				viewRef.showError(msg);

			},
			/**
			 * Adds Allow write access to the specified subject and access policy
			 *
			 * @param subject - subject to give write access to
			 * @param model - the model whose access policy is to be  modified
             * @returns {object} returns new access policy if the given access policy was updated
             */
			addAllowWriteAccess: function(subject, model){
				// Create the access policy for the given subject
				var share_access_policy = {
						subject: subject,
						read: true
					};

				// get the access policy from the model
				var accessPolicy = model.get("accessPolicy");

				// Now inspect the access policy to see if
				// thes subject has already been given write access.
				if (!accessPolicy || accessPolicy.length == 0 ){
					// No access policy
					return [share_access_policy];
				}
				else if (accessPolicy.length >=0) {
					 // There is one but lets see if the subject has read
					 var alreadyRequested = accessPolicy.any(
						 function(policy){ return policy.get("subject") == subject; },
						 subject);


					 // Did they already request to be published
					 if (alreadyRequested ) return null;

					 // Give the subject write access
					 accessPolicy.push(share_access_policy);
					 return accessPolicy
				}
				else {
					// This is a special case where accessPolicy.allow is not an array
					if (accessPolicy.read == true && accessPolicy.subject == subject) return null;
					return  {
						subject: share_access_policy,
						read: true
					};
				}
			},
            /**
             * Override the publish function the mark a dataset for publishing.
             *
             * @param event
             */
            publish: function(event){
                // target may not actually prevent click events, so double check
                var disabled = $(event.target).closest("a").attr("disabled");
                if (disabled) {
                    return false;
                }
                var pid = $(event.target).closest("a").attr("pid");
                var ret = confirm("Are you sure you want to publish? Publishing the data " +
					"package will make it publicly available for search and download." +
					"\n\nThe data package will be published with an existing DOI, if you supplied one, or " +
					"else a new DOI will be issued through ESS-DIVE." +
					"\n\nIf you click \"OK\", this data package will be put into a publication queue. " +
					"An ESS-DIVE admin will check the submission and contact you through the email address in your profile. " +
					"Note that the publication status will not prevent you from editing your data package. " +
					"The data package will not be published until you respond to our email " +
					"and address all issues regarding your submission.");


                if (ret) {

					// DataONEObject.save expects this to be in the
					// global rootDataPackage
                    MetacatUI.rootDataPackage = this.dataPackage;

					// Fetch the metadata model from the archive
				    var viewRef = this;
					var metadataModel = new DataONEObject({id: this.pid, sync:true});
                	metadataModel.fetch( {
						success: function(model, response, options){
							// We have the model let's see if they already request access
							var accessPolicy = viewRef.addAllowWriteAccess(MetacatUI.appModel.get("shareGroup"), model);
							if (accessPolicy) {
								// This is the first time they have requested access
								// update the metadata model with a new access policy
								model.once("successSaving", viewRef.handleSaveMetadata, viewRef);
								model.set("accessPolicy", accessPolicy);
								model.save({accessPolicy: accessPolicy});
							}
							else{
								viewRef.handleAlreadyRequested(model,response, options);
							}
						}
						,
						error: function(model, response, options){
							viewRef.handleError(model, viewRef)}
					}
					);






                }
            }

        });

        return MetadataView

    }
);