////////////////////////////////// // 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("" + text + ""); }); Handlebars.registerHelper("ayLogo", function (size) { var url = `${Handlebars.escapeExpression( this.ayServerMetaData.ayApiUrl )}logo/${size}`; return new Handlebars.SafeString(""); }); 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; }

ayServerMetaData

{{ ayJSON ayServerMetaData }}

ayClientMetaData

{{ ayJSON ayClientMetaData }}

ayReportMetaData

{{ ayJSON ayReportMetaData }}

myData

(Fetched dynamically from API route enum-list/list/AyaType)
{{ ayJSON myData }}

ayReportData

{{#each ayReportData}}

{{ Name }}

Notes: {{ Notes }}
{{/each}}
*/