This commit is contained in:
529
wwwroot/js/app.api.js
Normal file
529
wwwroot/js/app.api.js
Normal file
@@ -0,0 +1,529 @@
|
||||
/*
|
||||
* app.api.js
|
||||
* Ajax api helper module
|
||||
*/
|
||||
|
||||
/*jslint browser : true, continue : true,
|
||||
devel : true, indent : 2, maxerr : 50,
|
||||
newcap : true, nomen : true, plusplus : true,
|
||||
regexp : true, sloppy : true, vars : false,
|
||||
white : true
|
||||
*/
|
||||
/*global $, io, app */
|
||||
|
||||
app.api = (function () {
|
||||
'use strict';
|
||||
var
|
||||
initModule, getAuthHeaderObject,
|
||||
GZAppVersion,
|
||||
get, remove, create, update, uploadFile,
|
||||
doSync, getListFromStore, putListInStore,
|
||||
goToNextList, getActiveList, replaceActiveList, renameActiveList, toggleDeleteActiveList,
|
||||
getActiveListIndex, replaceRecordInStore, insertRecordInStore, getRecordFromStore,
|
||||
getListItemCoordinates, setActiveListId, getActiveListId, newList
|
||||
;
|
||||
|
||||
|
||||
GZAppVersion = "1.3";
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// NOT AUTHORIZED ERROR HANDLER
|
||||
|
||||
|
||||
$(document).ajaxError(function (event, jqxhr, settings, thrownError) {
|
||||
//unauthorized? Trigger logout which will trigger login after clearing creds
|
||||
if (jqxhr.status == 401) {
|
||||
window.location.replace('#!/logout');
|
||||
}
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// UTILITY
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Return the auth token header
|
||||
//
|
||||
//
|
||||
getAuthHeaderObject = function () {
|
||||
return {
|
||||
"Authorization": "Bearer " + app.shell.stateMap.user.token
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Fetch the list from local storage
|
||||
//
|
||||
//
|
||||
getListFromStore = function () {
|
||||
return store.get('pecklist.list');
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Replace the list in local store
|
||||
//
|
||||
//
|
||||
putListInStore = function (theList) {
|
||||
store.set('pecklist.list', theList);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Get the active list id or first if active not found
|
||||
//
|
||||
getActiveListId = function (theId) {
|
||||
var ret = store.get('pecklist.activeListId');
|
||||
|
||||
//validate it's ok
|
||||
var l = app.api.getListFromStore();
|
||||
var firstListId = l[0].id;//get a default in case it's not found
|
||||
|
||||
var len = l.length, i = 0;
|
||||
for (i; i < len; i++) {
|
||||
if (l[i].id == ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
//if we're here then it's not a valid id so use the first one instead and set it
|
||||
store.set('pecklist.activeListId', firstListId);
|
||||
return firstListId;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Set the active list id
|
||||
//
|
||||
//
|
||||
setActiveListId = function (theId) {
|
||||
if (theId) {
|
||||
store.set('pecklist.activeListId', theId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// ADVANCE ACTIVE LIST ID TO NEXT LIST
|
||||
//
|
||||
//
|
||||
goToNextList = function () {
|
||||
var l = getListFromStore();
|
||||
var allLength = l.length;
|
||||
//is there more than one list?
|
||||
if (allLength < 2) {
|
||||
//Nope
|
||||
return;
|
||||
}
|
||||
|
||||
//figure out what the next list id should be
|
||||
var currentIndex = getActiveListIndex();
|
||||
var highestPossibleIndex = allLength - 1;
|
||||
|
||||
//are we already at the last list?
|
||||
if (currentIndex == highestPossibleIndex) {
|
||||
//go to first list (wrap)
|
||||
setActiveListId(l[0].id);
|
||||
return;
|
||||
}
|
||||
|
||||
//advance to the next list
|
||||
setActiveListId(l[currentIndex + 1].id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// GET LIST INDEX
|
||||
//
|
||||
getActiveListIndex = function () {
|
||||
var activeListId = getActiveListId();
|
||||
var l = app.api.getListFromStore();
|
||||
var len = l.length, i = 0;
|
||||
for (i; i < len; i++) {
|
||||
if (l[i].id == activeListId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
//This should never happen, if it does something is very wrong:
|
||||
throw new Error("Error: app.main.js::getActiveListIndex - active list ID not found in list store");
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// GET ACTIVE LIST
|
||||
//
|
||||
getActiveList = function () {
|
||||
var activeListId = getActiveListId();
|
||||
var l = app.api.getListFromStore();
|
||||
var len = l.length, i = 0;
|
||||
for (i; i < len; i++) {
|
||||
if (l[i].id == activeListId) {
|
||||
return l[i];
|
||||
}
|
||||
}
|
||||
//This should never happen, if it does something is very wrong:
|
||||
throw new Error("Error: app.main.js::getActiveList - activeListId not found in list store");
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// CREATE NEW LIST
|
||||
//
|
||||
newList = function () {
|
||||
|
||||
var l = app.api.getListFromStore();
|
||||
var newListRecord={
|
||||
id:"NEW_"+ _.now(),
|
||||
name: "New list "+Date(),
|
||||
v:1,
|
||||
name_v:1,
|
||||
items:[]
|
||||
}
|
||||
|
||||
l.push(newListRecord);
|
||||
app.api.putListInStore(l);
|
||||
setActiveListId(newListRecord.id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// RENAME ACTIVE LIST
|
||||
//
|
||||
renameActiveList = function (newName) {
|
||||
var activeListId = getActiveListId();
|
||||
var l = app.api.getListFromStore();
|
||||
var len = l.length, i = 0;
|
||||
for (i; i < len; i++) {
|
||||
if (l[i].id == activeListId) {
|
||||
l[i].name = newName;
|
||||
putListInStore(l);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//This should never happen, if it does something is very wrong:
|
||||
throw new Error("Error: app.main.js::renameActiveList - activeListId not found in list store");
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// DELETE ACTIVE LIST
|
||||
//
|
||||
toggleDeleteActiveList = function () {
|
||||
var activeListId = getActiveListId();
|
||||
var l = app.api.getListFromStore();
|
||||
var len = l.length, i = 0;
|
||||
for (i; i < len; i++) {
|
||||
if (l[i].id == activeListId) {
|
||||
if (l[i].deleted) {
|
||||
delete l[i].deleted;
|
||||
} else {
|
||||
l[i].deleted = true;//tag it as deleted
|
||||
}
|
||||
putListInStore(l);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//This should never happen, if it does something is very wrong:
|
||||
throw new Error("Error: app.main.js::toggleDeleteActiveList - activeListId not found in list store");
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// REPLACE ACTIVE LIST
|
||||
//
|
||||
replaceActiveList = function (replacementList) {
|
||||
var activeListId = getActiveListId();
|
||||
var l = app.api.getListFromStore();
|
||||
var len = l.length, i = 0;
|
||||
for (i; i < len; i++) {
|
||||
if (l[i].id == activeListId) {
|
||||
l[i] = replacementList;
|
||||
putListInStore(l);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//This should never happen, if it does something is very wrong:
|
||||
throw new Error("Error: app.main.js::replaceActiveList - activeListId not found in list store");
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// GET LIST ITEM CO-ORDINATES
|
||||
//
|
||||
getListItemCoordinates = function (itemId) {
|
||||
var allLists = app.api.getListFromStore();
|
||||
var allLength = allLists.length, j = 0;
|
||||
for (j; j < allLength; j++) {
|
||||
//iterate the list and find it
|
||||
var len = allLists[j].items.length, i = 0;
|
||||
for (i; i < len; i++) {
|
||||
if (allLists[j].items[i].id == itemId) {
|
||||
return { listIndex: j, itemIndex: i };
|
||||
}
|
||||
}
|
||||
}
|
||||
//This should never happen, if it does something is very wrong:
|
||||
throw new Error("Error: app.main.js::getListItemCoordinates - List item ID not found in list store");
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// GET RECORD FROM STORE
|
||||
//
|
||||
getRecordFromStore = function (itemId) {
|
||||
var co = getListItemCoordinates(itemId);
|
||||
var allLists = app.api.getListFromStore();
|
||||
return allLists[co.listIndex].items[co.itemIndex];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// REPLACE RECORD IN STORE
|
||||
//
|
||||
replaceRecordInStore = function (itemId, replacementRecord) {
|
||||
var co = getListItemCoordinates(itemId);
|
||||
var l = app.api.getListFromStore();
|
||||
//Todo: is this the proper way to do it?
|
||||
l[co.listIndex].items[co.itemIndex] = replacementRecord;
|
||||
app.api.putListInStore(l);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// INSERT RECORD IN STORE
|
||||
//
|
||||
insertRecordInStore = function (newRecord) {
|
||||
var activeListIndex = getActiveListIndex();
|
||||
var l = app.api.getListFromStore();
|
||||
l[activeListIndex].items.push(newRecord);
|
||||
app.api.putListInStore(l);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// PECKLIST SPECIFIC ROUTES
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//
|
||||
// DOSYNC - Synchronize the stored data
|
||||
//
|
||||
doSync = function (callback) {
|
||||
//get the list from the store
|
||||
var theList = getListFromStore();
|
||||
|
||||
$.ajax({
|
||||
method: "post",
|
||||
dataType: "json",
|
||||
url: app.shell.stateMap.apiUrl + 'sync',
|
||||
headers: getAuthHeaderObject(),
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
data: JSON.stringify(theList),
|
||||
success: function (ret, textStatus) {
|
||||
//Put the new list in the store
|
||||
putListInStore(JSON.parse(ret));
|
||||
callback({ ok: 1 });
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
callback({
|
||||
error: 1,
|
||||
msg: textStatus + '\n' + errorThrown,
|
||||
error_detail: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// STANDARD API CORE ROUTES
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//Create
|
||||
//Route app.post('/api/:obj_type/create', function (req, res) {
|
||||
//
|
||||
create = function (apiRoute, objData, callback) {
|
||||
$.ajax({
|
||||
method: "post",
|
||||
dataType: "json",
|
||||
url: app.shell.stateMap.apiUrl + apiRoute,
|
||||
headers: getAuthHeaderObject(),
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
data: JSON.stringify(objData),
|
||||
success: function (data, textStatus) {
|
||||
callback(data);
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
callback({
|
||||
error: 1,
|
||||
msg: textStatus + '\n' + errorThrown,
|
||||
error_detail: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/////////////////
|
||||
//Get - get anything, the caller provides the route, this should replace most legacy get
|
||||
//
|
||||
get = function (apiRoute, callback) {
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
dataType: "json",
|
||||
url: app.shell.stateMap.apiUrl + apiRoute,
|
||||
headers: getAuthHeaderObject(),
|
||||
|
||||
success: function (data, textStatus) {
|
||||
callback(data);
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
callback({
|
||||
error: 1,
|
||||
msg: textStatus + '\n' + errorThrown,
|
||||
error_detail: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//Update
|
||||
//route: app.post('/api/:obj_type/update/:id', function (req, res) {
|
||||
//
|
||||
update = function (objType, objData, callback) {
|
||||
var theId;
|
||||
if (!objData.id) {
|
||||
return callback({
|
||||
error: 1,
|
||||
msg: 'app.api.js::update->Error: missing id field in update document',
|
||||
error_detail: objData
|
||||
});
|
||||
}
|
||||
theId = objData.id;
|
||||
$.ajax({
|
||||
method: "put",
|
||||
dataType: "json",
|
||||
url: app.shell.stateMap.apiUrl + objType + '/' + theId,
|
||||
headers: getAuthHeaderObject(),
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
data: JSON.stringify(objData),
|
||||
success: function (data, textStatus) {
|
||||
if (data == null) {
|
||||
data = { ok: 1 };
|
||||
}
|
||||
|
||||
callback(data);
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
callback({
|
||||
error: 1,
|
||||
msg: textStatus + '\n' + errorThrown,
|
||||
error_detail: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//remove Item
|
||||
remove = function (apiRoute, callback) {
|
||||
$.ajax({
|
||||
method: "DELETE",
|
||||
dataType: "json",
|
||||
url: app.shell.stateMap.apiUrl + apiRoute,
|
||||
headers: getAuthHeaderObject(),
|
||||
success: function (data, textStatus) {
|
||||
callback(data);
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
callback({
|
||||
error: 1,
|
||||
msg: textStatus + '\n' + errorThrown,
|
||||
error_detail: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// uploadFile
|
||||
// (ajax route to upload a file)
|
||||
//
|
||||
uploadFile = function (apiRoute, objData, callback) {
|
||||
$.ajax({
|
||||
method: "post",
|
||||
dataType: "json",
|
||||
url: app.shell.stateMap.apiUrl + apiRoute,
|
||||
headers: getAuthHeaderObject(),
|
||||
contentType: false,
|
||||
processData: false,
|
||||
data: objData,
|
||||
success: function (data, textStatus) {
|
||||
callback(data);
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
callback({
|
||||
error: 1,
|
||||
msg: textStatus + '\n' + errorThrown,
|
||||
error_detail: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
initModule = function () { };
|
||||
|
||||
return {
|
||||
initModule: initModule,
|
||||
getAuthHeaderObject: getAuthHeaderObject,
|
||||
GZAppVersion: GZAppVersion,
|
||||
get: get,
|
||||
remove: remove,
|
||||
create: create,
|
||||
update: update,
|
||||
uploadFile: uploadFile,
|
||||
doSync: doSync,
|
||||
getListFromStore: getListFromStore,
|
||||
putListInStore: putListInStore,
|
||||
goToNextList: goToNextList,
|
||||
getActiveList: getActiveList,
|
||||
replaceActiveList: replaceActiveList,
|
||||
getActiveListIndex: getActiveListIndex,
|
||||
replaceRecordInStore: replaceRecordInStore,
|
||||
insertRecordInStore: insertRecordInStore,
|
||||
getRecordFromStore: getRecordFromStore,
|
||||
getListItemCoordinates: getListItemCoordinates,
|
||||
renameActiveList: renameActiveList,
|
||||
toggleDeleteActiveList: toggleDeleteActiveList,
|
||||
newList: newList
|
||||
|
||||
|
||||
};
|
||||
}());
|
||||
Reference in New Issue
Block a user