1// Common javascript functions and variables to be reused across the site. 2var dateFormat = 'yyyy-MM-dd'; 3var timeFormat = 'HH:mm:ss'; 4var dateTimeFormat = 'yyyy-MM-dd HH:mm:ss'; 5var zeroDateTime = '0000-00-00 00:00:00'; 6var zeroTime = '00:00:00'; 7var AccessToken = false; 8 9async function selectBoxFill(URL, selector, key_name, value_name, first_option) { 10 let obj = await $.post(URL, { AccessToken }, null, "json"); 11 // we need to always return a promise or the chain run out of order, giving undefined results. 12 let sel = $(selector); 13 //console.log("selectBoxFill",obj); 14 if (obj.success) { 15 let rows = obj.rows; 16 if (typeof first_option != 'undefined') { 17 sel.append( 18 $('<option>', { 19 value: 0, 20 text: first_option 21 }) 22 ); 23 } 24 if (!rows) throw "Error: undefined rows." 25 rows.forEach(r => { 26 let key = r[key_name]; // can't use compound elements in a json object. 27 let Name = r[value_name]; 28 sel.append($('<option>', { 29 value: key, 30 text: Name 31 })); 32 }); 33 return rows; // useful for debugging! 34 } throw obj.error_msg; 35} 36 37 38async function selectBoxFillEx(URL, options_ar, selector, key_name, value_name, first_option) { 39 // If you have extra parameters you can pass them in the options_ar. For example: [{"EmployeeID":EmployeeID}] 40 let data = { AccessToken }; 41 options_ar.forEach((ob, index) => { 42 Object.assign(data, ob); 43 }); 44 let obj = await $.post(URL, data, null, "json"); 45 // we need to always return a promise or the chain run out of order, giving undefined results. 46 let sel = $(selector); 47 //console.log("selectBoxFill",obj); 48 if (obj.success) { 49 let rows = obj.rows; 50 if (typeof first_option != 'undefined') { 51 sel.append( 52 $('<option>', { 53 value: 0, 54 text: first_option 55 }) 56 ); 57 } 58 if (!rows) throw "Error: undefined rows." 59 rows.forEach(r => { 60 let key = r[key_name]; // can't use compound elements in a json object. 61 let Name = r[value_name]; 62 sel.append($('<option>', { 63 value: key, 64 text: Name 65 })); 66 }); 67 return rows; // useful for debugging! 68 } throw obj.error_msg; 69} 70 71async function selectPairFill(url, selector) { // json files 72 let obj = await $.getJSON(url); 73 //console.log(obj); 74 let sel = $(selector); 75 for (let key in obj) { 76 let value = obj[key]; 77 sel.append( 78 $('<option>', { 79 value: key, 80 text: value 81 }) 82 ); 83 } 84 return obj; 85} 86 87function catchMsg(er, selector) { 88 let msg; 89 if (typeof er == 'undefined') { 90 msg = 'Error: Undefined Error.'; 91 } else if (typeof er == "string") { 92 msg = er; 93 } else { 94 switch (er.status) { 95 case 400: msg = `Error: Malformed request`; break; 96 case 401: msg = `Error: Unauthorized Access`; break; 97 case 404: msg = `Error: Page not Found`; break; 98 case 429: msg = `Error: You've made too many requests, try again in 15 minutes.`; break; 99 case 500: msg = `Error: Internal Server Error`; break; 100 default: msg = `Error: Unknown Error - ${er.status}`; 101 } 102 } 103 $(selector).html(msg); 104} 105 106 107function accessCheck() { 108 let str = window.localStorage.getItem('access'); 109 //console.log(str); 110 let authorized = false; 111 if (str) { 112 let access = JSON.parse(str); 113 if (luxon.DateTime.now() < luxon.DateTime.fromSQL(access.expires)) { // expires in utc 114 authorized = true; 115 AccessToken = access.token; 116 RouteKey = access.route_key; 117 $('nav').addClass('authorized'); 118 } 119 //console.log([access, authorized]); 120 } 121 if ($('body').hasClass('need-auth') && !authorized) { 122 window.location.assign('/signinv'); 123 } 124} 125 126function setAccessTokenSubdomain() { 127 // This copies the access tokens fromm vegeworx.com, 128 // to plant.vegeworx.com. Allowing the access system to 129 // work with both domains. Call this routine from window.load 130 // on any page that is targetted after a sign in, such as /user/dash. 131 // Make sure the target page has an iframe of form: 132 // <iframe src="https://plants.vegeworx.com/framework/localStorage.html" class="invisible"></iframe> 133 let win = document.getElementById('subdomain-iframe').contentWindow; 134 let key = 'access'; 135 let astr = window.localStorage.getItem(key); 136 if (!astr) { 137 console.log("Access token not set."); 138 return; 139 } 140 let value = JSON.parse(astr); 141 //console.log(value); 142 // load previously saved data 143 win.postMessage(JSON.stringify({ method: "set", key, value }), "*"); 144 //win.postMessage(JSON.stringify({ method: "get", key }), "*"); 145} 146 147async function signout() { 148 // snick todo redirect on access.created expired. 149 window.localStorage.clear(); 150 try { 151 await $.post('/signout', { AccessToken }, null, "json"); 152 } catch (er) { 153 catchMsg(er, '#error-msg'); 154 } 155 window.location.assign('/'); 156} 157 158function dateOnly(datetimeString) { 159 if (!datetimeString) return null; 160 // Convert the string to a Date object 161 let datetimeObject = new Date(datetimeString); 162 // Format the Date object to get only the date part 163 return datetimeObject.toISOString().split('T')[0]; 164} 165 166function strToMinutes(timeString) { // convert HH:MM:SS to minutes
167 const [hours, minutes] = timeString.split(':').map(Number); 168 if (isNaN(hours) || hours < 0 || (minutes !== undefined && (isNaN(minutes) || minutes < 0))) return null; 169 const totalMinutes = (minutes !== undefined) ? hours * 60 + minutes : hours * 60; // If minutes are not provided, assume 0 170 return totalMinutes; 171} 172function minutesToStr(totalMinutes) { // convert to HH:MM:SS 173 if (!totalMinutes) return ""; 174 const hours = Math.floor(totalMinutes / 60); 175 const minutes = totalMinutes % 60; 176 const formattedHours = String(hours).padStart(2, '0'); 177 const formattedMinutes = String(minutes).padStart(2, '0'); 178 return `${formattedHours}:${formattedMinutes}`; 179} 180 181$(() => { 182 $('#signout').click(ev => { signout(); }); 183 accessCheck(); 184}); 185 186 187
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.