This commit is contained in:
337
wwwroot/js/app.api.js
Normal file
337
wwwroot/js/app.api.js
Normal file
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* 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,
|
||||
RockFishVersion,
|
||||
get,
|
||||
remove,
|
||||
create,
|
||||
update,
|
||||
uploadFile,
|
||||
putAction,
|
||||
createLicense,
|
||||
getLicenseRequests,
|
||||
generateFromRequest,
|
||||
licenseEmailResponse;
|
||||
|
||||
RockFishVersion = "6.1";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
};
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// ROCKFISH 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: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//putAction - ad-hoc put method used to trigger actions etc
|
||||
//
|
||||
putAction = function(apiRoute, callback) {
|
||||
$.ajax({
|
||||
method: "put",
|
||||
dataType: "json",
|
||||
url: app.shell.stateMap.apiUrl + apiRoute,
|
||||
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: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// LICENSE KEY RELATED API METHODS
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//CreateLicense
|
||||
//Route app.post('/api/license/create', function (req, res) {
|
||||
//
|
||||
createLicense = function(objData, callback) {
|
||||
$.ajax({
|
||||
method: "post",
|
||||
dataType: "text",
|
||||
url: app.shell.stateMap.apiUrl + "license/generate",
|
||||
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: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//GetLicenseRequests
|
||||
//Fetch license requests
|
||||
//route: app.get('/api/license/requests', function (req, res) {
|
||||
//
|
||||
getLicenseRequests = function(callback) {
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
dataType: "json",
|
||||
url: app.shell.stateMap.apiUrl + "license/requests",
|
||||
headers: getAuthHeaderObject(),
|
||||
success: function(data, textStatus) {
|
||||
callback(data);
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
callback({
|
||||
error: 1,
|
||||
msg: textStatus + "\n" + errorThrown,
|
||||
error_detail: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//GenerateFromRequest
|
||||
//Fetch generated response to license request
|
||||
//route: app.get('/api/license/generateFromRequest/:uid', function (req, res) {
|
||||
//
|
||||
generateFromRequest = function(uid, callback) {
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
dataType: "json",
|
||||
url: app.shell.stateMap.apiUrl + "license/generateFromRequest/" + uid,
|
||||
headers: getAuthHeaderObject(),
|
||||
success: function(data, textStatus) {
|
||||
callback(data);
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
callback({
|
||||
error: 1,
|
||||
msg: textStatus + "\n" + errorThrown,
|
||||
error_detail: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//Email license request response
|
||||
//app.post('/api/license/email_response', function (req, res) {
|
||||
//
|
||||
licenseEmailResponse = function(objData, callback) {
|
||||
$.ajax({
|
||||
method: "post",
|
||||
dataType: "text",
|
||||
url: app.shell.stateMap.apiUrl + "license/email_response",
|
||||
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: {}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
initModule = function() {};
|
||||
|
||||
return {
|
||||
initModule: initModule,
|
||||
getAuthHeaderObject: getAuthHeaderObject,
|
||||
RockFishVersion: RockFishVersion,
|
||||
get: get,
|
||||
remove: remove,
|
||||
create: create,
|
||||
update: update,
|
||||
uploadFile: uploadFile,
|
||||
putAction: putAction,
|
||||
createLicense: createLicense,
|
||||
getLicenseRequests: getLicenseRequests,
|
||||
generateFromRequest: generateFromRequest,
|
||||
licenseEmailResponse: licenseEmailResponse
|
||||
};
|
||||
})();
|
||||
103
wwwroot/js/app.authenticate.js
Normal file
103
wwwroot/js/app.authenticate.js
Normal file
@@ -0,0 +1,103 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.authenticate = (function() {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
onSubmit,
|
||||
configModule,
|
||||
initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
onSubmit = function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
//get creds
|
||||
var login = $('#login').val();
|
||||
var password = $('#password').val();
|
||||
|
||||
|
||||
$.ajax({
|
||||
method: "post",
|
||||
dataType: "json",
|
||||
url: app.shell.stateMap.apiUrl.replace('/api/', '/authenticate'),
|
||||
data: {
|
||||
login: login,
|
||||
password: password
|
||||
},
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
if (data.ok == 1) {
|
||||
app.shell.stateMap.user.authenticated = true;
|
||||
app.shell.stateMap.user.token = data.token;
|
||||
app.shell.stateMap.user.name = data.name;
|
||||
app.shell.stateMap.user.id=data.id;
|
||||
//token expiry date
|
||||
app.shell.stateMap.user.expires = data.expires;
|
||||
|
||||
//tell the shell we've logged in successfully
|
||||
$.gevent.publish('app-login', {
|
||||
name: login
|
||||
});
|
||||
} else {
|
||||
if (data.error) {
|
||||
$.gevent.publish('app-show-error',data.error);
|
||||
}
|
||||
app.shell.stateMap.user.authenticated = false;
|
||||
app.shell.stateMap.user.token = '';
|
||||
app.shell.stateMap.user.name = 'please sign in';
|
||||
$.gevent.publish('app-logout');
|
||||
}
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
app.shell.stateMap.user.authenticated = false;
|
||||
app.shell.stateMap.user.token = '';
|
||||
app.shell.stateMap.user.name = 'please sign in';
|
||||
$.gevent.publish('app-logout');
|
||||
$.gevent.publish('app-show-error',textStatus + " " + errorThrown);
|
||||
}
|
||||
});
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function(context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
$container.html(Handlebars.templates['app.authenticate']({}));
|
||||
$('#btnSubmit').bind('click', onSubmit);
|
||||
};
|
||||
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
143
wwwroot/js/app.customerEdit.js
Normal file
143
wwwroot/js/app.customerEdit.js
Normal file
@@ -0,0 +1,143 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.customerEdit = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
onSave, onDelete,
|
||||
configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
//ONSAVE
|
||||
//
|
||||
onSave = function (event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
|
||||
//is this a new record?
|
||||
if (stateMap.id != 'new') {
|
||||
//put id into the form data
|
||||
submitData.id = stateMap.id;
|
||||
|
||||
|
||||
app.api.update('customer', submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//it's a new record - create
|
||||
app.api.create('customer', submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
page('#!/customerEdit/' + res.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
//ONDELETE
|
||||
//
|
||||
onDelete = function (event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
var r = confirm("Are you sure you want to delete this record?");
|
||||
if (r == true) {
|
||||
//Delete customer and children
|
||||
app.api.remove('customer/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//deleted, return to customers list
|
||||
page('#!/customers');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
|
||||
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.customerEdit']({}));
|
||||
|
||||
////app.nav.setContextTitle("Customer");
|
||||
|
||||
//id should always have a value, either a record id or the keyword 'new' for making a new object
|
||||
if (stateMap.id != 'new') {
|
||||
//fetch existing record
|
||||
app.api.get('customer/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//fill out form
|
||||
app.utilB.formData(res);
|
||||
}
|
||||
});
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("customerSites/" + stateMap.id, "Sites", "city");//url title icon
|
||||
|
||||
|
||||
} else {
|
||||
$('#btn-delete').hide();
|
||||
app.nav.contextClear();
|
||||
}
|
||||
|
||||
// bind actions
|
||||
$('#btn-save').bind('click', onSave);
|
||||
$('#btn-delete').bind('click', onDelete);
|
||||
};
|
||||
|
||||
|
||||
// RETURN PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
168
wwwroot/js/app.customerSiteEdit.js
Normal file
168
wwwroot/js/app.customerSiteEdit.js
Normal file
@@ -0,0 +1,168 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.customerSiteEdit = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
onSave, onDelete, configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
onSave = function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
|
||||
|
||||
//is this a new record?
|
||||
if (stateMap.id != 'new') {
|
||||
//put id into the form data
|
||||
submitData.id = stateMap.id;
|
||||
|
||||
app.api.update('site', submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//create new record
|
||||
app.api.create('site', submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
page('#!/customerSiteEdit/' + res.id + '/' + stateMap.context.params.cust_id);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
return false; //prevent default
|
||||
};
|
||||
|
||||
|
||||
//ONDELETE
|
||||
//
|
||||
onDelete = function (event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
|
||||
var r = confirm("Are you sure you want to delete this record?");
|
||||
if (r == true) {
|
||||
//--------------------------------------------
|
||||
//==== DELETE THE site and it's children ====
|
||||
app.api.remove('site/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//deleted, return to customers list
|
||||
page('#!/customerSites/' + stateMap.context.params.cust_id);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
//--------------------
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.customerSiteEdit']({}));
|
||||
var title = "Site";
|
||||
|
||||
if (stateMap.context.params.cust_id) {
|
||||
//Append customer id as a hidden form field for referential integrity
|
||||
$('<input />').attr('type', 'hidden')
|
||||
.attr('name', "customerId")
|
||||
.attr('value', stateMap.context.params.cust_id)
|
||||
.appendTo('#frm');
|
||||
|
||||
//fetch existing record
|
||||
app.api.get('customer/' + stateMap.context.params.cust_id + '/name', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
title = 'Site - ' + res.name;
|
||||
if (stateMap.id != 'new') {
|
||||
//fetch existing record
|
||||
app.api.get('site/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//fill out form
|
||||
app.utilB.formData(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
//set customer name
|
||||
//app.nav.setContextTitle(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// bind actions
|
||||
$('#btn-save').bind('click', onSave);
|
||||
$('#btn-delete').bind('click', onDelete);
|
||||
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("customerEdit/" + stateMap.context.params.cust_id, "Customer", "account");
|
||||
app.nav.contextAddLink("customerSites/" + stateMap.context.params.cust_id, "Sites", "city");
|
||||
|
||||
if (stateMap.id != 'new') {
|
||||
app.nav.contextAddLink("purchases/" + stateMap.id, "Purchases", "basket");
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
131
wwwroot/js/app.customerSites.js
Normal file
131
wwwroot/js/app.customerSites.js
Normal file
@@ -0,0 +1,131 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.customerSites = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
|
||||
configMap = {
|
||||
//main_html: '',
|
||||
|
||||
settable_map: {}
|
||||
},
|
||||
stateMap = {
|
||||
$append_target: null
|
||||
},
|
||||
onSubmit,
|
||||
configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//--------------------- BEGIN DOM METHODS --------------------
|
||||
|
||||
|
||||
|
||||
|
||||
// Begin private DOM methods
|
||||
|
||||
|
||||
|
||||
// End private DOM methods
|
||||
//---------------------- END DOM METHODS ---------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
// Begin public method /initModule/
|
||||
// Example : app.customer.initModule( $('#div_id') );
|
||||
// Purpose : directs the module to being offering features
|
||||
// Arguments : $container - container to use
|
||||
// Action : Provides interface
|
||||
// Returns : none
|
||||
// Throws : none
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.customerSites']({}));
|
||||
|
||||
var title = "Sites";
|
||||
|
||||
if (stateMap.id) {
|
||||
|
||||
|
||||
app.api.get('customer/' + stateMap.id + '/name', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//set customer name
|
||||
title = 'Sites - ' + res.name;
|
||||
//app.nav.setContextTitle(title);
|
||||
|
||||
|
||||
if (stateMap.id) {
|
||||
|
||||
//fetch sites list
|
||||
|
||||
//fetch existing record
|
||||
app.api.get('customer/' + stateMap.id + '/sites', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//get the list ul
|
||||
var $appList = $('#rf-list');
|
||||
|
||||
$.each(res, function (i, obj) {
|
||||
$appList.append("<li><a href=\"#!/customerSiteEdit/" + obj.id + "/" + stateMap.id + "\">" +
|
||||
app.utilB.genListColumn(obj.name) +
|
||||
"</a></li>")
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink('customerSiteEdit/new/' + stateMap.id, "New", "plus");
|
||||
app.nav.contextAddLink("customerEdit/" + stateMap.id, "Customer", "account");
|
||||
|
||||
|
||||
};
|
||||
// End public method /initModule/
|
||||
|
||||
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
192
wwwroot/js/app.customers.js
Normal file
192
wwwroot/js/app.customers.js
Normal file
@@ -0,0 +1,192 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.customers = (function() {
|
||||
"use strict";
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var stateMap = {},
|
||||
configModule,
|
||||
initModule,
|
||||
generateCard,
|
||||
onShowMore;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//////////////////
|
||||
//Generate a card with collapsible middle section with more details
|
||||
//
|
||||
generateCard = function(obj) {
|
||||
var editUrl = "#!/customerEdit/" + obj.id;
|
||||
var cardClass = obj.active
|
||||
? "border-primary text-primary"
|
||||
: "border-secondary text-secondary";
|
||||
var urlClass = obj.active ? "" : "text-secondary";
|
||||
|
||||
return (
|
||||
'<div class="card ' +
|
||||
cardClass +
|
||||
' mb-3">' +
|
||||
'<h4 class="card-header"><a class="' +
|
||||
urlClass +
|
||||
'" href=' +
|
||||
editUrl +
|
||||
">" +
|
||||
obj.name +
|
||||
"</a></h4>" +
|
||||
'<div class="collapse" id="card-collapse' +
|
||||
obj.id +
|
||||
'">' +
|
||||
'<div id="card-body' +
|
||||
obj.id +
|
||||
'" class="card-body"/>' +
|
||||
"</div>" +
|
||||
'<div class="card-footer">' +
|
||||
'<button id="btnMore' +
|
||||
obj.id +
|
||||
'" class="btn btn-outline-dark mdi mdi-basket mdi-24px mr-3" type="button"/>' +
|
||||
// '<a href="' + editUrl + '" class="btn btn-outline-success mdi mdi-account-edit mdi-24px "></a>' +
|
||||
"</div>" +
|
||||
"</div>"
|
||||
);
|
||||
};
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
////////////////////////////////////////////
|
||||
//ONMORE
|
||||
//
|
||||
onShowMore = function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
var customerId = event.data;
|
||||
var $cardbody = $("#card-body" + customerId);
|
||||
var $collapseDiv = $("#card-collapse" + customerId);
|
||||
|
||||
var isOpen = $collapseDiv.hasClass("show");
|
||||
|
||||
//either way we don't want the old contents hanging around
|
||||
$cardbody.empty();
|
||||
|
||||
//Reload the data?
|
||||
if (!isOpen) {
|
||||
//===================
|
||||
//Get sites
|
||||
app.api.get("customer/" + customerId + "/activesubforsites", function(
|
||||
sites
|
||||
) {
|
||||
if (sites.error) {
|
||||
$.gevent.publish("app-show-error", sites.msg);
|
||||
} else {
|
||||
var cardDisplay = '<ul class="list-unstyled">';
|
||||
|
||||
//Iterate the sites
|
||||
for (var y = 0; y < sites.length; y++) {
|
||||
//append the site name
|
||||
cardDisplay +=
|
||||
'<li class="font-weight-bold">' + sites[y].name + "</li>";
|
||||
|
||||
//append the active subs
|
||||
//purchase link for future
|
||||
//https://rockfish.ayanova.com/default.htm#!/purchaseEdit/<PURCHASEID>/<SITEID>
|
||||
if (sites[y].children.length > 0) {
|
||||
cardDisplay += '<ul class="mb-2">';
|
||||
for (var x = 0; x < sites[y].children.length; x++) {
|
||||
cardDisplay += "<li>" + sites[y].children[x].name + "</li>";
|
||||
}
|
||||
cardDisplay += "</ul>";
|
||||
} else {
|
||||
cardDisplay +=
|
||||
'<ul class="text-danger"><li>NO ACTIVE SUBS</li></ul>';
|
||||
}
|
||||
}
|
||||
cardDisplay += "</ul>";
|
||||
$cardbody.append(cardDisplay);
|
||||
//Toggle open after populating the card
|
||||
$collapseDiv.collapse("toggle");
|
||||
}
|
||||
});
|
||||
//=========/sites==============
|
||||
} else {
|
||||
//Toggle closed
|
||||
$collapseDiv.collapse("toggle");
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function(context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function($container) {
|
||||
if (typeof $container === "undefined") {
|
||||
$container = $("#app-shell-main-content");
|
||||
}
|
||||
$container.html(Handlebars.templates["app.customers"]({}));
|
||||
|
||||
//===================
|
||||
//Get customers
|
||||
app.api.get("customer/list", function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
} else {
|
||||
var $appList = $("#rf-list");
|
||||
|
||||
var activeCount = 0;
|
||||
var inactiveCount = 0;
|
||||
|
||||
$.each(res, function(i, obj) {
|
||||
if (obj.active) {
|
||||
activeCount++;
|
||||
} else {
|
||||
inactiveCount++;
|
||||
}
|
||||
|
||||
$appList.append(generateCard(obj));
|
||||
$("#btnMore" + obj.id).bind("click", obj.id, onShowMore);
|
||||
});
|
||||
|
||||
//Show the count of customers active and inactive
|
||||
$("#rf-list-count")
|
||||
.empty()
|
||||
.append(
|
||||
res.length +
|
||||
" items (" +
|
||||
activeCount +
|
||||
" active, " +
|
||||
inactiveCount +
|
||||
" inactive)"
|
||||
);
|
||||
}
|
||||
});
|
||||
//=========/customers==============
|
||||
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("customerEdit/new", "New", "plus");
|
||||
app.nav.contextAddLink("search", "Search", "magnify");
|
||||
};
|
||||
|
||||
//PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
})();
|
||||
56
wwwroot/js/app.fourohfour.js
Normal file
56
wwwroot/js/app.fourohfour.js
Normal file
@@ -0,0 +1,56 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.fourohfour = (function() {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
|
||||
stateMap = {},
|
||||
configModule,
|
||||
initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function(context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
$container.html(Handlebars.templates['app.fourohfour']({}));
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
//PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
167
wwwroot/js/app.inbox.js
Normal file
167
wwwroot/js/app.inbox.js
Normal file
@@ -0,0 +1,167 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.inbox = (function() {
|
||||
"use strict";
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var stateMap = {},
|
||||
configModule,
|
||||
initModule,
|
||||
terminateModule,
|
||||
getMessages,
|
||||
timerVar=null;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
getMessages = function() {
|
||||
stateMap.$appList.html("<h4>Checking...</h4>");
|
||||
|
||||
app.api.get("mail/salesandsupportsummaries", function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
} else {
|
||||
stateMap.$appList.empty();
|
||||
var newMessageCount = 0;
|
||||
var lastAccount = "";
|
||||
//The list
|
||||
var displayedItems = 0;
|
||||
var generatedHtml = '<ul class="list-group">';
|
||||
|
||||
//Iterate the results
|
||||
for (var y = 0; y < res.length; y++) {
|
||||
var obj = res[y];
|
||||
if (!obj.flags.includes("deleted")) {
|
||||
if (!obj.flags.includes("seen")) {
|
||||
newMessageCount++;
|
||||
}
|
||||
var displayClass = obj.flags.includes("seen")
|
||||
? "border-secondary text-secondary"
|
||||
: "border-primary text-primary";
|
||||
var answeredIconClass = obj.flags.includes("answered")
|
||||
? " mdi mdi-reply"
|
||||
: "";
|
||||
|
||||
//Make a group on change of account
|
||||
if (lastAccount !== obj.account) {
|
||||
lastAccount = obj.account;
|
||||
//Insert as 'header' in list
|
||||
generatedHtml +=
|
||||
'<li class="list-group-item active">' + lastAccount + "</li>";
|
||||
}
|
||||
|
||||
//LIST ITEM
|
||||
generatedHtml +=
|
||||
'<li class="list-group-item" ><a href="#!/mailEdit/' +
|
||||
obj.account +
|
||||
"/Inbox/" +
|
||||
obj.id +
|
||||
"\"><span class='" +
|
||||
displayClass +
|
||||
answeredIconClass +
|
||||
"'>" +
|
||||
obj.subject +
|
||||
" - " +
|
||||
obj.from +
|
||||
"</span></a></li>";
|
||||
displayedItems++;
|
||||
} //if not deleted
|
||||
} //loop
|
||||
|
||||
//Nothing to display?
|
||||
if (!displayedItems) {
|
||||
generatedHtml +=
|
||||
'<li class="list-group-item">NO MESSAGES - ' +
|
||||
moment().format("YYYY-MM-DD LT") +
|
||||
"</li>";
|
||||
}
|
||||
|
||||
//close list group
|
||||
generatedHtml += "</ul>";
|
||||
|
||||
generatedHtml +=
|
||||
'<div class="mt-5"><h6><small class="text-muted">Last check: ' +
|
||||
moment().format("YYYY-MM-DD LT") +
|
||||
"</small><h6></div>";
|
||||
//SET IT
|
||||
stateMap.$appList.append(generatedHtml);
|
||||
|
||||
//case 3516
|
||||
if (newMessageCount > 0) {
|
||||
document.title =
|
||||
newMessageCount +
|
||||
" NEW message" +
|
||||
(newMessageCount == 1 ? "" : "s");
|
||||
} else {
|
||||
document.title = "No new messages";
|
||||
}
|
||||
}
|
||||
//do it every 5 minutes
|
||||
timerVar=setTimeout(getMessages,5*60*1000);
|
||||
console.log("INBOX.GETMESSAGES - started timer " + timerVar);
|
||||
});
|
||||
};
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function(context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function($container) {
|
||||
if (typeof $container === "undefined") {
|
||||
$container = $("#app-shell-main-content");
|
||||
}
|
||||
$container.html(Handlebars.templates["app.inbox"]({}));
|
||||
stateMap.$appList = $("#rf-list-div");
|
||||
|
||||
getMessages();
|
||||
|
||||
//auto refresh every 10 minutes
|
||||
|
||||
// intervalRef = setInterval(function() {
|
||||
// getMessages();
|
||||
// }, 10 * 60 * 1000);
|
||||
|
||||
app.nav.contextClear();
|
||||
////app.nav.setContextTitle("inbox");
|
||||
};
|
||||
|
||||
// TERMINATE MODULE
|
||||
//
|
||||
terminateModule = function() {
|
||||
|
||||
if(timerVar!=null){
|
||||
clearTimeout(timerVar);
|
||||
console.log("INBOX.TERMINATEMODULE - cleared timer" + timerVar);
|
||||
}
|
||||
//clear up event handler
|
||||
// clearInterval(intervalRef);
|
||||
// intervalRef=null;
|
||||
//console.log("INBOX.TERMINATEMODULE");
|
||||
};
|
||||
|
||||
//PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule,
|
||||
terminateModule: terminateModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
})();
|
||||
156
wwwroot/js/app.license.js
Normal file
156
wwwroot/js/app.license.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* app.license.js
|
||||
* License key generator
|
||||
*/
|
||||
|
||||
/*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 $, app */
|
||||
|
||||
app.license = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
|
||||
stateMap = {},
|
||||
configModule, initModule, onGenerate, onSelectAllAddOns;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
onGenerate = function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
|
||||
app.api.createLicense(submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
$('#key').val(res);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return false; //prevent default
|
||||
};
|
||||
|
||||
|
||||
onSelectAllAddOns = function (event) {
|
||||
event.preventDefault();
|
||||
$('#wbi').prop('checked', true);
|
||||
$('#mbi').prop('checked', true);
|
||||
$('#ri').prop('checked', true);
|
||||
$('#qbi').prop('checked', true);
|
||||
$('#qboi').prop('checked', true);
|
||||
$('#pti').prop('checked', true);
|
||||
$('#quickNotification').prop('checked', true);
|
||||
$('#exportToXls').prop('checked', true);
|
||||
$('#outlookSchedule').prop('checked', true);
|
||||
$('#oli').prop('checked', true);
|
||||
$('#importExportCSVDuplicate').prop('checked', true);
|
||||
|
||||
|
||||
|
||||
return false; //prevent default
|
||||
};
|
||||
|
||||
// onTemplates = function(event) {
|
||||
// event.preventDefault();
|
||||
// alert("STUB: templates");
|
||||
|
||||
|
||||
// return false; //prevent default
|
||||
// };
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
$container.html(Handlebars.templates['app.license']({}));
|
||||
|
||||
|
||||
//case 3233 customer list
|
||||
//Fill customer list combo
|
||||
var customerList = {};
|
||||
|
||||
|
||||
//get customers
|
||||
app.api.get('customer/list', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
|
||||
var html = '<option value="0"><TRIAL></option>';
|
||||
|
||||
for (var i = 0, len = res.length; i < len; ++i) {
|
||||
html += ('<option value="' + res[i]['id'] + '">' + res[i]['name'] + '</option>');
|
||||
customerList[res[i]['id']] = res[i]['name'];
|
||||
}
|
||||
$('#customerId').append(html);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
|
||||
////app.nav.setContextTitle("License");
|
||||
|
||||
//make context menu
|
||||
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddButton('btn-generate', 'Make', 'key', onGenerate);
|
||||
app.nav.contextAddButton('btn-select-all-addons', 'All', 'check-all', onSelectAllAddOns);
|
||||
// app.nav.contextAddLink("licenseRequests/", "Requests", "voice");
|
||||
app.nav.contextAddLink("licenseTemplates/", "", "layers");
|
||||
//case 3233
|
||||
app.nav.contextAddLink("licenses/", "List", "");
|
||||
|
||||
|
||||
//set all date inputs to today plus one year
|
||||
var oneYearFromNow = moment().add(1, 'years').toISOString().substring(0, 10);
|
||||
var oneMonthFromNow = moment().add(1, 'months').toISOString().substring(0, 10);
|
||||
$('input[type="date"]').val(oneYearFromNow);
|
||||
$('#lockoutDate').val(oneMonthFromNow);
|
||||
|
||||
};
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
138
wwwroot/js/app.licenseRequestEdit.js
Normal file
138
wwwroot/js/app.licenseRequestEdit.js
Normal file
@@ -0,0 +1,138 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.licenseRequestEdit = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
onSend, onCancel, onRegenerate, configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
////////////////////
|
||||
//
|
||||
onSend = function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
|
||||
app.api.licenseEmailResponse(submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//navigate back to licenseRequests
|
||||
//alert("key has been sent!");
|
||||
window.location.href = "#!/inbox/";
|
||||
|
||||
//$('#key').val(res);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return false; //prevent default
|
||||
};
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.licenseRequestEdit']({}));
|
||||
////app.nav.setContextTitle("Request");
|
||||
|
||||
//Append key hidden values for submit and processing by server
|
||||
//This is set from the original click to open this form
|
||||
$('<input />').attr('type', 'hidden')
|
||||
.attr('name', "request_email_uid")
|
||||
.attr('value', stateMap.id)
|
||||
.appendTo('#frm');
|
||||
|
||||
//These are empty but will be filled in when the server responds with the "record"
|
||||
//They are for re-submission back to the server to save a step of refetching the original info
|
||||
//and recalculating stuff that was already done
|
||||
|
||||
$('<input />').attr('type', 'hidden')
|
||||
.attr('name', "requestReplyToAddress")
|
||||
.attr('value', '')
|
||||
.appendTo('#frm');
|
||||
|
||||
$('<input />').attr('type', 'hidden')
|
||||
.attr('name', "requestFromReplySubject")
|
||||
.attr('value', '')
|
||||
.appendTo('#frm');
|
||||
|
||||
//rfcore unused?
|
||||
$('<input />').attr('type', 'hidden')
|
||||
.attr('name', "greetingReplySubject")
|
||||
.attr('value', '')
|
||||
.appendTo('#frm');
|
||||
|
||||
$('<input />').attr('type', 'hidden')
|
||||
.attr('name', "requestFromReplySubject")
|
||||
.attr('value', '')
|
||||
.appendTo('#frm');
|
||||
|
||||
|
||||
|
||||
|
||||
//fetch existing record
|
||||
app.api.generateFromRequest(stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//fill out form
|
||||
app.utilB.formData(res);
|
||||
}
|
||||
});
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddButton('btn-generate', 'Send', 'send', onSend);
|
||||
app.nav.contextAddLink("inbox/", "Inbox", "inbox");
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
102
wwwroot/js/app.licenseTemplates.js
Normal file
102
wwwroot/js/app.licenseTemplates.js
Normal file
@@ -0,0 +1,102 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.licenseTemplates = (function () {
|
||||
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
onSave, configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
|
||||
//different than the other edit routes because it's global and there is only one
|
||||
//so no ID
|
||||
onSave = function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
submitData["id"] = '1';
|
||||
|
||||
app.api.update('licenseTemplates', submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
}
|
||||
});
|
||||
|
||||
return false; //prevent default
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
// if (stateMap.context.params.id) {
|
||||
// stateMap.id = stateMap.context.params.id;
|
||||
// }
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.licenseTemplates']({}));
|
||||
|
||||
//fetch existing record
|
||||
//Note license templates record id is always 1 as there is only ever one record in db
|
||||
app.api.get('licenseTemplates/' + '1', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//fill out form
|
||||
app.utilB.formData(res);
|
||||
}
|
||||
});
|
||||
|
||||
//set title
|
||||
// var title = "License message templates";
|
||||
// //app.nav.setContextTitle(title);
|
||||
|
||||
// bind actions
|
||||
$('#btn-save').bind('click', onSave);
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("license/", "License", "key");
|
||||
};
|
||||
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
116
wwwroot/js/app.licenseView.js
Normal file
116
wwwroot/js/app.licenseView.js
Normal file
@@ -0,0 +1,116 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.licenseView = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
onSave, onDelete,
|
||||
configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
//ONSAVE
|
||||
//
|
||||
onSave = function (event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
|
||||
var isFetched=$('#fetched').prop('checked')
|
||||
|
||||
// var submitData = { isFetched: isFetched };
|
||||
app.api.putAction('license/fetched/' + stateMap.id + "/" + isFetched, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
}
|
||||
});
|
||||
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
//ONDELETE
|
||||
//
|
||||
onDelete = function (event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
var r = confirm("Are you sure you want to delete this record?");
|
||||
if (r == true) {
|
||||
app.api.remove('license/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
page('#!/licenses');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
|
||||
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.licenseView']({}));
|
||||
|
||||
document.title = 'License ';
|
||||
|
||||
//fetch existing record
|
||||
app.api.get('license/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
//fill out form
|
||||
app.utilB.formData(res);
|
||||
}
|
||||
});
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("licenses/", "List", "");
|
||||
|
||||
|
||||
|
||||
// bind actions
|
||||
$('#btn-save').bind('click', onSave);
|
||||
$('#btn-delete').bind('click', onDelete);
|
||||
};
|
||||
|
||||
|
||||
// RETURN PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
108
wwwroot/js/app.licenses.js
Normal file
108
wwwroot/js/app.licenses.js
Normal file
@@ -0,0 +1,108 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.licenses = (function() {
|
||||
"use strict";
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var stateMap = {},
|
||||
configModule,
|
||||
initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function(context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function($container) {
|
||||
if (typeof $container === "undefined") {
|
||||
$container = $("#app-shell-main-content");
|
||||
}
|
||||
$container.html(Handlebars.templates["app.licenses"]({}));
|
||||
|
||||
//case 3513
|
||||
document.title = "Licenses";
|
||||
|
||||
//===================
|
||||
//Get licenses
|
||||
app.api.get("license/list", function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
} else {
|
||||
var $appList = $("#rf-list");
|
||||
|
||||
$appList.append('<ul class="list-group">');
|
||||
|
||||
$.each(res, function(i, obj) {
|
||||
if (obj.fetched) {
|
||||
$appList.append(
|
||||
"<li class='rfc-list-item-inactive list-group-item'><a href=\"#!/licenseView/" +
|
||||
obj.id +
|
||||
'">' +
|
||||
"<span class='text-muted'>" +
|
||||
(obj.trial
|
||||
? "Trial "
|
||||
: "") +
|
||||
app.utilB.genListColumn(obj.regto) +
|
||||
" " +
|
||||
app.utilB.genListColumn(
|
||||
app.utilB.epochToShortDate(obj.created)
|
||||
) +
|
||||
"</span>" +
|
||||
"</a></li>"
|
||||
);
|
||||
} else {
|
||||
$appList.append(
|
||||
"<li class='list-group-item'><a href=\"#!/licenseView/" +
|
||||
obj.id +
|
||||
'">' +
|
||||
(obj.trial
|
||||
? "Trial "
|
||||
: "") +
|
||||
app.utilB.genListColumn(obj.regto) +
|
||||
" " +
|
||||
app.utilB.genListColumn(
|
||||
app.utilB.epochToShortDate(obj.created)
|
||||
) +
|
||||
"</a></li>"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$appList.append("</ul>");
|
||||
}
|
||||
});
|
||||
//=========/licenses==============
|
||||
|
||||
app.nav.contextClear();
|
||||
};
|
||||
|
||||
//PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
})();
|
||||
160
wwwroot/js/app.mailEdit.js
Normal file
160
wwwroot/js/app.mailEdit.js
Normal file
@@ -0,0 +1,160 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.mailEdit = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
onSave, onDelete, onSend,
|
||||
configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
///////////////////////////////////
|
||||
// SEND A REPLY OR NEW MESSAGE
|
||||
//
|
||||
onSend = function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
$.gevent.publish('app-clear-error');
|
||||
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
//var submitData = {composition:$("#composition").val()};
|
||||
var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
|
||||
//is this a new record?
|
||||
if (stateMap.id != 'new') {
|
||||
//put id into the form data
|
||||
// submitData.id = stateMap.id;
|
||||
|
||||
app.api.create('mail/reply/' +
|
||||
stateMap.context.params.mail_account +
|
||||
'/' + stateMap.context.params.mail_id, submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
page('#!/inbox');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert("STUB: New message composition not implemented yet");
|
||||
// //it's a new record - create
|
||||
// app.api.create('customer', submitData, function (res) {
|
||||
// if (res.error) {
|
||||
// $.gevent.publish('app-show-error',res.msg);
|
||||
// } else {
|
||||
// page('#!/inbox');
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
//ONDELETE
|
||||
//
|
||||
//removed
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
|
||||
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.mailEdit']({}));
|
||||
// stateMap.replyMode = false;
|
||||
// if (stateMap.context.querystring.endsWith('reply')) {
|
||||
// stateMap.replyMode = true;
|
||||
// }
|
||||
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("inbox/", "Inbox", "inbox");
|
||||
|
||||
//id should always have a value, either a record id or the keyword 'new' for making a new object
|
||||
if (stateMap.id != 'new') {
|
||||
|
||||
//fetch existing record
|
||||
app.api.get(
|
||||
'mail/preview/' +
|
||||
stateMap.context.params.mail_account +
|
||||
'/' + stateMap.context.params.mail_folder +
|
||||
'/' + stateMap.context.params.mail_id, function (res) {
|
||||
if (res.error) {
|
||||
// app.nav.contextClear();
|
||||
// app.nav.contextAddLink("inbox/", "Inbox", "inbox");
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
//fill out form
|
||||
// app.nav.contextClear();
|
||||
//app.nav.contextAddLink("inbox/", "Inbox", "inbox");
|
||||
$('#message').text(res.preview);
|
||||
if(res.isKeyRequest){
|
||||
app.nav.contextAddLink("licenseRequestEdit/" + res.id, "Make", "key");
|
||||
}else{
|
||||
$('#composition').text("\n\n- John\nwww.ayanova.com");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#btn-send').bind('click', onSend);
|
||||
|
||||
//Context menu
|
||||
|
||||
//app.nav.contextAddButton('btn-send', 'Send reply', 'send', onSend);
|
||||
|
||||
// app.nav.contextAddButton('btn-generate', 'Build', 'key', onReply);
|
||||
// app.nav.contextAddLink("customerSites/" + stateMap.id, "Sites", "city");//url title icon
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
//NEW email options
|
||||
var $group = $("#sendToGroup");
|
||||
$group.removeClass("invisible");
|
||||
|
||||
// app.nav.contextClear();
|
||||
// app.nav.contextAddLink("inbox/", "Inbox", "inbox");
|
||||
// app.nav.contextAddButton('btn-send', 'Send', 'send', onSend);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
// RETURN PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
102
wwwroot/js/app.nav.js
Normal file
102
wwwroot/js/app.nav.js
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* app.nav.js
|
||||
* Handle dynamic navigation related operations
|
||||
* toobar, menu, fab etc
|
||||
*
|
||||
*/
|
||||
|
||||
/*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 $, app */
|
||||
|
||||
app.nav = (function () {
|
||||
var contextClear, contextAddButton, contextAddLink, backUrl, backRemove, moreMenuInitialized,
|
||||
setContextTitle, setSelectedMenuItem;
|
||||
|
||||
|
||||
|
||||
// ///////////////////////////////////////////
|
||||
// //Set context menu title
|
||||
// //
|
||||
// var setContextTitle = function (title) {
|
||||
// $("#rf-context-title").html(title + "...");
|
||||
// }
|
||||
|
||||
////////////////////////////////////////////////
|
||||
//Clear the contents of the context menu (reset it)
|
||||
//
|
||||
contextClear = function () {
|
||||
$("#rf-context-group").empty();
|
||||
$("#rf-context-group").addClass("invisible");
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
//Add a non nav button item to the context menu
|
||||
//
|
||||
contextAddButton = function (id, title, icon, clickHandler) {
|
||||
var $group=$("#rf-context-group");
|
||||
$group.removeClass("invisible");
|
||||
|
||||
var iconClass = '';
|
||||
if (icon) {
|
||||
iconClass = "mdi mdi-" + icon;
|
||||
}
|
||||
$group.append(
|
||||
'<button type="button" id="' + id + '" class="btn btn-outline-dark ' + iconClass + '" href="#">' + title + '</a>'
|
||||
);
|
||||
|
||||
$('#' + id).bind('click', clickHandler);
|
||||
|
||||
};
|
||||
|
||||
// <button type="button" class="btn btn-outline-dark mdi mdi-key">Left</button>
|
||||
|
||||
////////////////////////////////////////////////
|
||||
//Add an url item to the context menu handling
|
||||
//phone vs larger sizes
|
||||
//
|
||||
contextAddLink = function (url, title, icon) {
|
||||
var $group=$("#rf-context-group");
|
||||
$group.removeClass("invisible");
|
||||
var iconClass = '';
|
||||
if (icon) {
|
||||
iconClass = "mdi mdi-" + icon;
|
||||
}
|
||||
$group.append(
|
||||
'<a class="btn btn-outline-dark ' + iconClass + '" href="#!/' + encodeURI(url) + '">' + title + '</a>'
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
//Set the active class on the selected menu item
|
||||
//
|
||||
setSelectedMenuItem = function (selectedMenuItem) {
|
||||
$(".nav-item").removeClass("active");
|
||||
if (selectedMenuItem) {
|
||||
$("#" + selectedMenuItem).addClass("active");
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return {
|
||||
contextClear: contextClear,
|
||||
contextAddButton: contextAddButton,
|
||||
contextAddLink: contextAddLink,
|
||||
setContextTitle: setContextTitle,
|
||||
setSelectedMenuItem: setSelectedMenuItem
|
||||
|
||||
};
|
||||
}());
|
||||
266
wwwroot/js/app.purchaseEdit.js
Normal file
266
wwwroot/js/app.purchaseEdit.js
Normal file
@@ -0,0 +1,266 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.purchaseEdit = (function() {
|
||||
"use strict";
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var stateMap = {},
|
||||
onSave,
|
||||
onDelete,
|
||||
onRenew,
|
||||
configModule,
|
||||
initModule,
|
||||
onPasteNotes;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
onSave = function(event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish("app-clear-error");
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
|
||||
//is this a new record?
|
||||
if (stateMap.id != "new") {
|
||||
//put id into the form data
|
||||
submitData.id = stateMap.id;
|
||||
|
||||
app.api.update("purchase", submitData, function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//create new record
|
||||
app.api.create("purchase", submitData, function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
} else {
|
||||
page(
|
||||
"#!/purchaseEdit/" + res.id + "/" + stateMap.context.params.site_id
|
||||
);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
return false; //prevent default
|
||||
};
|
||||
|
||||
onRenew = function(event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish("app-clear-error");
|
||||
|
||||
if (stateMap.id == "new") {
|
||||
$.gevent.publish(
|
||||
"app-show-error",
|
||||
"Save this record before attempting to renew it"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
stateMap.id = "new";
|
||||
|
||||
//case 3396, no more renewal or dupe names
|
||||
// var nm = $('#name').val();
|
||||
// nm = "DUPE-" + nm;
|
||||
// $('#name').val(nm);
|
||||
|
||||
//case 3396, set values accordingly
|
||||
|
||||
//Clear salesOrderNumber
|
||||
$("#salesOrderNumber").val("");
|
||||
|
||||
//set purchaseDate to today
|
||||
$("#purchaseDate").val(
|
||||
moment()
|
||||
.toISOString()
|
||||
.substring(0, 10)
|
||||
);
|
||||
|
||||
//set expireDate to plus one year from today
|
||||
$("#expireDate").val(
|
||||
moment()
|
||||
.add(1, "years")
|
||||
.toISOString()
|
||||
.substring(0, 10)
|
||||
);
|
||||
|
||||
//clear the couponCode
|
||||
$("#couponCode").val("");
|
||||
|
||||
//clear the notes
|
||||
$("#notes").val("");
|
||||
|
||||
$("#renewNoticeSent").prop("checked", false);
|
||||
$("#cancelDate").val("");
|
||||
|
||||
return false; //prevent default
|
||||
};
|
||||
|
||||
//ONDELETE
|
||||
//
|
||||
onDelete = function(event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish("app-clear-error");
|
||||
|
||||
var r = confirm("Are you sure you want to delete this record?");
|
||||
if (r == true) {
|
||||
//==== DELETE ====
|
||||
app.api.remove("purchase/" + stateMap.id, function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
} else {
|
||||
//deleted, return to master list
|
||||
page("#!/purchases/" + stateMap.context.params.site_id);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
onPasteNotes = function(event) {
|
||||
var clipboardData, pastedData;
|
||||
var e = event.originalEvent;
|
||||
|
||||
// // Stop data actually being pasted into div
|
||||
// e.stopPropagation();
|
||||
// e.preventDefault();
|
||||
|
||||
// Get pasted data via clipboard API
|
||||
clipboardData = e.clipboardData || window.clipboardData;
|
||||
pastedData = clipboardData.getData("Text");
|
||||
|
||||
//Iterate through the lines looking for the SHareIt name=value lines (they all contain equal signs)
|
||||
var lines = pastedData.split("\n"); // lines is an array of strings
|
||||
var purchaseData = {};
|
||||
|
||||
// Loop through all lines
|
||||
for (var j = 0; j < lines.length; j++) {
|
||||
var thisLine = lines[j];
|
||||
if (thisLine.includes("=")) {
|
||||
var thisElement = thisLine.split("=");
|
||||
purchaseData[thisElement[0].trim()] = thisElement[1].trim();
|
||||
}
|
||||
}
|
||||
|
||||
//Now have an object with the value pairs in it
|
||||
if (purchaseData["ShareIt Ref #"]) {
|
||||
$("#salesOrderNumber").val(purchaseData["ShareIt Ref #"]);
|
||||
}
|
||||
|
||||
// if (purchaseData["E-Mail"]) {
|
||||
// $("#email").val(purchaseData["E-Mail"]);
|
||||
// }
|
||||
};
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function(context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function($container) {
|
||||
if (typeof $container === "undefined") {
|
||||
$container = $("#app-shell-main-content");
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates["app.purchaseEdit"]({}));
|
||||
var title = "Purchase";
|
||||
|
||||
if (!stateMap.context.params.site_id) {
|
||||
throw "app.purchaseEdit.js::initModule - There is no stateMap.context.params.site_id!";
|
||||
}
|
||||
|
||||
//Append master record id as a hidden form field for referential integrity
|
||||
$("<input />")
|
||||
.attr("type", "hidden")
|
||||
.attr("name", "siteId")
|
||||
.attr("value", stateMap.context.params.site_id)
|
||||
.appendTo("#frm");
|
||||
|
||||
//fetch entire site record to get name *and* customer id which is required for redundancy
|
||||
|
||||
//RFC - get site name and customer name for form
|
||||
|
||||
app.api.get("site/" + stateMap.context.params.site_id, function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
} else {
|
||||
//Also append customer ID redundantly
|
||||
$("<input />")
|
||||
.attr("type", "hidden")
|
||||
.attr("name", "customerId")
|
||||
.attr("value", res.customerId)
|
||||
.appendTo("#frm");
|
||||
|
||||
title = "Purchase - " + res.name;
|
||||
if (stateMap.id != "new") {
|
||||
//fetch existing record
|
||||
app.api.get("purchase/" + stateMap.id, function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
} else {
|
||||
//fill out form
|
||||
app.utilB.formData(res);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//it's a new record, set default
|
||||
$("#purchaseDate").val(new Date().toISOString().substring(0, 10));
|
||||
}
|
||||
//set title
|
||||
//app.nav.setContextTitle(title);
|
||||
}
|
||||
});
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink(
|
||||
"purchases/" + stateMap.context.params.site_id,
|
||||
"Purchases",
|
||||
"basket"
|
||||
);
|
||||
|
||||
// bind actions
|
||||
$("#btn-save").bind("click", onSave);
|
||||
$("#btn-delete").bind("click", onDelete);
|
||||
$("#btn-renew").bind("click", onRenew);
|
||||
$("#notes").bind("paste", onPasteNotes);
|
||||
|
||||
//Autocomplete
|
||||
app.utilB.autoComplete("name", "purchase.name");
|
||||
app.utilB.autoComplete("productCode", "purchase.productCode");
|
||||
app.utilB.autoComplete("vendorName", "purchase.vendorName");
|
||||
};
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
})();
|
||||
145
wwwroot/js/app.purchases.js
Normal file
145
wwwroot/js/app.purchases.js
Normal file
@@ -0,0 +1,145 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.purchases = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
|
||||
configMap = {
|
||||
//main_html: '',
|
||||
|
||||
settable_map: {}
|
||||
},
|
||||
stateMap = {
|
||||
$append_target: null
|
||||
},
|
||||
onSubmit, loadList, configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
loadList = function () {
|
||||
//----
|
||||
//fetch
|
||||
app.api.get('site/' + stateMap.id + '/purchases', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//get the list ul
|
||||
var $appList = $('#rf-list');
|
||||
$appList.empty();
|
||||
$.each(res, function (i, obj) {
|
||||
|
||||
if (obj.cancelDate) {
|
||||
$appList.append("<li class='rfc-list-item-inactive'><a href=\"#!/purchaseEdit/" + obj.id + "/" + stateMap.id + "\">" +
|
||||
// app.utilB.genListColumn(app.utilB.epochToShortDate(obj.purchaseDate)) +
|
||||
// ' ' +
|
||||
"<span class='text-muted'>"+
|
||||
app.utilB.genListColumn(obj.name) +
|
||||
" cancelled " +
|
||||
app.utilB.genListColumn(app.utilB.epochToShortDate(obj.cancelDate)) +
|
||||
"</span>"+
|
||||
"</a></li>");
|
||||
} else {
|
||||
$appList.append("<li><a href=\"#!/purchaseEdit/" + obj.id + "/" + stateMap.id + "\">" +
|
||||
// app.utilB.genListColumn(app.utilB.epochToShortDate(obj.purchaseDate)) +
|
||||
// ' ' +
|
||||
app.utilB.genListColumn(obj.name) +
|
||||
" expires " +
|
||||
app.utilB.genListColumn(app.utilB.epochToShortDate(obj.expireDate)) +
|
||||
"</a></li>");
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
//------
|
||||
}
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//--------------------- BEGIN DOM METHODS --------------------
|
||||
|
||||
|
||||
|
||||
|
||||
// Begin private DOM methods
|
||||
|
||||
|
||||
|
||||
// End private DOM methods
|
||||
//---------------------- END DOM METHODS ---------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
// Begin public method /initModule/
|
||||
// Example : app.customer.initModule( $('#div_id') );
|
||||
// Purpose : directs the module to being offering features
|
||||
// Arguments : $container - container to use
|
||||
// Action : Provides interface
|
||||
// Returns : none
|
||||
// Throws : none
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
stateMap.sortOrder = 'd';
|
||||
$container.html(Handlebars.templates['app.purchases']({}));
|
||||
|
||||
if (!stateMap.id) {
|
||||
throw ('app.purchases.js::initModule - There is no stateMap.id!');
|
||||
}
|
||||
|
||||
app.api.get('site/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink('purchaseEdit/new/' + stateMap.id, "New", "plus");
|
||||
app.nav.contextAddLink("customerEdit/" + res.customerId, "Customer", "account");
|
||||
app.nav.contextAddLink("customerSiteEdit/" + stateMap.id + '/' + res.customerId, "Site", "city");
|
||||
if (stateMap.id) {
|
||||
loadList();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
// End public method /initModule/
|
||||
|
||||
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
67
wwwroot/js/app.reportData.js
Normal file
67
wwwroot/js/app.reportData.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.reportData = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
|
||||
stateMap = {},
|
||||
configModule,
|
||||
initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
$container.html(Handlebars.templates['app.reportData']({}));
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
////app.nav.setContextTitle("Reports");
|
||||
app.nav.contextAddLink("templates", "Templates", "widgets");//url title icon
|
||||
|
||||
|
||||
|
||||
|
||||
var $appList = $('#rf-list');
|
||||
$appList.empty();
|
||||
$appList.append("<li><a href=\"#!/reportDataProdEmails/\">" + app.utilB.genListColumn("Get emails CSV by product code") + "</a></li>");
|
||||
$appList.append("<li><a href=\"#!/reportDataExpires/\">" + app.utilB.genListColumn("Expiring subscriptions") + "</a></li>");
|
||||
|
||||
};
|
||||
|
||||
//PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
79
wwwroot/js/app.reportDataExpires.js
Normal file
79
wwwroot/js/app.reportDataExpires.js
Normal file
@@ -0,0 +1,79 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.reportDataExpires = (function () {
|
||||
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
configModule,
|
||||
initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.reportDataExpires']({}));
|
||||
|
||||
//fetch data
|
||||
app.api.get('report/expires', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
|
||||
//get the list ul
|
||||
var $appList = $('#rf-list');
|
||||
$appList.empty();
|
||||
$.each(res, function (i, obj) {
|
||||
$appList.append("<li><a href=\"#!/purchaseEdit/" + obj.id + "/" + obj.site_id + "\">" +
|
||||
app.utilB.genListColumn(app.utilB.epochToShortDate(obj.expireDate)) +
|
||||
app.utilB.genListColumn(obj.customer) +
|
||||
app.utilB.genListColumn(obj.name) +
|
||||
"</a></li>")
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("reportData/", "Reports", "book-open-variant");//url title icon
|
||||
|
||||
};
|
||||
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
139
wwwroot/js/app.reportDataProdEmail.js
Normal file
139
wwwroot/js/app.reportDataProdEmail.js
Normal file
@@ -0,0 +1,139 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.reportDataProdEmail = (function () {
|
||||
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
onGenerate, configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
onGenerate = function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
//var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
|
||||
//Now convert this specially for this method into a clean object to send with only what is required
|
||||
var submitData = {};
|
||||
submitData.products = [];
|
||||
var l = formData.length;
|
||||
for (var i = 0; i < l; i++) {
|
||||
var fname = formData[i].name;
|
||||
var fvalue = formData[i].value;
|
||||
|
||||
if (fname == 'ckIncidental') {
|
||||
submitData.ckIncidental = (fvalue == 'true');
|
||||
} else if (fname == 'ckNoContact') {
|
||||
submitData.ckNoContact = (fvalue == 'true');
|
||||
} else if (fname == 'csvdata') {
|
||||
;//do nothing
|
||||
} else {
|
||||
//it's a product key
|
||||
if (fvalue == 'true') {
|
||||
submitData.products.push(fname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
app.api.create('report/emailsforproductcodes',submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
$('#csvdata').val(res);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return false; //prevent default
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
// if (stateMap.context.params.id) {
|
||||
// stateMap.id = stateMap.context.params.id;
|
||||
// }
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.reportDataProdEmail']({}));
|
||||
|
||||
//fetch data
|
||||
app.api.get('purchase/productcodes',function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
|
||||
$.each(res, function (i, obj) {
|
||||
|
||||
var pcode = obj.productCode;
|
||||
var badCode = (!pcode);
|
||||
|
||||
//-----------
|
||||
$('<input />', {
|
||||
type: 'checkbox',
|
||||
id: 'id' + i,
|
||||
name: obj.productCode,
|
||||
disabled: badCode
|
||||
}).appendTo("#cbdiv");
|
||||
|
||||
$('#cbdiv').append('<label for="' + 'id' + i + '"> ' + (badCode ? '[NO PRODUCT CODE ENTERED]' : obj.productCode) + ' ' + obj.name + '</label>');
|
||||
$('#cbdiv').append('<br/>');
|
||||
|
||||
//--------------
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//set title
|
||||
var title="Email addresses by product code";
|
||||
//app.nav.setContextTitle(title);
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddButton('btn-generate', 'Build list', 'build', onGenerate);
|
||||
app.nav.contextAddLink("reportData/", "Reports", "book-open-variant");
|
||||
|
||||
};
|
||||
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
283
wwwroot/js/app.rfcaseEdit.js
Normal file
283
wwwroot/js/app.rfcaseEdit.js
Normal file
@@ -0,0 +1,283 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.rfcaseEdit = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
onSave, onDelete,
|
||||
configModule, initModule, onAttachment, onUpload, onAppend;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
//ONSAVE
|
||||
//
|
||||
onSave = function (event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
|
||||
//is this a new record?
|
||||
if (stateMap.id != 'new') {
|
||||
//put id into the form data
|
||||
submitData.id = stateMap.id;
|
||||
|
||||
|
||||
app.api.update('rfcase', submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//it's a new record - create
|
||||
|
||||
//set dtCreated as it's not a form field
|
||||
submitData.dtCreated = app.utilB.getCurrentDateTimeAsEpoch();
|
||||
|
||||
app.api.create('rfcase', submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
page('#!/rfcaseEdit/' + res.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
//ONDELETE
|
||||
//
|
||||
onDelete = function (event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
|
||||
var r = confirm("Are you sure you want to delete this record?");
|
||||
if (r == true) {
|
||||
//Delete
|
||||
app.api.remove('rfCase/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
//deleted, return to list
|
||||
page('#!/rfcases');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
//Handle click on attachment
|
||||
//
|
||||
onAttachment = function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
var attachmentId = event.data;
|
||||
alert("STUB: Attachment click id = " + attachmentId);
|
||||
app.api.get('rfcase/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
//Handle upload click
|
||||
//
|
||||
onUpload = function (event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
|
||||
var fileUpload = $("#files").get(0);
|
||||
var files = fileUpload.files;
|
||||
var fileData = new FormData();
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
fileData.append(files[i].name, files[i]);
|
||||
}
|
||||
|
||||
app.api.uploadFile('rfcaseblob/upload?rfcaseid=' + stateMap.id, fileData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
page('#!/rfcaseEdit/' + stateMap.id);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
////////////////////////////////////
|
||||
//ONAPPEND
|
||||
// Append date and time and a horizontal line to make a new entry
|
||||
//
|
||||
onAppend = function (event) {
|
||||
event.preventDefault();
|
||||
var $notes = $('#notes');
|
||||
var txt = $notes.val();
|
||||
txt += "\r\n====================\r\n";
|
||||
txt += moment().format('MMM Do YYYY H:mm A');//"Aug 28th 2017 11:01 AM"
|
||||
txt += ' Edited by ' + app.shell.stateMap.user.name;
|
||||
txt += '\r\n\r\n';
|
||||
|
||||
$notes.focus()
|
||||
.val("")
|
||||
.val(txt);
|
||||
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
|
||||
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.rfcaseEdit']({}));
|
||||
|
||||
////app.nav.setContextTitle("Case");
|
||||
|
||||
var $cbProjects = $('#rfCaseProjectId');
|
||||
var projectList = {};
|
||||
|
||||
//get projects
|
||||
app.api.get('rfcaseproject', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
|
||||
var html = '';
|
||||
|
||||
for (var i = 0, len = res.length; i < len; ++i) {
|
||||
html += ('<option value="' + res[i]['id'] + '">' + res[i]['name'] + '</option>');
|
||||
projectList[res[i]['id']] = res[i]['name'];
|
||||
}
|
||||
$cbProjects.append(html);
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("rfcases/", "Cases", "bug");
|
||||
app.nav.contextAddLink("rfcaseEdit/new", "New", "plus");
|
||||
app.nav.contextAddButton('btn-save-top', 'Save', '', onSave);
|
||||
|
||||
//#####
|
||||
//Now load the case itself
|
||||
//------------
|
||||
//id should always have a value, either a record id or the keyword 'new' for making a new object
|
||||
if (stateMap.id != 'new') {
|
||||
//case 3513 (ironically I can't see it yet)
|
||||
document.title = 'Case ' + stateMap.id;
|
||||
//fetch existing record
|
||||
app.api.get('rfcase/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
|
||||
//set the caseid header //<span class="badge badge-secondary">New</span>
|
||||
$('#caseid').html(stateMap.id);
|
||||
$('#dtcreated').html('created ' + app.utilB.epochToLocalShortDateTime(res.dtCreated));
|
||||
//fill out form
|
||||
app.utilB.formData(res);
|
||||
|
||||
//Get attachments separately
|
||||
//===============
|
||||
|
||||
app.api.get('rfcase/' + stateMap.id + '/attachments', function (attachments) {
|
||||
if (attachments.error) {
|
||||
$.gevent.publish('app-show-error', attachments.msg);
|
||||
} else {
|
||||
|
||||
//Create a list item for each attachment
|
||||
var alist = '';
|
||||
for (var x = 0; x < attachments.attach.length; x++) {
|
||||
var attachment = attachments.attach[x];
|
||||
alist += '<a target="_blank" href="/api/rfcaseblob/download/' + attachment.id + '?dlkey=' + attachments.dlkey + '" class="btn btn-default list-group-item list-group-item-action">' + attachment.name + '</a>'
|
||||
}
|
||||
|
||||
$('#attachments').html(alist);
|
||||
}
|
||||
});
|
||||
|
||||
//================
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$('#btn-upload').bind('click', onUpload);
|
||||
$('#frmUpload').removeClass('invisible');
|
||||
|
||||
} else {
|
||||
$('#btn-delete').hide();
|
||||
//select rockfish as the default project
|
||||
$cbProjects.val(44);
|
||||
//3 is the default new item priority
|
||||
$('#priority').val(3);
|
||||
|
||||
//case 3513
|
||||
document.title = 'NEW CASE';
|
||||
}
|
||||
//-------------
|
||||
//#####
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// bind actions
|
||||
$('#btn-save').bind('click', onSave);
|
||||
$('#btn-delete').bind('click', onDelete);
|
||||
$('#btn-append').bind('click', onAppend);
|
||||
};
|
||||
|
||||
|
||||
// RETURN PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
196
wwwroot/js/app.rfcases.js
Normal file
196
wwwroot/js/app.rfcases.js
Normal file
@@ -0,0 +1,196 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.rfcases = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
configModule, initModule,
|
||||
$cbProjects, $appList, $open, $priority, $search,
|
||||
projectList,
|
||||
onFilterChange, loadCases, getPriorityColorClass,
|
||||
restoreSelections;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
|
||||
|
||||
|
||||
getPriorityColorClass = function (priority) {
|
||||
switch (priority) {
|
||||
case 1:
|
||||
return 'success';
|
||||
break;
|
||||
case 2:
|
||||
return 'warning';
|
||||
break;
|
||||
case 3:
|
||||
return 'danger';
|
||||
break;
|
||||
default:
|
||||
return 'secondary';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//case 3363
|
||||
restoreSelections = function () {
|
||||
//if there are selections then restore them
|
||||
if (stateMap.savedSelections) {
|
||||
$cbProjects.val(stateMap.savedSelections.project);
|
||||
$open.prop('checked', stateMap.savedSelections.open);
|
||||
$priority.val(stateMap.savedSelections.priority);
|
||||
$search.val(stateMap.savedSelections.search);
|
||||
} else {
|
||||
//Defaults
|
||||
//select Rockfish as the default project
|
||||
$cbProjects.val(44);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
loadCases = function (projects) {
|
||||
|
||||
$appList.empty();
|
||||
|
||||
//get the filters
|
||||
// public JsonResult GetList(long? Project, bool? Open, int? Priority, string Search)
|
||||
var selectedProject = $cbProjects.val();
|
||||
var selectedOpen = $open.prop('checked')
|
||||
var selectedPriority = $priority.val();
|
||||
var selectedSearch = $search.val();
|
||||
|
||||
stateMap.savedSelections = {
|
||||
project: selectedProject,
|
||||
open: selectedOpen,
|
||||
priority: selectedPriority,
|
||||
search: selectedSearch
|
||||
}
|
||||
|
||||
if (selectedSearch) {
|
||||
selectedSearch = encodeURI(selectedSearch);
|
||||
}
|
||||
|
||||
|
||||
//case 3363 save settings here
|
||||
|
||||
var filterUrl = '?project=' + selectedProject + '&open=' + selectedOpen + '&priority=' + selectedPriority + '&search=' + selectedSearch;
|
||||
var that = this;
|
||||
//get the cases
|
||||
app.api.get('rfcase/list' + filterUrl, function (res) {
|
||||
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
|
||||
//case 3450 count
|
||||
$('#rf-list-count').empty().append(res.length+" items");
|
||||
|
||||
$.each(res, function (i, obj) {
|
||||
|
||||
var badgeClass = getPriorityColorClass(obj.priority);
|
||||
var idColumn = '<span class="rf-larger"><strong>' + obj.id + '</strong></span><span class="rf-smaller ml-2 badge badge-' + badgeClass + '">' + obj.priority + '</span>';
|
||||
|
||||
|
||||
|
||||
$appList.append("<li class='mdc-list-item'><a href=\"#!/rfcaseEdit/" + obj.id + "\">" +
|
||||
app.utilB.genListColumn(idColumn) +
|
||||
' ' +
|
||||
(selectedProject == 0 ? app.utilB.genListColumn(projects[obj.rfCaseProject_Id]) : '') +
|
||||
' ' +
|
||||
app.utilB.genListColumn(obj.title) +
|
||||
' ' +
|
||||
app.utilB.genListColumn(app.utilB.epochToLocalShortDateTime(obj.dtCreated)) +
|
||||
"</a></li>");
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
onFilterChange = function (event) {
|
||||
event.preventDefault();
|
||||
loadCases(projectList);
|
||||
return false; //prevent default
|
||||
};
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
$container.html(Handlebars.templates['app.rfcases']({}));
|
||||
|
||||
//cache dom items
|
||||
$appList = $('#rf-list');
|
||||
$cbProjects = $('#projects');
|
||||
$open = $('#open');
|
||||
$priority = $("#priority");
|
||||
$search = $("#csearch");
|
||||
|
||||
projectList = {};
|
||||
|
||||
//get projects
|
||||
app.api.get('rfcaseproject', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error', res.msg);
|
||||
} else {
|
||||
|
||||
var html = '<option value="0">All</option>';
|
||||
|
||||
for (var i = 0, len = res.length; i < len; ++i) {
|
||||
html += ('<option value="' + res[i]['id'] + '">' + res[i]['name'] + '</option>');
|
||||
projectList[res[i]['id']] = res[i]['name'];
|
||||
}
|
||||
$cbProjects.append(html);
|
||||
|
||||
|
||||
//case 3363 re-hydrate settings here
|
||||
restoreSelections();
|
||||
|
||||
//subscribe to change event
|
||||
$cbProjects.change(onFilterChange);
|
||||
$open.change(onFilterChange);
|
||||
$priority.change(onFilterChange);
|
||||
$search.change(onFilterChange);
|
||||
|
||||
|
||||
loadCases(projectList);
|
||||
}
|
||||
});
|
||||
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("rfcaseEdit/new", "New", "plus");
|
||||
};
|
||||
|
||||
//PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
101
wwwroot/js/app.rfsettings.js
Normal file
101
wwwroot/js/app.rfsettings.js
Normal file
@@ -0,0 +1,101 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.rfsettings = (function() {
|
||||
"use strict";
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var stateMap = {},
|
||||
configModule,
|
||||
onChangePassword,
|
||||
initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
///////////////////////////////
|
||||
//ONUPDATE
|
||||
//
|
||||
onChangePassword = function(event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish("app-clear-error");
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
|
||||
app.api.create(
|
||||
"user/" + app.shell.stateMap.user.id + "/changepassword",
|
||||
submitData,
|
||||
function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
} else {
|
||||
page("#!/logout");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return false; //prevent default?
|
||||
};
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function(context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function($container) {
|
||||
if (typeof $container === "undefined") {
|
||||
$container = $("#app-shell-main-content");
|
||||
}
|
||||
$container.html(Handlebars.templates["app.rfsettings"]({}));
|
||||
|
||||
// bind actions
|
||||
$("#btn-change-password").bind("click", onChangePassword);
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
|
||||
app.api.get("meta/server_version/", function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
} else {
|
||||
$("#about").append(
|
||||
"<p>Rockfish client version: " +
|
||||
app.api.RockFishVersion +
|
||||
"</p><p>Rockfish server version: " +
|
||||
res.server_version +
|
||||
"</p>"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
////app.nav.setContextTitle("Search");
|
||||
};
|
||||
|
||||
//PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
})();
|
||||
119
wwwroot/js/app.search.js
Normal file
119
wwwroot/js/app.search.js
Normal file
@@ -0,0 +1,119 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.search = (function() {
|
||||
"use strict";
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var stateMap = {},
|
||||
configModule,
|
||||
onSearch,
|
||||
initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
//ONSEARCH
|
||||
//
|
||||
onSearch = function(event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish("app-clear-error");
|
||||
|
||||
//get form data
|
||||
var query = $("#searchquery").val();
|
||||
//app.api.get('customer/' + stateMap.id, function (res) {
|
||||
//app.get('/api/search?query=querytext'
|
||||
app.api.get("search?query=" + query, function(res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish("app-show-error", res.msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
var $appList = $("#rf-list");
|
||||
$appList.empty();
|
||||
$.each(res, function(i, obj) {
|
||||
var editUrl = "";
|
||||
switch (obj.obj) {
|
||||
case "customer":
|
||||
editUrl = "customerEdit/" + obj.id;
|
||||
break;
|
||||
case "site":
|
||||
editUrl = "customerSiteEdit/" + obj.id + "/" + obj.customerId;
|
||||
break;
|
||||
case "purchase":
|
||||
editUrl = "purchaseEdit/" + obj.id + "/" + obj.site_id;
|
||||
break;
|
||||
case "license":
|
||||
editUrl = "licenseView/" + obj.id;
|
||||
break;
|
||||
default:
|
||||
alert("UNKNOWN SEARCH TYPE OBJECT RESULT: " + obj.obj + " WHUPS!");
|
||||
}
|
||||
|
||||
$appList.append(
|
||||
'<li><a href="#!/' +
|
||||
editUrl +
|
||||
'">' +
|
||||
app.utilB.genListColumn(
|
||||
obj.name + " @ " + obj.obj + "." + obj.fld
|
||||
) +
|
||||
"</a></li>"
|
||||
);
|
||||
|
||||
//cache it
|
||||
app.shell.stateMap.search_cache.has_cache = true;
|
||||
app.shell.stateMap.search_cache.html = $("#rf-list").html();
|
||||
app.shell.stateMap.search_cache.query = query;
|
||||
});
|
||||
});
|
||||
|
||||
return false; //prevent default?
|
||||
};
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function(context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function($container) {
|
||||
if (typeof $container === "undefined") {
|
||||
$container = $("#app-shell-main-content");
|
||||
}
|
||||
$container.html(Handlebars.templates["app.search"]({}));
|
||||
|
||||
// bind actions
|
||||
$("#searchbutton").bind("click", onSearch);
|
||||
|
||||
//reconstitute from last search cache
|
||||
if (app.shell.stateMap.search_cache.has_cache == true) {
|
||||
$("#rf-list").html(app.shell.stateMap.search_cache.html);
|
||||
$("#searchquery").val(app.shell.stateMap.search_cache.query);
|
||||
}
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
////app.nav.setContextTitle("Search");
|
||||
};
|
||||
|
||||
//PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
})();
|
||||
561
wwwroot/js/app.shell.js
Normal file
561
wwwroot/js/app.shell.js
Normal file
@@ -0,0 +1,561 @@
|
||||
/*
|
||||
* app.shell.js
|
||||
* Shell module for SPA
|
||||
*/
|
||||
|
||||
/*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 $, app */
|
||||
|
||||
app.shell = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
|
||||
var
|
||||
|
||||
stateMap = {
|
||||
$container: undefined,
|
||||
anchor_map: {},
|
||||
user: {
|
||||
authenticated: false,
|
||||
token: '',
|
||||
name: '',
|
||||
id: 0
|
||||
},
|
||||
apiUrl: '',
|
||||
search_cache: {
|
||||
has_cache: false
|
||||
}
|
||||
},
|
||||
tokenExpired,
|
||||
//onUPdate,
|
||||
onLogin, onLogout, onShowError, onClearError,
|
||||
initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
|
||||
|
||||
tokenExpired = function () {
|
||||
//fetch stored creds if available
|
||||
var creds = store.get('rockfish.usercreds');
|
||||
if (creds) {
|
||||
//check if token has expired
|
||||
//is the date greater than the expires date
|
||||
var rightNowUtc = new Date();
|
||||
var expDate = new Date(creds.expires * 1000);
|
||||
if (rightNowUtc > expDate) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
onLogin = function (event, login_user) {
|
||||
//store creds
|
||||
store.set('rockfish.usercreds', stateMap.user);
|
||||
//New token needs to reset lastNav
|
||||
stateMap.lastNav = new Date();
|
||||
//Go to the home page
|
||||
page('#!/customers/');
|
||||
return false;
|
||||
};
|
||||
|
||||
onLogout = function (event) {
|
||||
store.clear();
|
||||
stateMap.user.authenticated = false;
|
||||
stateMap.user.name = '';
|
||||
stateMap.user.token = '';
|
||||
stateMap.user.id = 0;
|
||||
page('#!/authenticate/');
|
||||
return false;
|
||||
};
|
||||
|
||||
// onUpdate = function (event) {
|
||||
|
||||
// window.location.reload(true);
|
||||
// return false;
|
||||
// };
|
||||
|
||||
|
||||
onShowError = function (event, msg) {
|
||||
$("#app-error-div").removeClass("d-none");
|
||||
$('#app-error-message').text(msg);
|
||||
return false;
|
||||
};
|
||||
|
||||
onClearError = function (event) {
|
||||
$("#app-error-div").addClass("d-none");
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
initModule = function ($container) {
|
||||
|
||||
document.title = 'Rockfish ' + app.api.RockFishVersion;
|
||||
|
||||
|
||||
//PRE FLIGHT CHECK
|
||||
//================
|
||||
|
||||
|
||||
|
||||
//local storage required
|
||||
if (!store.enabled) {
|
||||
alert('Local storage is not supported by your browser. Please disable "Private Mode", or upgrade to a modern browser.');
|
||||
return;
|
||||
}
|
||||
|
||||
//wait indicator for ajax functions
|
||||
$(document).ajaxStart(function () {
|
||||
|
||||
//disable all buttons
|
||||
$('.app-frm-buttons button').prop('disabled', true).addClass('disabled');
|
||||
//$('.app-frm-buttons button').attr('disabled', 'disabled');
|
||||
$("body").css("cursor", "progress");
|
||||
//add app-ajax-busy style to buttons div where user clicked
|
||||
$('.app-frm-buttons').addClass('app-ajax-busy');
|
||||
|
||||
}).ajaxStop(function () {
|
||||
|
||||
//with delay in case it's too fast to see
|
||||
setTimeout(function () {
|
||||
$('.app-frm-buttons button').prop('disabled', false).removeClass('disabled');
|
||||
//$('.app-frm-buttons button').removeAttr('disabled');
|
||||
$("body").css("cursor", "default");
|
||||
$('.app-frm-buttons').removeClass('app-ajax-busy');
|
||||
}, 250);
|
||||
|
||||
});
|
||||
|
||||
|
||||
//save on app so can call from anywhere
|
||||
// app.mdInit = mdInit;
|
||||
|
||||
// load HTML and map jQuery collections
|
||||
stateMap.$container = $container;
|
||||
$container.html(Handlebars.templates['app.shell']({}));
|
||||
|
||||
//auto hide navbar on click
|
||||
//rfac is a class only on the items that should trigger collapse
|
||||
$('.rfac').on('click', function () {
|
||||
$('.navbar-collapse').collapse('hide');
|
||||
});
|
||||
|
||||
//SEARCH
|
||||
// $('#searchbutton').bind('click', onSearch);
|
||||
|
||||
//determine API url and save it
|
||||
stateMap.apiUrl = app.utilB.getApiUrl();
|
||||
|
||||
|
||||
//fetch stored creds if available
|
||||
var creds = store.get('rockfish.usercreds');
|
||||
// if (creds) {
|
||||
|
||||
//check if token has expired
|
||||
|
||||
|
||||
if (tokenExpired()) {
|
||||
stateMap.user.authenticated = false;
|
||||
stateMap.user.name = '';
|
||||
stateMap.user.token = '';
|
||||
stateMap.user.id = 0;
|
||||
|
||||
} else {
|
||||
//Show the logout item in the menu
|
||||
$(".app-mnu-logout").removeClass("app-hidden");
|
||||
stateMap.user.authenticated = true;
|
||||
stateMap.user.name = creds.name;
|
||||
stateMap.user.token = creds.token;
|
||||
stateMap.user.id = creds.id;
|
||||
}
|
||||
//}
|
||||
|
||||
|
||||
//EVENT SUBSCRIPTIONS
|
||||
$.gevent.subscribe($container, 'app-login', onLogin);
|
||||
$.gevent.subscribe($container, 'app-logout', onLogout);
|
||||
//$.gevent.subscribe($container, 'rf-update', onUpdate);
|
||||
$.gevent.subscribe($container, 'app-show-error', onShowError);
|
||||
$.gevent.subscribe($container, 'app-clear-error', onClearError);
|
||||
|
||||
|
||||
//ROUTES
|
||||
//
|
||||
page.base('/default.htm');
|
||||
page('*', beforeUrlChange);
|
||||
page('/authenticate', authenticate);
|
||||
page('/', inbox);
|
||||
page('/reportData', reportData);
|
||||
page('/reportDataProdEmails', reportDataProdEmail);
|
||||
page('/reportDataExpires', reportDataExpires);
|
||||
page('/search', search);
|
||||
page('/logout', function () {
|
||||
$.gevent.publish('app-logout');
|
||||
});
|
||||
page('/customers', customers);
|
||||
page('/customerEdit/:id', customerEdit);
|
||||
page('/customerSites/:id', customerSites);
|
||||
page('/customerSiteEdit/:id/:cust_id', customerSiteEdit);
|
||||
page('/purchases/:id', purchases);
|
||||
page('/purchaseEdit/:id/:site_id', purchaseEdit);
|
||||
page('/license', license);
|
||||
page('/licenseTemplates', licenseTemplates);
|
||||
page('/licenseRequests', licenseRequests);
|
||||
page('/licenseRequestEdit/:id', licenseRequestEdit);
|
||||
//case 3233
|
||||
page('/licenses', licenses);
|
||||
page('/licenseView/:id', licenseView);
|
||||
page('/subscription', subscription);
|
||||
page('/subnotify', subnotify);
|
||||
page('/templates', templates);
|
||||
page('/templateEdit/:id', templateEdit);
|
||||
page('/inbox', inbox);
|
||||
page.exit('/inbox', function(ctx,next) {
|
||||
app.inbox.terminateModule();
|
||||
next();
|
||||
});
|
||||
page('/mailEdit/:mail_account/:mail_folder/:mail_id', mailEdit);
|
||||
page('/rfcases', rfcases);
|
||||
page('/rfcaseEdit/:id', rfcaseEdit);
|
||||
page('/rfsettings', rfsettings);
|
||||
page('*', notFound);
|
||||
page({
|
||||
hashbang: true
|
||||
});
|
||||
// /ROUTES
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
// End PUBLIC method /initModule/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var beforeUrlChange = function (ctx, next) {
|
||||
$.gevent.publish('app-clear-error');
|
||||
app.shell.stateMap.mediaSize = app.utilB.getMediaSize();
|
||||
|
||||
//case 3513
|
||||
document.title = 'Rockfish ' + app.api.RockFishVersion;
|
||||
|
||||
//bypass stuff below if about to logout
|
||||
if (ctx.path == '/logout') {
|
||||
return next();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
//Check authentication token to see if expired, but only if it's been a few minutes since last navigation
|
||||
if (stateMap.user.authenticated) {
|
||||
//This first bit sets the last nav in cases where it's never been set before
|
||||
//default to one hour ago in case it hasn't ever been set yet or isn't in statemap
|
||||
if (!stateMap.lastNav) {
|
||||
//Isn't this sketchy? Is this a date or a moment being set here
|
||||
stateMap.lastNav = moment().subtract(3600, 's').toDate();//60 minutes ago
|
||||
}
|
||||
|
||||
|
||||
var mNow = moment(new Date()); //todays date
|
||||
var mLastNav = moment(stateMap.lastNav); // another date
|
||||
var duration = moment.duration(mNow.diff(mLastNav));
|
||||
var secondsSinceLastNav = duration.asSeconds();
|
||||
|
||||
if (secondsSinceLastNav > 300)//have we checked in the last 5 minutes?
|
||||
{
|
||||
if (tokenExpired()) {
|
||||
stateMap.user.authenticated = false;
|
||||
}
|
||||
|
||||
}
|
||||
stateMap.lastNav = new Date();
|
||||
}
|
||||
//===============================================================
|
||||
|
||||
//Not logged in and trying to go somewhere but authenticate?
|
||||
if (!stateMap.user.authenticated) {
|
||||
//hide nav
|
||||
$("#rf-nav").hide({
|
||||
duration: 200
|
||||
});
|
||||
|
||||
|
||||
//page nav to authenticate
|
||||
if (ctx.path != '/authenticate/')
|
||||
return page('#!/authenticate/');
|
||||
|
||||
} else {
|
||||
//logged in so make sure to show toolbar here
|
||||
$("#rf-nav").show({
|
||||
duration: 200
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//TODO: Clean up this coral reef steaming mess
|
||||
//replace with a function that generates these functions since they are all (nearly) identical
|
||||
|
||||
var authenticate = function (ctx) {
|
||||
|
||||
app.authenticate.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.authenticate.initModule();
|
||||
}
|
||||
|
||||
var reportData = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('reportData');
|
||||
app.reportData.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.reportData.initModule();
|
||||
}
|
||||
|
||||
var reportDataProdEmail = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('reportData');
|
||||
app.reportDataProdEmail.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.reportDataProdEmail.initModule();
|
||||
}
|
||||
|
||||
var reportDataExpires = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('reportData');
|
||||
app.reportDataExpires.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.reportDataExpires.initModule();
|
||||
}
|
||||
|
||||
var search = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('search');
|
||||
app.search.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.search.initModule();
|
||||
}
|
||||
|
||||
var customers = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('customers');
|
||||
app.customers.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.customers.initModule();
|
||||
}
|
||||
|
||||
var customerEdit = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('customers');
|
||||
app.customerEdit.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.customerEdit.initModule();
|
||||
}
|
||||
|
||||
var customerSites = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('customers');
|
||||
app.customerSites.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.customerSites.initModule();
|
||||
}
|
||||
|
||||
var customerSiteEdit = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('customers');
|
||||
app.customerSiteEdit.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.customerSiteEdit.initModule();
|
||||
}
|
||||
|
||||
var purchases = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('customers');
|
||||
app.purchases.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.purchases.initModule();
|
||||
}
|
||||
|
||||
var purchaseEdit = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('customers');
|
||||
app.purchaseEdit.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.purchaseEdit.initModule();
|
||||
}
|
||||
|
||||
|
||||
var license = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('license');
|
||||
app.license.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.license.initModule();
|
||||
}
|
||||
|
||||
var licenseTemplates = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('license');
|
||||
app.licenseTemplates.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.licenseTemplates.initModule();
|
||||
}
|
||||
|
||||
var licenseRequests = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('license');
|
||||
app.licenseRequests.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.licenseRequests.initModule();
|
||||
}
|
||||
|
||||
var licenseRequestEdit = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('license');
|
||||
app.licenseRequestEdit.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.licenseRequestEdit.initModule();
|
||||
}
|
||||
|
||||
//case 3233
|
||||
var licenses = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('license');
|
||||
app.licenses.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.licenses.initModule();
|
||||
}
|
||||
|
||||
//case 3233
|
||||
var licenseView = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('license');
|
||||
app.licenseView.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.licenseView.initModule();
|
||||
}
|
||||
|
||||
|
||||
|
||||
var subscription = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('subscription');
|
||||
app.subscription.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.subscription.initModule();
|
||||
}
|
||||
|
||||
var subnotify = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('subscription');
|
||||
app.subnotify.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.subnotify.initModule();
|
||||
}
|
||||
|
||||
var templates = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('templates');
|
||||
app.templates.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.templates.initModule();
|
||||
}
|
||||
|
||||
var templateEdit = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('templates');
|
||||
app.templateEdit.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.templateEdit.initModule();
|
||||
}
|
||||
|
||||
|
||||
var inbox = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('inbox');
|
||||
app.inbox.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.inbox.initModule();
|
||||
}
|
||||
|
||||
var mailEdit = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('inbox');
|
||||
app.mailEdit.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.mailEdit.initModule();
|
||||
}
|
||||
|
||||
|
||||
var rfcases = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('rfcases');
|
||||
app.rfcases.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.rfcases.initModule();
|
||||
}
|
||||
|
||||
var rfcaseEdit = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('rfcases');
|
||||
app.rfcaseEdit.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.rfcaseEdit.initModule();
|
||||
}
|
||||
|
||||
var rfsettings = function (ctx) {
|
||||
app.nav.setSelectedMenuItem('rfsettings');
|
||||
app.rfsettings.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.rfsettings.initModule();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
var notFound = function (ctx) {
|
||||
app.fourohfour.configModule({
|
||||
context: ctx
|
||||
});
|
||||
app.fourohfour.initModule();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return {
|
||||
initModule: initModule,
|
||||
stateMap: stateMap
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
132
wwwroot/js/app.subnotify.js
Normal file
132
wwwroot/js/app.subnotify.js
Normal file
@@ -0,0 +1,132 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.subnotify = (function () {
|
||||
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
configModule,
|
||||
initModule,
|
||||
onSend;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
/////////////////////////
|
||||
//SEND (create draft) of renewal warning notification email
|
||||
//
|
||||
onSend = function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
//Gather purchase id's
|
||||
var s = $(this).data("purchaseidlist");
|
||||
|
||||
if(s==undefined || s==null){
|
||||
return false;
|
||||
}
|
||||
|
||||
//Convert string of comma separate numeric values to numeric array
|
||||
var ids = new Array();
|
||||
if (typeof s == 'string') {
|
||||
ids = s.split(",");
|
||||
var arrayLength = ids.length;
|
||||
for (var i = 0; i < arrayLength; i++) {
|
||||
ids[i] = parseInt(ids[i], 10);
|
||||
}
|
||||
} else {
|
||||
//it's a number
|
||||
ids[0] = s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//post to a route that will make the draft emails then tag the purchase as notified
|
||||
app.api.create('subscription/sendnotify', ids, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
page('#!/subnotify');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return false; //prevent default
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.subnotify']({}));
|
||||
|
||||
//fetch data
|
||||
app.api.get('subscription/notifylist', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
|
||||
//get the list ul
|
||||
var $appList = $('#rf-list');
|
||||
$appList.empty();
|
||||
var displayedItems = 0;
|
||||
$.each(res, function (i, obj) {
|
||||
$appList.append("<li>" +
|
||||
app.utilB.genListColumnNoLink(obj.customer + ' -> ') +
|
||||
' ' +
|
||||
app.utilB.genListColumnNoLink(obj.purchasenames) +
|
||||
' ' +
|
||||
app.utilB.genListColumnNoLink("<span class='RFSEND mdi mdi-cube-send btn btn-sm btn-outline-primary' data-purchaseidlist='" + obj.purchaseidlist.toString() + "'>Send</span>") +
|
||||
"</li>");
|
||||
|
||||
displayedItems++;
|
||||
});
|
||||
|
||||
if(displayedItems==0){
|
||||
$appList.append('<li>NO RENEWALS IMMINENT - ' + moment().format('YYYY-MM-DD LT') + '</li>');
|
||||
}
|
||||
|
||||
|
||||
//event handler for buttons added dynamically
|
||||
$('.RFSEND').bind('click', onSend);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("subscription/", "Subscriptions", "basket");
|
||||
|
||||
};
|
||||
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
69
wwwroot/js/app.subscription.js
Normal file
69
wwwroot/js/app.subscription.js
Normal file
@@ -0,0 +1,69 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.subscription = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
|
||||
stateMap = {},
|
||||
configModule,
|
||||
initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
$container.html(Handlebars.templates['app.subscription']({}));
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
////app.nav.setContextTitle("Subscriptions");
|
||||
|
||||
var $appList = $('#rf-list');
|
||||
$appList.empty();
|
||||
$appList.append('<ul class="list-group">');
|
||||
$appList.append("<li><a class=\"list-group-item\" href=\"#!/subnotify/\">" + app.utilB.genListColumn("Notify users with imminent expiring subscriptions") + "</a></li>");
|
||||
$appList.append("<li><a class=\"list-group-item\" href=\"#!/reportDataExpires/\">" + app.utilB.genListColumn("Show subscriptions by expiry") + "</a></li>");
|
||||
$appList.append("<li><a class=\"list-group-item\" href=\"#!/reportDataProdEmails/\">" + app.utilB.genListColumn("Build email address CSV by product code") + "</a></li>");
|
||||
$appList.append('</ul>');
|
||||
//not implemented yet
|
||||
// $appList.append("<li><a href=\"#!/subrenew/\">" + app.utilB.genListColumn("Renew") + "</a></li>");
|
||||
|
||||
|
||||
};
|
||||
|
||||
//PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
141
wwwroot/js/app.templateEdit.js
Normal file
141
wwwroot/js/app.templateEdit.js
Normal file
@@ -0,0 +1,141 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.templateEdit = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
onSave, onDelete,
|
||||
configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
|
||||
//ONSAVE
|
||||
//
|
||||
onSave = function (event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
|
||||
//get form data
|
||||
var formData = $("form").serializeArray({
|
||||
checkboxesAsBools: true
|
||||
});
|
||||
|
||||
var submitData = app.utilB.objectifyFormDataArray(formData);
|
||||
|
||||
//is this a new record?
|
||||
if (stateMap.id != 'new') {
|
||||
//put id into the form data
|
||||
submitData.id = stateMap.id;
|
||||
|
||||
|
||||
app.api.update('textTemplate', submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//it's a new record - create
|
||||
app.api.create('textTemplate', submitData, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
page('#!/templateEdit/' + res.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
//ONDELETE
|
||||
//
|
||||
onDelete = function (event) {
|
||||
event.preventDefault();
|
||||
$.gevent.publish('app-clear-error');
|
||||
|
||||
var r = confirm("Are you sure you want to delete this record?");
|
||||
if (r == true) {
|
||||
app.api.remove('textTemplate/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//deleted, return to list
|
||||
page('#!/templates');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false; //prevent default?
|
||||
};
|
||||
|
||||
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
|
||||
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
|
||||
$container.html(Handlebars.templates['app.templateEdit']({}));
|
||||
|
||||
//id should always have a value, either a record id or the keyword 'new' for making a new object
|
||||
if (stateMap.id != 'new') {
|
||||
//fetch existing record
|
||||
app.api.get('textTemplate/' + stateMap.id, function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
//fill out form
|
||||
app.utilB.formData(res);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
$('#btn-delete').hide();
|
||||
}
|
||||
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("templates/", "Templates", "layers");
|
||||
|
||||
// bind actions
|
||||
$('#btn-save').bind('click', onSave);
|
||||
$('#btn-delete').bind('click', onDelete);
|
||||
};
|
||||
|
||||
|
||||
// RETURN PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
68
wwwroot/js/app.templates.js
Normal file
68
wwwroot/js/app.templates.js
Normal file
@@ -0,0 +1,68 @@
|
||||
/*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 $, app */
|
||||
|
||||
app.templates = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
stateMap = {},
|
||||
configModule, initModule;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
//CONFIGMODULE
|
||||
//
|
||||
configModule = function (context) {
|
||||
stateMap.context = context.context;
|
||||
if (stateMap.context.params.id) {
|
||||
stateMap.id = stateMap.context.params.id;
|
||||
}
|
||||
};
|
||||
|
||||
//INITMODULE
|
||||
//
|
||||
initModule = function ($container) {
|
||||
if (typeof $container === 'undefined') {
|
||||
$container = $('#app-shell-main-content');
|
||||
}
|
||||
$container.html(Handlebars.templates['app.templates']({}));
|
||||
|
||||
app.api.get('texttemplate/list', function (res) {
|
||||
if (res.error) {
|
||||
$.gevent.publish('app-show-error',res.msg);
|
||||
} else {
|
||||
var $appList = $('#rf-list');
|
||||
$.each(res, function (i, obj) {
|
||||
$appList.append("<li><a href=\"#!/templateEdit/" + obj.id + "\">" +
|
||||
app.utilB.genListColumn(obj.name) +
|
||||
"</a></li>")
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//Context menu
|
||||
app.nav.contextClear();
|
||||
app.nav.contextAddLink("templateEdit/new", "New", "plus");
|
||||
};
|
||||
|
||||
//PUBLIC METHODS
|
||||
//
|
||||
return {
|
||||
configModule: configModule,
|
||||
initModule: initModule
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
80
wwwroot/js/app.util.js
Normal file
80
wwwroot/js/app.util.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* app.util.js
|
||||
* General JavaScript utilities
|
||||
*
|
||||
* Michael S. Mikowski - mmikowski at gmail dot com
|
||||
* These are routines I have created, compiled, and updated
|
||||
* since 1998, with inspiration from around the web.
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
*/
|
||||
|
||||
/*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 $, app */
|
||||
|
||||
app.util = (function () {
|
||||
var makeError, setConfigMap;
|
||||
|
||||
// Begin Public constructor /makeError/
|
||||
// Purpose: a convenience wrapper to create an error object
|
||||
// Arguments:
|
||||
// * name_text - the error name
|
||||
// * msg_text - long error message
|
||||
// * data - optional data attached to error object
|
||||
// Returns : newly constructed error object
|
||||
// Throws : none
|
||||
//
|
||||
makeError = function ( name_text, msg_text, data ) {
|
||||
var error = new Error();
|
||||
error.name = name_text;
|
||||
error.message = msg_text;
|
||||
|
||||
if ( data ){ error.data = data; }
|
||||
|
||||
return error;
|
||||
};
|
||||
// End Public constructor /makeError/
|
||||
|
||||
// Begin Public method /setConfigMap/
|
||||
// Purpose: Common code to set configs in feature modules
|
||||
// Arguments:
|
||||
// * input_map - map of key-values to set in config
|
||||
// * settable_map - map of allowable keys to set
|
||||
// * config_map - map to apply settings to
|
||||
// Returns: true
|
||||
// Throws : Exception if input key not allowed
|
||||
//
|
||||
setConfigMap = function ( arg_map ){
|
||||
var
|
||||
input_map = arg_map.input_map,
|
||||
settable_map = arg_map.settable_map,
|
||||
config_map = arg_map.config_map,
|
||||
key_name, error;
|
||||
|
||||
for ( key_name in input_map ){
|
||||
if ( input_map.hasOwnProperty( key_name ) ){
|
||||
if ( settable_map.hasOwnProperty( key_name ) ){
|
||||
config_map[key_name] = input_map[key_name];
|
||||
}
|
||||
else {
|
||||
error = makeError( 'Bad Input',
|
||||
'Setting config key |' + key_name + '| is not supported'
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// End Public method /setConfigMap/
|
||||
|
||||
return {
|
||||
makeError : makeError,
|
||||
setConfigMap : setConfigMap
|
||||
};
|
||||
}());
|
||||
334
wwwroot/js/app.utilB.js
Normal file
334
wwwroot/js/app.utilB.js
Normal file
@@ -0,0 +1,334 @@
|
||||
/**
|
||||
* app.utilB.js
|
||||
* JavaScript browser utilities
|
||||
*
|
||||
*/
|
||||
|
||||
/*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 $, app, getComputedStyle */
|
||||
|
||||
app.utilB = (function () {
|
||||
'use strict';
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
configMap = {
|
||||
regex_encode_html: /[&"'><]/g,
|
||||
regex_encode_noamp: /["'><]/g,
|
||||
html_encode_map: {
|
||||
'&': '&',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
'>': '>',
|
||||
'<': '<'
|
||||
}
|
||||
},
|
||||
|
||||
decodeHtml, encodeHtml, getEmSize, getApiUrl, getUrlParams, formData, objectifyFormDataArray,
|
||||
getMediaSize, prepareObjectForClient, fixDatesToStrings,
|
||||
epochToShortDate, epochToLocalShortDate, epochToLocalShortDateTime, getCurrentDateTimeAsEpoch,
|
||||
genListColumn,
|
||||
genListColumnNoLink, autoComplete, prepareObjectDatesForServer,
|
||||
fixStringToServerDate;
|
||||
|
||||
configMap.encode_noamp_map = $.extend({}, configMap.html_encode_map);
|
||||
delete configMap.encode_noamp_map['&'];
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
|
||||
|
||||
// Begin decodeHtml
|
||||
// Decodes HTML entities in a browser-friendly way
|
||||
// See http://stackoverflow.com/questions/1912501/\
|
||||
// unescape-html-entities-in-javascript
|
||||
//
|
||||
decodeHtml = function (str) {
|
||||
return $('<div/>').html(str || '').text();
|
||||
};
|
||||
// End decodeHtml
|
||||
|
||||
|
||||
// Begin encodeHtml
|
||||
// This is single pass encoder for html entities and handles
|
||||
// an arbitrary number of characters
|
||||
//
|
||||
encodeHtml = function (input_arg_str, exclude_amp) {
|
||||
var
|
||||
input_str = String(input_arg_str),
|
||||
regex, lookup_map;
|
||||
|
||||
if (exclude_amp) {
|
||||
lookup_map = configMap.encode_noamp_map;
|
||||
regex = configMap.regex_encode_noamp;
|
||||
} else {
|
||||
lookup_map = configMap.html_encode_map;
|
||||
regex = configMap.regex_encode_html;
|
||||
}
|
||||
return input_str.replace(regex,
|
||||
function (match, name) {
|
||||
return lookup_map[match] || '';
|
||||
}
|
||||
);
|
||||
};
|
||||
// End encodeHtml
|
||||
|
||||
// Begin getEmSize
|
||||
// returns size of ems in pixels
|
||||
//
|
||||
getEmSize = function (elem) {
|
||||
return Number(
|
||||
getComputedStyle(elem, '').fontSize.match(/\d*\.?\d*/)[0]
|
||||
);
|
||||
};
|
||||
// End getEmSize
|
||||
|
||||
|
||||
//Begin getApiUrl
|
||||
//returns url for api methods by parsing current window location url
|
||||
//
|
||||
getApiUrl = function () {
|
||||
var u = window.location.href.replace(window.location.hash, "").replace('default.htm', '') + "api/";
|
||||
//is it a dev local url?
|
||||
if (u.indexOf("localhost:8080") != -1) {
|
||||
u = u.replace("8080", "8081");
|
||||
}
|
||||
// End getApiUrl
|
||||
|
||||
//fix for random recurrence of extraneous ? on iPhone when using api
|
||||
//(Cannot post to http://gl-gztw.rhcloud.com/?api/list (404))
|
||||
u = u.replace("?", "");
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Begin formData
|
||||
// Get or set all form fields
|
||||
//
|
||||
formData = function (data) {
|
||||
|
||||
//fix dates into strings
|
||||
prepareObjectForClient(data);
|
||||
|
||||
|
||||
var inps = $(":input").get();
|
||||
|
||||
if (typeof data != "object") {
|
||||
// return all data
|
||||
data = {};
|
||||
|
||||
$.each(inps, function () {
|
||||
if (this.name && (this.checked || /select|textarea/i.test(this.nodeName) || /text|hidden|password/i.test(this.type))) {
|
||||
data[this.name] = $(this).val();
|
||||
}
|
||||
});
|
||||
return data;
|
||||
} else {
|
||||
$.each(inps, function () {
|
||||
if (this.name && data[this.name]) {
|
||||
if (this.type == "checkbox" || this.type == "radio") {
|
||||
$(this).prop("checked", (data[this.name]));
|
||||
} else {
|
||||
$(this).val(data[this.name]);
|
||||
}
|
||||
} else if (this.type == "checkbox") {
|
||||
$(this).prop("checked", false);
|
||||
}
|
||||
});
|
||||
return $(this);
|
||||
}
|
||||
};
|
||||
// End formdata
|
||||
|
||||
// Begin getMediaSize
|
||||
// Retrieves results of css media query in hidden pseudo element
|
||||
// :after body element
|
||||
//objectifyFormDataArray
|
||||
getMediaSize = function () {
|
||||
return window.getComputedStyle(document.querySelector('body'), ':after').getPropertyValue('content').replace(/\"/g, '');
|
||||
};
|
||||
// End getMediaSize
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Begin objectifyFormDataArray
|
||||
//takes name value form input pairs in array and turns into a keyed object
|
||||
//suitable for sending as json object
|
||||
//
|
||||
objectifyFormDataArray = function (arr) {
|
||||
var rv = {};
|
||||
for (var i = 0; i < arr.length; ++i)
|
||||
if (arr[i] !== undefined) {
|
||||
rv[arr[i].name] = arr[i].value.trim();//case 3205 added trim
|
||||
}
|
||||
return prepareObjectDatesForServer(rv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Prepare an object for server needed format before submission
|
||||
//called by objectifyFormDataArray
|
||||
prepareObjectDatesForServer = function (obj) {
|
||||
if (Array.isArray(obj)) {
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
fixStringToServerDate(obj[i]);
|
||||
}
|
||||
} else {
|
||||
fixStringToServerDate(obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
//
|
||||
|
||||
//Turn string date fields from client into server compatible format (Unix epoch like this: 1498262400 1499904000)
|
||||
fixStringToServerDate = function (obj) {
|
||||
var keys = Object.keys(obj);
|
||||
keys.forEach(function (key) {
|
||||
if (key.endsWith('Date') || key.startsWith('dt')) {
|
||||
var value = obj[key];
|
||||
if (value == null) {
|
||||
obj[key] = '';
|
||||
} else {
|
||||
//this is the sample format we will see: 2017-07-13
|
||||
//TODO: is this assuming UTC?
|
||||
obj[key] = moment.utc(value, "YYYY-MM-DD").unix();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//This function exists to change the properties of the passed in object
|
||||
//to values compatible with jquery form filling functions (mostly dates to strings for now)
|
||||
//
|
||||
prepareObjectForClient = function (obj) {
|
||||
if (Array.isArray(obj)) {
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
fixDatesToStrings(obj[i]);
|
||||
}
|
||||
} else {
|
||||
fixDatesToStrings(obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
//
|
||||
|
||||
//Turn date fields of object coming from db into stringified values for consumption by client
|
||||
//turn null dates into empty strings and iso date values into strings in iso format
|
||||
fixDatesToStrings = function (obj) {
|
||||
var keys = Object.keys(obj);
|
||||
keys.forEach(function (key) {
|
||||
if (key.endsWith('Date') || key.startsWith('dt')) {
|
||||
var value = obj[key];
|
||||
if (value == null) {
|
||||
obj[key] = '';
|
||||
} else {
|
||||
//Now with sqlite they come and go as unix epoch seconds
|
||||
//needs to be yyyy-MM-dd
|
||||
obj[key] = moment.utc(new Date(value * 1000)).format("YYYY-MM-DD");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//
|
||||
|
||||
//Turn date values coming in from server into displayable short date format
|
||||
//used to display dates in various lists (where the source epoch is already localized)
|
||||
epochToShortDate = function (epoch) {
|
||||
if (epoch == null || epoch == 0) return '';
|
||||
return moment.utc(new Date(epoch * 1000)).format("YYYY-MM-DD");
|
||||
}
|
||||
//
|
||||
|
||||
//LOCAL VERSION: Turn date values coming in from server into displayable short date format
|
||||
//used to display dates in various lists where the source epoch is in UTC
|
||||
epochToLocalShortDate = function (epoch) {
|
||||
if (epoch == null || epoch == 0) return '';
|
||||
var utdate = moment.utc(new Date(epoch * 1000));
|
||||
var localdate = moment(utdate).local();
|
||||
return localdate.format("YYYY-MM-DD");
|
||||
}
|
||||
|
||||
//LOCAL VERSION: Turn date values coming in from server into displayable short date AND TIME format
|
||||
//used to display dates in various lists where the source epoch is in UTC
|
||||
epochToLocalShortDateTime = function (epoch) {
|
||||
if (epoch == null || epoch == 0) return '';
|
||||
var utdate = moment.utc(new Date(epoch * 1000));
|
||||
var localdate = moment(utdate).local();
|
||||
return localdate.format("YYYY-MM-DD LT");
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//Get current date and time as a utc unix epoch
|
||||
getCurrentDateTimeAsEpoch = function () {
|
||||
return moment().utc().unix();
|
||||
}
|
||||
|
||||
// Begin genListColumn
|
||||
// This function is used to demarcate 'columns' of fields in basic list forms by wrapping each column field in html
|
||||
//
|
||||
genListColumn = function (val) {
|
||||
return '<span class="rf-list-column">' + val + '</span>'
|
||||
};
|
||||
// End genListColumn
|
||||
|
||||
// Begin genListColumnNoLink
|
||||
// This function is used to demarcate and style 'columns' of fields in basic list forms by wrapping each column field in html
|
||||
// that are not link columns
|
||||
genListColumnNoLink = function (val) {
|
||||
return '<span class="rf-list-column-nolink">' + val + '</span>'
|
||||
};
|
||||
// End genListColumn
|
||||
|
||||
|
||||
// Begin autoComplete
|
||||
// This function is used to attach an autocomplete method to an input
|
||||
//
|
||||
autoComplete = function (controlId, acGetToken) {
|
||||
$('#' + controlId).autocomplete({
|
||||
serviceUrl: app.shell.stateMap.apiUrl + 'autocomplete',
|
||||
params: {
|
||||
acget: acGetToken
|
||||
},
|
||||
ajaxSettings: {
|
||||
headers: app.api.getAuthHeaderObject()
|
||||
}
|
||||
});
|
||||
};
|
||||
// End autoComplete
|
||||
|
||||
|
||||
|
||||
// export methods
|
||||
return {
|
||||
decodeHtml: decodeHtml,
|
||||
encodeHtml: encodeHtml,
|
||||
getEmSize: getEmSize,
|
||||
getApiUrl: getApiUrl,
|
||||
getUrlParams: getUrlParams,
|
||||
formData: formData,
|
||||
getMediaSize: getMediaSize,
|
||||
objectifyFormDataArray: objectifyFormDataArray,
|
||||
epochToShortDate: epochToShortDate,
|
||||
epochToLocalShortDate: epochToLocalShortDate,
|
||||
epochToLocalShortDateTime: epochToLocalShortDateTime,
|
||||
getCurrentDateTimeAsEpoch: getCurrentDateTimeAsEpoch,
|
||||
genListColumn: genListColumn,
|
||||
genListColumnNoLink: genListColumnNoLink,
|
||||
autoComplete: autoComplete
|
||||
};
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
}());
|
||||
23
wwwroot/js/index.js
Normal file
23
wwwroot/js/index.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* app.js
|
||||
* Root namespace 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 $, app */
|
||||
|
||||
var app = (function () {
|
||||
'use strict';
|
||||
var initModule = function ( $container ) {
|
||||
app.api.initModule();
|
||||
// app.model.initModule();
|
||||
app.shell.initModule( $container );
|
||||
};
|
||||
|
||||
return { initModule: initModule };
|
||||
}());
|
||||
1240
wwwroot/js/lib/handlebars.runtime-v4.0.5.js
Normal file
1240
wwwroot/js/lib/handlebars.runtime-v4.0.5.js
Normal file
File diff suppressed because it is too large
Load Diff
8
wwwroot/js/lib/jquery.autocomplete.min.js
vendored
Normal file
8
wwwroot/js/lib/jquery.autocomplete.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
154
wwwroot/js/lib/jquery.event.gevent.js
Normal file
154
wwwroot/js/lib/jquery.event.gevent.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* jQuery global custom event plugin (gevent)
|
||||
*
|
||||
* Copyright (c) 2013 Michael S. Mikowski
|
||||
* (mike[dot]mikowski[at]gmail[dotcom])
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 2
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* Versions
|
||||
* 0.1.5 - initial release
|
||||
* 0.1.6 - enhanced publishEvent (publish) method pass
|
||||
* a non-array variable as the second argument
|
||||
* to a subscribed function (the first argument
|
||||
* is always the event object).
|
||||
* 0.1.7-10, 0.2.0
|
||||
* - documentation changes
|
||||
* 1.0.2 - cleaned-up logic, bumped version
|
||||
* 1.1.2 - added keywords
|
||||
*
|
||||
*/
|
||||
|
||||
/*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 jQuery*/
|
||||
|
||||
(function ( $ ) {
|
||||
'use strict';
|
||||
$.gevent = (function () {
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
subscribeEvent, publishEvent, unsubscribeEvent,
|
||||
$customSubMap = {}
|
||||
;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN PUBLIC METHODS -------------------
|
||||
// BEGIN public method /publishEvent/
|
||||
// Example :
|
||||
// $.gevent.publish(
|
||||
// 'spa-model-msg-receive',
|
||||
// [ { user : 'fred', msg : 'Hi gang' } ]
|
||||
// );
|
||||
// Purpose :
|
||||
// Publish an event with an optional list of arguments
|
||||
// which a subscribed handler will receive after the event object.
|
||||
// Arguments (positional)
|
||||
// * 0 ( event_name ) - The global event name
|
||||
// * 1 ( data ) - Optional data to be passed as argument(s)
|
||||
// to subscribed functions after the event
|
||||
// object. Provide an array for multiple
|
||||
// arguments.
|
||||
// Throws : none
|
||||
// Returns : none
|
||||
//
|
||||
publishEvent = function () {
|
||||
var arg_list = [],
|
||||
arg_count, event_name,
|
||||
event_obj, data, data_list;
|
||||
|
||||
arg_list = arg_list.slice.call( arguments, 0 );
|
||||
arg_count = arg_list.length;
|
||||
|
||||
if ( arg_count === 0 ) { return false; }
|
||||
|
||||
event_name = arg_list.shift();
|
||||
event_obj = $customSubMap[ event_name ];
|
||||
|
||||
if ( ! event_obj ) { return false; }
|
||||
|
||||
if ( arg_count > 1 ) {
|
||||
data = arg_list.shift();
|
||||
data_list = $.isArray( data ) ? data : [ data ];
|
||||
}
|
||||
else {
|
||||
data_list = [];
|
||||
}
|
||||
|
||||
event_obj.trigger( event_name, data_list );
|
||||
return true;
|
||||
};
|
||||
// END public method /publishEvent/
|
||||
|
||||
// BEGIN public method /subscribeEvent/
|
||||
// Example :
|
||||
// $.gevent.subscribe(
|
||||
// $( '#msg' ),
|
||||
// 'spa-msg-receive',
|
||||
// onModelMsgReceive
|
||||
// );
|
||||
// Purpose :
|
||||
// Subscribe a function to a published event on a jQuery collection
|
||||
// Arguments (positional)
|
||||
// * 0 ( $collection ) - The jQuery collection on which to bind event
|
||||
// * 1 ( event_name ) - The global event name
|
||||
// * 2 ( fn ) - The function to bound to the event on the collection
|
||||
// Throws : none
|
||||
// Returns : none
|
||||
//
|
||||
subscribeEvent = function ( $collection, event_name, fn ) {
|
||||
$collection.on( event_name, fn );
|
||||
|
||||
if ( $customSubMap[ event_name ] ) {
|
||||
$customSubMap[ event_name ]
|
||||
= $customSubMap[ event_name ].add( $collection );
|
||||
}
|
||||
else {
|
||||
$customSubMap[ event_name ] = $collection;
|
||||
}
|
||||
};
|
||||
// END public method /subscribeEvent/
|
||||
|
||||
// BEGIN public method /unsubscribeEvent/
|
||||
// Example :
|
||||
// $.gevent.unsubscribe(
|
||||
// $( '#msg' ),
|
||||
// 'spa-model-msg-receive'
|
||||
// );
|
||||
// Purpose :
|
||||
// Remove a binding for the named event on a provided collection
|
||||
// Arguments (positional)
|
||||
// * 0 ( $collection ) - The jQuery collection on which to bind event
|
||||
// * 1 ( event_name ) - The global event name
|
||||
// Throws : none
|
||||
// Returns : none
|
||||
//
|
||||
unsubscribeEvent = function ( $collection, event_name ) {
|
||||
if ( ! $customSubMap[ event_name ] ){ return false; }
|
||||
|
||||
$customSubMap[ event_name ]
|
||||
= $customSubMap[ event_name ].not( $collection );
|
||||
|
||||
if ( $customSubMap[ event_name ].length === 0 ){
|
||||
delete $customSubMap[ event_name ];
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
// END public method /unsubscribeEvent/
|
||||
//------------------- END PUBLIC METHODS ---------------------
|
||||
|
||||
// return public methods
|
||||
return {
|
||||
publish : publishEvent,
|
||||
subscribe : subscribeEvent,
|
||||
unsubscribe : unsubscribeEvent
|
||||
};
|
||||
}());
|
||||
}( jQuery ));
|
||||
|
||||
783
wwwroot/js/lib/jquery.event.ue.js
Normal file
783
wwwroot/js/lib/jquery.event.ue.js
Normal file
@@ -0,0 +1,783 @@
|
||||
/*
|
||||
* jQuery plugin for unified mouse and touch events
|
||||
*
|
||||
* Copyright (c) 2013 Michael S. Mikowski
|
||||
* (mike[dot]mikowski[at]gmail[dotcom])
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 2
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* Versions
|
||||
* 1.2.0 - ignore_class => ignore_select, now defaults to ''
|
||||
* 1.1.9 - Fixed ue-test.html demo to scale properly
|
||||
* 1.1.8 - Removed prevent default from non-ue events
|
||||
* 1.1.7 - Corrected desktop zoom motion description
|
||||
* 1.1.0-5 - No code changes. Updated npm keywords. Fixed typos.
|
||||
* Bumped version to represent maturity and stability.
|
||||
* 0.6.1 - Change px_radius from 5 to 10 pixels
|
||||
* 0.6.0 - Added px_tdelta_x and px_tdelta_y for deltas from start
|
||||
* - Fixed onheld and drag conflicts
|
||||
* 0.5.0 - Updated docs, removed cruft, updated for jslint,
|
||||
* updated test page (zoom)
|
||||
* 0.4.3 - Removed fatal execption possibility if originalEvent
|
||||
* is not defined on event object
|
||||
* 0.4.2 - Updated documentation
|
||||
* 0.3.2 - Updated to jQuery 1.9.1.
|
||||
* Confirmed 1.7.0-1.9.1 compatibility.
|
||||
* 0.3.1 - Change for jQuery plugins site
|
||||
* 0.3.0 - Initial jQuery plugin site release
|
||||
* - Replaced scrollwheel zoom with drag motion.
|
||||
* This resolved a conflict with scrollable areas.
|
||||
*
|
||||
*/
|
||||
|
||||
/*jslint browser : true, continue : true,
|
||||
devel : true, indent : 2, maxerr : 50,
|
||||
newcap : true, plusplus : true, regexp : true,
|
||||
sloppy : true, vars : false, white : true
|
||||
*/
|
||||
/*global jQuery */
|
||||
|
||||
(function ( $ ) {
|
||||
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
||||
var
|
||||
$Special = $.event.special, // Shortcut for special event
|
||||
motionMapMap = {}, // Map of pointer motions by cursor
|
||||
isMoveBound = false, // Flag if move handlers bound
|
||||
pxPinchZoom = -1, // Distance between pinch-zoom points
|
||||
optionKey = 'ue_bound', // Data key for storing options
|
||||
doDisableMouse = false, // Flag to discard mouse input
|
||||
defaultOptMap = { // Default option map
|
||||
bound_ns_map : {}, // Map of bound namespaces e.g.
|
||||
// bound_ns_map.utap.fred
|
||||
px_radius : 10, // Tolerated distance before dragstart
|
||||
ignore_select : '', // Selector of elements to ignore (e.g. :input)
|
||||
max_tap_ms : 200, // Maximum time allowed for tap
|
||||
min_held_ms : 300 // Minimum time require for long-press
|
||||
},
|
||||
|
||||
callbackList = [], // global callback stack
|
||||
zoomMouseNum = 1, // multiplier for mouse zoom
|
||||
zoomTouchNum = 4, // multiplier for touch zoom
|
||||
|
||||
boundList, Ue,
|
||||
motionDragId, motionHeldId, motionDzoomId,
|
||||
motion1ZoomId, motion2ZoomId,
|
||||
|
||||
checkMatchVal, removeListVal, pushUniqVal, makeListPlus,
|
||||
fnHeld, fnMotionStart, fnMotionMove,
|
||||
fnMotionEnd, onMouse, onTouch
|
||||
;
|
||||
//----------------- END MODULE SCOPE VARIABLES ---------------
|
||||
|
||||
//------------------- BEGIN UTILITY METHODS ------------------
|
||||
// Begin utiltity /makeListPlus/
|
||||
// Returns an array with much desired methods:
|
||||
// * remove_val(value) : remove element that matches
|
||||
// the provided value. Returns number of elements
|
||||
// removed.
|
||||
// * match_val(value) : shows if a value exists
|
||||
// * push_uniq(value) : pushes a value onto the stack
|
||||
// iff it does not already exist there
|
||||
// Note: the reason I need this is to compare objects to
|
||||
// objects (perhaps jQuery has something similar?)
|
||||
checkMatchVal = function ( data ) {
|
||||
var match_count = 0, idx;
|
||||
for ( idx = this.length; idx; 0 ) {
|
||||
if ( this[--idx] === data ) { match_count++; }
|
||||
}
|
||||
return match_count;
|
||||
};
|
||||
removeListVal = function ( data ) {
|
||||
var removed_count = 0, idx;
|
||||
for ( idx = this.length; idx; 0 ) {
|
||||
if ( this[--idx] === data ) {
|
||||
this.splice(idx, 1);
|
||||
removed_count++;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
return removed_count;
|
||||
};
|
||||
pushUniqVal = function ( data ) {
|
||||
if ( checkMatchVal.call(this, data ) ) { return false; }
|
||||
this.push( data );
|
||||
return true;
|
||||
};
|
||||
// primary utility
|
||||
makeListPlus = function ( input_list ) {
|
||||
if ( input_list && $.isArray(input_list) ) {
|
||||
if ( input_list.remove_val ) {
|
||||
console.warn( 'The array appears to already have listPlus capabilities' );
|
||||
return input_list;
|
||||
}
|
||||
}
|
||||
else {
|
||||
input_list = [];
|
||||
}
|
||||
input_list.remove_val = removeListVal;
|
||||
input_list.match_val = checkMatchVal;
|
||||
input_list.push_uniq = pushUniqVal;
|
||||
|
||||
return input_list;
|
||||
};
|
||||
// End utility /makeListPlus/
|
||||
//-------------------- END UTILITY METHODS -------------------
|
||||
|
||||
//--------------- BEGIN JQUERY SPECIAL EVENTS ----------------
|
||||
// Unique array for bound objects
|
||||
boundList = makeListPlus();
|
||||
|
||||
// Begin define special event handlers
|
||||
Ue = {
|
||||
setup : function( data, name_list, bind_fn ) {
|
||||
var
|
||||
this_el = this,
|
||||
$to_bind = $(this_el),
|
||||
seen_map = {},
|
||||
option_map, idx, namespace_key, ue_namespace_code, namespace_list
|
||||
;
|
||||
|
||||
// jslint hack to allow unused arguments
|
||||
if ( data && bind_fn ) { console.log( 'unused arguments' ); }
|
||||
|
||||
// if previous related event bound do not rebind, but do add to
|
||||
// type of event bound to this element, if not already noted
|
||||
if ( $.data( this, optionKey ) ) { return; }
|
||||
|
||||
option_map = {};
|
||||
$.extend( true, option_map, defaultOptMap );
|
||||
$.data( this_el, optionKey, option_map );
|
||||
|
||||
namespace_list = makeListPlus(name_list.slice(0));
|
||||
if ( ! namespace_list.length
|
||||
|| namespace_list[0] === ""
|
||||
) { namespace_list = ["000"]; }
|
||||
|
||||
NSPACE_00:
|
||||
for ( idx = 0; idx < namespace_list.length; idx++ ) {
|
||||
namespace_key = namespace_list[idx];
|
||||
|
||||
if ( ! namespace_key ) { continue NSPACE_00; }
|
||||
if ( seen_map.hasOwnProperty(namespace_key) ) { continue NSPACE_00; }
|
||||
|
||||
seen_map[namespace_key] = true;
|
||||
|
||||
ue_namespace_code = '.__ue' + namespace_key;
|
||||
|
||||
$to_bind.bind( 'mousedown' + ue_namespace_code, onMouse );
|
||||
$to_bind.bind( 'touchstart' + ue_namespace_code, onTouch );
|
||||
}
|
||||
|
||||
boundList.push_uniq( this_el ); // record as bound element
|
||||
|
||||
if ( ! isMoveBound ) {
|
||||
// console.log('first element bound - adding global binds');
|
||||
$(document).bind( 'mousemove.__ue', onMouse );
|
||||
$(document).bind( 'touchmove.__ue', onTouch );
|
||||
$(document).bind( 'mouseup.__ue' , onMouse );
|
||||
$(document).bind( 'touchend.__ue' , onTouch );
|
||||
$(document).bind( 'touchcancel.__ue', onTouch );
|
||||
isMoveBound = true;
|
||||
}
|
||||
},
|
||||
|
||||
// arg_map.type = string - name of event to bind
|
||||
// arg_map.data = poly - whatever (optional) data was passed when binding
|
||||
// arg_map.namespace = string - A sorted, dot-delimited list of namespaces
|
||||
// specified when binding the event
|
||||
// arg_map.handler = fn - the event handler the developer wishes to be bound
|
||||
// to the event. This function should be called whenever the event
|
||||
// is triggered
|
||||
// arg_map.guid = number - unique ID for event handler, provided by jQuery
|
||||
// arg_map.selector = string - selector used by 'delegate' or 'live' jQuery
|
||||
// methods. Only available when these methods are used.
|
||||
//
|
||||
// this - the element to which the event handler is being bound
|
||||
// this always executes immediate after setup (if first binding)
|
||||
add : function ( arg_map ) {
|
||||
var
|
||||
this_el = this,
|
||||
option_map = $.data( this_el, optionKey ),
|
||||
namespace_str = arg_map.namespace,
|
||||
event_type = arg_map.type,
|
||||
bound_ns_map, namespace_list, idx, namespace_key
|
||||
;
|
||||
if ( ! option_map ) { return; }
|
||||
|
||||
bound_ns_map = option_map.bound_ns_map;
|
||||
|
||||
if ( ! bound_ns_map[event_type] ) {
|
||||
// this indicates a non-namespaced entry
|
||||
bound_ns_map[event_type] = {};
|
||||
}
|
||||
|
||||
if ( ! namespace_str ) { return; }
|
||||
|
||||
namespace_list = namespace_str.split('.');
|
||||
|
||||
for ( idx = 0; idx < namespace_list.length; idx++ ) {
|
||||
namespace_key = namespace_list[idx];
|
||||
bound_ns_map[event_type][namespace_key] = true;
|
||||
}
|
||||
},
|
||||
|
||||
remove : function ( arg_map ) {
|
||||
var
|
||||
elem_bound = this,
|
||||
option_map = $.data( elem_bound, optionKey ),
|
||||
bound_ns_map = option_map.bound_ns_map,
|
||||
event_type = arg_map.type,
|
||||
namespace_str = arg_map.namespace,
|
||||
namespace_list, idx, namespace_key
|
||||
;
|
||||
|
||||
if ( ! bound_ns_map[event_type] ) { return; }
|
||||
|
||||
// No namespace(s) provided:
|
||||
// Remove complete record for custom event type (e.g. utap)
|
||||
if ( ! namespace_str ) {
|
||||
delete bound_ns_map[event_type];
|
||||
return;
|
||||
}
|
||||
|
||||
// Namespace(s) provided:
|
||||
// Remove namespace flags from each custom event typei (e.g. utap)
|
||||
// record. If all claimed namespaces are removed, remove
|
||||
// complete record.
|
||||
namespace_list = namespace_str.split('.');
|
||||
|
||||
for ( idx = 0; idx < namespace_list.length; idx++ ) {
|
||||
namespace_key = namespace_list[idx];
|
||||
if (bound_ns_map[event_type][namespace_key]) {
|
||||
delete bound_ns_map[event_type][namespace_key];
|
||||
}
|
||||
}
|
||||
|
||||
if ( $.isEmptyObject( bound_ns_map[event_type] ) ) {
|
||||
delete bound_ns_map[event_type];
|
||||
}
|
||||
},
|
||||
|
||||
teardown : function( name_list ) {
|
||||
var
|
||||
elem_bound = this,
|
||||
$bound = $(elem_bound),
|
||||
option_map = $.data( elem_bound, optionKey ),
|
||||
bound_ns_map = option_map.bound_ns_map,
|
||||
idx, namespace_key, ue_namespace_code, namespace_list
|
||||
;
|
||||
|
||||
// do not tear down if related handlers are still bound
|
||||
if ( ! $.isEmptyObject( bound_ns_map ) ) { return; }
|
||||
|
||||
namespace_list = makeListPlus(name_list);
|
||||
namespace_list.push_uniq('000');
|
||||
|
||||
NSPACE_01:
|
||||
for ( idx = 0; idx < namespace_list.length; idx++ ) {
|
||||
namespace_key = namespace_list[idx];
|
||||
|
||||
if ( ! namespace_key ) { continue NSPACE_01; }
|
||||
|
||||
ue_namespace_code = '.__ue' + namespace_key;
|
||||
$bound.unbind( 'mousedown' + ue_namespace_code );
|
||||
$bound.unbind( 'touchstart' + ue_namespace_code );
|
||||
$bound.unbind( 'mousewheel' + ue_namespace_code );
|
||||
}
|
||||
|
||||
$.removeData( elem_bound, optionKey );
|
||||
|
||||
// Unbind document events only after last element element is removed
|
||||
boundList.remove_val(this);
|
||||
if ( boundList.length === 0 ) {
|
||||
// console.log('last bound element removed - removing global binds');
|
||||
$(document).unbind( 'mousemove.__ue');
|
||||
$(document).unbind( 'touchmove.__ue');
|
||||
$(document).unbind( 'mouseup.__ue');
|
||||
$(document).unbind( 'touchend.__ue');
|
||||
$(document).unbind( 'touchcancel.__ue');
|
||||
isMoveBound = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
// End define special event handlers
|
||||
//--------------- BEGIN JQUERY SPECIAL EVENTS ----------------
|
||||
|
||||
//------------------ BEGIN MOTION CONTROLS -------------------
|
||||
// Begin motion control /fnHeld/
|
||||
fnHeld = function ( arg_map ) {
|
||||
var
|
||||
timestamp = +new Date(),
|
||||
motion_id = arg_map.motion_id,
|
||||
motion_map = arg_map.motion_map,
|
||||
bound_ns_map = arg_map.bound_ns_map,
|
||||
event_ue
|
||||
;
|
||||
|
||||
delete motion_map.tapheld_toid;
|
||||
|
||||
if ( ! motion_map.do_allow_held ) { return; }
|
||||
|
||||
motion_map.px_end_x = motion_map.px_start_x;
|
||||
motion_map.px_end_y = motion_map.px_start_y;
|
||||
motion_map.ms_timestop = timestamp;
|
||||
motion_map.ms_elapsed = timestamp - motion_map.ms_timestart;
|
||||
|
||||
if ( bound_ns_map.uheld ) {
|
||||
event_ue = $.Event('uheld');
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
}
|
||||
|
||||
// remove tracking, as we want no futher action on this motion
|
||||
if ( bound_ns_map.uheldstart ) {
|
||||
event_ue = $.Event('uheldstart');
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
motionHeldId = motion_id;
|
||||
}
|
||||
else {
|
||||
delete motionMapMap[motion_id];
|
||||
}
|
||||
};
|
||||
// End motion control /fnHeld/
|
||||
|
||||
|
||||
// Begin motion control /fnMotionStart/
|
||||
fnMotionStart = function ( arg_map ) {
|
||||
var
|
||||
motion_id = arg_map.motion_id,
|
||||
event_src = arg_map.event_src,
|
||||
request_dzoom = arg_map.request_dzoom,
|
||||
|
||||
option_map = $.data( arg_map.elem, optionKey ),
|
||||
bound_ns_map = option_map.bound_ns_map,
|
||||
$target = $(event_src.target ),
|
||||
do_zoomstart = false,
|
||||
motion_map, cb_map, event_ue
|
||||
;
|
||||
|
||||
// this should never happen, but it does
|
||||
if ( motionMapMap[ motion_id ] ) { return; }
|
||||
|
||||
// ignore on zoom
|
||||
if ( request_dzoom && ! bound_ns_map.uzoomstart ) { return; }
|
||||
|
||||
// :input selector includes text areas
|
||||
if ( $target.is( option_map.ignore_select ) ) { return; }
|
||||
|
||||
// Prevent default only after confirming handling this event
|
||||
event_src.preventDefault();
|
||||
|
||||
cb_map = callbackList.pop();
|
||||
while ( cb_map ) {
|
||||
if ( $target.is( cb_map.selector_str )
|
||||
|| $( arg_map.elem ).is( cb_map.selector_str )
|
||||
) {
|
||||
if ( cb_map.callback_match ) {
|
||||
cb_map.callback_match( arg_map );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( cb_map.callback_nomatch ) {
|
||||
cb_map.callback_nomatch( arg_map );
|
||||
}
|
||||
}
|
||||
cb_map = callbackList.pop();
|
||||
}
|
||||
|
||||
motion_map = {
|
||||
do_allow_tap : bound_ns_map.utap ? true : false,
|
||||
do_allow_held : ( bound_ns_map.uheld || bound_ns_map.uheldstart )
|
||||
? true : false,
|
||||
elem_bound : arg_map.elem,
|
||||
elem_target : event_src.target,
|
||||
ms_elapsed : 0,
|
||||
ms_timestart : event_src.timeStamp,
|
||||
ms_timestop : undefined,
|
||||
option_map : option_map,
|
||||
orig_target : event_src.target,
|
||||
px_current_x : event_src.clientX,
|
||||
px_current_y : event_src.clientY,
|
||||
px_end_x : undefined,
|
||||
px_end_y : undefined,
|
||||
px_start_x : event_src.clientX,
|
||||
px_start_y : event_src.clientY,
|
||||
timeStamp : event_src.timeStamp
|
||||
};
|
||||
|
||||
motionMapMap[ motion_id ] = motion_map;
|
||||
|
||||
if ( bound_ns_map.uzoomstart ) {
|
||||
if ( request_dzoom ) {
|
||||
motionDzoomId = motion_id;
|
||||
}
|
||||
else if ( ! motion1ZoomId ) {
|
||||
motion1ZoomId = motion_id;
|
||||
}
|
||||
else if ( ! motion2ZoomId ) {
|
||||
motion2ZoomId = motion_id;
|
||||
event_ue = $.Event('uzoomstart');
|
||||
do_zoomstart = true;
|
||||
}
|
||||
|
||||
if ( do_zoomstart ) {
|
||||
event_ue = $.Event( 'uzoomstart' );
|
||||
motion_map.px_delta_zoom = 0;
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bound_ns_map.uheld || bound_ns_map.uheldstart ) {
|
||||
motion_map.tapheld_toid = setTimeout(
|
||||
function() {
|
||||
fnHeld({
|
||||
motion_id : motion_id,
|
||||
motion_map : motion_map,
|
||||
bound_ns_map : bound_ns_map
|
||||
});
|
||||
},
|
||||
option_map.min_held_ms
|
||||
);
|
||||
}
|
||||
};
|
||||
// End motion control /fnMotionStart/
|
||||
|
||||
// Begin motion control /fnMotionMove/
|
||||
fnMotionMove = function ( arg_map ) {
|
||||
var
|
||||
motion_id = arg_map.motion_id,
|
||||
event_src = arg_map.event_src,
|
||||
do_zoommove = false,
|
||||
|
||||
motion_map, option_map, bound_ns_map,
|
||||
is_over_rad, event_ue, px_pinch_zoom,
|
||||
px_delta_zoom, mzoom1_map, mzoom2_map
|
||||
;
|
||||
|
||||
if ( ! motionMapMap[ motion_id ] ) { return; }
|
||||
|
||||
// Prevent default only after confirming handling this event
|
||||
event_src.preventDefault();
|
||||
|
||||
motion_map = motionMapMap[motion_id];
|
||||
option_map = motion_map.option_map;
|
||||
bound_ns_map = option_map.bound_ns_map;
|
||||
|
||||
motion_map.timeStamp = event_src.timeStamp;
|
||||
motion_map.elem_target = event_src.target;
|
||||
motion_map.ms_elapsed = event_src.timeStamp - motion_map.ms_timestart;
|
||||
|
||||
motion_map.px_delta_x = event_src.clientX - motion_map.px_current_x;
|
||||
motion_map.px_delta_y = event_src.clientY - motion_map.px_current_y;
|
||||
|
||||
motion_map.px_current_x = event_src.clientX;
|
||||
motion_map.px_current_y = event_src.clientY;
|
||||
|
||||
motion_map.px_tdelta_x = motion_map.px_start_x - event_src.clientX;
|
||||
motion_map.px_tdelta_y = motion_map.px_start_y - event_src.clientY;
|
||||
|
||||
is_over_rad = (
|
||||
Math.abs( motion_map.px_tdelta_x ) > option_map.px_radius
|
||||
|| Math.abs( motion_map.px_tdelta_y ) > option_map.px_radius
|
||||
);
|
||||
// native event object override
|
||||
motion_map.timeStamp = event_src.timeStamp;
|
||||
|
||||
// disallow held or tap if outside of zone
|
||||
if ( is_over_rad ) {
|
||||
motion_map.do_allow_tap = false;
|
||||
motion_map.do_allow_held = false;
|
||||
}
|
||||
|
||||
// disallow tap if time has elapsed
|
||||
if ( motion_map.ms_elapsed > option_map.max_tap_ms ) {
|
||||
motion_map.do_allow_tap = false;
|
||||
}
|
||||
|
||||
if ( motion1ZoomId && motion2ZoomId
|
||||
&& ( motion_id === motion1ZoomId
|
||||
|| motion_id === motion2ZoomId
|
||||
)) {
|
||||
motionMapMap[motion_id] = motion_map;
|
||||
mzoom1_map = motionMapMap[motion1ZoomId];
|
||||
mzoom2_map = motionMapMap[motion2ZoomId];
|
||||
|
||||
px_pinch_zoom = Math.floor(
|
||||
Math.sqrt(
|
||||
Math.pow((mzoom1_map.px_current_x - mzoom2_map.px_current_x),2)
|
||||
+ Math.pow((mzoom1_map.px_current_y - mzoom2_map.px_current_y),2)
|
||||
) +0.5
|
||||
);
|
||||
|
||||
if ( pxPinchZoom === -1 ) { px_delta_zoom = 0; }
|
||||
else { px_delta_zoom = ( px_pinch_zoom - pxPinchZoom ) * zoomTouchNum;}
|
||||
|
||||
// save value for next iteration delta comparison
|
||||
pxPinchZoom = px_pinch_zoom;
|
||||
do_zoommove = true;
|
||||
}
|
||||
else if ( motionDzoomId === motion_id ) {
|
||||
if ( bound_ns_map.uzoommove ) {
|
||||
px_delta_zoom = motion_map.px_delta_y * zoomMouseNum;
|
||||
do_zoommove = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( do_zoommove ){
|
||||
event_ue = $.Event('uzoommove');
|
||||
motion_map.px_delta_zoom = px_delta_zoom;
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( motionHeldId === motion_id ) {
|
||||
if ( bound_ns_map.uheldmove ) {
|
||||
event_ue = $.Event('uheldmove');
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( motionDragId === motion_id ) {
|
||||
if ( bound_ns_map.udragmove ) {
|
||||
event_ue = $.Event('udragmove');
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( bound_ns_map.udragstart
|
||||
&& motion_map.do_allow_tap === false
|
||||
&& motion_map.do_allow_held === false
|
||||
&& !( motionDragId && motionHeldId )
|
||||
) {
|
||||
motionDragId = motion_id;
|
||||
event_ue = $.Event('udragstart');
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
|
||||
if ( motion_map.tapheld_toid ) {
|
||||
clearTimeout(motion_map.tapheld_toid);
|
||||
delete motion_map.tapheld_toid;
|
||||
}
|
||||
}
|
||||
};
|
||||
// End motion control /fnMotionMove/
|
||||
|
||||
// Begin motion control /fnMotionEnd/
|
||||
fnMotionEnd = function ( arg_map ) {
|
||||
var
|
||||
motion_id = arg_map.motion_id,
|
||||
event_src = arg_map.event_src,
|
||||
do_zoomend = false,
|
||||
motion_map, option_map, bound_ns_map, event_ue
|
||||
;
|
||||
|
||||
doDisableMouse = false;
|
||||
|
||||
if ( ! motionMapMap[motion_id] ) { return; }
|
||||
|
||||
motion_map = motionMapMap[motion_id];
|
||||
option_map = motion_map.option_map;
|
||||
bound_ns_map = option_map.bound_ns_map;
|
||||
|
||||
motion_map.elem_target = event_src.target;
|
||||
motion_map.ms_elapsed = event_src.timeStamp - motion_map.ms_timestart;
|
||||
motion_map.ms_timestop = event_src.timeStamp;
|
||||
|
||||
if ( motion_map.px_current_x ) {
|
||||
motion_map.px_delta_x = event_src.clientX - motion_map.px_current_x;
|
||||
motion_map.px_delta_y = event_src.clientY - motion_map.px_current_y;
|
||||
}
|
||||
|
||||
motion_map.px_current_x = event_src.clientX;
|
||||
motion_map.px_current_y = event_src.clientY;
|
||||
|
||||
motion_map.px_end_x = event_src.clientX;
|
||||
motion_map.px_end_y = event_src.clientY;
|
||||
|
||||
motion_map.px_tdelta_x = motion_map.px_start_x - motion_map.px_end_x;
|
||||
motion_map.px_tdelta_y = motion_map.px_start_y - motion_map.px_end_y;
|
||||
|
||||
// native event object override
|
||||
motion_map.timeStamp = event_src.timeStamp
|
||||
;
|
||||
|
||||
// clear-out any long-hold tap timer
|
||||
if ( motion_map.tapheld_toid ) {
|
||||
clearTimeout(motion_map.tapheld_toid);
|
||||
delete motion_map.tapheld_toid;
|
||||
}
|
||||
|
||||
// trigger utap
|
||||
if ( bound_ns_map.utap
|
||||
&& motion_map.ms_elapsed <= option_map.max_tap_ms
|
||||
&& motion_map.do_allow_tap
|
||||
) {
|
||||
event_ue = $.Event('utap');
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
}
|
||||
|
||||
// trigger udragend
|
||||
if ( motion_id === motionDragId ) {
|
||||
if ( bound_ns_map.udragend ) {
|
||||
event_ue = $.Event('udragend');
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
}
|
||||
motionDragId = undefined;
|
||||
}
|
||||
|
||||
// trigger heldend
|
||||
if ( motion_id === motionHeldId ) {
|
||||
if ( bound_ns_map.uheldend ) {
|
||||
event_ue = $.Event('uheldend');
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
}
|
||||
motionHeldId = undefined;
|
||||
}
|
||||
|
||||
// trigger uzoomend
|
||||
if ( motion_id === motionDzoomId ) {
|
||||
do_zoomend = true;
|
||||
motionDzoomId = undefined;
|
||||
}
|
||||
|
||||
// cleanup zoom info
|
||||
else if ( motion_id === motion1ZoomId ) {
|
||||
if ( motion2ZoomId ) {
|
||||
motion1ZoomId = motion2ZoomId;
|
||||
motion2ZoomId = undefined;
|
||||
do_zoomend = true;
|
||||
}
|
||||
else { motion1ZoomId = undefined; }
|
||||
pxPinchZoom = -1;
|
||||
}
|
||||
if ( motion_id === motion2ZoomId ) {
|
||||
motion2ZoomId = undefined;
|
||||
pxPinchZoom = -1;
|
||||
do_zoomend = true;
|
||||
}
|
||||
|
||||
if ( do_zoomend && bound_ns_map.uzoomend ) {
|
||||
event_ue = $.Event('uzoomend');
|
||||
motion_map.px_delta_zoom = 0;
|
||||
$.extend( event_ue, motion_map );
|
||||
$(motion_map.elem_bound).trigger(event_ue);
|
||||
}
|
||||
// remove pointer from consideration
|
||||
delete motionMapMap[motion_id];
|
||||
};
|
||||
// End motion control /fnMotionEnd/
|
||||
//------------------ END MOTION CONTROLS -------------------
|
||||
|
||||
//------------------- BEGIN EVENT HANDLERS -------------------
|
||||
// Begin event handler /onTouch/ for all touch events.
|
||||
// We use the 'type' attribute to dispatch to motion control
|
||||
onTouch = function ( event ) {
|
||||
var
|
||||
this_el = this,
|
||||
timestamp = +new Date(),
|
||||
o_event = event.originalEvent,
|
||||
touch_list = o_event ? o_event.changedTouches || [] : [],
|
||||
touch_count = touch_list.length,
|
||||
idx, touch_event, motion_id, handler_fn
|
||||
;
|
||||
|
||||
doDisableMouse = true;
|
||||
|
||||
event.timeStamp = timestamp;
|
||||
|
||||
switch ( event.type ) {
|
||||
case 'touchstart' : handler_fn = fnMotionStart; break;
|
||||
case 'touchmove' : handler_fn = fnMotionMove; break;
|
||||
case 'touchend' :
|
||||
case 'touchcancel' : handler_fn = fnMotionEnd; break;
|
||||
default : handler_fn = null;
|
||||
}
|
||||
|
||||
if ( ! handler_fn ) { return; }
|
||||
|
||||
for ( idx = 0; idx < touch_count; idx++ ) {
|
||||
touch_event = touch_list[idx];
|
||||
|
||||
motion_id = 'touch' + String(touch_event.identifier);
|
||||
|
||||
event.clientX = touch_event.clientX;
|
||||
event.clientY = touch_event.clientY;
|
||||
handler_fn({
|
||||
elem : this_el,
|
||||
motion_id : motion_id,
|
||||
event_src : event
|
||||
});
|
||||
}
|
||||
};
|
||||
// End event handler /onTouch/
|
||||
|
||||
|
||||
// Begin event handler /onMouse/ for all mouse events
|
||||
// We use the 'type' attribute to dispatch to motion control
|
||||
onMouse = function ( event ) {
|
||||
var
|
||||
this_el = this,
|
||||
motion_id = 'mouse' + String(event.button),
|
||||
request_dzoom = false,
|
||||
handler_fn
|
||||
;
|
||||
|
||||
if ( doDisableMouse ) {
|
||||
event.stopImmediatePropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( event.shiftKey ) { request_dzoom = true; }
|
||||
|
||||
// skip left or middle clicks
|
||||
if ( event.type !== 'mousemove' ) {
|
||||
if ( event.button !== 0 ) { return true; }
|
||||
}
|
||||
|
||||
switch ( event.type ) {
|
||||
case 'mousedown' : handler_fn = fnMotionStart; break;
|
||||
case 'mouseup' : handler_fn = fnMotionEnd; break;
|
||||
case 'mousemove' : handler_fn = fnMotionMove; break;
|
||||
default : handler_fn = null;
|
||||
}
|
||||
|
||||
if ( ! handler_fn ) { return; }
|
||||
|
||||
handler_fn({
|
||||
elem : this_el,
|
||||
event_src : event,
|
||||
request_dzoom : request_dzoom,
|
||||
motion_id : motion_id
|
||||
});
|
||||
};
|
||||
// End event handler /onMouse/
|
||||
//-------------------- END EVENT HANDLERS --------------------
|
||||
|
||||
// Export special events through jQuery API
|
||||
$Special.ue
|
||||
= $Special.utap = $Special.uheld
|
||||
= $Special.uzoomstart = $Special.uzoommove = $Special.uzoomend
|
||||
= $Special.udragstart = $Special.udragmove = $Special.udragend
|
||||
= $Special.uheldstart = $Special.uheldmove = $Special.uheldend
|
||||
= Ue
|
||||
;
|
||||
$.ueSetGlobalCb = function ( selector_str, callback_match, callback_nomatch ) {
|
||||
callbackList.push( {
|
||||
selector_str : selector_str || '',
|
||||
callback_match : callback_match || null,
|
||||
callback_nomatch : callback_nomatch || null
|
||||
});
|
||||
};
|
||||
}(jQuery));
|
||||
87
wwwroot/js/lib/jquery.gzserialize.js
Normal file
87
wwwroot/js/lib/jquery.gzserialize.js
Normal file
@@ -0,0 +1,87 @@
|
||||
(function($) {
|
||||
|
||||
$.fn.serialize = function(options) {
|
||||
return $.param(this.serializeArray(options));
|
||||
};
|
||||
|
||||
$.fn.serializeArray = function(options) {
|
||||
var o = $.extend({
|
||||
checkboxesAsBools: false
|
||||
}, options || {});
|
||||
|
||||
var rselectTextarea = /select|textarea/i;
|
||||
var rinput = /text|hidden|password|date|search/i;
|
||||
|
||||
return this.map(function() {
|
||||
return this.elements ? $.makeArray(this.elements) : this;
|
||||
})
|
||||
.filter(function() {
|
||||
return this.name && !this.disabled &&
|
||||
(this.checked || (o.checkboxesAsBools && this.type === 'checkbox') || rselectTextarea.test(this.nodeName) || rinput.test(this.type));
|
||||
})
|
||||
.map(function(i, elem) {
|
||||
|
||||
var val = $(this).val();
|
||||
|
||||
//this block changed here by me to break out the overly tight but obscure code
|
||||
|
||||
if (val == null) return null;
|
||||
|
||||
if ($.isArray(val)) {
|
||||
//Array return
|
||||
return $.map(val, function(val, i) {
|
||||
return {
|
||||
name: elem.name,
|
||||
value: val
|
||||
};
|
||||
})
|
||||
} else {
|
||||
|
||||
if (o.checkboxesAsBools && this.type === 'checkbox') {
|
||||
return {
|
||||
name: elem.name,
|
||||
value: (this.checked ? 'true' : 'false')
|
||||
}
|
||||
}
|
||||
|
||||
//for now dates are handled at the backend
|
||||
//by convention of field name ending in "Date" (sentDate, readDate etc)
|
||||
// if (this.type === 'date') {
|
||||
// return {
|
||||
// name: elem.name,
|
||||
// value: (val === '' ? '' : val) //empty dates sb null for mongo db backend
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
//default all other types
|
||||
return {
|
||||
name: elem.name,
|
||||
value: val
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /changed by me
|
||||
|
||||
|
||||
//ORIGINAL BLOCK:
|
||||
// return val == null ?
|
||||
// null :
|
||||
// $.isArray(val) ?
|
||||
// $.map(val, function (val, i) {
|
||||
// return { name: elem.name, value: val };
|
||||
// }) :
|
||||
// {
|
||||
|
||||
// name: elem.name,
|
||||
// value: (o.checkboxesAsBools && this.type === 'checkbox') ? //moar ternaries!
|
||||
// (this.checked ? 'true' : 'false') :
|
||||
// val
|
||||
// };
|
||||
|
||||
|
||||
}).get();
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
7
wwwroot/js/lib/moment.min.js
vendored
Normal file
7
wwwroot/js/lib/moment.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1113
wwwroot/js/lib/page.js
Normal file
1113
wwwroot/js/lib/page.js
Normal file
File diff suppressed because it is too large
Load Diff
7
wwwroot/js/lib/store.min.js
vendored
Normal file
7
wwwroot/js/lib/store.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Copyright (c) 2010-2016 Marcus Westin */
|
||||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.store = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
(function (global){
|
||||
"use strict";module.exports=function(){function e(){try{return o in n&&n[o]}catch(e){return!1}}var t,r={},n="undefined"!=typeof window?window:global,i=n.document,o="localStorage",a="script";if(r.disabled=!1,r.version="1.3.20",r.set=function(e,t){},r.get=function(e,t){},r.has=function(e){return void 0!==r.get(e)},r.remove=function(e){},r.clear=function(){},r.transact=function(e,t,n){null==n&&(n=t,t=null),null==t&&(t={});var i=r.get(e,t);n(i),r.set(e,i)},r.getAll=function(){},r.forEach=function(){},r.serialize=function(e){return JSON.stringify(e)},r.deserialize=function(e){if("string"==typeof e)try{return JSON.parse(e)}catch(t){return e||void 0}},e())t=n[o],r.set=function(e,n){return void 0===n?r.remove(e):(t.setItem(e,r.serialize(n)),n)},r.get=function(e,n){var i=r.deserialize(t.getItem(e));return void 0===i?n:i},r.remove=function(e){t.removeItem(e)},r.clear=function(){t.clear()},r.getAll=function(){var e={};return r.forEach(function(t,r){e[t]=r}),e},r.forEach=function(e){for(var n=0;n<t.length;n++){var i=t.key(n);e(i,r.get(i))}};else if(i&&i.documentElement.addBehavior){var c,u;try{u=new ActiveXObject("htmlfile"),u.open(),u.write("<"+a+">document.w=window</"+a+'><iframe src="/favicon.ico"></iframe>'),u.close(),c=u.w.frames[0].document,t=c.createElement("div")}catch(l){t=i.createElement("div"),c=i.body}var f=function(e){return function(){var n=Array.prototype.slice.call(arguments,0);n.unshift(t),c.appendChild(t),t.addBehavior("#default#userData"),t.load(o);var i=e.apply(r,n);return c.removeChild(t),i}},d=new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]","g"),s=function(e){return e.replace(/^d/,"___$&").replace(d,"___")};r.set=f(function(e,t,n){return t=s(t),void 0===n?r.remove(t):(e.setAttribute(t,r.serialize(n)),e.save(o),n)}),r.get=f(function(e,t,n){t=s(t);var i=r.deserialize(e.getAttribute(t));return void 0===i?n:i}),r.remove=f(function(e,t){t=s(t),e.removeAttribute(t),e.save(o)}),r.clear=f(function(e){var t=e.XMLDocument.documentElement.attributes;e.load(o);for(var r=t.length-1;r>=0;r--)e.removeAttribute(t[r].name);e.save(o)}),r.getAll=function(e){var t={};return r.forEach(function(e,r){t[e]=r}),t},r.forEach=f(function(e,t){for(var n,i=e.XMLDocument.documentElement.attributes,o=0;n=i[o];++o)t(n.name,r.deserialize(e.getAttribute(n.name)))})}try{var v="__storejs__";r.set(v,v),r.get(v)!=v&&(r.disabled=!0),r.remove(v)}catch(l){r.disabled=!0}return r.enabled=!r.disabled,r}();
|
||||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||||
},{}]},{},[1])(1)
|
||||
});
|
||||
9
wwwroot/js/templates/app.authenticate.handlebars
Normal file
9
wwwroot/js/templates/app.authenticate.handlebars
Normal file
@@ -0,0 +1,9 @@
|
||||
<div>
|
||||
<img src="android-chrome-192x192.png" alt="Rockfish logo" >
|
||||
<h2>Login</h2>
|
||||
<form method="post" action="index.html">
|
||||
<p><input type="text" id="login" value="" placeholder="Username" autocapitalize="none"></p>
|
||||
<p><input type="password" id="password" value="" placeholder="Password"></p>
|
||||
<p class="submit"><input type="submit" id="btnSubmit" value="Login"></p>
|
||||
</form>
|
||||
</div>
|
||||
54
wwwroot/js/templates/app.customerEdit.handlebars
Normal file
54
wwwroot/js/templates/app.customerEdit.handlebars
Normal file
@@ -0,0 +1,54 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input class="form-control" type="text" id="name" name="name" value="">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="adminEmail">Admin / license / support emails</label>
|
||||
<input class="form-control" type="text" id="adminEmail" name="adminEmail" placeholder="License related, comma separated" value="">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="supportEmail">Support only emails</label>
|
||||
<input class="form-control" type="text" id="supportEmail" name="supportEmail" placeholder="License related, comma separated" value="">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="affiliateNumber">Affiliate number</label>
|
||||
<input class="form-control" type="text" id="affiliateNumber" name="affiliateNumber" value="">
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="doNotContact">
|
||||
<input class="form-check-input" type="checkbox" name="doNotContact" id="doNotContact">
|
||||
Do not contact
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="active">
|
||||
<input class="form-check-input" type="checkbox" name="active" id="active">
|
||||
Active</label>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="notes">Notes</label>
|
||||
<textarea class="form-control form-control-lg" id="notes" name="notes" rows="10"/>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="app-frm-buttons mt-5">
|
||||
<button id="btn-save" class="btn btn-success">Save</button>
|
||||
<button id="btn-delete" class="btn btn-outline-dark">Delete</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
88
wwwroot/js/templates/app.customerSiteEdit.handlebars
Normal file
88
wwwroot/js/templates/app.customerSiteEdit.handlebars
Normal file
@@ -0,0 +1,88 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input class="form-control" type="text" id="name" name="name" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="country">Country</label>
|
||||
<input class="form-control" type="text" id="country" name="country" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="stateProvince">State / Province</label>
|
||||
<input class="form-control" type="text" id="stateProvince" name="stateProvince" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="networked">
|
||||
<input class="form-check-input" type="checkbox" name="networked" id="networked">
|
||||
Networked</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="dbType">Database type</label>
|
||||
<input class="form-control" type="text" id="dbType" name="dbType" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="serverOS">Server OS</label>
|
||||
<input class="form-control" type="text" id="serverOS" name="serverOS" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="serverBits">Server bits</label>
|
||||
<input class="form-control" type="text" id="serverBits" name="serverBits" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="hosted">
|
||||
<input class="form-check-input" type="checkbox" name="hosted" id="hosted">
|
||||
Hosted</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="hostName">Host name</label>
|
||||
<input class="form-control" type="text" id="hostName" name="hostName" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="hostingStartDate">Hosting start</label>
|
||||
<input class="form-control" type="date" id="hostingStartDate" name="hostingStartDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="hostingEndDate">Hosting end</label>
|
||||
<input class="form-control" type="date" id="hostingEndDate" name="hostingEndDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="notes">Notes</label>
|
||||
<textarea class="form-control" id="notes" name="notes" rows="10"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="app-frm-buttons mt-5">
|
||||
<button id="btn-save" class="btn btn-success">Save</button>
|
||||
<button id="btn-delete" class="btn btn-outline-dark">Delete</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
3
wwwroot/js/templates/app.customerSites.handlebars
Normal file
3
wwwroot/js/templates/app.customerSites.handlebars
Normal file
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<ul id="rf-list" class="rf-list" />
|
||||
</div>
|
||||
4
wwwroot/js/templates/app.customers.handlebars
Normal file
4
wwwroot/js/templates/app.customers.handlebars
Normal file
@@ -0,0 +1,4 @@
|
||||
<div>
|
||||
<div id="rf-list-count"/>
|
||||
<div id="rf-list" class="rf-list"/>
|
||||
</div>
|
||||
3
wwwroot/js/templates/app.fourohfour.handlebars
Normal file
3
wwwroot/js/templates/app.fourohfour.handlebars
Normal file
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<h2>404 NOT FOUND 404</h2>
|
||||
</div>
|
||||
3
wwwroot/js/templates/app.inbox.handlebars
Normal file
3
wwwroot/js/templates/app.inbox.handlebars
Normal file
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<ul id="rf-list-div" />
|
||||
</div>
|
||||
183
wwwroot/js/templates/app.license.handlebars
Normal file
183
wwwroot/js/templates/app.license.handlebars
Normal file
@@ -0,0 +1,183 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
<div class="row">
|
||||
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="keyWillLockout">
|
||||
<input class="form-check-input" type="checkbox" name="keyWillLockout" id="keyWillLockout"> Expiring test key</label>
|
||||
</div>
|
||||
<input class="form-control" type="date" id="lockoutDate" name="lockoutDate" value="">
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="isLite">
|
||||
<input class="form-check-input" type="checkbox" name="isLite" id="isLite"> AyaNova LITE</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="licenseType">License type</label>
|
||||
<select class="form-control" name="licenseType">
|
||||
<option value="new">New</option>
|
||||
<option value="addon">Renewal / Add-on</option>
|
||||
<option value="licensedTrial">Licensed trial</option>
|
||||
<option value="webRequestedTrial">Web requested trial</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="registeredTo">Registered to</label>
|
||||
<input class="form-control" type="text" id="registeredTo" name="registeredTo" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="customerId">Customer</label>
|
||||
<select class="form-control" id="customerId" name="customerId" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="emailAddress">Email address</label>
|
||||
<input class="form-control" type="text" id="emailAddress" name="emailAddress" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="users">Users</label>
|
||||
<select class="form-control" name="users">
|
||||
<option value="1">1</option>
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="15">15</option>
|
||||
<option value="20">20</option>
|
||||
<option value="50">50</option>
|
||||
<option value="999">999</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="supportExpiresDate">Support expires</label>
|
||||
<input class="form-control" type="date" id="supportExpiresDate" name="supportExpiresDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="wbi">
|
||||
<input class="form-check-input" type="checkbox" name="wbi" id="wbi"> WBI
|
||||
</label>
|
||||
<input class="form-control" type="date" id="wbiSupportExpiresDate" name="wbiSupportExpiresDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="mbi">
|
||||
<input class="form-check-input" type="checkbox" name="mbi" id="mbi"> MBI
|
||||
</label>
|
||||
<input class="form-control" type="date" id="mbiSupportExpiresDate" name="mbiSupportExpiresDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="ri">
|
||||
<input class="form-check-input" type="checkbox" name="ri" id="ri"> RI
|
||||
</label>
|
||||
<input class="form-control" type="date" id="riSupportExpiresDate" name="riSupportExpiresDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="qbi">
|
||||
<input class="form-check-input" type="checkbox" name="qbi" id="qbi"> QBI
|
||||
</label>
|
||||
<input class="form-control" type="date" id="qbiSupportExpiresDate" name="qbiSupportExpiresDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="qboi">
|
||||
<input class="form-check-input" type="checkbox" name="qboi" id="qboi"> QBOI
|
||||
</label>
|
||||
<input class="form-control" type="date" id="qboiSupportExpiresDate" name="qboiSupportExpiresDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="pti">
|
||||
<input class="form-check-input" type="checkbox" name="pti" id="pti"> PTI
|
||||
</label>
|
||||
<input class="form-control" type="date" id="ptiSupportExpiresDate" name="ptiSupportExpiresDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="quickNotification">
|
||||
<input class="form-check-input" type="checkbox" name="quickNotification" id="quickNotification"> Quick notification</label>
|
||||
<input class="form-control" type="date" id="quickNotificationSupportExpiresDate" name="quickNotificationSupportExpiresDate"
|
||||
value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="exportToXls">
|
||||
<input class="form-check-input" type="checkbox" name="exportToXls" id="exportToXls"> Export to XLS</label>
|
||||
<input class="form-control" type="date" id="exportToXlsSupportExpiresDate" name="exportToXlsSupportExpiresDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="outlookSchedule">
|
||||
<input class="form-check-input" type="checkbox" name="outlookSchedule" id="outlookSchedule"> Outlook Schedule</label>
|
||||
<input class="form-control" type="date" id="outlookScheduleSupportExpiresDate" name="outlookScheduleSupportExpiresDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="oli">
|
||||
<input class="form-check-input" type="checkbox" name="oli" id="oli"> OLI
|
||||
</label>
|
||||
<input class="form-control" type="date" id="oliSupportExpiresDate" name="oliSupportExpiresDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="importExportCSVDuplicate">
|
||||
<input class="form-check-input" type="checkbox" name="importExportCSVDuplicate" id="importExportCSVDuplicate"> Import / export CSV duplicate</label>
|
||||
<input class="form-control" type="date" id="importExportCSVDuplicateSupportExpiresDate" name="importExportCSVDuplicateSupportExpiresDate"
|
||||
value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="key">Key</label>
|
||||
<textarea class="form-control" id="key" name="key" rows="10" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="app-frm-buttons">
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
26
wwwroot/js/templates/app.licenseRequestEdit.handlebars
Normal file
26
wwwroot/js/templates/app.licenseRequestEdit.handlebars
Normal file
@@ -0,0 +1,26 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="request">Request</label>
|
||||
<textarea class="form-control" readonly id="request" name="request" rows="10"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="greeting">Greeting message</label>
|
||||
<textarea class="form-control" id="greeting" name="greeting" rows="10"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="keycode">Keycode message</label>
|
||||
<textarea class="form-control" readonly id="keycode" name="keycode" rows="10"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
75
wwwroot/js/templates/app.licenseTemplates.handlebars
Normal file
75
wwwroot/js/templates/app.licenseTemplates.handlebars
Normal file
@@ -0,0 +1,75 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-12">
|
||||
<h2>FULL KEY</h2>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="fullNew">New</label>
|
||||
<textarea class="form-control" id="fullNew" name="fullNew" rows="10" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="fullAddOn">Add-On</label>
|
||||
<textarea class="form-control" id="fullAddOn" name="fullAddOn" rows="10" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="fullTrial">Licensed Trial</label>
|
||||
<textarea class="form-control" id="fullTrial" name="fullTrial" rows="10" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<h2>Full trial greeting</h2>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="fullTrialGreeting">Greeting</label>
|
||||
<textarea class="form-control" id="fullTrialGreeting" name="fullTrialGreeting" rows="10" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
|
||||
<h2>LITE KEY</h2>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="liteNew">Lite New</label>
|
||||
<textarea class="form-control" id="liteNew" name="liteNew" rows="10" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="liteAddOn">Lite Add-On</label>
|
||||
<textarea class="form-control" id="liteAddOn" name="liteAddOn" rows="10" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="liteTrial">Lite Licensed Trial</label>
|
||||
<textarea class="form-control" id="liteTrial" name="liteTrial" rows="10">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<h2>Lite trial greeting</h2>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="liteTrialGreeting">Lite Greeting</label>
|
||||
<textarea class="form-control" id="liteTrialGreeting" name="liteTrialGreeting"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="app-frm-buttons mt-5">
|
||||
<button id="btn-save" class="btn btn-success">Save</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
56
wwwroot/js/templates/app.licenseView.handlebars
Normal file
56
wwwroot/js/templates/app.licenseView.handlebars
Normal file
@@ -0,0 +1,56 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="regTo">Registered to</label>
|
||||
<input class="form-control" type="text" id="regTo" name="regTo" value="" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="customerName">Rockfish customer name</label>
|
||||
<input class="form-control" type="text" id="customerName" name="customerName" value="" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="dtcreated">Created</label>
|
||||
<input class="form-control" type="date" id="dtcreated" name="dtcreated" value="" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">Email</label>
|
||||
<input class="form-control" type="text" id="email" name="email" value="" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="code">Fetch code</label>
|
||||
<input class="form-control" type="text" id="code" name="code" value="" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<label class="form-check-label text-success font-weight-bold" for="fetched">
|
||||
<input class="form-check-input" type="checkbox" name="fetched" id="fetched"> License fetched</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="dtFetched">Fetched on</label>
|
||||
<input class="form-control" type="date" id="dtfetched" name="dtfetched" value="" readonly>
|
||||
</div>
|
||||
|
||||
{{!-- <div class="form-group">
|
||||
<label for="fetchFrom">Fetched from</label>
|
||||
<input class="form-control" type="text" id="fetchFrom" name="fetchFrom" value="" readonly>
|
||||
</div> --}}
|
||||
|
||||
<div class="form-group">
|
||||
<label for="key">Key</label>
|
||||
<textarea class="form-control form-control-lg" id="key" name="key" rows="10" readonly/>
|
||||
</div>
|
||||
|
||||
<div class="app-frm-buttons mt-5">
|
||||
<button id="btn-save" class="btn btn-success">Save</button>
|
||||
<button id="btn-delete" class="btn btn-outline-dark">Delete</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
3
wwwroot/js/templates/app.licenses.handlebars
Normal file
3
wwwroot/js/templates/app.licenses.handlebars
Normal file
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<div id="rf-list" class="rf-list"/>
|
||||
</div>
|
||||
30
wwwroot/js/templates/app.mailEdit.handlebars
Normal file
30
wwwroot/js/templates/app.mailEdit.handlebars
Normal file
@@ -0,0 +1,30 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
<div class="form-group">
|
||||
<label for="message">Message</label>
|
||||
<textarea class="form-control" id="message" rows="20" readonly />
|
||||
</div>
|
||||
|
||||
<div id="sendToGroup" class="form-group invisible">
|
||||
<label for="sendTo">Send to</label>
|
||||
<input class="form-control" type="text" id="sendTo" name="sendTo" value="">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="composition">Reply</label>
|
||||
|
||||
<div class="btn-group float-right ml-5" role="group">
|
||||
<button id="btn-send" type="button" class="btn btn-sm btn-outline-primary mdi mdi-send"></button>
|
||||
</div>
|
||||
|
||||
<div class="form-check form-check-inline float-right">
|
||||
<label class="form-check-label">
|
||||
<input class="form-check-input" type="checkbox" id="trackDelivery" name="trackDelivery" >Receipt
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<textarea class="form-control" id="composition" name="composition" rows="10" />
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
82
wwwroot/js/templates/app.purchaseEdit.handlebars
Normal file
82
wwwroot/js/templates/app.purchaseEdit.handlebars
Normal file
@@ -0,0 +1,82 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="name">Product name</label>
|
||||
<input class="form-control" type="text" id="name" name="name" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="productCode">Product code</label>
|
||||
<input class="form-control" type="text" id="productCode" name="productCode" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="salesOrderNumber">Sales order number</label>
|
||||
<input class="form-control" type="text" id="salesOrderNumber" name="salesOrderNumber" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="vendorName">Vendor</label>
|
||||
<input class="form-control" type="text" id="vendorName" name="vendorName" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="purchaseDate">Purchased</label>
|
||||
<input class="form-control" type="date" id="purchaseDate" name="purchaseDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="renewNoticeSent">
|
||||
<input class="form-check-input" type="checkbox" name="renewNoticeSent" id="renewNoticeSent">
|
||||
Renew notice sent</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="expireDate">Subscription expire</label>
|
||||
<input class="form-control" type="date" id="expireDate" name="expireDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="cancelDate">Cancel date</label>
|
||||
<input class="form-control" type="date" id="cancelDate" name="cancelDate" value="">
|
||||
</div>
|
||||
</div>
|
||||
{{!-- <div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="email">Email</label>
|
||||
<input class="form-control" type="text" id="email" name="email" value="">
|
||||
</div>
|
||||
</div> --}}
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="couponCode">Coupon code</label>
|
||||
<input class="form-control" type="text" id="couponCode" name="couponCode" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="notes">ShareIt Order</label>
|
||||
<textarea class="form-control" id="notes" name="notes" rows="10"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="app-frm-buttons mt-5">
|
||||
<button id="btn-save" class="btn btn-success">Save</button>
|
||||
<button id="btn-delete" class="btn btn-outline-dark">Delete</button>
|
||||
<button id="btn-renew" class="btn btn-outline-primary">Renew</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
3
wwwroot/js/templates/app.purchases.handlebars
Normal file
3
wwwroot/js/templates/app.purchases.handlebars
Normal file
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<ul id="rf-list" class="rf-list" />
|
||||
</div>
|
||||
3
wwwroot/js/templates/app.reportData.handlebars
Normal file
3
wwwroot/js/templates/app.reportData.handlebars
Normal file
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<ul id="rf-list" class="rf-list" />
|
||||
</div>
|
||||
4
wwwroot/js/templates/app.reportDataExpires.handlebars
Normal file
4
wwwroot/js/templates/app.reportDataExpires.handlebars
Normal file
@@ -0,0 +1,4 @@
|
||||
<div>
|
||||
<ul id="rf-list" class="rf-list" />
|
||||
</div>
|
||||
|
||||
32
wwwroot/js/templates/app.reportDataProdEmail.handlebars
Normal file
32
wwwroot/js/templates/app.reportDataProdEmail.handlebars
Normal file
@@ -0,0 +1,32 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
<div class="row">
|
||||
<div class="half column">
|
||||
<h6>Note: this will fetch all support and admin email addresses</h6>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nocontact">Include 'Do not contact' emails</label>
|
||||
<input type="checkbox" name="ckNoContact" id="ckNoContact">
|
||||
</div>
|
||||
|
||||
<fieldset>
|
||||
<legend>Products:</legend>
|
||||
<div id="cbdiv"></div>
|
||||
</fieldset>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="half column">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="csvdata">Emails</label>
|
||||
<textarea id="csvdata" name="csvdata" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
109
wwwroot/js/templates/app.rfcaseEdit.handlebars
Normal file
109
wwwroot/js/templates/app.rfcaseEdit.handlebars
Normal file
@@ -0,0 +1,109 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
<div class="mb-4">
|
||||
<span class="display-4" id="caseid"></span>
|
||||
<span class="text-muted align-top" id="dtcreated"></span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="title">Title</label>
|
||||
<input class="form-control" type="text" id="title" name="title" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="project">Project</label>
|
||||
<select class="form-control" name="rfCaseProjectId" id="rfCaseProjectId" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="priority">Priority</label>
|
||||
<select class="form-control" name="priority" id="priority">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!--
|
||||
<div class="col-sm-12">
|
||||
<div class="btn-group" role="group">
|
||||
<button id="btn-append" type="button" class="btn btn-outline-primary">Append</button>
|
||||
</div>
|
||||
</div> --}}
|
||||
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="notes">Notes</label>
|
||||
<div class="btn-group float-right" role="group">
|
||||
<button id="btn-append" type="button" class="btn btn-sm btn-outline-primary">Append</button>
|
||||
</div>
|
||||
|
||||
<textarea class="form-control" id="notes" name="notes" rows="15" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="dtClosed"> Closed</label>
|
||||
<input class="form-control" type="date" id="dtClosed" name="dtClosed" value="">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="title">Released in version</label>
|
||||
<input class="form-control" type="text" id="releaseVersion" name="releaseVersion" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="title">Release notes</label>
|
||||
<input class="form-control" type="text" id="releaseNotes" name="releaseNotes" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="col-sm-12">
|
||||
<label for="attachments">Attachments</label>
|
||||
<ul id="attachments" class="list-group">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="app-frm-buttons mt-5">
|
||||
<button id="btn-save" class="btn btn-success">Save</button>
|
||||
<button id="btn-delete" class="btn btn-outline-dark">Delete</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
<form id="frmUpload" class="invisible my-5" method="post" enctype="multipart/form-data" action="/api/rfcaseblob/upload?rfcaseid=1">
|
||||
<hr/>
|
||||
<div>
|
||||
<p>Upload attachments:</p>
|
||||
<input type="file" name="files" id="files" multiple/>
|
||||
</div>
|
||||
<input type="button" id="btn-upload" value="Attach selected files" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
50
wwwroot/js/templates/app.rfcases.handlebars
Normal file
50
wwwroot/js/templates/app.rfcases.handlebars
Normal file
@@ -0,0 +1,50 @@
|
||||
<div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
|
||||
<div class="col-sm-3">
|
||||
<div class="form-group">
|
||||
<label for="project">Projects</label>
|
||||
<select class="form-control" id="projects" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label" for="open">
|
||||
<input class="form-check-input" type="checkbox" id="open" checked/>
|
||||
Open</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3">
|
||||
<div class="form-group">
|
||||
<label for="priority">Priority</label>
|
||||
<select class="form-control" id="priority">
|
||||
<option value="0" selected >All</option>
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3">
|
||||
<div class="form-group">
|
||||
<label for="csearch">Search</label>
|
||||
<input class="form-control" type="text" id="csearch" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
|
||||
<div>
|
||||
<div id="rf-list-count"/>
|
||||
<ul id="rf-list" class="rf-list" />
|
||||
</div>
|
||||
</div>
|
||||
15
wwwroot/js/templates/app.rfsettings.handlebars
Normal file
15
wwwroot/js/templates/app.rfsettings.handlebars
Normal file
@@ -0,0 +1,15 @@
|
||||
<div>
|
||||
<div class="alert alert-success mb-5" id="about" />
|
||||
|
||||
<form id="frm" method="post" action="index.html">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="oldpassword">Change password</label>
|
||||
<input class="form-control" type="text" id="oldpassword" name="oldpassword" placeholder="current password" value="">
|
||||
<input class="form-control" type="text" id="newpassword" name="newpassword" placeholder="new password" value="">
|
||||
<div class="app-frm-buttons mt-5">
|
||||
<button id="btn-change-password">Update</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
18
wwwroot/js/templates/app.search.handlebars
Normal file
18
wwwroot/js/templates/app.search.handlebars
Normal file
@@ -0,0 +1,18 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="query">Search</label>
|
||||
<input class="form-control" type="text" id="searchquery" value="">
|
||||
<div class="app-frm-buttons">
|
||||
<button id="searchbutton">Search</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ul id="rf-list" class="rf-list" />
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
57
wwwroot/js/templates/app.shell.handlebars
Normal file
57
wwwroot/js/templates/app.shell.handlebars
Normal file
@@ -0,0 +1,57 @@
|
||||
<nav id="rf-nav" class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
|
||||
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
|
||||
<li id="inbox" class="nav-item">
|
||||
<a class="rfac nav-link mdi mdi-inbox" href="#!/inbox">Inbox </a>
|
||||
</li>
|
||||
|
||||
<li id="customers" class="nav-item">
|
||||
<a class="rfac nav-link mdi mdi-contacts" href="#!/customers">Customers </a>
|
||||
</li>
|
||||
|
||||
<li id="subscriptions" class="nav-item">
|
||||
<a class="rfac nav-link mdi mdi-basket" href="#!/subscription">Subscriptions </a>
|
||||
</li>
|
||||
|
||||
<li id="license" class="nav-item">
|
||||
<a class="rfac nav-link mdi mdi-key" href="#!/license">License </a>
|
||||
</li>
|
||||
|
||||
<li id="rfcases" class="nav-item">
|
||||
<a class="rfac nav-link mdi mdi-bug" href="#!/rfcases">Cases </a>
|
||||
</li>
|
||||
|
||||
<li id="rfsettings" class="nav-item">
|
||||
<a class="rfac nav-link mdi mdi-settings" href="#!/rfsettings">Settings </a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="rfac nav-link mdi mdi-logout" href="#!/logout">Log off </a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
<div class="rf-content mx-2 ">
|
||||
<div id="app-error-div" class="alert alert-danger d-none" role="alert">
|
||||
<p id="app-error-message"></p>
|
||||
</div>
|
||||
<div>
|
||||
<div id="rf-context-group" class="btn-group my-3" role="group">
|
||||
</div>
|
||||
</div>
|
||||
<main id="app-shell-main-content">
|
||||
|
||||
</main>
|
||||
</div>
|
||||
4
wwwroot/js/templates/app.subnotify.handlebars
Normal file
4
wwwroot/js/templates/app.subnotify.handlebars
Normal file
@@ -0,0 +1,4 @@
|
||||
<div>
|
||||
<ul id="rf-list" class="rf-list" />
|
||||
</div>
|
||||
|
||||
3
wwwroot/js/templates/app.subscription.handlebars
Normal file
3
wwwroot/js/templates/app.subscription.handlebars
Normal file
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<ul id="rf-list" class="rf-list" />
|
||||
</div>
|
||||
28
wwwroot/js/templates/app.templateEdit.handlebars
Normal file
28
wwwroot/js/templates/app.templateEdit.handlebars
Normal file
@@ -0,0 +1,28 @@
|
||||
<div>
|
||||
<form id="frm" method="post" action="index.html">
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input class="form-control" type="text" id="name" name="name" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="template">template</label>
|
||||
<textarea class="form-control" id="template" name="template" rows="15" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="app-frm-buttons mt-5">
|
||||
<button id="btn-save" class="btn btn-success">Save</button>
|
||||
<button id="btn-delete" class="btn btn-outline-dark">Delete</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
3
wwwroot/js/templates/app.templates.handlebars
Normal file
3
wwwroot/js/templates/app.templates.handlebars
Normal file
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<ul id="rf-list" class="rf-list" />
|
||||
</div>
|
||||
2
wwwroot/js/templates/templates.js
Normal file
2
wwwroot/js/templates/templates.js
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user