From 74ddbfaa5a5e0c4894f54994254eb253aa797352 Mon Sep 17 00:00:00 2001 From: Andrew Downes Date: Sun, 5 May 2013 21:53:44 +0100 Subject: [PATCH] Disable unusable moderator buttons This is a relatively stable commit. --- TinReport/TinReport.js | 671 +++++++++++++++++++---------------------- tinrepo.css | 10 +- 2 files changed, 321 insertions(+), 360 deletions(-) diff --git a/TinReport/TinReport.js b/TinReport/TinReport.js index a40c6af..0c70cd8 100644 --- a/TinReport/TinReport.js +++ b/TinReport/TinReport.js @@ -1,6 +1,5 @@ - /* -=============COPYRIGHT============ +=============COPYRIGHT============ Tin Report - A prototype for Tin Can API 1.0.0 Copyright (C) 2012 Andrew Downes @@ -20,7 +19,6 @@ GNU General Public License for more details. //TODO: get defintiions from the LRS (pending TinCanJs functionality). //TODO: filters and searches. - //Create an instance of the Tin Can Library var myTinCan = new TinCan(); @@ -30,242 +28,269 @@ var myTinCan = new TinCan(); myTinCan.DEBUG = 0; //define the arrays of statements as global variables -var makeModeratorStatements, -makeModeratorStatementsLength, -revokeModeratorStatements, -revokeModeratorStatementsLength, -revertExtensionStatements, -deprecateExtensionStatements, -recogniseExtensionStatements, -acceptExtensionStatements, -registerExtensionStatements, -moderatorLoginStatements; - +var makeModeratorStatements, makeModeratorStatementsLength, revokeModeratorStatements, revokeModeratorStatementsLength, revertExtensionStatements, deprecateExtensionStatements, recogniseExtensionStatements, acceptExtensionStatements, registerExtensionStatements, moderatorLoginStatements; //track the number of LRS requests completed: -var LRSGetsCompleted = 0, -LRSGetsDue=7; - +var LRSGetsCompleted = 0, LRSGetsDue = 7; //TODO: get this data from the repository itself #recursion //Define legal activity types (see profile) -var legalActivityTypes = [ - "http://tincanapi.co.uk/tinrepo/activitytypes/verb", - "http://tincanapi.co.uk/tinrepo/activitytypes/activity_type", - "http://tincanapi.co.uk/tinrepo/activitytypes/activity_definition_extension", - "http://tincanapi.co.uk/tinrepo/activitytypes/result_extension", - "http://tincanapi.co.uk/tinrepo/activitytypes/context_extension", - "http://tincanapi.co.uk/tinrepo/activitytypes/attachment_extension", - "http://tincanapi.co.uk/tinrepo/activitytypes/state_api_document", - "http://tincanapi.co.uk/tinrepo/activitytypes/agent_profile_api_document", - "http://tincanapi.co.uk/tinrepo/activitytypes/activity_profile_api_document", - "http://tincanapi.co.uk/tinrepo/activitytypes/repository" -]; +var legalActivityTypes = ["http://tincanapi.co.uk/tinrepo/activitytypes/verb", "http://tincanapi.co.uk/tinrepo/activitytypes/activity_type", "http://tincanapi.co.uk/tinrepo/activitytypes/activity_definition_extension", "http://tincanapi.co.uk/tinrepo/activitytypes/result_extension", "http://tincanapi.co.uk/tinrepo/activitytypes/context_extension", "http://tincanapi.co.uk/tinrepo/activitytypes/attachment_extension", "http://tincanapi.co.uk/tinrepo/activitytypes/state_api_document", "http://tincanapi.co.uk/tinrepo/activitytypes/agent_profile_api_document", "http://tincanapi.co.uk/tinrepo/activitytypes/activity_profile_api_document", "http://tincanapi.co.uk/tinrepo/activitytypes/repository"]; //TODO: get this data from the repository itself #recursion var extensionManagementVerbsList = { "http://tincanapi.co.uk/tinrepo/verbs/reverted_extension" : { - status : "reverted", - display : "reverted extension" - }, - "http://tincanapi.co.uk/tinrepo/verbs/deprecated_extension": { + status : "registered", + display : "reverted extension", + action : "revert" + }, + "http://tincanapi.co.uk/tinrepo/verbs/deprecated_extension" : { status : "deprecated", - display : "deprecated extension" - }, - "http://tincanapi.co.uk/tinrepo/verbs/recognised_extension": { + display : "deprecated extension", + action : "deprecate" + }, + "http://tincanapi.co.uk/tinrepo/verbs/recognised_extension" : { status : "recognised", - display : "recognised extension" - }, - "http://tincanapi.co.uk/tinrepo/verbs/accepted_extension": { + display : "recognised extension", + action : "recognise" + }, + "http://tincanapi.co.uk/tinrepo/verbs/accepted_extension" : { status : "accepted", - display : "accepted extension" - }, - "http://tincanapi.co.uk/tinrepo/verbs/registered_extension": { + display : "accepted extension", + action : "accept" + }, + "http://tincanapi.co.uk/tinrepo/verbs/registered_extension" : { status : "registered", - display : "registered extension" - } + display : "registered extension", + action : "register" + } +} + +//list of what actions are allowable for moderators to perform on extensions of which status +// e.g. you can't accept an extension that already has recognised status +var allowableModeratorActions = { + registered : { + accept : true, + recognise : true, + revert : true, + deprecate : true, + register : false + }, + accepted : { + accept : false, + recognise : true, + revert : true, + deprecate : true, + register : false + }, + recognised : { + accept : false, + recognise : false, + revert : true, + deprecate : true, + register : false + }, + deprecated : { + accept : false, + recognise : false, + revert : true, + deprecate : false, + register : false + }, + reverted : { + accept : true, + recognise : true, + revert : false, + deprecate : true, + register : false + } } //BaseURI var baseURI = {}; -baseURI.activityTypes ="http://tincanapi.co.uk/tinrepo/activitytypes/"; +baseURI.activityTypes = "http://tincanapi.co.uk/tinrepo/activitytypes/"; //Details of the admin account hard coded here for now as a single item array of objects var adminAuth = [{ - account:{ - name:"gddikCN6KrbdWZaXq36T@mrandrewdownes", - homePage:"https://mrandrewdownes.waxlrs.com/TCAPI" - } - }] - + account : { + name : "gddikCN6KrbdWZaXq36T@mrandrewdownes", + homePage : "https://mrandrewdownes.waxlrs.com/TCAPI" + } +}] + //Moderator details - an object with properties credentials and actor var moderator = getObjectFromQueryString("params"); //Create an LRS with public credentials and add to the list of record stores var myLRS = new TinCan.LRS({ - endpoint:"https://mrandrewdownes.waxlrs.com/TCAPI/", - version: "0.95", - auth: 'Basic ' + Base64.encode('uomcAcOeWBxCF6NvWUDh' + ':' + 'Weyr9VvZoGKic40lzNTv'), + endpoint : "https://mrandrewdownes.waxlrs.com/TCAPI/", + version : "0.95", + auth : 'Basic ' + Base64.encode('uomcAcOeWBxCF6NvWUDh' + ':' + 'Weyr9VvZoGKic40lzNTv'), }); myLRS.alertOnRequestFailure = false; -//If moderator credentials are provided, use those instead. -if (!(typeof moderator === "undefined")) -{ +//If moderator credentials are provided, use those instead. +if(!( typeof moderator === "undefined")) { myLRS.auth = moderator.credentials } myTinCan.recordStores[0] = myLRS; +//============DOCUMENT READY============================= +$(function() { + console.log(new Date().getTime() + ' HTML page loaded. LRS data retrieval will begin in a few milliseconds...'); -//============DOCUMENT READY============================= -$(function(){ - - console.log (new Date().getTime() + ' HTML page loaded. LRS data retrieval will begin in a few milliseconds...'); - - //Get all the data from the LRS. Calls getDataComplete when all requests are complete. + //Get all the data from the LRS. Calls getDataComplete when all requests are complete. getDataFromLRS(); - + }); -function getDataComplete(){ - validateStatements (); +function getDataComplete() { + validateStatements(); var repositoryItems = buildRespositoryObject(); outputrepositoryItems(repositoryItems); - - console.log (new Date().getTime() + ' All done. Enjoy!'); + + console.log(new Date().getTime() + ' All done. Enjoy!'); } //============XHR FUNCTIONS================================= -//Sets all the XHR requests running. We don't know the order they will complete. -function getDataFromLRS() -{ - console.log (new Date().getTime() + ' Getting data from the LRS (this may take a few seconds, please wait)...'); - +//Sets all the XHR requests running. We don't know the order they will complete. +function getDataFromLRS() { + console.log(new Date().getTime() + ' Getting data from the LRS (this may take a few seconds, please wait)...'); + //get the make moderator statements myTinCan.getStatements({ - params:{ - verb:{id:"http://tincanapi.co.uk/tinrepo/verbs/make_moderator"} + params : { + verb : { + id : "http://tincanapi.co.uk/tinrepo/verbs/make_moderator" + } }, - callback: getMakeModerator + callback : getMakeModerator }); - + //Get the revoke statements myTinCan.getStatements({ - params:{ - verb:{id:"http://tincanapi.co.uk/tinrepo/verbs/revoke_moderator"}, + params : { + verb : { + id : "http://tincanapi.co.uk/tinrepo/verbs/revoke_moderator" + }, }, - callback: getRevokeModerator + callback : getRevokeModerator }); - + //Get the revert statements myTinCan.getStatements({ - params:{ - verb:{id:"http://tincanapi.co.uk/tinrepo/verbs/reverted_extension"}, + params : { + verb : { + id : "http://tincanapi.co.uk/tinrepo/verbs/reverted_extension" + }, }, - callback: getRevertExtension + callback : getRevertExtension }); - + //Get the deprecate statements myTinCan.getStatements({ - params:{ - verb:{id:"http://tincanapi.co.uk/tinrepo/verbs/deprecated_extension"}, + params : { + verb : { + id : "http://tincanapi.co.uk/tinrepo/verbs/deprecated_extension" + }, }, - callback: getDeprecateExtension + callback : getDeprecateExtension }); - + //Get the recognise statements myTinCan.getStatements({ - params:{ - verb:{id:"http://tincanapi.co.uk/tinrepo/verbs/recognised_extension"}, + params : { + verb : { + id : "http://tincanapi.co.uk/tinrepo/verbs/recognised_extension" + }, }, - callback: getRecogniseExtension + callback : getRecogniseExtension }); - + //Get the accept statements myTinCan.getStatements({ - params:{ - verb:{id:"http://tincanapi.co.uk/tinrepo/verbs/accepted_extension"}, + params : { + verb : { + id : "http://tincanapi.co.uk/tinrepo/verbs/accepted_extension" + }, }, - callback: getAcceptExtension + callback : getAcceptExtension }); - + //Get the statements myTinCan.getStatements({ - params:{ - verb:{id:"http://tincanapi.co.uk/tinrepo/verbs/registered_extension"}, + params : { + verb : { + id : "http://tincanapi.co.uk/tinrepo/verbs/registered_extension" + }, }, - callback: getRegisterExtension + callback : getRegisterExtension }); - - if (!(typeof moderator === "undefined")) - { + + if(!( typeof moderator === "undefined")) { LRSGetsDue++; //get the make moderator statements - myTinCan.getStatement(moderator.loginStatementId,getModeratorLogin); + myTinCan.getStatement(moderator.loginStatementId, getModeratorLogin); } } -function getMakeModerator(err,result){ +function getMakeModerator(err, result) { makeModeratorStatements = result.statements; handleDataReturned(); } -function getRevokeModerator (err,result){ +function getRevokeModerator(err, result) { revokeModeratorStatements = result.statements; handleDataReturned(); - + } -function getRevertExtension (err,result){ +function getRevertExtension(err, result) { revertExtensionStatements = result.statements; handleDataReturned(); } -function getDeprecateExtension (err,result){ +function getDeprecateExtension(err, result) { deprecateExtensionStatements = result.statements; handleDataReturned(); } -function getRecogniseExtension (err,result){ +function getRecogniseExtension(err, result) { recogniseExtensionStatements = result.statements; handleDataReturned(); } -function getAcceptExtension (err,result){ +function getAcceptExtension(err, result) { acceptExtensionStatements = result.statements; handleDataReturned(); } -function getRegisterExtension (err,result){ +function getRegisterExtension(err, result) { registerExtensionStatements = result.statements; handleDataReturned(); } -function getModeratorLogin (err,result){ - //Note: this is an array of statements even though it will always be one item in order to keep it uniform with the other sets of statements +function getModeratorLogin(err, result) { + //Note: this is an array of statements even though it will always be one item in order to keep it uniform with the other sets of statements //and avoid re-writting functions that cycle through arrays - if (!err) - { + if(!err) { moderatorLoginStatements = [result]; - } - else - { + } else { moderatorLoginStatements = []; } handleDataReturned(); } -function handleDataReturned () -{ +function handleDataReturned() { LRSGetsCompleted++ - console.log (new Date().getTime() + ' ' + LRSGetsCompleted + ' ' + ' out of ' + LRSGetsDue + ' requests completed...'); - - if (LRSGetsCompleted == LRSGetsDue){ + console.log(new Date().getTime() + ' ' + LRSGetsCompleted + ' ' + ' out of ' + LRSGetsDue + ' requests completed...'); + + if(LRSGetsCompleted == LRSGetsDue) { getDataComplete(); } } @@ -273,10 +298,9 @@ function handleDataReturned () //============VALIDATION FUNCTIONS========================== //remove any statements that do not meet validation criteria defined in the profile or are not from authorised authorities -function validateStatements () -{ - console.log (new Date().getTime() + ' Validating returned data...'); - +function validateStatements() { + console.log(new Date().getTime() + ' Validating returned data...'); + //validate administrator statements makeModeratorStatements = validateAdministratorStatements(makeModeratorStatements); revokeModeratorStatements = validateAdministratorStatements(revokeModeratorStatements); @@ -289,144 +313,118 @@ function validateStatements () deprecateExtensionStatements = validateModeratorStatements(deprecateExtensionStatements); recogniseExtensionStatements = validateModeratorStatements(recogniseExtensionStatements); acceptExtensionStatements = validateModeratorStatements(acceptExtensionStatements); - + //validate the statement that the moderator used to log in - if (!(typeof moderator === "undefined")) - { + if(!( typeof moderator === "undefined")) { moderatorLoginStatements = validateModeratorStatements(moderatorLoginStatements); } - //After this validation, if moderatorLoginStatements.length = 1 then login was successful. If 0, then it wasn't! - + //After this validation, if moderatorLoginStatements.length = 1 then login was successful. If 0, then it wasn't! + //Validate public statements registerExtensionStatements = validatePublicStatements(registerExtensionStatements); - console.log (new Date().getTime() + ' Data validated.'); + console.log(new Date().getTime() + ' Data validated.'); } -function validateAdministratorStatements(statements){ +function validateAdministratorStatements(statements) { //timestamp is important for administrator statements, not stored, so change the order return sortStatementsByTimestamp( - //But before we check that, the object of all administrator statements will always be an Agent - validateObjectType( - //But first, the authority of all administrator statements will always be the authority defined above and stored in the global variable 'adminAuth' - validateAuth( - statements, - adminAuth - ), - "Agent" - ) - ); + //But before we check that, the object of all administrator statements will always be an Agent + validateObjectType( + //But first, the authority of all administrator statements will always be the authority defined above and stored in the global variable 'adminAuth' + validateAuth(statements, adminAuth), "Agent")); } //This function checks an array of statements to see if their authorities were moderators at the time the statement was made. -//It returns an array of statements where this was true. -function validateModeratorStatements(statements){ - var authorisedStatements = new Array(), - statementsLength = statements.length; - +//It returns an array of statements where this was true. +function validateModeratorStatements(statements) { + var authorisedStatements = new Array(), statementsLength = statements.length; + //cycle through the array of statements - for (var i = 0; i < statementsLength; i++) { + for(var i = 0; i < statementsLength; i++) { //get the current statement var statement = statements[i], //get the most recent time the authority was promoted to moderator prior to the stored time of the current statement - matchingMakeModeratorStatement = matchModeratorStatement(makeModeratorStatements,makeModeratorStatementsLength,statement), + matchingMakeModeratorStatement = matchModeratorStatement(makeModeratorStatements, makeModeratorStatementsLength, statement), //get the most recent time the authority was demoted from moderator prior to the stored time of the current statement - matchingRevokeModeratorStatement = matchModeratorStatement(revokeModeratorStatements,revokeModeratorStatementsLength,statement); - //If we have found a matching make moderator statement + matchingRevokeModeratorStatement = matchModeratorStatement(revokeModeratorStatements, revokeModeratorStatementsLength, statement); + //If we have found a matching make moderator statement //AND EITHER we have not found a matching revoke moderator statement OR the make moderator statement is most recent, THEN... - if ((matchingMakeModeratorStatement.success) - && ((!matchingRevokeModeratorStatement.success)||(Date.parse(matchingMakeModeratorStatement.timestamp) >= Date.parse(matchingRevokeModeratorStatement.timestamp)))){ + if((matchingMakeModeratorStatement.success) && ((!matchingRevokeModeratorStatement.success) || (Date.parse(matchingMakeModeratorStatement.timestamp) >= Date.parse(matchingRevokeModeratorStatement.timestamp)))) { authorisedStatements.push(statement); } } - + //Check that the activity type is valid return validateActivityTypes( - //but first, make sure it's an activity. - validateObjectType( - authorisedStatements, - "Activity" - ), - legalActivityTypes - ); + //but first, make sure it's an activity. + validateObjectType(authorisedStatements, "Activity"), legalActivityTypes); } //This function checks if any moderator management statements have modified made the statement authority's moderator status prior to the stored property of the statement. -//If so, it returns the most recent timestamp that the authority's moderator status was modified. -function matchModeratorStatement(moderatorManagementStatements,moderatorManagementStatementsLength,statementToValidate) -{ +//If so, it returns the most recent timestamp that the authority's moderator status was modified. +function matchModeratorStatement(moderatorManagementStatements, moderatorManagementStatementsLength, statementToValidate) { var parsedStoredOfStatementToValidate = Date.parse(statementToValidate.stored); //cycle through the moderator management statements - for (var i = 0; i < moderatorManagementStatementsLength; i++) { + for(var i = 0; i < moderatorManagementStatementsLength; i++) { var moderatorManagementStatement = moderatorManagementStatements[i]; //Find the most recent moderator management statement whose object matches the statement being validated. //TODO: either allow for using inverse functional identifiers other than account, or validate moderator management statements to filter out those that - //don't use account. + //don't use account. //To match, the timestamp of the moderator management statement must be before (or equal to) the stored property of the statement being validated - if (_.isEqual(deleteEmptyProperties(moderatorManagementStatement.target.account),deleteEmptyProperties(statementToValidate.authority.account)) - && (Date.parse(moderatorManagementStatement.timestamp) <= parsedStoredOfStatementToValidate)) { - + if(_.isEqual(deleteEmptyProperties(moderatorManagementStatement.target.account), deleteEmptyProperties(statementToValidate.authority.account)) && (Date.parse(moderatorManagementStatement.timestamp) <= parsedStoredOfStatementToValidate)) { + //return that a match has been found and give the timestamp. return { - success:true, - timestamp:moderatorManagementStatement.timestamp + success : true, + timestamp : moderatorManagementStatement.timestamp }; } - + } //No match found return { - success:false, - timestamp:null + success : false, + timestamp : null }; } + //Make sure that the object is an activity with a legal activity type -function validatePublicStatements(statements){ - return validateActivityTypes( - validateObjectType( - statements, - "Activity" - ), - legalActivityTypes - ); +function validatePublicStatements(statements) { + return validateActivityTypes(validateObjectType(statements, "Activity"), legalActivityTypes); } //Checks that the statements authority matches a given array if authorities -function validateAuth(statements,auths) -{ +function validateAuth(statements, auths) { //some variables to be used in the loops - var returnStatements = new Array(), - statementsLength = statements.length, - authsLength = auths.length; + var returnStatements = new Array(), statementsLength = statements.length, authsLength = auths.length; //cycle through the array of statements - for (var i = 0; i < statementsLength; i++) { + for(var i = 0; i < statementsLength; i++) { //get the current statement var statement = statements[i]; //cycle through the array of authorities to compare against - for (var j = 0; j < authsLength; j++) { + for(var j = 0; j < authsLength; j++) { //get the current authority var auth = auths[j]; //If the statement authority and the comparision authority match... - if (_.isEqual(deleteEmptyProperties(statement.authority),deleteEmptyProperties(auth))) { + if(_.isEqual(deleteEmptyProperties(statement.authority), deleteEmptyProperties(auth))) { //add the statement to the array returnStatements.push(statement); //just in case the authority appears in our array twice, break the auths loop break; - } + } } } - //return an array of statements with invalid statements not included. + //return an array of statements with invalid statements not included. return returnStatements; } - -function validateObjectType(statements,objectType) -{ +function validateObjectType(statements, objectType) { var returnStatements = new Array(); var statementsLength = statements.length; - for (var i = 0; i < statementsLength; i++) { + for(var i = 0; i < statementsLength; i++) { var statement = statements[i]; - if (statement.target.objectType == objectType) { + if(statement.target.objectType == objectType) { returnStatements.push(statement); } } @@ -434,13 +432,12 @@ function validateObjectType(statements,objectType) } //Note: make sure all statements passed to this function have an object objectType of Activity -function validateActivityTypes(statements,activityTypes) -{ +function validateActivityTypes(statements, activityTypes) { var returnStatements = new Array(); var statementsLength = statements.length; - for (var i = 0; i < statementsLength; i++) { + for(var i = 0; i < statementsLength; i++) { var statement = statements[i]; - if ($.inArray(statement.target.definition.type,activityTypes) != -1) { + if($.inArray(statement.target.definition.type, activityTypes) != -1) { returnStatements.push(statement); } } @@ -449,81 +446,85 @@ function validateActivityTypes(statements,activityTypes) //==============DATA PROCESSING FUNCTIONS===================== -function buildRespositoryObject (){ - console.log (new Date().getTime() + ' Processing data...'); +function buildRespositoryObject() { + console.log(new Date().getTime() + ' Processing data...'); var repositoryItems = {}; - + //Add all registered items to the array var registerExtensionStatementsLength = registerExtensionStatements.length; - for (var i = 0; i < registerExtensionStatementsLength; i++) { - repositoryItems = modifyRepository(repositoryItems, registerExtensionStatements[i], "registered", ["registered","reverted","deprecated","recognised","accepted"]) + for(var i = 0; i < registerExtensionStatementsLength; i++) { + repositoryItems = modifyRepository(repositoryItems, registerExtensionStatements[i], "registered", "register") } - - //Get the most recent revert to registered status. - //The status "reverted" is used for now, but this will be replaced with "registered" at the end of processing. + + //Get the most recent revert to registered status. + //The status "reverted" is used for now, but this will be replaced with "registered" at the end of processing. //This prevents registered statements overwritting accept and recognise statements. //From here onwards, we know there are no revert statements after the modified timestamp of each extension. var revertExtensionStatementsLength = revertExtensionStatements.length; - for (var i = 0; i < revertExtensionStatementsLength; i++) { - repositoryItems = modifyRepository(repositoryItems, revertExtensionStatements[i], "reverted", []) + for(var i = 0; i < revertExtensionStatementsLength; i++) { + repositoryItems = modifyRepository(repositoryItems, revertExtensionStatements[i], "reverted", "revert") } //Deprecate any extensions that have been deprecated after the most recent time they were reverted - //If a statement has been deprecated after this point, it cannot have been accepted or recognised since. + //If a statement has been deprecated after this point, it cannot have been accepted or recognised since. var deprecateExtensionStatementsLength = deprecateExtensionStatements.length; - for (var i = 0; i < deprecateExtensionStatementsLength; i++) { - repositoryItems = modifyRepository(repositoryItems, deprecateExtensionStatements[i], "deprecated", ["deprecated"]) + for(var i = 0; i < deprecateExtensionStatementsLength; i++) { + repositoryItems = modifyRepository(repositoryItems, deprecateExtensionStatements[i], "deprecated", "deprecate") } - + //Recognise any extensions that have been recognised after the most recent time they were reverted - //If a statement has been recognised after this point, it cannot have been accepted since. + //If a statement has been recognised after this point, it cannot have been accepted since. var recogniseExtensionStatementsLength = recogniseExtensionStatements.length; - for (var i = 0; i < recogniseExtensionStatementsLength; i++) { - repositoryItems = modifyRepository(repositoryItems, recogniseExtensionStatements[i], "recognised", ["deprecated","recognised"]) + for(var i = 0; i < recogniseExtensionStatementsLength; i++) { + repositoryItems = modifyRepository(repositoryItems, recogniseExtensionStatements[i], "recognised", "recognise") } - + //Accept any extensions that have been accepeted after the most recent time they were reverted var acceptExtensionStatementsLength = acceptExtensionStatements.length; - for (var i = 0; i < acceptExtensionStatementsLength; i++) { - repositoryItems = modifyRepository(repositoryItems, acceptExtensionStatements[i], "accepted", ["deprecated","recognised","accepted"]) + for(var i = 0; i < acceptExtensionStatementsLength; i++) { + repositoryItems = modifyRepository(repositoryItems, acceptExtensionStatements[i], "accepted", "accept") } - console.log (new Date().getTime() + ' Processing complete.'); + console.log(new Date().getTime() + ' Processing complete.'); + + //Replace all reverted statuses with accepted + $.each(repositoryItems, function(key, value) { + if(value.status == "reverted") { + repositoryItems[key].status = "registered" + } + }); + return repositoryItems; } -function modifyRepository(repositoryItems, statement, status, dontOverwrite) -{ +function modifyRepository(repositoryItems, statement, status, action) { var extensionId = statement.target.id; //if the extension already exists in the repository object.. - if (repositoryItems.hasOwnProperty(extensionId)) - { + if(repositoryItems.hasOwnProperty(extensionId)) { + //if timstamp is older than the current statement and the status is ok to overwrite - if((Date.parse(repositoryItems[extensionId].modified) < Date.parse(statement.stored)) - &&($.inArray(repositoryItems[extensionId].status, dontOverwrite) == -1 )){ + if((Date.parse(repositoryItems[extensionId].modified) < Date.parse(statement.stored)) && (allowableModeratorActions[repositoryItems[extensionId].status][action])) { repositoryItems[extensionId].status = status; repositoryItems[extensionId].modified = statement.stored; } - - } - else{ + + } else { //create the extension in the repository object repositoryItems[extensionId] = { - id:extensionId, + id : extensionId, status : status, definition : statement.target.definition, - modified: statement.stored + modified : statement.stored } - + } return repositoryItems; } //TODO: add additional parameters to this function and move to TinCan.Utils //sorts by newest timestamp first - reverse chronological order -function sortStatementsByTimestamp(statements) -{ - return statements.sort(function(x, y){ +function sortStatementsByTimestamp(statements) { + return statements.sort(function(x, y) { timestamp1 = new Date(x.timestamp); timestamp2 = new Date(y.timestamp); return timestamp2 - timestamp1; @@ -532,109 +533,86 @@ function sortStatementsByTimestamp(statements) //==============OUTPUT TO DOM FUNCTIONS===================== +function outputrepositoryItems(repositoryItems) { + + var isModerator = checkIfModerator(); -function outputrepositoryItems(repositoryItems){ - - var isModerator = checkIfModerator(); - //For each repo item... - $.each(repositoryItems, function(i, repositoryItem){ - + $.each(repositoryItems, function(i, repositoryItem) { + var itemId = encodeURIComponent(repositoryItem.id); var itemDiv = $('
'); itemDiv.attr('data-repositoryItem', JSON.stringify(repositoryItem)); - + //Add extension title itemDiv.append('

' + getLangFromMapInGBOrDefault(repositoryItem.definition.name) + '

'); - + var propertiesTable = $('
'); - + //Add moderator buttons - if (isModerator) - { - propertiesTable.append('' + moderatorButton('accept', itemId) + moderatorButton('recognise', itemId) + '' - + '' + moderatorButton('deprecate', itemId) + moderatorButton('revert', itemId) + ''); + if(isModerator) { + propertiesTable.append('' + moderatorButton('accept', itemId) + moderatorButton('recognise', itemId) + '' + '' + moderatorButton('deprecate', itemId) + moderatorButton('revert', itemId) + ''); } - + //Add properties header - + propertiesTable.append(propertiesTableRow('Type', repositoryItem.definition.type.slice(baseURI.activityTypes.length))); propertiesTable.append(propertiesTableRow('Status', repositoryItem.status)); itemDiv.append(propertiesTable); itemDiv.append('

' + getLangFromMapInGBOrDefault(repositoryItem.definition.description) + '

'); - + $('body').append(itemDiv); }); - + //Add funtionality to moderator buttons - if (isModerator) - { - //TODO: grey out and disable buttons that do nothing - - $('.moderatorButton').each(function(index){ - var repositoryItemToModerate = JSON.parse($(this).parents('.repositoryItemDiv').attr('data-repositoryItem')); - if (IsAllowableModeratorAction (repositoryItemToModerate.status, $(this).attr('data-action'))){ - $(this).click(sendModeratorAction); - } - else - { - //TODO: hide or grey out buttons - } - }); - - + if(isModerator) { + updateModeratorButtons('body'); } - + } -function propertiesTableRow (label,value){ +function propertiesTableRow(label, value) { return '' + label + ':' + value + ''; } - //==============MODERATOR BUTTON FUNCTIONS===================== -function moderatorButton (action, itemId){ +function moderatorButton(action, itemId) { return ' '; } -function checkIfModerator() -{ +function checkIfModerator() { //If no moderator credentials were provided, or if we were unable to verify the log in statement, then the user is not a moderator. //Note: in the event of a delay between sending the statement and the LRS returning it, the user can simply refresh the page to re-check moderator status based on their earlier login - if ((typeof moderator === "undefined") || (moderatorLoginStatements.length == 0)) - { + if(( typeof moderator === "undefined") || (moderatorLoginStatements.length == 0)) { return false; - } - else - { + } else { return true; } } -function sendModeratorAction() -{ - +function sendModeratorAction() { + //send a statement carrying out the action - //object - look up details of activity in repository items based on id of parent div (Note, this is URI encoded). - + //object - look up details of activity in repository items based on id of parent div (Note, this is URI encoded). + //Actor var myActor = moderator.actor; myTinCan.actor = myActor; - + //Verb var verbId; - - if ($(this).hasClass('accept')){ + + if($(this).hasClass('accept')) { verbId = 'http://tincanapi.co.uk/tinrepo/verbs/accepted_extension'; - } else if ($(this).hasClass('recognise')){ + } else if($(this).hasClass('recognise')) { verbId = 'http://tincanapi.co.uk/tinrepo/verbs/recognised_extension'; - } else if ($(this).hasClass('deprecate')){ + } else if($(this).hasClass('deprecate')) { verbId = 'http://tincanapi.co.uk/tinrepo/verbs/deprecated_extension'; - } else if ($(this).hasClass('revert')){ + } else if($(this).hasClass('revert')) { verbId = 'http://tincanapi.co.uk/tinrepo/verbs/reverted_extension'; - } - + } + var myVerb = new TinCan.Verb({ id : verbId, display : { @@ -642,91 +620,66 @@ function sendModeratorAction() "en-US" : extensionManagementVerbsList[verbId].display } }); - - + //Object var repositoryItemParentDiv = $(this).parents('.repositoryItemDiv'); - var repositoryItemToModerate = JSON.parse(repositoryItemParentDiv.attr('data-repositoryItem')); + var repositoryItemToModerate = JSON.parse(repositoryItemParentDiv.attr('data-repositoryItem')); var myActivityDefinition = new TinCan.ActivityDefinition(repositoryItemToModerate.definition); - + //Create the activity var myActivity = new TinCan.Activity({ id : repositoryItemToModerate.id, definition : myActivityDefinition }); - + var stmt = new TinCan.Statement({ actor : deleteEmptyProperties(myActor), verb : deleteEmptyProperties(myVerb), target : deleteEmptyProperties(myActivity) - },true); - - console.log ('sending: ' + JSON.stringify(stmt)); - + }, true); + + console.log('sending: ' + JSON.stringify(stmt)); + myTinCan.sendStatement(stmt, updateRepositoryItemAfterModeratorModification); - + } -function updateRepositoryItemAfterModeratorModification(response,result) -{ - if (response[0].err) - { - console.log ('failed to send moderator statement') - //Notify user and/or try again - } - else - { - //escape percentages (from url encoding) and periods (from .com etc.) in the id. - repositoryItemParentDiv = $('#' + encodeURIComponent(result.target.id).replace(/\./g,'\\.').replace(/\%/g,'\\%')); - //Edit the div to show the result of the action - //TODO: only update the status based on the rules in the profile. +function updateRepositoryItemAfterModeratorModification(response, result) { + if(response[0].err) { + console.log('failed to send moderator statement') + //TODO: Notify user and/or try again (depending on the reason for the failure) + } else { + //escape percentages (from url encoding) and periods (from .com etc.) in the id. + repositoryItemParentDiv = $('#' + encodeURIComponent(result.target.id).replace(/\./g, '\\.').replace(/\%/g, '\\%')); + //Edit the div to show the result of the action var newStatus = extensionManagementVerbsList[result.verb.id].status; //update the class of the div - repositoryItemParentDiv.attr("class","section repositoryItemDiv " + result.target.definition.type + ' ' + newStatus) + repositoryItemParentDiv.attr("class", "section repositoryItemDiv " + result.target.definition.type + ' ' + newStatus) //update text of status field in the table repositoryItemParentDiv.find('td.Status').text(newStatus); - - //TODO: update which buttons are active. + //update the data-repositoryItem property + var repositoryItem = JSON.parse(repositoryItemParentDiv.attr('data-repositoryItem')); + repositoryItem.status = newStatus; + repositoryItemParentDiv.attr('data-repositoryItem', JSON.stringify(repositoryItem)); + //update which buttons are enabled and disabled. + updateModeratorButtons(repositoryItemParentDiv); } } -function IsAllowableModeratorAction (currentStatus, action) -{ - var allowableModeratorActions = - { - registered : { - accept : true, - recognise: true, - revert : false, - deprecate : true - }, - accepted : { - accept : false, - recognise: true, - revert : true, - deprecate : true - }, - recognised : { - accept : false, - recognise: false, - revert : true, - deprecate : true - }, - deprecated : { - accept : false, - recognise: false, - revert : true, - deprecate : false - }, - reverted : { - accept : true, - recognise: true, - revert : false, - deprecate : true - } - } - +function IsAllowableModeratorAction(currentStatus, action) { return allowableModeratorActions[currentStatus][action]; } +function updateModeratorButtons(parent) { + $(parent).find('.moderatorButton').each(function(index) { + var repositoryItemToModerate = JSON.parse($(this).parents('.repositoryItemDiv').attr('data-repositoryItem')); + $(this).removeClass('disabled_button'); + if(IsAllowableModeratorAction(repositoryItemToModerate.status, $(this).attr('data-action'))) { + $(this).click(sendModeratorAction); + } else { + //TODO: hide or grey out buttons + $(this).addClass('disabled_button'); + } + }); +} diff --git a/tinrepo.css b/tinrepo.css index 72a283b..4d051b9 100755 --- a/tinrepo.css +++ b/tinrepo.css @@ -78,9 +78,17 @@ font-weight:bold; } .button:hover { - background-color: #DDCEF2; } +.disabled_button +{ + background-color: #ccc; + border-color: #ccc; + color: #ddd; +} +.disabled_button:hover { + background-color: #ccc; +} .displayNone { display: none;