314 lines
8.8 KiB
JavaScript
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>
|
|
|
|
*/
|