Files
raven/server/AyaNova/resource/rpt/ay-report.js
2020-09-09 17:32:53 +00:00

314 lines
8.8 KiB
JavaScript

//////////////////////////////////
// Pre render function
//
async function ayPreRender(ayAllData) {
if (typeof ayPrepareData === "function") {
return await ayPrepareData(ayAllData);
} else {
return ayAllData;
}
}
/*
"AYMETA": {
"ayReportMetaData": { "Id": 1, "Name": "report translation test", "Notes": "", "ObjectType": "Widget", "DataListKey": "", "ListView":"", "SelectedRowIds": "90" },
"ayClientMetaData": {
"UserName": "AyaNova SuperUser",
"Authorization": "BearereyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNjAwMjYzOTEzIiwiaXNzIjoiYXlhbm92YS5jb20iLCJpZCI6IjEifQ.NGpDgg8mf54oTU8fyExBf1yXnsaIaHedGFmKLKlNCZ4",
"TimeZoneName": "America/Los_Angeles", "LanguageName": "en-US", "Hour12": true, "CurrencyName": "USD", "DefaultLocale": "en" }
*/
///////////////////////////////////////
// Set our stock handlebars helpers
//
function ayRegisterHelpers() {
Handlebars.registerHelper("ayCaps", function (aString) {
return aString.toUpperCase();
});
Handlebars.registerHelper("ayDateTime", function (timestamp) {
return utcDateToShortDateAndTimeLocalized(timestamp);
});
Handlebars.registerHelper("ayDate", function (timestamp) {
return utcDateToShortDateLocalized(timestamp);
});
Handlebars.registerHelper("ayTime", function (timestamp) {
return utcDateToShortTimeLocalized(timestamp);
});
Handlebars.registerHelper("ayDecimal", function (value) {
return decimalLocalized(value);
});
Handlebars.registerHelper("ayCurrency", function (value) {
return currencyLocalized(value);
});
Handlebars.registerHelper("ayMarkdown", function (astring) {
return marked(astring, { breaks: true });
});
Handlebars.registerHelper("ayJSON", function (obj) {
return JSON.stringify(obj, null, 3);
});
Handlebars.registerHelper("ayLink", function (text, url) {
var url = Handlebars.escapeExpression(url),
text = Handlebars.escapeExpression(text);
return new Handlebars.SafeString("<a href='" + url + "'>" + text + "</a>");
});
Handlebars.registerHelper("ayLogo", function (size) {
var url = `${Handlebars.escapeExpression(
this.ayServerMetaData.ayApiUrl
)}logo/${size}`;
return new Handlebars.SafeString("<img src='" + url + "'/>");
});
Handlebars.registerHelper("ayT", function (translationKey) {
if (ayTranslationKeyCache[translationKey] == undefined) {
return translationKey;
}
return ayTranslationKeyCache[translationKey];
});
} //eof
///////////////////////////////////////////
// Turn a utc date into a displayable
// short date and time
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString
//
function utcDateToShortDateAndTimeLocalized(value) {
if (!value) {
return "";
}
//parse the date which is identified as utc ("2020-02-06T18:18:49.148011Z")
let parsedDate = new Date(value);
//is it a valid date?
if (!(parsedDate instanceof Date && !isNaN(parsedDate))) {
return "not valid";
}
return parsedDate.toLocaleString(AYMETA.ayClientMetaData.LanguageName || "en-US", {
timeZone: AYMETA.ayClientMetaData.TimeZoneName || "America/Winnipeg",
dateStyle: "short",
timeStyle: "short",
hour12: AYMETA.ayClientMetaData.Hour12
});
}
///////////////////////////////////////////
// Turn a utc date into a displayable
// short date
//
function utcDateToShortDateLocalized(value) {
if (!value) {
return "";
}
//parse the date which is identified as utc ("2020-02-06T18:18:49.148011Z")
let parsedDate = new Date(value);
//is it a valid date?
if (!(parsedDate instanceof Date && !isNaN(parsedDate))) {
return "not valid";
}
return parsedDate.toLocaleDateString(AYMETA.ayClientMetaData.LanguageName || "en-US", {
timeZone: AYMETA.ayClientMetaData.TimeZoneName || "America/Winnipeg",
dateStyle: "short"
});
}
///////////////////////////////////////////
// Turn a utc date into a displayable
// short time
//
function utcDateToShortTimeLocalized(value) {
if (!value) {
return "";
}
//parse the date which is identified as utc ("2020-02-06T18:18:49.148011Z")
let parsedDate = new Date(value);
//is it a valid date?
if (!(parsedDate instanceof Date && !isNaN(parsedDate))) {
return "not valid";
}
return parsedDate.toLocaleTimeString(AYMETA.ayClientMetaData.LanguageName || "en-US", {
timeZone: AYMETA.ayClientMetaData.TimeZoneName || "America/Winnipeg",
timeStyle: "short",
hour12: AYMETA.ayClientMetaData.Hour12
});
}
///////////////////////////////////////////
// CURRENCY LOCALIZATION
//
//
function currencyLocalized(value) {
if (!value) {
return "";
}
return new Intl.NumberFormat(
AYMETA.ayClientMetaData.LanguageName || "en-US",
{ style: 'currency', currency: AYMETA.ayClientMetaData.CurrencyName || "USD" }
).format(value)
}
///////////////////////////////////////////
// DECIMAL LOCALIZATION
//
//
function decimalLocalized(value) {
if (!value) {
return "";
}
return new Intl.NumberFormat(
AYMETA.ayClientMetaData.LanguageName || "en-US"
).format(value)
}
//////////////////////////////////
// cache to hold translations keys
//
var ayTranslationKeyCache = {};
///////////////////////////////////
// GET TRANSLATIONS FROM API SERVER
//
async function ayGetTranslations(keys) {
if (!keys || keys.length == 0) {
return;
}
try {
let transData = await ayPostToAPI("translation/subset", keys);
transData.data.forEach(function storeFetchedTranslationItemsInCache(item) {
ayTranslationKeyCache[item.key] = item.value;
});
} catch (error) {
//fundamental error, can't proceed with this call
// handleError("GET", error, route);
//todo: deal with this properly
throw error;
}
}
///////////////////////////////////
// GET DATA FROM API SERVER
//
async function ayGetFromAPI(route, token) {
token = token || AYMETA.ayClientMetaData.Authorization;
if (route && !route.startsWith("http")) {
route = AYMETA.ayServerMetaData.ayApiUrl + route;
}
try {
let r = await fetch(route, {
method: "get",
mode: "cors",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: token
}
});
return await r.json();
} catch (error) {
//fundamental error, can't proceed with this call
// handleError("GET", error, route);
//todo: deal with this properly
throw error;
}
}
///////////////////////////////////
// POST DATA TO API SERVER
//
async function ayPostToAPI(route, data, token) {
token = token || AYMETA.ayClientMetaData.Authorization;
if (route && !route.startsWith("http")) {
route = AYMETA.ayServerMetaData.ayApiUrl + route;
}
try {
fetchOptions = {
method: "post",
mode: "cors",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: token
},
body: JSON.stringify(data)
};
let r = await fetch(route, fetchOptions);
return await r.json();
} catch (error) {
//todo: better handle this
throw error;
}
}
/*
async function ayPrepareData(reportData) {
//this function (if present) is called with the report data
//before the report is rendered
//modify data as required here and return it to change the data before the report renders
//Example of using API GET method to fetch data from API server and make it available to the report template
let route=`${reportData.ayServerMetaData.ayApiUrl}server-info`;
//Put the data into the main report data object so it's available to the template
reportData.myData={ServerInfo:await ayGetFromAPI(route, reportData.ayClientMetaData.Authorization)};
//Example API POST method to fetch data from api server
route=`${reportData.ayServerMetaData.ayApiUrl}search`;
let searchPostData={phrase: "Fish"};
reportData.myData.SearchResults=await ayPostToAPI(route, reportData.ayClientMetaData.Authorization,searchPostData);
return reportData;
}
<html>
<body>
<div>
<h4>ayServerMetaData</h4>
{{ ayJSON ayServerMetaData }}
</div>
<div>
<h4>ayClientMetaData</h4>
{{ ayJSON ayClientMetaData }}
</div>
<div>
<h4>ayReportMetaData</h4>
{{ ayJSON ayReportMetaData }}
</div>
<div>
<h4>myData</h4>
<h5>(Fetched dynamically from API route <strong>enum-list/list/AyaType</strong>)</h5>
{{ ayJSON myData }}
</div>
<div>
<h4>ayReportData</h4>
{{#each ayReportData}}
<h2>{{ Name }}</h2>
<div>Notes: <span class="example">{{ Notes }}</span></div>
{{/each}}
</div>
</body>
</html>
*/