Rally Software

Expand all | Collapse all

Rally SDK2 WSAPI - Javascript - How to retrieve the revision history of a deleted feature?

Jump to Best Answer
  • 1.  Rally SDK2 WSAPI - Javascript - How to retrieve the revision history of a deleted feature?

    Posted 01-12-2020 08:39 AM
    Edited by Gregory Garcia 01-12-2020 08:51 AM
    Hello,

    Using Javascript in a custom app, I try to retrieve the revision history of a delete feature thanks to the Rally SDK 2.1 WSAPI.

    I manage to retrieve the delete feature information this way:
    function loadFeaturesCurrentRecycleBin() {
    	var features = Ext.create('Rally.data.wsapi.Store', {
    		model: 'RecycleBinEntry',
    		fetch: true,
    		filters: [{
    				property: 'ID',
    				operator: 'in',
    				value: ['F14921']
    			}
    		],
    		listeners: {
    			load: loadedFeaturesCurrentRecycleBin,
    			scope: this
    		},
    	});
    	features.load();
    };
    function loadedFeaturesCurrentRecycleBin(store, features) {
    	console.log(' - ' + (features ? features.length : 0) + ' features retrieved from recycle bin...');
    	console.log(features);
    };

    Only part of the feature information is available from the recycle bin, and the revision history isn't available, not event its _ref attribute:


    If I had a revision history reference, like for a feature that is not deleted, I could retrieve its revision history.
    The following example shows how to retrieve the revision history for all the features I have in memory in gvRetrievedFeaturesBeingLoaded[] array. In short, it is based on :
    	var _onModelCreated = function(model) {
    		var promises = [];
    		for (var i in gvRetrievedFeaturesBeingLoaded) {
    			var f = gvRetrievedFeaturesBeingLoaded[i];
    			var revisionHistoryRef = f.RevisionHistory._ref;
    			promises.push(model.load(Rally.util.Ref.getOidFromRef(revisionHistoryRef)));
    		}				
    		Deft.Promise.all(promises).then(
    					(histories) => 		{ 	_onModelLoaded(histories); }, 
    					(rejectReason) => 	{ 	console.log(rejectReason); } 
    				);
    	};
    Full example:
    function loadFeaturesRevisionHistoryCurrent() {
    	console.log(' - search for features rank revision hstory...');
    	// https://github.com/nmusaelian-rally/revisions/blob/master/App.js
    	
    	// Get the RevisionHistory model (common to all features)
    	var _getRevisionHistory = function() {
    		// console.log('Create the model for RevisionHistory');
    		this._revisionModel = Rally.data.ModelFactory.getModel({
    			type: 'RevisionHistory',
    			scope: this,
    			success: _onModelCreated
    		});
    	};	
    	
    	// For each feature, build the RevisionHistory model and load it to retrieve the revision history
    	var _onModelCreated = function(model) {
    		// console.log('Load the models (histories)');				
    		var nbFeaturesWithRevisionHistory = 0;
    		var promises = [];
    		// Parse features and identify the ones with a revision history to be loaded
    		for (var i in gvRetrievedFeaturesBeingLoaded) {
    			var f = gvRetrievedFeaturesBeingLoaded[i];
    			if (f.RevisionHistory) {
    				if (f.RevisionHistory.Revisions) {
    					if (f.RevisionHistory.Revisions.Count > 0) {
    						// Promise to load the model for this revision history
    						nbFeaturesWithRevisionHistory ++;
    						var revisionHistoryRef = f.RevisionHistory._ref;
    						promises.push(model.load(Rally.util.Ref.getOidFromRef(revisionHistoryRef)));
    						// console.log(' - ' + f.FormattedID, revisionHistoryRef);
    					}
    				}
    			}
    		}				
    		// Run the queries and wait for completion
    		// console.log(' -- ' + nbFeaturesWithRevisionHistory + ' features have a revision hstory');
    		if (promises.length > 0) {
    			Deft.Promise.all(promises).then(
    						(histories) => 		{ 	_onModelLoaded(histories); }, 
    						(rejectReason) => 	{ 	console.log(rejectReason); } 
    					);
    		} else {
    			console.log(' - no feature hstory to be retrieved.');
    			loadStoriesCurrent();
    		}
    	};
    	
    	// For each revision history (1 by feature), retrieve the list of revisions
    	var _onModelLoaded = function(histories) {
    		// console.log(' - ' + (histories ? histories.length : 0) + ' histories retrieved...');
    		// console.log(histories);
    		var promises = [];
    		_.each(histories, function(history){
    			var revisions = history.get('Revisions');
    			revisions.store = history.getCollection('Revisions',{
    				fetch:['Description', 'CreationDate', 'RevisionHistory'], // 'User', 'RevisionNumber', 
    				filters: [{
    						property: 'Description',
    						operator: 'contains',
    						value: 'Rank',
    						caseSensitive: false
    					}
    				],
    			});
    			promises.push(revisions.store.load());
    		});
    		// Run the queries and wait for completion
    		if (promises.length > 0) {
    			Deft.Promise.all(promises).then(
    						(revhistories) => 	{ 	_attachRevisionsToFeatures(revhistories); }, 
    						(rejectReason) => 	{ 	console.log(rejectReason); } 
    					);
    		} else {
    			console.log(' - no revision hstory to be retrieved.');
    			loadStoriesCurrent();
    		} 
    	};
    	
    	// Link together the features and their revisions
    	var _attachRevisionsToFeatures = function(revhistories) {
    		console.log(' - ' + (revhistories ? revhistories.length : 0) + ' rank revision histories retrieved...');
    		// console.log(revhistories);
    		
    		// Parse the retrieved revision histories
    		_.each(revhistories, function(revisions){
    			if (revisions.length > 0 ) { // it may be empty as there is a filter on "Description contains 'Rank'"
    				// Identify the revisions history reference
    				var historyRefTheRevisionsBelongTo = revisions[0].data.RevisionHistory._ref;
    				// console.log(historyRefTheRevisionsBelongTo);
    				// Search for this hostory reference in the features list
    				for (var i in gvRetrievedFeaturesBeingLoaded) {
    					var f = gvRetrievedFeaturesBeingLoaded[i];
    					if (f.RevisionHistory) {
    						if (f.RevisionHistory.Revisions) {
    							if (f.RevisionHistory.Revisions.Count > 0) {
    								if (f.RevisionHistory._ref == historyRefTheRevisionsBelongTo) {
    									// Found a feature that matches!
    									// console.log(f.FormattedID + ' -> ' + f.RevisionHistory.Revisions.Count + ' total rev and ' + revisions.length + ' rank rev found');
    									f.RetrievedRevisionsRank = revisions;
    									break;
    								}
    							}
    						}
    					}
    				}
    			}
    		});	
    
    		loadStoriesCurrent();
    	};
    	
    	// Trigger the callbacks sequence
    	_getRevisionHistory();
    };

    So, as I have no revision history reference I could build my query from, I tried to query all existing revision histories in order to try to identify a reference toward my deleted feature identifiers (ObjectID, ID, _ref) but I get no result at all...

    Attempt 1:
    function loadFeaturesRevisionHistoryFromRecycleBin() {
    
    	var _getRevisionHistory = function() {
    		this._revisionModel = Rally.data.ModelFactory.getModel({
    			type: 'RevisionHistory',
    			scope: this,
    			success: _onModelCreated
    		});
    	};	
    	
    	var _onModelCreated = function(model) {
    		var promises = [];
    		promises.push(model.load());		
    		Deft.Promise.all(promises).then(
    					(histories) => 		{ 	_onModelLoaded(histories); }, 
    					(rejectReason) => 	{ 	console.log(rejectReason); } 
    				);
    	};
    	
    	var _onModelLoaded = function(histories) {
    		console.log(' - ' + (histories ? histories.length : 0) + ' histories retrieved...');
    		// console.log(histories);
    	};
    	
    	_getRevisionHistory();
    };


    Attempt 2:
    function loadRevHistories() {
    	var artefacts = Ext.create('Rally.data.wsapi.Store', {
    		model: 'RevisionHistory',
    		fetch: true,
    		listeners: {
    			load: loadedRevHistories,
    			scope: this
    		},
    	});
    	artefacts.load();
    };
    
    function loadedRevHistories(store, rh) {
    	console.log(' - ' + (rh ? rh.length : 0) + ' rh retrieved...');			
    };

    So, in the end, I have 2 questions:
    - is there a way to retrieve the revision history of a deleted feature?
    - is there a way to retrieve the full list of all the revision histories, without specifying a reference to the model?

    Thanks for any help :)
    Greg.


  • 2.  RE: Rally SDK2 WSAPI - Javascript - How to retrieve the revision history of a deleted feature?
    Best Answer

    Posted 01-13-2020 07:25 AM
    Hi Greg,

    #1. The only way I know is to 'restore' the item first and then look at stuff. You can always delete it again afterwards. If you want to see how the system restores things then set your browser developer tools to track the netwrok activity when you use the restore option from the item menu o​n the recyclebin page (icon in bottom left of UI).

    #2. No as far as I know. You only have the info available to you as shown in the API docs.

    ------------------------------
    Nik
    Rally Sales Engineer
    Rally Software
    ------------------------------



  • 3.  RE: Rally SDK2 WSAPI - Javascript - How to retrieve the revision history of a deleted feature?

    Posted 01-13-2020 08:01 AM
    Thanks for this clarification Nik, this is exactly what I was afraid of :-)