gnm_deliverables/static/gnm_deliverables/naughtylist.js (120 lines of code) (raw):

/** * empty the body of the main table, for loading in fresh data */ function clearMainTable(){ $('#naughtylist-body').empty(); } /** * set the UI state to indicate loading */ function setLoading(){ $('#naughtylist').hide(); $('#loadingblock').show(); } /** * set the UI state to indicate normal usage */ function clearLoading(){ $('#naughtylist').show(); $('#loadingblock').hide(); } /** * initial creation of a table row. This only populates the first (projectid) column, with placeholder text everywhere else. * The other columns are filled in by `loadProjectDetails` * @param projectId * @returns {*|jQuery|HTMLElement} */ function createDataRow(projectId){ var row = $('<tr>'); $('<a>', {href: "/project/"+projectId,target: "_blank"}).text(projectId) .appendTo($('<td>', {class: "naughtylist-projectid"}).appendTo(row)); for(var n=0;n<5;++n) { /*add holding text for other columns, they get ajax'd in later*/ $('<td>').text("loading").appendTo(row); } return row; } /** * Looks up the given user id to translate it into a username. Trys a cache in the local browser storage first, * if not then it makes an ajax call to the server to find it. * @param uid user id number to look up * @returns {Promise<Object>} a Promise that will resolve to a function called with (uid, username, otherdata) or * reject with a dictionary describing the error if user can't be looked up */ function lookupUserId(uid){ return new Promise(function(resolve, reject) { var cachedUserData = localStorage.getItem("portal-user-" + uid); if (cachedUserData) { console.log("Local cache hit for user id " + uid); resolve(JSON.parse(cachedUserData)); } else { console.log("Local cache miss for user id " + uid + ", looking up from server"); $.ajax('/project/api/owner/' + uid) .done(function (data, textStatus, jqXHR){ data.uid = uid; localStorage.setItem("portal-user-" + uid, JSON.stringify(data)); resolve(data) }) .fail(function(jqXHR,textStatus, errorThrown){ console.error(textStatus); try { var responseJson = JSON.parse(jqXHR.responseText); reject(responseJson) } catch(e) { console.error("Could not parse server response", jqXHR.responseText); reject({detail: jqXHR.responseText, error: "Parse error", status: "error"}); } }) } }); } /** * Goes through any user id references in the project data, removes duplicates and translates them into usernames * @param projectData project data as returned from /project/{projectid}/api * @returns {Promise<Array<Object>>} - a Promise containing a list of results from `lookupUserId` */ function lookupUserIds(projectData) { var idList = projectData.gnm_project_username ? [projectData.user].concat(projectData.gnm_project_username) : [projectData.user]; var filteredIdList = idList.filter(function(value, index, self){ return self.indexOf(value) === index }); return Promise.all(filteredIdList.map(function(uid){ return lookupUserId(uid) })); } /** * Initiate an ajax request for the rest of the project details * @param projectId project ID to query * @param uiDataRow the table data row to update */ function loadProjectDetails(projectId, uiDataRow) { $.ajax("/project/" + projectId + "/api") .done(function(data, textStatus, jqXHR){ uiDataRow.find('td:eq(1)').text(data.gnm_project_status); console.log("username list", data.gnm_project_username); //Promise.all([lookupUserId(data.user)].concat(data.gnm_project_username.map(function(uid){ return lookupUserId(uid) }))) lookupUserIds(data) .then(function(userdataArray){ console.log("got", userdataArray); //console.log("lookupUserId resolved", userdataArray[0]); var containingList = $('<ul>',{"class": "user-list"}); userdataArray.map(function(item){ $('<li>', {"class": "user-entry"}).text(item.user_name).appendTo(containingList)}); uiDataRow.find('td:eq(2)').empty().append(containingList); }) .catch(function(error){ console.error("Could not look up user id " + data.user, error); uiDataRow.find('td:eq(2)').text(data.user); }); uiDataRow.find('td:eq(3)').text(data.gnm_project_headline); uiDataRow.find('td:eq(4)').text(data.created); uiDataRow.find('td:eq(5)').text(data.updated); }) .fail(function(jqXHR, textStatus, errorThrown){ console.error(textStatus); console.error(jqXHR.responseText); }) } /** * Main function to get more data to fill the main table */ function updateMainTable(){ setLoading(); var since = $('#start-search-date').val(); var until = $('#end-search-date').val(); $.ajax("/deliverables/api/missing?since=" + since + "&until=" + until) .done(function(data, textStatus, jqXHR){ $.each(data.projects, function(idx, ptr){ var datarow = createDataRow(ptr).appendTo($('#naughtylist-body')); loadProjectDetails(ptr, datarow); }); if(data.limited){ $('#limitedtext').text("Your search returned " + data.total + " results, limiting to the first " + data.projects.length + "."); $('#limitedblock').show(); } else { $('#limitedblock').hide(); } clearLoading(); }) .fail(function(jqXHR, textStatus, errorThrown){ console.error(textStatus); console.error(jqXHR.responseText); clearLoading(); }) } /** * Prep widgets on page load and load in some data immediately */ $(document).ready(function() { $('#limitedblock').hide(); $('#updateMainTable').on("click", function(evt){ evt.preventDefault(); clearMainTable(); updateMainTable(); }); $('#start-search-date').datepicker({ dateFormat: "yy-mm-dd", defaultDate: -30 }); $('#end-search-date').datepicker({ dateFormat: "yy-mm-dd", defaultDate: 0 }); console.log("Document ready, loading"); clearMainTable(); updateMainTable(); });