id,active,data,dateLastModified,description,name,note,typeId,fbVersion,fbName,published 1,_binary ," {% Template Default_Header %}

",2024-05-15 08:55:40.400000,Compares current fulfilled month to date revenue against last year,MTD Chart,,10,3,mtd-chart,1 2,_binary ,"const today = new Date(); var canvas = document.querySelector('canvas'); function createYearQuery(subtractYear) { let mm = (today.getMonth() + 1).toString().padStart(2, '0'); // January is 0! let timestamp = (today.getFullYear() - subtractYear) + '-' + mm + '-01 00:00:00'; return ""SELECT DAY(PostSo.postDate) AS PostedDate, SUM(PostSoItem.totalPrice) AS TotalPrice "" + ""FROM PostSoItem "" + ""JOIN PostSo ON PostSo.id = PostSoItem.postSoId "" + ""JOIN SoItem ON PostSoItem.soItemId = SoItem.id AND SoItem.typeId <> 40 AND SoItem.statusID = 50 "" + ""WHERE postDate >= '"" + timestamp + ""' "" + ""AND postDate < DATE_ADD('"" + timestamp + ""', INTERVAL 1 MONTH) "" + ""GROUP BY CAST(PostSo.postDate AS DATE)""; } function createData(query) { const result = runQuery(query); return JSON.parse(result); } function createDataset(label, data, backgroundColor, borderColor) { return { label: label, fill: true, data: data, backgroundColor: backgroundColor, borderColor: borderColor, borderWidth: 2, pointRadius: 3, pointHoverRadius: 5, pointHitRadius: 7, lineTension: 0 }; } const data = []; data.push(createData(createYearQuery(1))); data.push(createData(createYearQuery(0))); console.log(data); let runningTotal = 0; const monthData = []; const labels = []; for (let year = 0; year < data.length; year++) { if(data[year].length != 0){ data[year] = data[year].reduce( (obj, day) => { obj[day.posteddate] = day.totalprice; return obj; }, {}); runningTotal = 0; let mData = []; let yearOffset = 1 if (year == 1) {yearOffset = 0} for (let day = 1; day <= new Date((today.getFullYear() - yearOffset), today.getMonth() + 1, 0).getDate(); day++) { if (labels.length < moment().daysInMonth()) { labels.push(day); } if (year === data.length - 1 && day > today.getDate()) { continue; } runningTotal += data[year][day] || 0; mData.push(runningTotal); } monthData.push(mData); } } const chartData = []; const currentYearColor = '$COLOR{Current_Year|#33D566}'; const previousYearColor = '$COLOR{Previous_Year|#4682b4}'; if (monthData.length == 1) { chartData.push(createDataset(today.getFullYear(), monthData[0], UTIL.convertHex(currentYearColor, 50), currentYearColor)); chartData.push(createDataset(today.getFullYear() - 1, monthData[1], UTIL.convertHex(previousYearColor, 50), previousYearColor)); } else { chartData.push(createDataset(today.getFullYear(), monthData[1], UTIL.convertHex(currentYearColor, 50), currentYearColor)); chartData.push(createDataset(today.getFullYear() - 1, monthData[0], UTIL.convertHex(previousYearColor, 50), previousYearColor)); } const options = { legend: { position: 'right' }, scales: { yAxes: [{ ticks: { beginAtZero: true, callback: function (value, values) { return UTIL.dollarify(value, 0); } } }], }, tooltips: { callbacks: { label: function (tooltipItem, data) { return UTIL.dollarify(tooltipItem.yLabel); }, title: (tooltipItem) => { return moment().format('MMMM') + ' ' + tooltipItem[0].xLabel; } } }, responsive: true, maintainAspectRatio: false, plugins: { datalabels: { display: false } } }; const ctx = document.getElementById('myChart'); new Chart(ctx, { type: 'line', data: { labels: labels, datasets: chartData }, options: options }); document.getElementById(""title"").innerHTML = 'Revenue ' + moment().format('MMMM') + ' ' + today.getFullYear(); document.getElementById(""subTitle"").innerHTML = 'MTD - ' + UTIL.dollarify(runningTotal); document.getElementById(""description"").innerHTML = ''; ",2024-05-15 08:55:40.430000,Query and logic for the MTD Chart page,MTD Chart,,20,3,mtd-chart,0 3,_binary ," ",2023-01-05 17:28:06.927000,Default header that includes common library dependencies,Default Header,,40,2,fb-gadget-header,0 4,_binary ,"const UTIL = { ""convertHex"": function(hex,opacity) { hex = hex.replace('#',''); r = parseInt(hex.substring(0,2), 16); g = parseInt(hex.substring(2,4), 16); b = parseInt(hex.substring(4,6), 16); const result = 'rgba('+r+','+g+','+b+','+opacity/100+')'; return result; }, ""dollarify"": function (amount, decimalCount = 2, decimal = ""."", thousands = "","") { decimalCount = Math.abs(decimalCount); decimalCount = isNaN(decimalCount) ? 2 : decimalCount; const negativeSign = amount < 0 ? ""-"" : """"; let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString(); let j = (i.length > 3) ? i.length % 3 : 0; return '$' + negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, ""$1"" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : """"); }, ""uomify"" : function(qty, uom){ return qty.toString() + "" "" + uom; }, ""convertDate"": function(date, isFromDate) { const parsed = new Date(Date.parse(date)); if (isFromDate) { return moment(parsed.setDate(parsed.getDate() + 1)).format('MM/DD/YYYY'); } return moment(parsed.setDate(parsed.getDate())).format('MM/DD/YYYY'); }, ""makeTable"": function (query, headersArray, dontShow = []) { var tr = """"; // SET COLUMN HEADERS for (var h = 0; h < headersArray.length; h++) { tr += """" + headersArray[h] + """"; } //ADD ROW DATA FROM QUERY for (var i = 0; i < query.length; i++) { // ADD NEW ROW tr += """"; // PRINT COLUMN DATA FOR THIS ROW for (var j in query[i]) { // CHECK TO SEE IF IT IS IN DONT SHOW LIST if (dontShow.includes(j)) { continue; } else { if (query[i].hasOwnProperty(j)) { tr += """" + query[i][j] + """"; } } } tr += """" } return tr; }, ""unflatten"" : function(data) { ""use strict""; if (Object(data) !== data || Array.isArray(data)) { return data; } var result = {}, cur, prop, idx, last, temp; for(var p in data) { cur = result, prop = """", last = 0; do { idx = p.indexOf(""."", last); temp = p.substring(last, idx !== -1 ? idx : undefined); cur = cur[prop] || (cur[prop] = (!isNaN(parseInt(temp)) ? [] : {})); prop = temp; last = idx + 1; } while(idx >= 0); cur[prop] = data[p]; } return result[""""]; }, ""flatten"" : function(data) { var result = {}; function recurse (cur, prop) { if (Object(cur) !== cur) { result[prop] = cur; } else if (Array.isArray(cur)) { for(var i=0, l=cur.length; i=g.left&&c<=g.right&&k>=g.top&&k<=g.bottom)return!1}d=[[g.left,g.top],[g.left,g.bottom],[g.right,g.top],[g.right,g.bottom]];for(e=0;e=a&&c<=b&&k>=p&&k<=l)return!1}h.push({left:a,right:b,top:p,bottom:l});return!0},c.prototype.measureText=function(a){return""object""=== typeof a?{width:a.width,height:a.height}:this.ctx.measureText(a)},c.prototype.fillText=function(a,b,p){var c=this.ctx;""object""===typeof a?c.drawImage(a,b.x-a.width/2,b.y-a.height/2,a.width,a.height):(c.fillStyle=p,c.textBaseline=""top"",c.textAlign=""center"",c.fillText(a,b.x,b.y-this.fontSize/2))},c.prototype.loadImage=function(a){var b=new Image;b.src=a.src;b.width=a.width;b.height=a.height;return b},c.prototype.drawArcText=function(a,b,c,l){var h=this.ctx,f=c.x,g=c.y,d=c.startAngle;c=c.endAngle;h.save(); h.translate(f,g);g=c-d;d+=Math.PI/2;c+=Math.PI/2;var e=d;f=this.measureText(a);d+=(c-(f.width/b+d))/2;if(l||!(c-d>g))if(""string""===typeof a)for(h.rotate(d),l=0;l {% Template Default_Header %}

",2023-01-05 17:28:06.943000,Map that displays revenue by region,Sales By Region,"Default Location Syntax: United States: US California: US-CA Utah: US-UT Australia: AU New South Wales, AU: AU-NSW",10,3,sales-by-region,1 10,_binary ,"google.charts.load('current', { 'packages': ['geochart'], 'mapsApiKey': 'AIzaSyBZsbr4RQBre8LIOeEN9P-qlmiKGSi95aU' }); const dateRange = $RANGE{Date_Range|This year-to-date}; let defaultDrillDown = { region: ""$TEXT{Default_Location|Global}"" }; let dateStr = UTIL.convertDate(dateRange.fromDate, true) + "" - "" + UTIL.convertDate(dateRange.toDate, false); if (moment(dateRange.fromDate).isSame('1000-01-01', 'year') && moment(dateRange.toDate).isSame('3000-01-01', 'year')) { dateStr = 'All'; } const VIEW = { world: ""world"", country: ""country"", province: ""province"" }; let currentView = VIEW.world; let previousCountry; google.charts.setOnLoadCallback(drawWorldMap); const btnBack = document.getElementById('button'); const subTitleHTML = document.getElementById('subTitle'); const titleHTML = document.getElementById('title'); const descriptionHTML = document.getElementById('description'); btnBack.addEventListener(""click"", btnBackEvent); let chart; let currentData = {}; let subTitle = 'Global'; let worldData; let countryData; let countryOptions = { legend: { textStyle: { fontSize: 16 }, numberFormat: '¤#,##0.00' }, resolution: ""provinces"", keepAspectRatio: true, width: '100%', height: '100%' }; function getWorldData() { let worldFbData = JSON.parse(runQuery(""SELECT SUM(postSoItem.totalPrice) AS totalPrice, abbreviation FROM postSoItem "" + ""JOIN soItem ON postSoItem.soItemId = soItem.id "" + ""JOIN so ON so.id = soItem.soId AND soItem.statusID = 50 AND soItem.typeId <> 40 "" + ""JOIN CountryConst ON so.billToCountryId = CountryConst.id "" + ""JOIN postso ON postso.id = postsoitem.postsoid "" + ""WHERE postSoItem.totalPrice > 0 AND postSo.postDate >= '"" + dateRange.fromDate + ""' AND postSo.postDate <= '"" + dateRange.toDate + ""' "" + ""GROUP BY CountryConst.id"")); let worldData = [ ['Country', 'Revenue', { type: 'string', role: 'tooltip' }] ]; for (let i = 0; i < worldFbData.length; i++) { worldData.push([worldFbData[i].abbreviation, worldFbData[i].totalprice, 'Revenue: ' + UTIL.dollarify(worldFbData[i].totalprice)]); } return worldData; } // Solid color fill for US, CA, and AU function getSolidProvincesData(country) { let USCAdata = JSON.parse(runQuery(""SELECT SUM(postSoItem.totalPrice) AS totalPrice, code AS state, billToCity AS city FROM postSoItem "" + ""JOIN soItem ON postSoItem.soItemId = soItem.id "" + ""JOIN so ON so.Id = soItem.soId AND soItem.statusId = 50 AND soItem.typeId <> 40 "" + ""LEFT JOIN StateConst ON so.billToStateId = StateConst.id "" + ""JOIN CountryConst ON so.billToCountryId = CountryConst.id AND CountryConst.abbreviation = '"" + country + ""' "" + ""JOIN postso ON postso.soId = so.id "" + ""WHERE postSoItem.totalPrice > 0 AND postSo.postDate >= '"" + dateRange.fromDate + ""' AND postSo.postDate <= '"" + dateRange.toDate + ""' "" + ""GROUP BY state"")); let tableData = [ [""State"", ""Revenue"", { type: 'string', role: 'tooltip' }] ]; for (let i = 0; i < USCAdata.length; i++) { let region = country + ""-"" + USCAdata[i].state; tableData.push([region, USCAdata[i].totalprice, 'Revenue: ' + UTIL.dollarify(USCAdata[i].totalprice)]); } return tableData; } function getCountryData(country) { let countryFbData = JSON.parse(runQuery(""SELECT SUM(postSoItem.totalPrice) AS totalPrice, code AS state, billToCity AS city FROM postSoItem "" + ""JOIN soItem ON postSoItem.soItemId = soItem.id "" + ""JOIN so ON so.Id = soItem.soId AND soItem.statusId = 50 AND soItem.typeId <> 40 "" + ""LEFT JOIN StateConst ON so.billToStateId = StateConst.id "" + ""JOIN CountryConst ON so.billToCountryId = CountryConst.id AND CountryConst.abbreviation = '"" + country + ""' "" + ""JOIN postso ON postso.soId = so.id "" + ""WHERE postSoItem.totalPrice > 0 AND postSo.postDate >= '"" + dateRange.fromDate + ""' AND postSo.postDate <= '"" + dateRange.toDate + ""' "" + ""GROUP BY city"")); let tableData = [ [""City"", ""Revenue"", { type: 'string', role: 'tooltip' }] ]; for (let i = 0; i < countryFbData.length; i++) { tableData.push([countryFbData[i].city, countryFbData[i].totalprice, 'Revenue: ' + UTIL.dollarify(countryFbData[i].totalprice)]); } return tableData; } function getProvinceData(country, province) { let provinceData = JSON.parse(runQuery(""SELECT SUM(postSoItem.totalPrice) AS totalPrice, code AS state, billToCity AS city FROM postSoItem "" + ""JOIN soItem ON postSoItem.soItemId = soItem.id "" + ""JOIN so ON so.Id = soItem.soId AND soItem.statusId = 50 AND soItem.typeId <> 40 "" + ""LEFT JOIN StateConst ON so.billToStateId = StateConst.id "" + ""JOIN CountryConst ON so.billToCountryId = CountryConst.id AND CountryConst.abbreviation = '"" + country + ""' "" + ""JOIN postso ON postso.soId = so.id "" + ""WHERE postSoItem.totalPrice > 0 AND postSo.postDate >= '"" + dateRange.fromDate + ""' AND postSo.postDate <= '"" + dateRange.toDate + ""' "" + ""AND CODE = '"" + province + ""' "" + ""GROUP BY city"")); let tableData = [ [""City"", ""Revenue"", { type: 'string', role: 'tooltip' }] ]; for (let i = 0; i < provinceData.length; i++) { tableData.push([provinceData[i].city, provinceData[i].totalprice, 'Revenue: ' + UTIL.dollarify(provinceData[i].totalprice)]); } return tableData; } function drawWorldMap() { btnBack.style.visibility = 'hidden'; subTitle = 'Global'; currentView = VIEW.world; worldData = google.visualization.arrayToDataTable(getWorldData()); chart = new google.visualization.GeoChart(document.getElementById('regions_div')); google.visualization.events.addListener(chart, 'regionClick', drawCountryMap); const worldOptions = { legend: { textStyle: { fontSize: 16 }, numberFormat: '¤#,##0.00' }, displayMode: 'auto', keepAspectRatio: true, width: '100%', height: '100%' }; currentData.data = worldData; currentData.options = worldOptions; subTitleHTML.innerHTML = subTitle; chart.draw(currentData.data, currentData.options); if (defaultDrillDown && defaultDrillDown.region != ""Global"") { google.visualization.events.trigger(chart, 'regionClick', defaultDrillDown); if (defaultDrillDown.region.length > 2) { currentView = VIEW.province; previousCountry = { region: defaultDrillDown.region.substring(0, 2) }; } defaultDrillDown = null; } } function drawCountryMap(country) { if (currentView == VIEW.world) { previousCountry = country; } currentView = VIEW.country; btnBack.style.visibility = 'visible'; let countryStr = country.region.substring(0, 2); let hasProvinces = countryStr == 'US' || countryStr == 'CA' || countryStr == 'AU'; countryData = hasProvinces ? google.visualization.arrayToDataTable(getSolidProvincesData(countryStr)) : google.visualization.arrayToDataTable(getCountryData(countryStr)); subTitle = country.region; if (country.region.includes('-')) { currentView = VIEW.province; let provinceStr = country.region.substring(3); countryOptions.displayMode = 'markers'; countryOptions.region = country.region; if (countryStr == 'CA' || countryStr == 'AU') { countryOptions.region = countryStr; } let provinceData = google.visualization.arrayToDataTable(getProvinceData(countryStr, provinceStr)); currentData.data = provinceData; currentData.options = countryOptions; } else { countryOptions.region = countryStr; countryOptions.displayMode = hasProvinces ? 'auto' : 'markers'; currentData.data = countryData; currentData.options = countryOptions; } chart.draw(currentData.data, currentData.options); subTitleHTML.innerHTML = subTitle; } function btnBackEvent() { if (currentView == VIEW.province) { drawCountryMap(previousCountry); } else { drawWorldMap(); } } window.onresize = function (event) { chart.draw(currentData.data, currentData.options); } titleHTML.innerHTML = ""Sales By Region""; subTitleHTML.innerHTML = subTitle; descriptionHTML.innerHTML = dateStr;",2023-01-05 17:28:06.959000,Query and logic for the Sales By Region page,Sales By Region,,20,3,sales-by-region,0 11,_binary ," {% Template Default_Header %}

",2023-01-05 17:28:06.959000,Compares fulfilled revenue by rep,Sales By Rep,,10,5,sales-by-rep,1 12,_binary ,"const dateRange = $RANGE{Date_Range|this month}; const includeReturns = $CHECK{IncludeReturns|false}; const includeDiscounts = $CHECK{IncludeDiscounts|false}; const query = `SELECT so.salesman, SUM(postSoItem.totalPrice) AS totalPrice FROM postSoItem JOIN soItem ON postSoItem.soItemId = soitem.id AND soItem.typeId <> 40 AND soItem.qtyfulfilled > 0 JOIN so ON soItem.soId = so.id JOIN postSo ON postSo.Id = postsoitem.postsoid WHERE postSo.postDate between '${dateRange.fromDate}' AND '${dateRange.toDate}' AND IF(${includeReturns} = 1,1=1,soitem.typeid NOT IN (20,21)) AND IF(${includeDiscounts} = 1,1=1,soitem.typeid NOT IN (30,31)) GROUP BY so.salesmanId ORDER BY totalPrice DESC`; const data = JSON.parse(runQuery(query)); console.log(query); console.log(data); let dateStr = UTIL.convertDate(dateRange.fromDate, true) + "" - "" + UTIL.convertDate(dateRange.toDate, false); if (moment(dateRange.fromDate).isSame('1000-01-01', 'year') && moment(dateRange.toDate).isSame('3000-01-01', 'year')) { dateStr = 'All'; } function createBar(totalPrice, tableColors){ return { backgroundColor: tableColors.halfAlpha, borderColor: tableColors.fullAlpha, borderWidth: 3, data: totalPrice, }; } const barLabels = []; const barTotalPrices = []; let barTotalPriceOverall = 0; const chartData = []; for (let salesman = 0; salesman < data.length; salesman++) { barLabels.push(data[salesman].salesman); barTotalPrices.push(data[salesman].totalprice); barTotalPriceOverall += barTotalPrices[salesman]; } let tableColors = COLORS.get(data.length); chartData.push(createBar(barTotalPrices, tableColors)); const barChartData = { labels: barLabels, datasets: chartData } const barOptions = { title: { display: true, padding: 3 }, mode: 'index', position: 'cursor', intersect: false, legend: { display: false, }, scales: { xAxes: [{ ticks: { autoSkip: false } }], yAxes: [{ ticks: { beginAtZero: true, callback: function(value, index, values) { return UTIL.dollarify(value, 0); } } }] }, tooltips: { callbacks: { label: (tooltipItem, data) => { return UTIL.dollarify(tooltipItem.yLabel); }, title: (tooltipItem, data) => { return tooltipItem[0].xLabel; } }, }, responsive: true, maintainAspectRatio: false, plugins: { datalabels: { align: 'end', anchor: 'end', color: '#828891', font: { weight: 'bold', family: 'Helvetica' }, formatter: function(value, context) { return UTIL.dollarify(value); } } } }; const ctxBar = document.getElementById('topSalesman'); new Chart(ctxBar, { type: 'bar', data: barChartData, options: barOptions }); document.getElementById(""title"").innerHTML = 'Sales By Rep'; document.getElementById(""subTitle"").innerHTML = dateStr; document.getElementById(""description"").innerHTML = '';",2023-01-05 17:28:06.974000,Query and logic for the Sales By Rep page,Sales By Rep,,20,5,sales-by-rep,0 13,_binary ," {% Template Default_Header %}

",2023-01-05 17:28:06.974000,Shows progress towards revenue goal,Sales Goal Chart,,10,3,sales-goal,1 14,_binary ,"const dateRange = $RANGE{Date_Range|this month}; const currentSalesColor = '$COLOR{Current_Sales_Color|#33D566}'; let goal = ""$MONEY{Goal}""; goal = Number(goal.replace(/[^0-9\.-]+/g,"""")); let rep = ""$USER{Rep|%}""; if (rep != ""%""){ rep = parseInt(rep); } if (rep == -1) { rep = ""%""; } const data = JSON.parse(runQuery(""SELECT sysuser.firstName, sysuser.lastName, DAY(PostSo.postDate) AS PostedDate, SUM(PostSoItem.totalPrice) AS TotalPrice "" + ""FROM PostSoItem "" + ""JOIN PostSo ON PostSo.id = PostSoItem.postSoId "" + ""JOIN SoItem ON PostSoItem.soItemId = SoItem.id AND SoItem.typeId <> 40 "" + ""JOIN so ON so.id = soitem.soId "" + ""JOIN sysuser ON so.salesmanId = sysuser.id "" + ""WHERE postDate >= '"" + dateRange.fromDate + ""' "" + ""AND postDate <= '"" + dateRange.toDate + ""' "" + ""AND salesmanId LIKE '"" + rep + ""' "" + ""GROUP BY CAST(PostSo.postDate AS DATE), sysuser.firstName, sysuser.lastName"")); const doughnutLabels = [""Current Sales"",""Remaining Goal""]; const doughnutDatasets = []; const allSales = [] let totalSales = 0; for (let i = 0; i < data.length; i++) { totalSales += data[i].totalprice; } const goalSales = totalSales; let remainingGoal = goal - goalSales; remainingGoal = remainingGoal < 0 ? 0 : remainingGoal; allSales.push(goalSales); allSales.push(remainingGoal); doughnutDatasets.push(createDoughnut(allSales, [UTIL.convertHex(currentSalesColor,100),'rgba(0,0,0,0)'],[UTIL.convertHex(currentSalesColor,50),UTIL.convertHex(currentSalesColor,50)])); let dateStr = UTIL.convertDate(dateRange.fromDate, true) + "" - "" + UTIL.convertDate(dateRange.toDate, false); if (moment(dateRange.fromDate).isSame('1000-01-01', 'year') && moment(dateRange.toDate).isSame('3000-01-01', 'year')) { dateStr = 'All'; } const doughnutData = { labels: doughnutLabels, datasets: doughnutDatasets }; const doughnutOptions = { tooltips: { callbacks: { label: function (tooltipItem, data) { return UTIL.dollarify(data.datasets[0].data[tooltipItem.index]); }, title: (tooltipItem, data) => { return data.labels[tooltipItem[0].index]; } } }, plugins: { datalabels: { color: '#828891', display: false, font: { weight: 'bold', family: 'Roboto' }, formatter: function(value, context) { return UTIL.dollarify(value); } } }, responsive: true, maintainAspectRatio: false, pieceLabel: { render: 'label', fontColor: '#828891', fontSize: 14, fontStyle: 'bold', position: 'outside', render: function (args) { let label = (args.value/goal * 100).toFixed(1) + '%'; return label; } }, legend: { position: 'bottom', display: false }, layout: { padding: { right: 50, left: 50 } }, circumference: Math.PI, rotation: Math.PI, }; // DOM Population ================================================================================= const ctxBar = document.getElementById('topSalesman'); new Chart(ctxBar, { type: 'doughnut', data: doughnutData, options: doughnutOptions }); const titleHtml = document.getElementById(""title""); if (rep == ""%"") { titleHtml.innerHTML = ""Sales Goal""; } else if (data[0]) { titleHtml.innerHTML = ""Sales Goal - "" + data[0].firstname + ' ' + data[0].lastname; } else { const repName = JSON.parse(runQuery(""SELECT firstName, lastName FROM SysUser WHERE id='"" + rep + ""'"")); titleHtml.innerHTML = ""Sales Goal - "" + repName[0].firstname + ' ' + repName[0].lastname; } document.getElementById(""subTitle"").innerHTML = UTIL.dollarify(totalSales, 0) + "" of "" + UTIL.dollarify(goal, 0) + "" Goal""; document.getElementById(""description"").innerHTML = dateStr; // Function Declarations ========================================================================== function createDoughnut(data, colors, borderColor){ return { data: data, backgroundColor: colors, borderColor: borderColor, borderWidth: 2 }; } ",2023-01-05 17:28:06.990000,Query and logic for the Sales Goal page,Sales Goal,,20,3,sales-goal,0 15,_binary ," {% Template Default_Header %}

",2023-01-05 17:28:06.990000,Shows the top products by revenue,Top Products Chart,,10,4,top-products,1 16,_binary ,"const numOfProd = $NUM{Number_of_products|5}; const dateRange = $RANGE{Date_Range|this year}; const chartOption = ""$LIST{Chart_Type|^bar,pie}""; const displayLegend = $CHECK{Display_pie_legend|true}; const displayMiscSale = $CHECK{Display_Misc_Sales_Items|false}; let miscSale = ""AND soItem.typeId <> 11 "" if (displayMiscSale == true) { miscSale = "" ""; } else { miscSale = ""AND soItem.typeId <> 11 "" } const data = JSON.parse(runQuery(""SELECT soItem.productNum, SUM(postSoItem.totalPrice) AS totalPrice from postSoItem "" + ""JOIN soItem ON postSoItem.soItemId = soItem.id AND soItem.typeId <> 40 "" + ""WHERE statusId <> 40 AND dateLastFulfillment >= '"" + dateRange.fromDate + ""' AND dateLastFulfillment <= '"" + dateRange.toDate + ""' "" + miscSale + ""GROUP BY productNum "" + ""ORDER BY totalPrice "" + ""DESC LIMIT "" + numOfProd)); const other = JSON.parse(runQuery(""SELECT SUM(totalPrice) AS totalPrice "" + ""FROM (SELECT SUM(postSoItem.totalPrice) AS totalPrice "" + ""FROM postSoItem "" + ""JOIN soItem ON postSoItem.soItemId = soItem.id AND soItem.typeId <> 40 AND soItem.statusId = 50 "" + ""JOIN postSo ON postSo.soId = soItem.soId "" + ""WHERE postSo.postDate >= '"" + dateRange.fromDate + ""' AND postSo.postDate <= '"" + dateRange.toDate + ""' "" + ""GROUP BY productNum "" + ""ORDER BY totalPrice DESC "" + ""LIMIT "" + numOfProd + "", 18446744073709551615) AS subQuery"")); //This offset is MySQL Infitity. See https://dev.mysql.com/doc/refman/5.7/en/select.html#id4651990 let dateStr = UTIL.convertDate(dateRange.fromDate, true) + "" - "" + UTIL.convertDate(dateRange.toDate, false); if (moment(dateRange.fromDate).isSame('1000-01-01', 'year') && moment(dateRange.toDate).isSame('3000-01-01', 'year')) { dateStr = 'All'; } function createBar(totalPrice, tableColors){ return { backgroundColor: tableColors.halfAlpha, borderColor: tableColors.fullAlpha, borderWidth: 3, data: totalPrice, }; } function createPie(data, tableColors) { //Insert grey (other) into pie chart tableColors.halfAlpha.push(UTIL.convertHex('#757575', 50)); tableColors.fullAlpha.push(UTIL.convertHex('#757575', 100)); return { data: data, backgroundColor: tableColors.halfAlpha, borderColor: tableColors.fullAlpha, borderWidth: 2, }; } const barLabels = []; const pieLabels = []; const barTotalPrices = []; const pieTotalPrices = []; let barTotalPriceOverall = 0; let pieTotalPriceOverall = 0; const chartData = []; const pieData = []; for (let product = 0; product < data.length; product++) { barLabels.push(data[product].productnum); pieLabels.push(data[product].productnum); barTotalPrices.push(data[product].totalprice); pieTotalPrices.push(data[product].totalprice); barTotalPriceOverall += barTotalPrices[product]; } pieTotalPriceOverall = barTotalPriceOverall + other[0].totalprice; let tableColors = COLORS.get(numOfProd); chartData.push(createBar(barTotalPrices, tableColors)); pieTotalPrices.push(other[0].totalprice); pieData.push(createPie(pieTotalPrices, tableColors)); pieLabels.push('Other'); const barChartData = { labels: barLabels, datasets: chartData } const pieChartData = { labels: pieLabels, datasets: pieData } const barOptions = { title: { display: true, padding: 3 }, mode: 'index', position: 'cursor', intersect: false, legend: { display: false, }, scales: { xAxes: [{ stacked: true, ticks: { autoSkip: false } }], yAxes: [{ ticks: { beginAtZero: true, callback: function(value, index, values) { return UTIL.dollarify(value, 0); } } }] }, tooltips: { callbacks: { label: (tooltipItem, data) => { return UTIL.dollarify(tooltipItem.yLabel); }, title: (tooltipItem, data) => { return tooltipItem[0].xLabel; } }, }, responsive: true, maintainAspectRatio: false, plugins: { datalabels: { align: 'end', anchor: 'end', color: '#828891', font: { weight: 'bold', family: 'Helvetica' }, formatter: function(value, context) { return UTIL.dollarify(value); } } } }; const pieOptions = { plugins: { datalabels: { display: false } }, legend: { display: displayLegend }, responsive: true, maintainAspectRatio: false, pieceLabel: { render: 'label', fontColor: '#828891', fontSize: 14, fontStyle: 'bold', position: 'outside', render: function (args) { let label = (args.value/pieTotalPriceOverall * 100).toFixed(1) + '%'; return label; } }, tooltips: { backgroundColor: '#ffffff', titleFontColor: '#4e5156', bodyFontColor: '#4e5156', callbacks: { label: (tooltipItem, data) => { return (data.datasets[0].data[tooltipItem.index] / pieTotalPriceOverall * 100).toFixed(1) + '%'; }, title: (tooltipItem, data) => { return data.labels[tooltipItem[0].index]; } } } } if(chartOption === 'bar') { const ctxBar = document.getElementById('productChart'); new Chart(ctxBar, { type: 'bar', data: barChartData, options: barOptions }); } else { const ctxPie = document.getElementById('productChart'); new Chart(ctxPie, { type: 'pie', data: pieChartData, options: pieOptions }); } document.getElementById(""title"").innerHTML = 'Top ' + numOfProd + ' Products'; document.getElementById(""subTitle"").innerHTML = dateStr; document.getElementById(""description"").innerHTML = ''; ",2023-01-05 17:28:07.005000,Query and logic for the Top Products page,Top Products,,20,4,top-products,0 17,_binary ,"const displayHeader = $CHECK{Display_header|true}; let headerContainer = document.getElementById('headerContainer'); displayHeader ? headerContainer.style.display = 'block' : headerContainer.style.display = 'none'; ",2023-01-05 17:28:07.005000,Logic to hide or display the page header,Show Header,,20,1,show-header,0 18,_binary ," {% Template Bootstrap_Dependencies %}
",2023-01-05 17:28:07.005000,A report that displays your scheduled work orders and your total time scheduled per day. Also allows you to reschedule those Work Orders to manage your schedule.,Capacity Planning Report,,10,3,capacity-planning,1 19,_binary ," ",2023-01-05 17:28:07.021000,The necessary includes for bootstrap tables,Bootstrap Dependencies,,40,3,capacity-planning,0 20,_binary ,"/*! * FullCalendar v3.9.0 * Docs & License: https://fullcalendar.io/ * (c) 2018 Adam Shaw */ .fc { direction: ltr; text-align: left; } input[type=number]{ width: 33px; border: none; border-color: transparent; background: #f7f5ed; } .fc-rtl { text-align: right; } body .fc { /* extra precedence to overcome jqui */ font-size: 1em; } /* Colors --------------------------------------------------------------------------------------------------*/ .fc-highlight { /* when user is selecting cells */ background: #bce8f1; opacity: .3; } .fc-bgevent { /* default look for background events */ background: #8fdf82; opacity: .3; } .fc-nonbusiness { /* default look for non-business-hours areas */ /* will inherit .fc-bgevent's styles */ background: #d7d7d7; } /* Buttons (styled
",2023-01-05 17:28:07.037000,Capacity planning separated out by calendar category,Category Capacity Planning,,10,1,category-capacity-planning,1 23,_binary ," :root { --light: 80; --threshold: 60; --border-threshold: 80; } td.day:not(.busy) { padding-bottom: 40px !important; } td { padding: 8px !important; } div.event { min-height: 40px; margin-left: 5px; margin-right: 5px; padding: 8px; --switch: calc((var(--light) - var(--threshold)) * -100%); color: hsl(0, 0%, var(--switch)); --border-light: calc(var(--light) * 0.7%); --border-alpha: calc((var(--light) - var(--border-threshold)) * 10); border: 0.1em solid hsla( var(--hue), calc(var(--sat) * 1%), var(--border-light), var(--border-alpha) ); } div.event-wrapper { padding: 8px; } td.bg-danger { color: white !important; } div.capacity { border-bottom: 1px solid black; } div.wrapper { overflow: auto; width: 100%; } div.capacity-modal { position: absolute; display: none; width: 150px; height: fit-content; padding: 8px; text-align: right; } .dropdown-content { position: relative; right: 0; background-color: #f1f1f1; box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); z-index: 9999; } .capacity-input { width: 40px; } .resizer { width: 5px; min-height: 40px; height: 100%; background: transparent; position: relative; display: inline-block; } .resizer.left { float: left; cursor: w-resize; /*resizer cursor*/ } .resizer.right { float: right; cursor: e-resize; } #button-header { margin-bottom: 10px; text-align: right; } body { margin: 15px; font-family: 'Open Sans', sans-serif; } thead { background-color: #eaeaea; } .capacity-button { display: flex; }",2023-01-05 17:28:07.037000,Capacity planning separated out by calendar category,Category Capacity Planning,,30,1,category-capacity-planning,0 24,_binary ," let capacities; const daysInWeek = 7; const tableId = 'schedule-table'; const HeaderDateFormat = 'dddd MMM-D'; const NameOfResource = 'Machine'; let currentViewWeek = moment().startOf('day'); let getEventData = (momentDate) => { console.groupCollapsed('getEventData'); let queryDate = moment(momentDate); const QUERY = `SELECT CONCAT('WO#:',wo.num) AS eventName, wo.num AS eventNameRaw, wo.note AS eventDescription, DATE(wo.dateScheduledToStart) AS startDate, DATE(wo.dateScheduled) AS endDate, COALESCE(calcategory.id,0) AS resourceId, CONCAT('#',COALESCE(REPLACE(calcategory.color,'x',''),'A9A9A9')) AS color, (COALESCE(bom.estimatedduration,0) / 60) * wo.qtyTarget AS estimatedHours, ROUND(((COALESCE(bom.estimatedduration,0) / 60) * wo.qtyTarget) / (DATEDIFF(wo.dateScheduled,wo.dateScheduledToStart) + 1),2) AS estimatedDailyHours, (DATEDIFF(wo.dateScheduled,wo.dateScheduledToStart) + 1) AS datediff FROM wo LEFT JOIN calcategory ON wo.calcategoryid = calcategory.id LEFT JOIN moitem ON wo.moitemid = moitem.id LEFT JOIN bom ON moitem.bomid = bom.id WHERE wo.statusid < 40 AND (YEARWEEK(wo.dateScheduledToStart) = YEARWEEK('${queryDate.format( 'YYYY-MM-DD' )}') OR YEARWEEK(wo.dateScheduled) = YEARWEEK('${queryDate.format( 'YYYY-MM-DD' )}'))`; console.log('Query', QUERY); let events = JSON.parse(runQuery(QUERY)); if (events.length > 0) { console.log('events exist', events); } else { console.log( `No events found this week: ${queryDate.format('YYYY-MM-DD')}` ); } console.groupEnd('getEventData'); return events; }; function getOffset(el) { var _x = 0; var _y = 0; while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) { _x += el.offsetLeft - el.scrollLeft; _y += el.offsetTop - el.scrollTop; el = el.offsetParent; } return { top: _y, left: _x }; } let getResources = () => { console.groupCollapsed('getResources'); let QUERY = `SELECT name, id, """" AS limits, CONCAT('#',color) AS color FROM calcategory ORDER BY id DESC`; console.log('Query', QUERY); // ADD LOAD REPORT DATA HERE ONCE THE REPORT IS FUNCTIONAL. ALSO ADD THE ABILITY TO EASILY SWITCH BACK TO THIS TEST DATA // saveReportData(''); capacities = loadReportData(); if (!capacities) { capacities = []; console.log('capacities was blank'); } else { capacities = JSON.parse(capacities); console.log('parsed capacities object', capacities); capacities = capacities[0].capacities; console.log('capacities was found and parsed', capacities); } // capacities = [ // { resourceId: 102, defaultCapacity: [8, 7, 6, 5, 4, 3, 2] }, // { resourceId: 101, defaultCapacity: [1, 2, 3, 4, 5, 6, 7] }, // ]; let resources = [ { name: 'No Resource Assigned', id: '0', limits: [0, 0, 0, 0, 0, 0, 0], color: 'grey', }, ]; let results = JSON.parse(runQuery(QUERY)); console.log('Query Resluts', results); if (!!resources) { resources = resources.concat(results); } if (resources.length > 0) { for (resource of resources) { for (cap of capacities) { if (cap.id == resource.id) { resource.limits = cap.limits; console.log( 'default capacities found for resource', resource.limits ); } } if (!resource.limits) { console.log( 'No capacity settings found for this resource. Setting capacities to default' ); resource.limits = [8, 8, 8, 8, 8, 8, 8]; } } console.groupCollapsed('resourcesResults'); console.log('resources', resources); console.groupEnd('resourcesResults'); } else { console.error('No Resources Found'); } console.groupEnd('getResources'); return resources; }; const resources = getResources(); let calcUsage = () => { console.groupCollapsed('calcUsage'); let timestamp = Date.now(); for (resource of resources) { for (let i = 0; i < daysInWeek; i++) { let dayTotal = 0; let capacity; let days = $(`td.day${i}.${resource.id}.busy`); if (days[0]) { capacity = days[0].getAttribute('capacity'); } else { console.log('no busy days. removed warning'); $(`td.day${i}.${resource.id}`).removeClass('bg-danger'); continue; } days.children().each((index, cell) => { dayTotal += parseInt($(cell).attr('duration')); }); console.log(`day ${i} Total:`, dayTotal, 'capacity:', capacity); console.log($(`td.day${i}.${resource.id}`)); $(`td.day${i}.${resource.id}`).each((index, cell) => { if (cell.getAttribute('usage-calculated-ts') == timestamp) { return true; } if (capacity >= dayTotal) { console.log('removed warning'); $(cell).removeClass('bg-danger'); cell.setAttribute('usage-calculated-ts', timestamp); } else { console.log('added warning'); $(cell).addClass('bg-danger'); cell.setAttribute('usage-calculated-ts', timestamp); } }); } } console.groupEnd('calcUsage'); return true; }; let createRow = (resourceId) => { /* MAYBE I CAN INSERT THE CAPACITY INPUTS AFTER I HAVE ACTUALLY ADDED THE ROW IN THE DOM. JUST LOOP THROUGH MY NUMBER OF DAYS AND ADD A CAPACITY INPUT FOR EACH WITH THE VALUES PULLED FROM DATABASE*/ console.groupCollapsed('createRow'); let rowString = ''; let resource; let resourceNameCell = $(`td.resource-name.${resourceId}`); let rowCount; let rowId = Math.trunc(Math.random() * 1000000); let tableElement = document.getElementById(tableId); for (let item of resources) { if (item.id == resourceId) { resource = item; break; } } if (!resource) { console.log('no resource found with id', resourceId); console.groupEnd('createRow'); return false; } //If the resource doesn't exist create a new one if (!resourceNameCell.length) { console.log( `row for resource ${resource.name} does not exist. Adding new resource row` ); rowCount = 2; let newTbody = document.createElement('tbody', { id: `${resource.id}body`, class: resource.id, resource: resource.id, }); newTbody.setAttribute('id', `${resource.id}body`); newTbody.setAttribute('class', resource.id); newTbody.setAttribute('resource', resource.id); let newRow = document.createElement('tr'); newRow.setAttribute('id', rowId); newRow.setAttribute('class', `${resource.id} capacity`); newRow.setAttribute('resource', resource.id); console.log('newRow', newRow); let nameCell = newRow.insertCell(); nameCell.setAttribute('rowspan', 2); nameCell.setAttribute('class', `resource-name ${resource.id}`); $(nameCell) .append(`${resource.name}
`); newTbody.appendChild(newRow); console.log('newTbody', newTbody); tableElement.appendChild(newTbody); for (let i = 0; i < daysInWeek; i++) { $(newRow).append(`
Cap: ${resource.limits[i]} hrs
`); } $(`table#${tableId}`).append(newTbody); console.log('created new resource row', $(`tr#${rowId}`)); for (let dayOfWeek = 0; dayOfWeek < daysInWeek; dayOfWeek++) { let week = moment($('table').attr('date')); console.log('name of week', week.day(dayOfWeek).format('dddd')); let capacityString = `
`; $(`#capacity-modal-${resource.id}`).append(capacityString); } // Add the save button $(`#capacity-modal-${resource.id}`).append( `` ); } // Once the resource row exists, or if it already existed, do this let newRow = document.createElement('tr'); newRow.setAttribute('id', rowId); newRow.setAttribute('class', `${resource.id} day`); newRow.setAttribute('resource', resource.id); rowCount = $(`tr.${resource.id}`).length + 1; console.log('rowCount', rowCount); resourceNameCell.attr('rowspan', rowCount); for (let i = 0; i < daysInWeek; i++) { $(newRow).append(``); } console.log( `tbody resourceId:${resourceId}`, $(`tbody#${resourceId}body`) ); $(`tbody#${resourceId}body`).append(newRow); console.log( `added row to existing resource id:${resourceId}`, $(`tr#${rowId}`) ); console.groupEnd('createRow'); return $(`tr#${rowId}`); }; let addEvent = (event) => { console.groupCollapsed('addEvent'); let startDate = moment(event.startdate); let visualStartDate = moment(event.startdate).clone(); let endDate = moment(event.enddate); let visualEndDate = moment(event.enddate).clone(); // for events that leak into the current week I am viewing console.log( visualStartDate.week(), visualEndDate.week(), currentViewWeek.week() ); if (visualStartDate.week() != currentViewWeek.week()) { visualStartDate = currentViewWeek.clone().day(0); } else if (visualEndDate.week() != currentViewWeek.week()) { visualEndDate = currentViewWeek.clone().day(6); } let startDay = visualStartDate.clone().day(); let endDay = visualEndDate.clone().day(); console.log(startDate, visualStartDate, startDay); console.log(endDate, visualEndDate, endDay); let resourceId = event.resourceid; let resourceRows = $(`tr.${resourceId}.day`); let daysInRange = []; let busyDaysInRange = []; let openRow; let allEventDaysCells; let eventCell; console.log('Start Day: ', startDay, ' End Day: ', endDay); for (i = startDay; i <= endDay; i++) { daysInRange.push('.day' + i); busyDaysInRange.push('.day' + i + '.busy'); } daysInRange = daysInRange.join(); busyDaysInRange = busyDaysInRange.join(); resourceRows.each((index, cell) => { let rowBusy = false; $(cell) .children(busyDaysInRange) .each((i, c) => { rowBusy = true; return false; }); if (rowBusy == false) { openRow = cell; console.log(`Open Row found. row id = ${openRow.id}`); return false; } }); if (openRow) { console.log('Open row was found'); allEventDaysCells = $(openRow).children(daysInRange); eventCell = $(openRow).children(`.day${startDay}`); } else { console.log('No open rows for this event. Creating new row'); let newRow = createRow(resourceId); console.log('new row id', newRow.id); allEventDaysCells = $(newRow).children(daysInRange); eventCell = $(newRow).children(`.day${startDay}`); } let eventId = Math.trunc(Math.random() * 100000); let eventTitle; if (event.datediff > 1) { eventTitle = `${event.eventname} - ${event.estimateddailyhours} hrs/day (${event.estimatedhours} total)`; } else { eventTitle = `${event.eventname} - ${event.estimateddailyhours} hrs`; } let eventDivString = `
${eventTitle}
`; allEventDaysCells.each((index, cell) => { // Don't want to remove the first cell. That is where I am dropping the event if (index > 0) { cell.remove(); } }); let appendResult = eventCell .append(eventDivString) .on('dragstart', (event) => { dragEvent(event); }); if (appendResult.length == 0) { console.log('append result', appendResult); console.log('String: ', eventDivString); } eventCell.attr('colspan', endDay - startDay + 1); // add classes for every day in the range so that it can still be found by all of my searches let dayClasses; for (i = startDay; i <= endDay; i++) { dayClasses += ' day' + i; } eventCell.addClass(dayClasses); eventCell.addClass('busy'); let eventDiv = $(`#${eventId}`); console.log('color:', event.color); eventDiv.css({ 'background-color': event.color }); console.log('event add success. id=', eventDiv.attr('id'), eventDiv); console.groupEnd('addEvent'); calcUsage(); return eventDiv; }; let dragEvent = (event) => { let fromCellId = $(event.target).parent().parent().attr('id'); let type; if (event.target.id.includes('left')) { type = 'left'; } else if (event.target.id.includes('right')) { type = 'right'; } else { type = 'move'; } console.log( 'You are dragging div id=', event.target.id, 'from td id=', fromCellId, 'Type:', type ); let dataObject = JSON.stringify({ fromCellId: fromCellId, eventId: event.target.getAttribute('eventId'), targetId: event.target.id, type: type, }); event.originalEvent.dataTransfer.setData('text', dataObject); }; let eventClick = (event) => { event.preventDefault(); let woNum = event.target.getAttribute('name'); console.log('Trying to open wo', openModule('Work Order', woNum)); }; let allowDrop = (event) => { event.preventDefault(); }; let moveEvent = (event) => { console.groupCollapsed('moveEvent'); // PULL THE WO API CALLS OUT OF HERE // Move event now needs to Save the order to the database with the updated dates. Then run buildCalendar() event.preventDefault(); event.stopPropagation(); console.log('event', event); const dataTransfer = JSON.parse(event.dataTransfer.getData('text')); const eventWrapper = document.getElementById( `${dataTransfer.eventId + 'wrapper'}` ); // check all columns width against the cursor to see which day this was dropped into console.groupCollapsed('determine day based on position'); let newDay; let dropPosition = event.pageX; console.log('Drop Position', dropPosition); $('th').each((index, cell) => { left = getOffset(cell).left; right = left + cell.offsetWidth; console.log('left', left); console.log('right', right); if (dropPosition >= left && dropPosition <= right) { newDay = cell.getAttribute('day'); return false; } }); if (!newDay) { console.log('Day the event was dropped into could not be found'); return false; } console.groupEnd('determine day based on position'); let woNum = eventWrapper.getAttribute('name'); let resourceId = event.target.getAttribute('resource'); let startDate = eventWrapper.getAttribute('start-date'); let endDate = eventWrapper.getAttribute('end-date'); let newStartDate, newEndDate, daysToSubtract; switch (dataTransfer.type) { case 'left': daysToSubtract = moment( eventWrapper.getAttribute('start-date') ).diff(currentViewWeek.clone().day(newDay), 'days', true); console.log('daysToSubtract', daysToSubtract); newStartDate = moment(startDate) .subtract(daysToSubtract, 'days') .format('YYYY-MM-DD[T]HH:mm:ss'); newEndDate = moment(endDate).format('YYYY-MM-DD[T]HH:mm:ss'); break; case 'right': daysToSubtract = moment(eventWrapper.getAttribute('end-date')).diff( currentViewWeek.clone().day(newDay), 'days', true ); console.log('daysToSubtract', daysToSubtract); newStartDate = moment(startDate).format('YYYY-MM-DD[T]HH:mm:ss'); newEndDate = moment(endDate) .subtract(daysToSubtract, 'days') .format('YYYY-MM-DD[T]HH:mm:ss'); break; case 'move': daysToSubtract = moment(eventWrapper.getAttribute('end-date')).diff( currentViewWeek.clone().day(newDay), 'days', true ); console.log('daysToSubtract', daysToSubtract); newEndDate = moment(endDate) .subtract(daysToSubtract, 'days') .format('YYYY-MM-DD[T]HH:mm:ss'); newStartDate = moment(startDate) .subtract(daysToSubtract, 'days') .format('YYYY-MM-DD[T]HH:mm:ss'); } console.log('New Day: ' + newDay); console.log('Original Start Date: ' + startDate); console.log('New Start Date: ' + newStartDate); console.log('Original End Date: ' + endDate); console.log('New End Date: ' + newEndDate); console.log('WO Num: ' + woNum); console.log('Resource ID: ' + resourceId); let updateResponse = updateWOItem( newStartDate, newEndDate, woNum, resourceId ); if ((updateResponse = true)) { let table = $('table'); table.empty(); buildCalendar(tableId, resources, currentViewWeek); } else { // add a pop up that will tell hte user something went wrong } console.groupEnd('moveEvent'); return; }; let updateWOItem = (eventStart, eventEnd, woNum, resourceId) => { if (eventStart == null) { return 'No Start Date Found'; } console.log( '\r\nEvent Start = ' + eventStart + ' Event End = ' + eventEnd ); let WONum = { GetWorkOrderRq: { WorkOrderNumber: woNum } }; console.log('\r\nEvent WO Num = ', WONum); let WOAPIObject = JSON.parse( runApiRequest('GetWorkOrderRq', JSON.stringify(WONum)) ); if (WOAPIObject.hasOwnProperty('ErrorRs')) { console.log('\r\nUnable to parse API request. WO Num = ', WONum); console.log('API Response: ', WOAPIObject); return false; } else { let WO = WOAPIObject.GetWorkOrderRs.WO; // CHECK TO SEE IF THE EVENT HAS AN END DATE if (!moment(eventEnd).isValid()) { // CHANGE EACH WO ITEM DATE SCHEDULED for (i = 0; i < WO.WOItems; i++) { WO.WOItems[i].DateScheduled = eventStart; } // CHANGE WO DATE SCHEDULED/DATE SCHEDULED TO START console.log('Event end was null'); WO.DateScheduled = eventStart; WO.DateScheduledToStart = eventStart; } else { console.log('Event end was not null'); for (i = 0; i < WO.WOItems; i++) { WO.WOItems[i].DateScheduled = eventStart; } WO.DateScheduled = eventEnd; WO.DateScheduledToStart = eventStart; WO.CalCategoryID = resourceId; } // FORMAT REQUEST OBJECT let WONewDate = { SaveWorkOrderRq: { WO: WO } }; // UPDATE THE WORK ORDER AND WO ITEMS let SaveWorkOrderResponse = JSON.parse( runApiRequest('SaveWorkOrderRq', JSON.stringify(WONewDate)) ); if (SaveWorkOrderResponse.SaveWorkOrderRs.statusCode == 1000) { console.log( 'Work Order ' + woNum + ' has been successfully updated to start date and end date ' + eventStart ); return true; } else { console.log('An error occured while saving the WO'); console.log('SaveWorkOrderRs =', SaveWorkOrderResponse); return false; } } }; // let moveEventARCHIVED = (event) => { // event.preventDefault(); // event.stopPropagation(); // const dataTransfer = JSON.parse(event.dataTransfer.getData(""text"")); // if (dataTransfer.type == ""resize"") { // resizeEvent(event); // return true; // } // console.groupCollapsed(""moveEvent""); // console.log(`You dropped it into id=${event.target.id}`); // const toCellId = event.target.id, // fromCellId = dataTransfer.fromCellId, // eventId = dataTransfer.eventId, // toCell = $(`td#${toCellId}`), // toResourceId = toCell.attr(""resource""), // fromCell = $(`td#${fromCellId}`), // fromResourceId = fromCell.attr(""resource""), // eventDiv = $(`div#${eventId}wrapper`); // eventDiv.appendTo(toCell); // eventDiv.on(""dragstart"", (event) => { // dragEvent(event); // }); // let toColor; // for (resource of resources) { // resource.id == toResourceId ? (toColor = resource.color) : null; // } // console.log(""resource found"", toColor); // eventDiv.css({ ""background-color"": toColor }); // toCell.addClass(""busy""); // fromCell.removeClass(""busy""); // calcUsage(); // //Go to the previous row and see if any of the the cells in that row are busy. // //If there are none we are going to delete the row // let fromRow = fromCell.parent(); // // have to loop over all of the rows in the tbody so that I can have the index of the from row // let removeRow = false; // let firstRowFlag = false; // let currentRowCount = $(`tr.${fromResourceId}.day`).length; // if (currentRowCount == 1) { // console.log( // ""this is the last row for the resource. so it is not removed"" // ); // console.groupEnd(""moveEvent""); // return true; // } // $(`tbody#${fromResourceId}body`) // .children("".day"") // .each((index, element) => { // console.log(""element"", element, ""index"", index); // if (firstRowFlag) { // $(element).prepend($(`td.${fromResourceId}.resource-name`)); // removeRow = true; // } else if ($(element)[0] == fromRow[0]) // if (!fromRow.children("".busy"").length) { // // if the from row is the first row, and there are more rows. We need to do stuff to the next row and then remove the from row // console.log(""no children in this row are busy""); // if (index == 0) { // console.log(""This was the first row""); // firstRowFlag = true; // } else { // removeRow = true; // } // } else { // console.log(""children in from row are busy. Not removing it""); // $(`td.resource-name.${fromResourceId}`).attr( // ""rowspan"", // currentRowCount + 1 //adding 1 for capacity row // ); // } // }); // if (removeRow) { // console.log(""from row to be removed"", fromRow); // $(`td.resource-name.${fromResourceId}`).attr(""rowspan"", currentRowCount); // fromRow.remove(); // } // console.groupEnd(""moveEvent""); // return true; // }; // let moveEventBusy = (event) => { // event.preventDefault(); // event.stopPropagation(); // const dataTransfer = JSON.parse(event.dataTransfer.getData(""text"")); // if (dataTransfer.type == ""resize"") { // resizeEventBusy(event); // return true; // } // console.groupCollapsed(""moveEventBusy""); // console.log(`You dropped it into a busy cell eventId=${event.target.id}`); // const toCell = $(`div#${event.target.id}`).parent(), // fromCellId = dataTransfer.fromCellId, // eventId = dataTransfer.eventId, // toResourceId = toCell.attr(""resource""), // fromCell = $(`td#${fromCellId}`), // fromResourceId = fromCell.attr(""resource""), // eventDiv = $(`div#${eventId}`); // //Create new row after the current row // let rowCount = $(`tr.${toResourceId}`).length; // let newRow = createRow(toResourceId); // let newRowToCell = $(newRow).children( // `td.day${toCell.attr(""day"")}.${toResourceId}` // ); // newRowToCell.append(eventDiv).on(""dragstart"", (event) => { // dragEvent(event); // }); // let toColor; // for (resource of resources) { // resource.id == toResourceId ? (toColor = resource.color) : null; // } // console.log(""resource found"", toColor); // eventDiv.css({ ""background-color"": toColor }); // newRowToCell.addClass(""busy""); // fromCell.removeClass(""busy""); // calcUsage(); // //Go to the previous row and see if any of the the cells in that row are busy. // //If there are none we are going to delete the row // let fromRow = fromCell.parent(); // let currentRowCount = parseInt($(`tr.${fromResourceId}.day`).length); // if (currentRowCount == 1) { // console.log( // ""this is the last row for the resource. so it is not removed"" // ); // console.groupEnd(""moveEventBusy""); // return true; // } // // have to loop over all of the rows in the tbody so that I can have the index of the from row // let firstRowFlag = false; // let removeRow = false; // $(`tbody#${fromResourceId}body`) // .children("".day"") // .each((index, element) => { // if (firstRowFlag) { // $(element).prepend($(`td.${fromResourceId}.resource-name`)); // removeRow = true; // } else if ($(element)[0] == fromRow[0]) { // if (!fromRow.children("".busy"").length) { // // if the from row is the first row, and there are more rows. We need to do stuff to the next row and then remove the from row // console.log(""no children in this row are busy""); // if (index == 0) { // console.log(""This was the first row""); // firstRowFlag = true; // } else { // removeRow = true; // } // } else { // console.log(""Cell(s) in from row are busy. Not removing it""); // $(`td.resource-name.${fromResourceId}`).attr( // ""rowspan"", // currentRowCount + 1 //adding 1 for capacity row // ); // } // } // }); // if (removeRow) { // console.log(""from row to be removed"", fromRow); // $(`td.resource-name.${fromResourceId}`).attr(""rowspan"", currentRowCount); // fromRow.remove(); // } // console.groupEnd(""moveEventBusy""); // return true; // }; let changeCalendarWeek = (previous) => { let currentDate = moment($('table').attr('date')); console.groupCollapsed('changeCalendarWeek'); console.log('currentDate', currentDate); let table = $('table'); table.empty(); let newDate; if (previous) { console.log('subtracting week'); newDate = currentDate.clone().subtract(1, 'weeks'); } else { console.log('adding week'); newDate = currentDate.clone().add(1, 'weeks'); } console.log('new date:', newDate); table.attr('date', newDate.format('YYYY-MM-DD')); currentViewWeek = newDate; buildCalendar(tableId, resources, currentViewWeek); console.groupEnd('changeCalendarWeek'); return true; }; let showCapSettings = (event) => { event.stopPropagation(); let resourceId = $(event.target).attr('resource'); console.log(`showing capacity modal for ${resourceId}`); console.log('pageX', event.pageX, 'pageY', event.pageY); let modal = $(`.modal.${resourceId}`); modal.css({ top: event.pageY, left: event.pageX }); modal.toggle(); }; let buildCalendar = (tableId, resources, momentDate) => { console.groupCollapsed('buildCalendar'); let tableHeaderString = `${NameOfResource}`; for (let dayOfWeek = 0; dayOfWeek < daysInWeek; dayOfWeek++) { let dayName = momentDate.day(dayOfWeek).format(HeaderDateFormat); tableHeaderString += `${dayName}`; } tableHeaderString += ``; let table = $(`#${tableId}`); table.append(tableHeaderString); table.attr('date', momentDate.format('YYYY-MM-DD')); resources.forEach((resource) => { createRow(resource.id); }); console.log('schedule creation successful'); let events = getEventData(momentDate); for (event of events) { addEvent(event); } console.groupEnd('buildCalendar'); return true; }; let capacityChange = (event) => { let day = $(event.target).attr('day'); let resourceId = $(event.target).attr('resource'); let value = parseInt(event.target.value); for (resource of resources) { if (resource.id == resourceId) { resource.limits[day] = value; break; } } }; let saveCapacities = (event) => { let resourceId = $(event.target).attr('resource'); console.log('saving capacities for resource id:', resourceId); let currentInfo = loadReportData(); if (!currentInfo) { currentInfo = [{}]; } else { currentInfo = JSON.parse(currentInfo); } console.log('Current Info', currentInfo); let newCapacities = [...currentInfo]; newCapacities[0].capacities = resources; console.log('New Capacity Object', newCapacities); let saveResponse = saveReportData(JSON.stringify(newCapacities)); let table = $('table'); table.empty(); buildCalendar(tableId, resources, currentViewWeek); }; let resizeEventARCHIVED = (event) => { event.preventDefault(); event.stopPropagation(); console.groupCollapsed('resizeEvent'); console.log('You just dropped one of the resize elements'); console.groupEnd('resizeEvent'); return true; }; let resizeEventBusyARCHIVED = (event) => { event.preventDefault(); event.stopPropagation(); console.groupCollapsed('resizeEventBusy'); console.log( 'You just dropped one of the resize elements in a busy space' ); console.groupEnd('resizeEventBusy'); return true; }; $(document).ready(() => { console.log('Document Ready'); $('#prev-button').click((event) => changeCalendarWeek(true)); $('#next-button').click((event) => changeCalendarWeek(false)); buildCalendar(tableId, resources, currentViewWeek); let body = $(document.body); body.click((event) => { //check to see if we are interacting with any child of a capacity modal element if ($(event.target).parents('.capacity-modal').length) { return false; } else { $('.capacity-modal').hide(); } }); }); ",2023-01-05 17:28:07.037000,Capacity planning separated out by calendar category,Category Capacity Planning,,20,1,category-capacity-planning,0 25,_binary ,"@media print { html,body { height: 100%; width: 100%; margin: 0; padding: 0; overflow: hidden; } #button { display: none !important; } @page { $PRINT{Print|Letter|Print} } }",2023-01-05 17:28:07.052000,Default portrait print settings.,Print Portrait,,30,1,fb-print-portrait,0 26,_binary ,"@media print { html,body { height: 100%; width: 100%; margin: 0; padding: 0; overflow: hidden; } #button { display: none !important; } @page { $PRINT{Print|Letter:landscape|Print} } }",2023-01-05 17:28:07.052000,Default landscape print settings.,Print Landscape,,30,1,fb-print-landscape,0 27,_binary ," {% Template Inventory_Watch_List %} Inventory Watch List

Inventory Watch List

",2023-01-05 17:28:07.052000,"Replicates the functionality of the Monitor Module, but adds the option to display it on your dashboard. Watches must be created in the Monitor Module.",Inventory Watch List,,10,2,inventory-watch-list,1 28,_binary ," ",2023-01-05 17:28:07.052000,"Replicates the functionality of the Monitor Module, but adds the option to display it on your dashboard. Watches must be created in the Monitor Module.",Inventory Watch List,,40,2,inventory-watch-list,0 29,_binary ,"{% Style Print_Landscape %} .dot { height: 20px; width: 20px; border-radius: 50%; display: inline-block; } .fb10 { background-color: #28a745 !important; z-index: 99; } .fb20 { background-color: #ffc107; z-index: 99; } .fb30 { background-color: #dc3545; z-index: 99; } tr > td.stateText { color: rgba(0,0,0,0); font-size: 1px; text-align: center; } optgroup { background: #d3d3d3; } .selector { width: 100%; margin-bottom: 5px; } .csv-button-margin { margin-bottom: 10px; } body { height: 100%; font-family: ""Helvetica Neue"",Helvetica,Arial,sans-serif; } .dropdown-content { display: none; position: absolute; right: 0; background-color: #f1f1f1; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); z-index: 9999; } .show { display: block; } div.love-on-top { z-index: 2; position: relative; } /* The Modal (background) */ .modal { display: none; /* Hidden by default */ position: fixed; /* Stay in place */ z-index: 1; /* Sit on top */ padding-top: 100px; /* Location of the box */ left: 0; top: 0; width: 100%; /* Full width */ height: 100%; /* Full height */ overflow: auto; /* Enable scroll if needed */ background-color: rgb(0, 0, 0); /* Fallback color */ background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */ } /* Modal Content */ .modal-content { background-color: #fefefe; margin: auto; padding: 20px; width: 80%; } /* The Close Button */ .close { color: #aaaaaa; float: right; font-size: 28px; font-weight: bold; } .close:hover, .close:focus { color: #000; text-decoration: none; cursor: pointer; } div.columnWrapper { position: relative; float: left; margin: 5px; } div.columnWrapper:hover img { opacity: 0.5; } div.columnWrapper:hover button { display: block; } div.columnWrapper button { position: absolute; display: none; } div.columnWrapper button.delete { top: 1px; left: 83%; background: lightgray; opacity: 0.5; text-align: center; } div.columnWrapper button.delete:hover { background: gray; } .hide-button { float: right; margin-top: -13px; font-size: 11px; font-family: helvetica; color: gray; } input.columnTitle { margin: 3px; text-align: center; width: 75%; } div.columnWrapper { text-align: center; display: inline-block; } div.columnPreview { display: inline-block; min-width: 50px; overflow: stretch; } div.inline { margin-right: 10px; display: inline-block; margin-bottom: 15px; vertical-align: top; } body { margin: 15px; padding: 0; } div.header { margin-top: 20px; } .overflowHidden { overflow: hidden; } #chartContainer { position: relative; height: 85%; width: 100vw; padding-top: 20px; } @media (max-height: 450px) { #chartContainer { height: 75%; } } @media (max-height: 300px) { #chartContainer { height: 70%; } } #title { font-size: 24px;} #headerContainer { text-align: center; } .wrapper { position: relative; } div.button-wrapper { text-align: center; } div.column-preview-body { height: 105px; } .scrolling { overflow: auto; white-space: nowrap; } /* * Table styles */ table.dataTable { width: 100%; margin: 0 auto; clear: both; border-collapse: separate; border-spacing: 0; /* * Header and footer styles */ /* * Body styles */ } table.dataTable thead th, table.dataTable tfoot th { font-weight: bold; } table.dataTable thead th, table.dataTable thead td { padding: 10px 18px; border-bottom: 1px solid #111111; background-color: #eaeaea; font-size: 14px;} table.dataTable thead th:active, table.dataTable thead td:active { outline: none; } table.dataTable tfoot th, table.dataTable tfoot td { padding: 10px 18px 6px 18px; border-top: 1px solid #111111; } table.dataTable thead .sorting, table.dataTable thead .sorting_asc, table.dataTable thead .sorting_desc, table.dataTable thead .sorting_asc_disabled, table.dataTable thead .sorting_desc_disabled { cursor: pointer; *cursor: hand; background-repeat: no-repeat; background-position: center right; } table.dataTable thead .sorting { background-image: url(""../images/sort_both.png""); } table.dataTable thead .sorting_asc { background-image: url(""../images/sort_asc.png""); } table.dataTable thead .sorting_desc { background-image: url(""../images/sort_desc.png""); } table.dataTable thead .sorting_asc_disabled { background-image: url(""../images/sort_asc_disabled.png""); } table.dataTable thead .sorting_desc_disabled { background-image: url(""../images/sort_desc_disabled.png""); } table.dataTable tbody tr { background-color: white; font-size: 13px;} table.dataTable tbody tr.selected { background-color: #b0bed9; } table.dataTable tbody th, table.dataTable tbody td { padding: 8px 10px; } table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td { border-top: 1px solid #dddddd; } table.dataTable.row-border tbody tr:first-child th, table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th, table.dataTable.display tbody tr:first-child td { border-top: none; } table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td { border-top: 1px solid #dddddd; border-right: 1px solid #dddddd; } table.dataTable.cell-border tbody tr th:first-child, table.dataTable.cell-border tbody tr td:first-child { border-left: 1px solid #dddddd;} table.dataTable.cell-border tbody tr:first-child th, table.dataTable.cell-border tbody tr:first-child td { border-top: none; } table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd { background-color: #f9f9f9; } table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected { background-color: #abb9d3; } table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover { background-color: whitesmoke; } table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected { background-color: #a9b7d1; } table.dataTable.order-column tbody tr > .sorting_1, table.dataTable.order-column tbody tr > .sorting_2, table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1, table.dataTable.display tbody tr > .sorting_2, table.dataTable.display tbody tr > .sorting_3 { background-color: #f9f9f9; } table.dataTable.order-column tbody tr.selected > .sorting_1, table.dataTable.order-column tbody tr.selected > .sorting_2, table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1, table.dataTable.display tbody tr.selected > .sorting_2, table.dataTable.display tbody tr.selected > .sorting_3 { background-color: #acbad4; } table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 { background-color: #f1f1f1; } table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 { background-color: #f3f3f3; } table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 { background-color: whitesmoke; } table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 { background-color: #a6b3cd; } table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 { background-color: #a7b5ce; } table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 { background-color: #a9b6d0; } table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 { background-color: #f9f9f9; } table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 { background-color: #fbfbfb; } table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 { background-color: #fdfdfd; } table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 { background-color: #acbad4; } table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 { background-color: #adbbd6; } table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 { background-color: #afbdd8; } table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 { background-color: #eaeaea; } table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 { background-color: #ebebeb; } table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 { background-color: #eeeeee; } table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 { background-color: #a1aec7; } table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 { background-color: #a2afc8; } table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 { background-color: #a4b2cb; } table.dataTable.no-footer { border-bottom: 1px solid #111111; } table.dataTable.nowrap th, table.dataTable.nowrap td { white-space: nowrap; } table.dataTable.compact thead th, table.dataTable.compact thead td { padding: 4px 17px 4px 4px; } table.dataTable.compact tfoot th, table.dataTable.compact tfoot td { padding: 4px; } table.dataTable.compact tbody th, table.dataTable.compact tbody td { padding: 4px; } table.dataTable th.dt-left, table.dataTable td.dt-left { text-align: left; } table.dataTable th.dt-center, table.dataTable td.dt-center, table.dataTable td.dataTables_empty { text-align: center; } table.dataTable th.dt-right, table.dataTable td.dt-right { text-align: right; } table.dataTable th.dt-justify, table.dataTable td.dt-justify { text-align: justify; } table.dataTable th.dt-nowrap, table.dataTable td.dt-nowrap { white-space: nowrap; } table.dataTable thead th.dt-head-left, table.dataTable thead td.dt-head-left, table.dataTable tfoot th.dt-head-left, table.dataTable tfoot td.dt-head-left { text-align: left; } table.dataTable thead th.dt-head-center, table.dataTable thead td.dt-head-center, table.dataTable tfoot th.dt-head-center, table.dataTable tfoot td.dt-head-center { text-align: center; } table.dataTable thead th.dt-head-right, table.dataTable thead td.dt-head-right, table.dataTable tfoot th.dt-head-right, table.dataTable tfoot td.dt-head-right { text-align: right; } table.dataTable thead th.dt-head-justify, table.dataTable thead td.dt-head-justify, table.dataTable tfoot th.dt-head-justify, table.dataTable tfoot td.dt-head-justify { text-align: justify; } table.dataTable thead th.dt-head-nowrap, table.dataTable thead td.dt-head-nowrap, table.dataTable tfoot th.dt-head-nowrap, table.dataTable tfoot td.dt-head-nowrap { white-space: nowrap; } table.dataTable tbody th.dt-body-left, table.dataTable tbody td.dt-body-left { text-align: left; } table.dataTable tbody th.dt-body-center, table.dataTable tbody td.dt-body-center { text-align: center; } table.dataTable tbody th.dt-body-right, table.dataTable tbody td.dt-body-right { text-align: right; } table.dataTable tbody th.dt-body-justify, table.dataTable tbody td.dt-body-justify { text-align: justify; } table.dataTable tbody th.dt-body-nowrap, table.dataTable tbody td.dt-body-nowrap { white-space: nowrap; } table.dataTable, table.dataTable th, table.dataTable td { box-sizing: content-box; } /* * Control feature layout */ .dataTables_wrapper { position: relative; clear: both; *zoom: 1; zoom: 1; } .dataTables_wrapper .dataTables_length { float: left;} .dataTables_wrapper .dataTables_filter { float: right;} .dataTables_wrapper .dataTables_filter input { margin-left: 0.5em; } .dataTables_wrapper .dataTables_info { clear: both; float: left; padding-top: 0.755em; } .dataTables_wrapper .dataTables_paginate { float: right; text-align: right; padding-top: 0.25em; } .dataTables_wrapper .dataTables_paginate .paginate_button { box-sizing: border-box; display: inline-block; min-width: 1.5em; margin-left: 2px; text-align: center; text-decoration: none !important; cursor: pointer; *cursor: hand; color: #333333 !important; border: 1px solid transparent; border-radius: 2px; } .dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover { color: #333333 !important; border: 1px solid #979797; background-color: white; background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, gainsboro)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, white 0%, gainsboro 100%); /* Chrome10+,Safari5.1+ */ background: -moz-linear-gradient(top, white 0%, gainsboro 100%); /* FF3.6+ */ background: -ms-linear-gradient(top, white 0%, gainsboro 100%); /* IE10+ */ background: -o-linear-gradient(top, white 0%, gainsboro 100%); /* Opera 11.10+ */ background: linear-gradient(to bottom, white 0%, gainsboro 100%); /* W3C */ } .dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active { cursor: default; color: #666 !important; border: 1px solid transparent; background: transparent; box-shadow: none; } .dataTables_wrapper .dataTables_paginate .paginate_button:hover { color: white !important; border: 1px solid #d9d9d9; background-color: white; background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #d9d9d9)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, white 0%, #d9d9d9 100%); /* Chrome10+,Safari5.1+ */ background: -moz-linear-gradient(top, white 0%, #d9d9d9 100%); /* FF3.6+ */ background: -ms-linear-gradient(top, white 0%, #d9d9d9 100%); /* IE10+ */ background: -o-linear-gradient(top, white 0%, #d9d9d9 100%); /* Opera 11.10+ */ background: linear-gradient(to bottom, white 0%, #d9d9d9 100%); /* W3C */ } .dataTables_wrapper .dataTables_paginate .paginate_button:active { outline: none; background-color: #f3f3f3; background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f3f3f3), color-stop(100%, #d4d4d4)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, #f3f3f3 0%, #d4d4d4 100%); /* Chrome10+,Safari5.1+ */ background: -moz-linear-gradient(top, #f3f3f3 0%, #d4d4d4 100%); /* FF3.6+ */ background: -ms-linear-gradient(top, #f3f3f3 0%, #d4d4d4 100%); /* IE10+ */ background: -o-linear-gradient(top, #f3f3f3 0%, #d4d4d4 100%); /* Opera 11.10+ */ background: linear-gradient(to bottom, #f3f3f3 0%, #d4d4d4 100%); /* W3C */ box-shadow: inset 0 0 3px #111; } .dataTables_wrapper .dataTables_paginate .ellipsis { padding: 0 1em; } .dataTables_wrapper .dataTables_processing { position: absolute; top: 50%; left: 50%; width: 100%; height: 40px; margin-left: -50%; margin-top: -25px; padding-top: 20px; text-align: center; font-size: 10px; background-color: white; background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0))); background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); } .dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_processing, .dataTables_wrapper .dataTables_paginate { color: #333333; } .dataTables_wrapper .dataTables_scroll { clear: both; } .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody { *margin-top: -1px; -webkit-overflow-scrolling: touch; } .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td { vertical-align: middle; } .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td > div.dataTables_sizing { height: 0; overflow: hidden; margin: 0 !important; padding: 0 !important; } .dataTables_wrapper.no-footer .dataTables_scrollBody { border-bottom: 1px solid #111111; } .dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable, .dataTables_wrapper.no-footer div.dataTables_scrollBody > table { border-bottom: none; } .dataTables_wrapper:after { visibility: hidden; display: block; content: """"; clear: both; height: 0; } @media screen and (max-width: 767px) { .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_paginate { float: none; text-align: center; } .dataTables_wrapper .dataTables_paginate { margin-top: 0.5em; } } @media screen and (max-width: 640px) { .dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter { float: none; text-align: center; } .dataTables_wrapper .dataTables_filter { margin-top: 0.5em; } }",2023-01-05 17:28:07.068000,"Replicates the functionality of the Monitor Module, but adds the option to display it on your dashboard. Watches must be created in the Monitor Module.",Inventory Watch List,,30,2,inventory-watch-list,0 30,_binary ,"let partNum = '$PART{Part|%|General}'; partNum == -1 ? (partNum = '%') : true; let locationGroupId = '$LG{Location_Group|%|General}'; locationGroupId == -1 ? (locationGroupId = '%') : true; let user = JSON.parse(getUser()); let currentUser = user.id; let dataset; function monitor() { function getData() { let query = `SELECT COALESCE((SELECT (sysvalue) * 1000 FROM sysproperties WHERE syskey = 'Refresh Rate'),300000) as refresh, watch.id as watchid, part.num as partnum, part.description as partdescription, COALESCE(locationgroup.name,'Company Wide') as locationgroup, coalesce(uom.code,'') as uom, @avail:= coalesce(IF(coalesce(qtyonhand.qty,0) - coalesce(qtyallocated.qty,0) - coalesce(qtynotavailable.qty,0) + coalesce(qtydropship.qty,0) < 0,0,coalesce(qtyonhand.qty,0) - coalesce(qtyallocated.qty,0) - coalesce(qtynotavailable.qty,0) + coalesce(qtydropship.qty,0))) as avail, @onhand:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(qtyonhand.qty,0) ELSE coalesce(totals.qtyonhand, 0) END) as onhand, @available:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(@avail,0) ELSE coalesce(totals.qtyavailable, 0) END) as available, @committed:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(qtycommitted.qty,0) ELSE coalesce((SELECT sum(qty) FROM qtycommitted qtyc WHERE qtyc.partid = part.id GROUP BY partid),0) END) as committed, @allocated:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(qtyallocated.qty,0) ELSE coalesce(totals.qtyallocated, 0) END) as allocated, @notavailable:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(qtynotavailable.qty,0) ELSE coalesce(totals.qtynotavailable, 0) END) as 'not available', @onorder:=(CASE WHEN watch.locationgroupid IS NOT NULL THEN coalesce(qtyonorder.qty,0) ELSE coalesce(totals.qtyonorder, 0) END) as 'on order', (CASE WHEN @onhand > watch.alertlevel THEN 'fb10' WHEN @onhand <= watch.alertlevel && @onhand > watch.criticallevel THEN 'fb20' WHEN @onhand < watch.alertlevel && @onhand <= watch.criticallevel THEN 'fb30' END) as state, (CASE WHEN @onhand > watch.alertlevel THEN '1-Good' WHEN @onhand <= watch.alertlevel && @onhand > watch.criticallevel THEN '2-Alert' WHEN @onhand < watch.alertlevel && @onhand <= watch.criticallevel THEN '3-Critical' END) as statetext FROM watch INNER JOIN part ON watch.itemid = part.id INNER JOIN uom ON part.uomid = uom.id LEFT OUTER JOIN locationgroup ON watch.locationgroupid = locationgroup.id left outer join qtyonhand on (part.id = qtyonhand.partid and locationgroup.id = qtyonhand.locationgroupid) left outer join qtycommitted on (part.id = qtycommitted.partid and locationgroup.id = qtycommitted.locationgroupid) left outer join qtyallocated on (part.id = qtyallocated.partid and locationgroup.id = qtyallocated.locationgroupid) left outer join qtyonorder on (part.id = qtyonorder.partid and locationgroup.id = qtyonorder.locationgroupid) left outer join qtynotavailable on (part.id = qtynotavailable.partid and locationgroup.id = qtynotavailable.locationgroupid) left outer join qtydropship on (part.id = qtydropship.partid and locationgroup.id = qtydropship.locationgroupid) left outer join (select coalesce(sum(qti.qtyonhand),0) as qtyonhand, coalesce(sum(qti.qtyallocated),0) as qtyallocated, coalesce(sum(qti.qtyonorder),0) as qtyonorder, if(coalesce((sum(qti.qtyonhand) - sum(qti.qtyallocated) - sum(qti.qtynotavailable) + sum(qti.qtydropship)),0) < 0,0,coalesce((sum(qti.qtyonhand) - sum(qti.qtyallocated) - sum(qti.qtynotavailable) + sum(qti.qtydropship)),0)) as qtyavailable, coalesce(sum(qti.qtynotavailable),0) as qtynotavailable, coalesce(sum(qti.qtydropship),0) as qtydropship, qti.partid from qtyinventorytotals qti group by qti.partid) as totals on part.id = totals.partid WHERE part.id LIKE '${partNum}' AND COALESCE(locationgroup.id,'') LIKE '${locationGroupId}' AND watch.sysuserid LIKE '${currentUser}'`; console.log(query); let dataset = JSON.parse(runQuery(query)); console.log(dataset); return dataset; } function drawTable() { dataset = getData(); let table = $('#report-table'); table.empty(); table.DataTable({ dom: 'B<""clear"">lfrtip', data: dataset, columns: [ { title: 'State', data: 'statetext', defaultContent: '', className: 'stateText', createdCell: function(td, cellData, rowData, row, col) { let statecircle = document.createElement('div'); console.log(statecircle); statecircle.setAttribute('watchid', rowData.watchid); td.append(statecircle); statecircle.classList.add(rowData.state); statecircle.classList.add('dot'); } }, { title: 'Part Number', data: 'partnum' }, { title: 'Part Description', data: 'partdescription' }, { title: 'Location Group', data: 'locationgroup' }, { title: 'UOM', data: 'uom' }, { title: 'On Hand', data: 'onhand' }, { title: 'Available', data: 'available' }, { title: 'Committed', data: 'committed', defaultContent: '0' }, { title: 'Allocated', data: 'allocated' }, { title: 'Not Available', data: 'not available' }, { title: 'On Order', data: 'on order' } ], fixedHeader: true, colReorder: false, pagingType: 'simple', responsive: true, deferRender: true, buttons: ['csv'], language: { paginate: { previous: 'PREV', next: 'NEXT' } } }); } function refreshTable() { console.time('refreshRate'); let table = $('#report-table').DataTable(); dataset = getData(); table.clear(); table.rows.add(dataset); table.draw(false); console.timeEnd('refreshRate'); setTimeout(refreshTable, dataset[0].refresh); } drawTable(); $("".dt-buttons"").addClass( ""csv-button-margin"" ); console.log(dataset[0].refresh); setTimeout(refreshTable, dataset[0].refresh); } $(document).ready(function() { monitor(); }); ",2023-01-05 17:28:07.068000,"Replicates the functionality of the Monitor Module, but adds the option to display it on your dashboard. Watches must be created in the Monitor Module.",Inventory Watch List,,20,2,inventory-watch-list,0 31,_binary ,"
Edit Mode
+
-
",2023-04-20 16:40:15.578000,Resizable part labels with QR code,Part QR Code Label,,10,4,part-qr-code-label,1 32,_binary ,"let zoom = 100; let canvas = document.querySelector(""#canvas""); let printable = document.querySelector(""#printable""); const partContainer = document.querySelector('#partContainer'); let qr = document.querySelector("".qr-code""); let save = document.querySelector(""#save""); let edit = document.querySelector(""#edit""); let desc = document.querySelector("".desc-drag""); let part = document.querySelector("".part-drag""); let custText = document.querySelector("".custom-drag""); let select = document.querySelector("".selected""); let partNum = '$PART{Part_Number|%|General}'; let count = '$NUM{Count|90|General}' partNum == -1 ? (partNum = '%') : true; let showDesc = '$CHECK{Show_Description|1|General}'; let showPart = '$CHECK{Show_Part_Num|1|General}'; let showBarcode = '$CHECK{Show_Barcode|1|General}'; let showCustomText = '$CHECK{Show_Custom_Text|0|General}'; let startRange = '$NUM{Page_Start_From|1|General}'; let endRange = '$NUM{Through_To_Page|90|General}'; startRange -= 1; var total; var limit; var offset; var qrWidth; var editMode = false; let LABEL = { width: 2, height: 1, qrWidth: 84, qrTransform: ""translate(9px, 5px)"", qrTranslateX: 9, qrTranslateY: 5, partFontSize: 14, partTransform: ""translate(98px, 13px)"", partTranslateX: 98, partTranslateY: 13, partWidth: 84.375, partHeight: 17, partBold: ""false"", partItalic: ""false"", partUnderlined: ""false"", partAlign: ""center"", partVAlign: ""start"", partFontFamily: ""Arial"", descFontSize: 12, descTransform: ""translate(98px, 42px)"", descTranslateX: 98, descTranslateY: 42, descWidth: 84.0469, descHeight: 42, descBold: ""false"", descItalic: ""false"", descUnderlined: ""false"", descAlign: ""center"", descVAlign: ""start"", descFontFamily: ""Arial"", descFontSize: 12, custTransform: ""translate(0px, 0px)"", custTranslateX: 0, custTranslateY: 0, custWidth: 84.0469, custHeight: 17, custBold: ""false"", custItalic: ""false"", custUnderlined: ""false"", custAlign: ""center"", custVAlign: ""start"", custFontFamily: ""Arial"", custFontSize: 12, custText: ""Custom Text"", }; function getLabelData() { if (loadReportData() === '') { saveReportData(JSON.stringify(LABEL)); } return JSON.parse(loadReportData()); } //let savedLabel = LABEL; let savedLabel = getLabelData(); if(savedLabel.custWidth == null) { savedLabel.custTransform = LABEL.custTransform; savedLabel.custTranslateX = LABEL.custTranslateX; savedLabel.custTranslateY = LABEL.custTranslateY; savedLabel.custWidth = LABEL.custWidth; savedLabel.custHeight = LABEL.custHeight; savedLabel.custBold = LABEL.custBold; savedLabel.custItalic = LABEL.custItalic; savedLabel.custUnderlined = LABEL.custUnderlined; savedLabel.custAlign = LABEL.custAlign; savedLabel.custFontFamily = LABEL.custFontFamily; savedLabel.custFontSize = LABEL.custFontSize; savedLabel.custText = LABEL.custText; } if(savedLabel.partVAlign == null) { savedLabel.partVAlign = LABEL.partVAlign; savedLabel.descVAlign = LABEL.descVAlign; savedLabel.custVAlign = LABEL.custVAlign; } if (partNum == '%') { limit = endRange - startRange; offset = startRange; } else { limit = count; offset = 0; } var leftArrow = document.querySelector( '.arrow-left' ); var rightArrow = document.querySelector( '.arrow-right' ); var firstArrow = document.querySelector( '.arrow-first' ); var lastArrow = document.querySelector( '.arrow-last' ); let Items = JSON.parse(runQuery(` SELECT part.NUM AS partnum, part.description FROM part WHERE part.id > 0 AND part.activeflag = 1 AND part.id LIKE '${partNum}' LIMIT ${limit} OFFSET ${offset} `)); desc.innerHTML = Items[0].description; part.innerHTML = Items[0].partnum; function generateQR(data) { document.getElementById(""myCanvas"").setAttribute(""src"", ""http://bwipjs-api.metafloor.com/?bcid=qrcode&text="" + data + ""&scale=10""); }; generateQR(Items[0].partnum); function generateCards(length) { let i; for (let b = 0; b < length; b++) { if (partNum == '%'){i = b}else{i = 0}; document.getElementById(""partContainer"").insertAdjacentHTML('beforeend',`

`); document.getElementById(""partNum_"").setAttribute('id',""partNum_"" + b.toString()); document.getElementById(""qrBarcode_"").setAttribute('id',""qrBarcode_"" + b.toString()); document.getElementById(""partDesc_"").setAttribute('id',""partDesc_"" + b.toString()); document.getElementById(""customText_"").setAttribute('id',""customText_"" + b.toString()); document.getElementById(""qrBarcode_"" + b.toString()).setAttribute(""src"", ""http://bwipjs-api.metafloor.com/?bcid=qrcode&text="" + Items[i].partnum + ""&scale=10""); /******* Adding Text to the partnum and description divs *******/ document.getElementById(""partNum_"" + b.toString()).innerHTML = Items[i].partnum; document.getElementById(""partDesc_"" + b.toString()).innerHTML = Items[i].description; document.getElementById(""customText_"" + b.toString()).innerHTML = savedLabel.custText; } } function makeCards() { if (partNum == '%') { total = Items.length; generateCards(total); } else { total = count; generateCards(total); } } makeCards(); let index = 1; document.querySelector( '.counter' ).innerHTML = ( index ) + ' / ' + total; leftArrow.addEventListener('click', (e) => { if (index > 1) { index -= 1; document.querySelector( '.counter' ).innerHTML = ( index ) + ' / ' + total; } desc.innerHTML = Items[index - 1].description; part.innerHTML = Items[index - 1].partnum; generateQR(Items[index - 1].partnum); }); rightArrow.addEventListener('click', (e) => { if (index < total) { index += 1; document.querySelector( '.counter' ).innerHTML = ( index ) + ' / ' + total; } desc.innerHTML = Items[index - 1].description; part.innerHTML = Items[index - 1].partnum; generateQR(Items[index - 1].partnum); }); firstArrow.addEventListener('click', (e) => { if (index != 1) { index = 1; document.querySelector( '.counter' ).innerHTML = '1 / ' + total; } desc.innerHTML = Items[0].description; part.innerHTML = Items[0].partnum; generateQR(Items[0].partnum); }); lastArrow.addEventListener('click', (e) => { if (index != total) { index = total; document.querySelector( '.counter' ).innerHTML = ( total ) + ' / ' + total; } desc.innerHTML = Items[total - 1].description; part.innerHTML = Items[total - 1].partnum; generateQR(Items[total - 1].partnum); }); var cssPagedMedia = (function () { var style = document.createElement('style'); document.head.appendChild(style); return function (rule) { style.innerHTML = rule; }; }()); cssPagedMedia.size = function (size) { cssPagedMedia('@page {size: auto; margin: 0mm;} @media print {@page {size: ' + size + '}}'); }; cssPagedMedia.size(savedLabel.width + ""in "" + savedLabel.height + ""in""); function resize(Rect){ interact("".selected"").resizable({ edges: { left: true, right: true, bottom: true, top: true }, listeners: { move(event) { var target = event.target; var rect = event.rect; let drag = zoom / 100; // update the element's style if (target.classList.contains('qr-code')) { position.x += event.deltaRect.left / drag position.y += event.deltaRect.left / drag target.style.transform = 'translate(' + position.x + 'px,' + position.y + 'px)' target.setAttribute('data-x', position.x) target.setAttribute('data-y', position.y) target.style.width = Math.floor(rect.width / drag) + ""px""; target.style.height = Math.floor(rect.width / drag) + ""px""; qrWidth = Math.floor(rect.width / drag); savedLabel.qrWidth = Math.floor(rect.width / drag); let qrcodes = document.querySelectorAll("".qr-code""); qrcodes.forEach(function(elem) { elem.style.transform = 'translate(' + position.x + 'px,' + position.y + 'px)' elem.setAttribute('data-x', position.x) elem.setAttribute('data-y', position.y) elem.style.width = Math.floor(rect.width / drag) + ""px""; elem.style.height = Math.floor(rect.width / drag) + ""px""; }); } else { target.style.width = rect.width / drag + ""px""; target.style.height = rect.height / drag + ""px""; if (target.classList.contains(""part-drag"")) { partposition.x += event.deltaRect.left / drag partposition.y += event.deltaRect.top / drag target.style.transform = 'translate(' + partposition.x + 'px,' + partposition.y + 'px)' target.setAttribute('data-x', partposition.x) target.setAttribute('data-y', partposition.y) let parts = document.querySelectorAll("".part-drag""); parts.forEach(function(elem) { elem.style.transform = 'translate(' + partposition.x + 'px,' + partposition.y + 'px)' elem.setAttribute('data-x', partposition.x) elem.setAttribute('data-y', partposition.y) elem.style.width = Math.floor(rect.width / drag) + ""px""; elem.style.height = Math.floor(rect.height / drag) + ""px""; }); savedLabel.partWidth = rect.width / drag; savedLabel.partHeight = rect.height / drag; } else if (target.classList.contains(""desc-drag"")) { descposition.x += event.deltaRect.left / drag descposition.y += event.deltaRect.top / drag target.style.transform = 'translate(' + descposition.x + 'px,' + descposition.y + 'px)' target.setAttribute('data-x', descposition.x) target.setAttribute('data-y', descposition.y) let descs = document.querySelectorAll("".desc-drag""); descs.forEach(function(elem) { elem.style.transform = 'translate(' + descposition.x + 'px,' + descposition.y + 'px)' elem.setAttribute('data-x', descposition.x) elem.setAttribute('data-y', descposition.y) elem.style.width = Math.floor(rect.width / drag) + ""px""; elem.style.height = Math.floor(rect.height / drag) + ""px""; }); savedLabel.descWidth = rect.width / drag; savedLabel.descHeight = rect.height / drag; } else if (target.classList.contains(""custom-drag"")) { custposition.x += event.deltaRect.left / drag custposition.y += event.deltaRect.top / drag target.style.transform = 'translate(' + custposition.x + 'px,' + custposition.y + 'px)' target.setAttribute('data-x', custposition.x) target.setAttribute('data-y', custposition.y) let custs = document.querySelectorAll("".custom-drag""); custs.forEach(function(elem) { elem.style.transform = 'translate(' + custposition.x + 'px,' + custposition.y + 'px)' elem.setAttribute('data-x', custposition.x) elem.setAttribute('data-y', custposition.y) elem.style.width = Math.floor(rect.width / drag) + ""px""; elem.style.height = Math.floor(rect.height / drag) + ""px""; }); savedLabel.custWidth = rect.width / drag; savedLabel.custHeight = rect.height / drag; } } } }, modifiers: [ // minimum size interact.modifiers.restrictSize({ min: { width: 15, height: 15 } }), interact.modifiers.restrictEdges({ outer: { left: Rect.left, right: Rect.right, top: Rect.top, bottom: Rect.bottom } }) ] }); }; window.addEventListener(""resize"", (e) => { var divRectNew = printable.getBoundingClientRect(); resize(divRectNew); }); $('#labelH').on('change', function() { var size = $(this).val(); $('#printable').css('height', size + 'in'); $('.card').css('height', size + 'in'); savedLabel.height = size; cssPagedMedia.size($('#labelW').val() + ""in "" + $('#labelH').val() + ""in""); var divRectNew = printable.getBoundingClientRect(); resize(divRectNew); }); $('#labelW').on('change', function() { var size = $(this).val(); $('#printable').css('width', size + 'in'); $('.card').css('width', size + 'in'); savedLabel.width = size; cssPagedMedia.size($('#labelW').val() + ""in "" + $('#labelH').val() + ""in""); var divRectNew = printable.getBoundingClientRect(); resize(divRectNew); }); $('#size').on('change', function() { var size = $(this).val(); $('.selected').css('fontSize', size + 'px'); if ($('.selected').hasClass('desc-drag')) { let descs = document.querySelectorAll("".desc-drag""); savedLabel.descFontSize = size; descs.forEach(function(elem) { elem.style.fontSize = size; }); } else if ($('.selected').hasClass('part-drag')) { let parts = document.querySelectorAll("".part-drag""); savedLabel.partFontSize = size; parts.forEach(function(elem) { elem.style.fontSize = size; }); } else if ($('.selected').hasClass('custom-drag')) { let custs = document.querySelectorAll("".custom-drag""); savedLabel.custFontSize = size; custs.forEach(function(elem) { elem.style.fontSize = size; }); } }); $('#bold').on('click', function() { let parts = document.querySelectorAll("".part-drag""); let descs = document.querySelectorAll("".desc-drag""); let custs = document.querySelectorAll("".custom-drag""); if ($('.selected').hasClass('bold')) { if ($('.selected').hasClass('part-drag')) { parts.forEach(function(elem) { elem.classList.remove('bold'); }); } else if ($('.selected').hasClass('desc-drag')) { descs.forEach(function(elem) { elem.classList.remove('bold'); }); } else if ($('.selected').hasClass('custom-drag')) { custs.forEach(function(elem) { elem.classList.remove('bold'); }); }; } else { if ($('.selected').hasClass('part-drag')) { parts.forEach(function(elem) { elem.classList.add('bold'); }); } else if ($('.selected').hasClass('desc-drag')) { descs.forEach(function(elem) { elem.classList.add('bold'); }); } else if ($('.selected').hasClass('custom-drag')) { custs.forEach(function(elem) { elem.classList.add('bold'); }); }; } }); $('#italic').on('click', function() { let parts = document.querySelectorAll("".part-drag""); let descs = document.querySelectorAll("".desc-drag""); let custs = document.querySelectorAll("".custom-drag""); if ($('.selected').hasClass('italic')) { if ($('.selected').hasClass('part-drag')) { parts.forEach(function(elem) { elem.classList.remove('italic'); }); } else if ($('.selected').hasClass('desc-drag')) { descs.forEach(function(elem) { elem.classList.remove('italic'); }); } else if ($('.selected').hasClass('custom-drag')) { custs.forEach(function(elem) { elem.classList.remove('italic'); }); }; } else { if ($('.selected').hasClass('part-drag')) { parts.forEach(function(elem) { elem.classList.add('italic'); }); } else if ($('.selected').hasClass('desc-drag')) { descs.forEach(function(elem) { elem.classList.add('italic'); }); } else if ($('.selected').hasClass('custom-drag')) { custs.forEach(function(elem) { elem.classList.add('italic'); }); }; } }); $('#underline').on('click', function() { let parts = document.querySelectorAll("".part-drag""); let descs = document.querySelectorAll("".desc-drag""); let custs = document.querySelectorAll("".custom-drag""); if ($('.selected').hasClass('underline')) { if ($('.selected').hasClass('part-drag')) { parts.forEach(function(elem) { elem.classList.remove('underline'); }); } else if ($('.selected').hasClass('desc-drag')) { descs.forEach(function(elem) { elem.classList.remove('underline'); }); } else if ($('.selected').hasClass('custom-drag')) { custs.forEach(function(elem) { elem.classList.remove('underline'); }); }; } else { if ($('.selected').hasClass('part-drag')) { parts.forEach(function(elem) { elem.classList.add('underline'); }); } else if ($('.selected').hasClass('desc-drag')) { descs.forEach(function(elem) { elem.classList.add('underline'); }); } else if ($('.selected').hasClass('custom-drag')) { custs.forEach(function(elem) { elem.classList.add('underline'); }); }; } }); $('#align-left').on('click', function() { document.execCommand('justifyLeft', false, null); if ($('.selected').hasClass('part-drag')) { savedLabel.partAlign = ""left""; let parts = document.querySelectorAll("".part-drag""); parts.forEach(function(elem) { elem.style.justifyContent = ""left""; elem.style.textAlign = ""left""; }); } else if ($('.selected').hasClass('desc-drag')) { savedLabel.descAlign = ""left""; let descs = document.querySelectorAll("".desc-drag""); descs.forEach(function(elem) { elem.style.justifyContent = ""left""; elem.style.textAlign = ""left""; }); } else if ($('.selected').hasClass('custom-drag')) { savedLabel.custAlign = ""left""; let custs = document.querySelectorAll("".custom-drag""); custs.forEach(function(elem) { elem.style.justifyContent = ""left""; elem.style.textAlign = ""left""; }); } }); $('#align-center').on('click', function() { document.execCommand('justifyCenter', false, null); if ($('.selected').hasClass('part-drag')) { savedLabel.partAlign = ""center""; let parts = document.querySelectorAll("".part-drag""); parts.forEach(function(elem) { elem.style.justifyContent = ""center""; elem.style.textAlign = ""center""; }); } else if ($('.selected').hasClass('desc-drag')) { savedLabel.descAlign = ""center""; let descs = document.querySelectorAll("".desc-drag""); descs.forEach(function(elem) { elem.style.justifyContent = ""center""; elem.style.textAlign = ""center""; }); } else if ($('.selected').hasClass('custom-drag')) { savedLabel.custAlign = ""center""; let custs = document.querySelectorAll("".custom-drag""); custs.forEach(function(elem) { elem.style.justifyContent = ""center""; elem.style.textAlign = ""center""; }); } }); $('#align-right').on('click', function() { document.execCommand('justifyRight', false, null); if ($('.selected').hasClass('part-drag')) { savedLabel.partAlign = ""right""; let parts = document.querySelectorAll("".part-drag""); parts.forEach(function(elem) { elem.style.justifyContent = ""right""; elem.style.textAlign = ""right""; }); } else if ($('.selected').hasClass('desc-drag')) { savedLabel.descAlign = ""right""; let descs = document.querySelectorAll("".desc-drag""); descs.forEach(function(elem) { elem.style.justifyContent = ""right""; elem.style.textAlign = ""right""; }); } else if ($('.selected').hasClass('custom-drag')) { savedLabel.custAlign = ""right""; let custs = document.querySelectorAll("".custom-drag""); custs.forEach(function(elem) { elem.style.justifyContent = ""right""; elem.style.textAlign = ""right""; }); } }); $('#align-top').on('click', function() { if ($('.selected').hasClass('part-drag')) { savedLabel.partVAlign = ""start""; let parts = document.querySelectorAll("".part-drag""); parts.forEach(function(elem) { elem.style.alignContent = ""start""; }); } else if ($('.selected').hasClass('desc-drag')) { savedLabel.descVAlign = ""start""; let descs = document.querySelectorAll("".desc-drag""); descs.forEach(function(elem) { elem.style.alignContent = ""start""; }); } else if ($('.selected').hasClass('custom-drag')) { savedLabel.custVAlign = ""start""; let custs = document.querySelectorAll("".custom-drag""); custs.forEach(function(elem) { elem.style.alignContent = ""start""; }); } }); $('#align-middle').on('click', function() { if ($('.selected').hasClass('part-drag')) { savedLabel.partVAlign = ""center""; let parts = document.querySelectorAll("".part-drag""); parts.forEach(function(elem) { elem.style.alignContent = ""center""; }); } else if ($('.selected').hasClass('desc-drag')) { savedLabel.descVAlign = ""center""; let descs = document.querySelectorAll("".desc-drag""); descs.forEach(function(elem) { elem.style.alignContent = ""center""; }); } else if ($('.selected').hasClass('custom-drag')) { savedLabel.custVAlign = ""center""; let custs = document.querySelectorAll("".custom-drag""); custs.forEach(function(elem) { elem.style.alignContent = ""center""; }); } }); $('#align-bottom').on('click', function() { if ($('.selected').hasClass('part-drag')) { savedLabel.partVAlign = ""end""; let parts = document.querySelectorAll("".part-drag""); parts.forEach(function(elem) { elem.style.alignContent = ""end""; }); } else if ($('.selected').hasClass('desc-drag')) { savedLabel.descVAlign = ""end""; let descs = document.querySelectorAll("".desc-drag""); descs.forEach(function(elem) { elem.style.alignContent = ""end""; }); } else if ($('.selected').hasClass('custom-drag')) { savedLabel.custVAlign = ""end""; let custs = document.querySelectorAll("".custom-drag""); custs.forEach(function(elem) { elem.style.alignContent = ""end""; }); } }); $('#fonts').on('change', function() { var font = $(this).val(); if ($('.selected').hasClass('desc-drag')) { let descs = document.querySelectorAll("".desc-drag""); savedLabel.descFontFamily = font; descs.forEach(function(elem) { elem.style.fontFamily = font; }); } else if ($('.selected').hasClass('part-drag')) { let parts = document.querySelectorAll("".part-drag""); savedLabel.partFontFamily = font; parts.forEach(function(elem) { elem.style.fontFamily = font; }); } else if ($('.selected').hasClass('custom-drag')) { let custs = document.querySelectorAll("".custom-drag""); savedLabel.custFontFamily = font; custs.forEach(function(elem) { elem.style.fontFamily = font; }); } }); /******* zoom in & zoom out *******/ let plus = document.querySelector("".plus""); plus.addEventListener(""click"", (e) => { if(zoom < 325) {zoom += 25;}; printable.style.transform = ""scale("" + zoom / 100 + "")""; var divRect = printable.getBoundingClientRect(); resize(divRect); }); let minus = document.querySelector("".minus""); minus.addEventListener(""click"", (e) => { if(zoom > 25) {zoom -= 25;}; printable.style.transform = ""scale("" + zoom / 100 + "")""; var divRect = printable.getBoundingClientRect(); resize(divRect); }); /******* item selection functionality *******/ function removeSelect() { let select = document.querySelector("".selected""); if (select != null) { select.style.boxShadow = ""0 0 0px 1px grey"" select.classList.remove(""selected""); } } function canvasEvent() { let select = document.querySelector("".selected""); if (select != null) {select.classList.remove(""selected"");}; }; function qrEvent() { removeSelect(); qr.classList.add('selected'); qr.style.boxShadow = ""0 0 0px 2px #0984e3""; }; function partEvent() { removeSelect(); part.classList.add('selected'); part.style.boxShadow = ""0 0 0px 2px #0984e3""; let sizeOptions = document.getElementById('size').getElementsByTagName('option'); for(var i = 0; i < sizeOptions.length; i++){ if (sizeOptions[i].value + ""px"" == part.style.fontSize) { sizeOptions[i].selected = 'selected'; }; }; let fontOptions = document.getElementById('fonts').getElementsByTagName('option'); for(var i = 0; i < fontOptions.length; i++){ if (fontOptions[i].value == part.style.fontFamily) { fontOptions[i].selected = 'selected'; }; }; }; function descEvent() { removeSelect(); desc.classList.add('selected'); desc.style.boxShadow = ""0 0 0px 2px #0984e3""; let sizeOptions = document.getElementById('size').getElementsByTagName('option'); for(var i = 0; i < sizeOptions.length; i++){ if (sizeOptions[i].value + ""px"" == desc.style.fontSize) { sizeOptions[i].selected = 'selected'; }; }; let fontOptions = document.getElementById('fonts').getElementsByTagName('option'); for(var i = 0; i < fontOptions.length; i++){ if (fontOptions[i].value == desc.style.fontFamily) { fontOptions[i].selected = 'selected'; }; }; }; function custTextEvent() { removeSelect(); custText.classList.add('selected'); custText.style.boxShadow = ""0 0 0px 2px #0984e3""; let sizeOptions = document.getElementById('size').getElementsByTagName('option'); for(var i = 0; i < sizeOptions.length; i++){ if (sizeOptions[i].value + ""px"" == custText.style.fontSize) { sizeOptions[i].selected = 'selected'; }; }; let fontOptions = document.getElementById('fonts').getElementsByTagName('option'); for(var i = 0; i < fontOptions.length; i++){ if (fontOptions[i].value == custText.style.fontFamily) { fontOptions[i].selected = 'selected'; }; }; }; function activateEditMode() { if (editMode == false) { canvas.addEventListener(""click"", removeSelect, true); if (select != null) {select.classList.remove(""selected"");}; qr.addEventListener(""click"", qrEvent); desc.addEventListener(""click"", descEvent); part.addEventListener(""click"", partEvent); custText.addEventListener(""click"", custTextEvent); } else { canvas.removeEventListener(""click"", removeSelect, true); qr.removeEventListener(""click"", qrEvent); desc.removeEventListener(""click"", descEvent); part.removeEventListener(""click"", partEvent); custText.removeEventListener(""click"", custTextEvent); }; }; /******* dragging items functionality *******/ const position = { x: savedLabel.qrTranslateX, y: savedLabel.qrTranslateY }; const descposition = { x: savedLabel.descTranslateX, y: savedLabel.descTranslateY }; const partposition = { x: savedLabel.partTranslateX, y: savedLabel.partTranslateY }; const custposition = { x: savedLabel.custTranslateX, y: savedLabel.custTranslateY }; function changeToolbarColors(on) { let alignRight = document.querySelector(""#align-right""); let alignLeft = document.querySelector(""#align-left""); let alignCenter = document.querySelector(""#align-center""); let alignBox = document.querySelectorAll("".align-box""); let lineTop = document.querySelectorAll("".line-top""); let lineBottom = document.querySelectorAll("".line-bottom""); let bold = document.querySelector(""#bold""); let italic = document.querySelector(""#italic""); let underline = document.querySelector(""#underline""); let labelSizeTitle = document.querySelector(""#labelSizeTitle""); let labelSizeX = document.querySelector(""#labelSizeX""); let labelW = document.querySelector(""#labelW""); let labelH = document.querySelector(""#labelH""); let toolbarButtons = document.querySelectorAll("".toolbar button""); let save = document.querySelector(""#save""); let edit = document.querySelector(""#edit""); let size = document.querySelector(""#size""); let fonts = document.querySelector(""#fonts""); if (on == true) { alignRight.style.color = ""black""; alignLeft.style.color = ""black""; alignCenter.style.color = ""black""; alignBox.forEach(function(elem) { elem.style.borderColor = ""black""; }); lineTop.forEach(function(elem) { elem.style.background = ""black""; }); lineBottom.forEach(function(elem) { elem.style.background = ""black""; }); bold.style.color = ""black""; italic.style.color = ""black""; underline.style.color = ""black""; labelSizeTitle.style.color = ""black""; labelSizeX.style.color = ""black""; labelW.style.color = ""black""; labelH.style.color = ""black""; labelW.style.cursor = ""pointer""; labelH.style.cursor = ""pointer""; size.style.cursor = ""pointer""; fonts.style.cursor = ""pointer""; toolbarButtons.forEach(function(elem) { elem.classList.add('hover'); }); save.classList.add('hover'); save.style.background = ""#153dff""; edit.classList.remove('hover'); edit.style.background = ""#a6a6a6""; } else { alignRight.style.color = ""#a6a6a6""; alignLeft.style.color = ""#a6a6a6""; alignCenter.style.color = ""#a6a6a6""; alignBox.forEach(function(elem) { elem.style.borderColor = ""#a6a6a6""; }); lineTop.forEach(function(elem) { elem.style.background = ""#a6a6a6""; }); lineBottom.forEach(function(elem) { elem.style.background = ""#a6a6a6""; }); bold.style.color = ""#a6a6a6""; italic.style.color = ""#a6a6a6""; underline.style.color = ""#a6a6a6""; labelSizeTitle.style.color = ""#a6a6a6""; labelSizeX.style.color = ""#a6a6a6""; labelW.style.color = ""#a6a6a6""; labelH.style.color = ""#a6a6a6""; labelW.style.cursor = ""default""; labelH.style.cursor = ""default""; size.style.cursor = ""default""; fonts.style.cursor = ""default""; toolbarButtons.forEach(function(elem) { elem.classList.remove('hover'); }); edit.classList.add('hover'); edit.style.background = ""green""; save.classList.remove('hover'); save.style.background = ""#a6a6a6""; } } function editButton() { let editModeLabel = document.querySelector(""#editMode""); let labelW = document.querySelector(""#labelW""); let labelH = document.querySelector(""#labelH""); let size = document.querySelector(""#size""); let fonts = document.querySelector(""#fonts""); labelW.removeAttribute('readonly'); labelH.removeAttribute('readonly'); size.removeAttribute(""disabled""); size.removeChild(size.options[0]); fonts.removeAttribute(""disabled""); fonts.removeChild(fonts.options[0]); editModeLabel.style.display = ""block""; changeToolbarColors(true); interact('.qr-drag').draggable({ restrict: { restriction: printable, elementRect: { top: 0, left: 0, bottom: 1, right: 1 } }, listeners: { start (event) { console.log(event.type, event.target) }, move (event) { let drag = zoom / 100; let qrcodes = document.querySelectorAll("".qr-code""); qrcodes.forEach(function(elem) { elem.style.transform = `translate(${position.x}px, ${position.y}px)` }); position.x += event.dx / drag position.y += event.dy / drag event.target.style.transform = `translate(${position.x}px, ${position.y}px)`; savedLabel.qrTransform = `translate(${position.x}px, ${position.y}px)`; savedLabel.qrTranslateX = position.x; savedLabel.qrTranslateY = position.y; }, } }); interact('.desc-drag').draggable({ restrict: { restriction: printable, elementRect: { top: 0, left: 0, bottom: 1, right: 1 } }, listeners: { start (event) { console.log(event.type, event.target) }, move (event) { let drag = zoom / 100; descposition.x += event.dx / drag descposition.y += event.dy / drag let descriptions = document.querySelectorAll("".desc-drag""); descriptions.forEach(function(elem) { elem.style.transform = `translate(${descposition.x}px, ${descposition.y}px)` }); event.target.style.transform = `translate(${descposition.x}px, ${descposition.y}px)`; savedLabel.descTransform = `translate(${descposition.x}px, ${descposition.y}px)`; savedLabel.descTranslateX = descposition.x; savedLabel.descTranslateY = descposition.y; }, } }); interact('.part-drag').draggable({ restrict: { restriction: printable, elementRect: { top: 0, left: 0, bottom: 1, right: 1 } }, listeners: { start (event) { console.log(event.type, event.target) }, move (event) { let drag = zoom / 100; partposition.x += event.dx / drag partposition.y += event.dy / drag let parts = document.querySelectorAll("".part-drag""); parts.forEach(function(elem) { elem.style.transform = `translate(${partposition.x}px, ${partposition.y}px)` }); event.target.style.transform = `translate(${partposition.x}px, ${partposition.y}px)`; savedLabel.partTransform = `translate(${partposition.x}px, ${partposition.y}px)`; savedLabel.partTranslateX = partposition.x; savedLabel.partTranslateY = partposition.y; }, } }); interact('.custom-drag').draggable({ restrict: { restriction: printable, elementRect: { top: 0, left: 0, bottom: 1, right: 1 } }, listeners: { start (event) { console.log(event.type, event.target) }, move (event) { let drag = zoom / 100; custposition.x += event.dx / drag custposition.y += event.dy / drag let custs = document.querySelectorAll("".custom-drag""); custs.forEach(function(elem) { elem.style.transform = `translate(${custposition.x}px, ${custposition.y}px)` }); event.target.style.transform = `translate(${custposition.x}px, ${custposition.y}px)`; savedLabel.custTransform = `translate(${custposition.x}px, ${custposition.y}px)`; savedLabel.custTranslateX = custposition.x; savedLabel.custTranslateY = custposition.y; }, } }); document.querySelector(""#canvasPart"").style.boxShadow = ""0 0 0px 1px grey""; document.querySelector(""#canvasDesc"").style.boxShadow = ""0 0 0px 1px grey""; document.querySelector("".qr-code"").style.boxShadow = ""0 0 0px 1px grey""; document.querySelector(""#customText"").style.boxShadow = ""0 0 0px 1px grey""; custText.contentEditable = ""true""; canvas.addEventListener(""click"", removeSelect, true); if (select != null) {select.classList.remove(""selected"");}; qr.addEventListener(""click"", qrEvent); desc.addEventListener(""click"", descEvent); part.addEventListener(""click"", partEvent); custText.addEventListener(""click"", custTextEvent); edit.removeEventListener(""click"", editButton); save.addEventListener(""click"", saveButton); } function saveButton() { let editModeLabel = document.querySelector(""#editMode""); let labelW = document.querySelector(""#labelW""); let labelH = document.querySelector(""#labelH""); let size = document.querySelector(""#size""); let fonts = document.querySelector(""#fonts""); interact('.part-drag').unset(); interact('.desc-drag').unset(); interact('.qr-drag').unset(); interact('.custom-drag').unset(); editModeLabel.style.display = ""none""; changeToolbarColors(false); labelW.setAttribute('readonly', 'readonly'); labelH.setAttribute('readonly', 'readonly'); size.setAttribute(""disabled"", ""disabled""); size.insertAdjacentHTML('afterbegin',``); fonts.setAttribute(""disabled"", ""disabled""); fonts.insertAdjacentHTML('afterbegin',``); let select = document.querySelector("".selected""); if (select != null) { //select.contentEditable = ""false""; select.style.boxShadow = ""none"" select.classList.remove(""selected""); }; document.querySelector(""#canvasPart"").style.boxShadow = ""none""; document.querySelector(""#canvasDesc"").style.boxShadow = ""none""; document.querySelector("".qr-code"").style.boxShadow = ""none""; document.querySelector(""#customText"").style.boxShadow = ""none""; custText.contentEditable = ""false""; canvas.removeEventListener(""click"", removeSelect, true); qr.removeEventListener(""click"", qrEvent); desc.removeEventListener(""click"", descEvent); part.removeEventListener(""click"", partEvent); custText.removeEventListener(""click"", custTextEvent); savedLabel.custText = custText.innerHTML; setToolbarSettings(); saveReportData(JSON.stringify(savedLabel)); getToolbarSettings(); edit.addEventListener(""click"", editButton); save.removeEventListener(""click"", saveButton); }; /******* hide/show checkbox functionality *******/ if (showPart == false) { let parts = document.querySelectorAll("".part-drag""); parts.forEach(function(elem) { elem.style.display = 'none'; }); } else { let parts = document.querySelectorAll("".part-drag""); parts.forEach(function(elem) { elem.style.display = 'flex'; }); }; if (showDesc == false) { let descriptions = document.querySelectorAll("".desc-drag""); descriptions.forEach(function(elem) { elem.style.display = 'none'; }); } else { let descriptions = document.querySelectorAll("".desc-drag""); descriptions.forEach(function(elem) { elem.style.display = 'flex'; }); }; if (showBarcode == false) { let barcodes = document.querySelectorAll("".qr-code""); barcodes.forEach(function(elem) { elem.style.display = 'none'; }); } else { let barcodes = document.querySelectorAll("".qr-code""); barcodes.forEach(function(elem) { elem.style.display = 'block'; }); }; if (showCustomText == false) { let text = document.querySelectorAll("".custom-drag""); text.forEach(function(elem) { elem.style.display = 'none'; }); } else { let text = document.querySelectorAll("".custom-drag""); text.forEach(function(elem) { elem.style.display = 'flex'; }); }; function removeAllChildNodes(parent) { while (parent.firstChild) { parent.removeChild(parent.firstChild); } }; function setToolbarSettings() { if (part.classList.contains('bold')) { savedLabel.partBold = ""true""; } else { savedLabel.partBold = ""false""; } if (part.classList.contains('italic')) { savedLabel.partItalic = ""true""; } else { savedLabel.partItalic = ""false""; } if (part.classList.contains('underline')) { savedLabel.partUnderlined = ""true""; } else { savedLabel.partUnderlined = ""false""; } if (desc.classList.contains('bold')) { savedLabel.descBold = ""true""; } else { savedLabel.descBold = ""false""; } if (desc.classList.contains('italic')) { savedLabel.descItalic = ""true""; } else { savedLabel.descItalic = ""false""; } if (desc.classList.contains('underline')) { savedLabel.descUnderlined = ""true""; } else { savedLabel.descUnderlined = ""false""; } if (custText.classList.contains('bold')) { savedLabel.custBold = ""true""; } else { savedLabel.custBold = ""false""; } if (custText.classList.contains('italic')) { savedLabel.custItalic = ""true""; } else { savedLabel.custItalic = ""false""; } if (custText.classList.contains('underline')) { savedLabel.custUnderlined = ""true""; } else { savedLabel.custUnderlined = ""false""; } }; function getToolbarSettings() { let parts = document.querySelectorAll("".part-drag""); let descriptions = document.querySelectorAll("".desc-drag""); let customTexts = document.querySelectorAll("".custom-drag""); if (savedLabel.partBold == 'true') { parts.forEach(function(elem) { elem.classList.add('bold'); }); } if (savedLabel.partItalic == 'true') { parts.forEach(function(elem) { elem.classList.add('italic'); }); } if (savedLabel.partUnderlined == 'true') { parts.forEach(function(elem) { elem.classList.add('underline'); }); } if (savedLabel.descBold == 'true') { descriptions.forEach(function(elem) { elem.classList.add('bold'); }); } if (savedLabel.descItalic == 'true') { descriptions.forEach(function(elem) { elem.classList.add('italic'); }); } if (savedLabel.descUnderlined == 'true') { descriptions.forEach(function(elem) { elem.classList.add('underline'); }); } if (savedLabel.custBold == 'true') { customTexts.forEach(function(elem) { elem.classList.add('bold'); }); } if (savedLabel.custItalic == 'true') { customTexts.forEach(function(elem) { elem.classList.add('italic'); }); } if (savedLabel.custUnderlined == 'true') { customTexts.forEach(function(elem) { elem.classList.add('underline'); }); } } // save settings // let test; edit.addEventListener(""click"", editButton); getToolbarSettings(); qr.style.width = savedLabel.qrWidth + ""px""; qr.style.height = savedLabel.qrWidth + ""px""; qr.style.transform = savedLabel.qrTransform; desc.style.width = savedLabel.descWidth + ""px""; desc.style.height = savedLabel.descHeight + ""px""; desc.style.transform = savedLabel.descTransform; desc.style.fontSize = savedLabel.descFontSize + ""px""; desc.style.justifyContent = savedLabel.descAlign; desc.style.textAlign = savedLabel.descAlign; desc.style.alignContent = savedLabel.descVAlign; desc.style.fontFamily = savedLabel.descFontFamily; part.style.width = savedLabel.partWidth + ""px""; part.style.height = savedLabel.partHeight + ""px""; part.style.transform = savedLabel.partTransform; part.style.fontSize = savedLabel.partFontSize + ""px""; part.style.justifyContent = savedLabel.partAlign; part.style.textAlign = savedLabel.partAlign; part.style.alignContent = savedLabel.partVAlign; part.style.fontFamily = savedLabel.partFontFamily; custText.style.width = savedLabel.custWidth + ""px""; custText.style.height = savedLabel.custHeight + ""px""; custText.style.transform = savedLabel.custTransform; custText.style.fontSize = savedLabel.custFontSize + ""px""; custText.style.justifyContent = savedLabel.custAlign; custText.style.textAlgin = savedLabel.custAlign; custText.style.alignContent = savedLabel.custVAlign; custText.style.fontFamily = savedLabel.custFontFamily; custText.innerHTML = savedLabel.custText; $('.card').css('width', savedLabel.width + 'in'); $('.card').css('height', savedLabel.height + 'in'); $('#printable').css('width', savedLabel.width + 'in'); $('#printable').css('height', savedLabel.height + 'in'); $('#labelW').val(savedLabel.width); $('#labelH').val(savedLabel.height); var divRect = printable.getBoundingClientRect(); resize(divRect); ",2023-04-20 16:40:15.656000,Resizable part labels with QR code,Part QR Code Label,,20,4,part-qr-code-label,0 33,_binary ,"body { font-family: Arial, sans-serif; margin: 0; padding: 0; height: 100vh; width: 100vw; position: relative; background: #ECECEC; } #printable { width: 2in; height: 1in; box-shadow: 0 5px 8px 0 rgba(0,0,0,.4); position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; margin: auto; z-index: 0; background: white; transform: scale(1); border-radius: 10px; } #canvas { position: relative; width: 100vw; height: 100vh; overflow: scroll; overflow-x: scroll; overflow-y: scroll; } .wrap { display: flex; flex-direction: row; padding: 10px; width: 100% - 20px; min-width: 856px; background: #fafafa; box-shadow: 0 2px 8px 0 rgba(0,0,0,.4); z-index: 5; justify-content: space-between; position: absolute; left: 0px; top: 0px; right: 0px; margin: auto; z-index: 1; cursor: default; } #toolbarButtons { display: flex; fled-direction: row; } .qr-code { position: absolute; z-index: 2; max-width: 1064px; max-height: 1064px; min-width: 25px; min-height: 25px; } .desc-drag { flex-wrap: wrap; position: absolute; width: fit-content; height: fit-content; z-index: 2; overflow: hidden; } .part-drag { flex-wrap: wrap; position: absolute; width: fit-content; height: fit-content; z-index: 2; overflow: hidden; } .custom-drag { flex-wrap: wrap; position: absolute; width: fit-content; height: fit-content; z-index: 2; overflow: hidden; } #customText { outline: 0px solid transparent; } .selected { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } ::selection { background-color: transparent; } ::moz-selection { background-color: transparent; } ::webkit-selection { background-color: transparent; } .toolbar { width: 750px; display: flex; flex-direction: row; justify-content: space-around; align-items: center; } button { width: 30px; height: 30px; border-radius: 3px; background: none; border: none; box-sizing: border-box; padding: 0; color: #a6a6a6; font-size: 20px; outline: none; } .hover:hover { border: 1px solid #a6a6a6; color: #777; cursor: pointer; } #bold, #italic, #underline { font-size: 18px; } #underline, #align-bottom { margin-right: 17px; } #align-left { margin-left: 17px; } .align-box { margin: -2 auto 0; height: 18px; width: 20px; border: 1px solid #a6a6a6; border-radius: 2px; box-sizing: border-box; } .line-top { width: 12px; height: 2px; background: #a6a6a6; } .line-bottom { width: 9px; height: 2px; background: #a6a6a6; } #align-top .line-top { transform: translate(2px, 2.5px); } #align-top .line-bottom { transform: translate(2px, 4.5px); } #align-middle .line-top { transform: translate(2px, 5px); } #align-middle .line-bottom { transform: translate(2px, 7px); } #align-bottom .line-top { transform: translate(2px, 7.5px); } #align-bottom .line-bottom { transform: translate(2px, 9.5px); } select { height: 24px; font-size: 15px; font-weight: bold; color: #444; background: #fcfcfc; border: 1px solid #a6a6a6; border-radius: 3px; margin: 0; outline: none; } select > option { font-size: 15px; background: #fafafa; } #fonts { width: 140px; } .sp-replacer { background: #fcfcfc; padding: 1px 2px 1px 3px; border-radius: 3px; border-color: #a6a6a6; margin-top: -1px; } .sp-replacer:hover { border-color: #a6a6a6; color: inherit; } .sp-preview { width: 15px; height: 15px; border: none; margin-top: 2px; margin-right: 3px; } .sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner { border-radius: 3px; } #labelW, #labelH { height: 24px; width: 35px; font-size: 15px; font-weight: bold; color: #444; background: #fcfcfc; border: 1px solid #a6a6a6; border-radius: 3px; margin: 0; outline: none; text-align: center; cursor: default; } #editMode { position: absolute; top: 68px; left: 10px; z-index: 1; padding: 5px; background: #fafafa; box-shadow: 0 2px 8px 0 rgba(0,0,0,.4); text-align: center; display: none; } #mapZoom { width: 16px; height: 150px; position: absolute; top: 68px; right: 15px; z-index: 1; } .plus { padding: 5px; background: #fafafa; box-shadow: 0 2px 8px 0 rgba(0,0,0,.4); width: 12px; height: 12px; text-align: center; cursor: pointer; line-height: 12px; font-weight: medium; font-size: 16pt; } .minus { padding: 5px; background: #fafafa; box-shadow: 0 2px 8px 0 rgba(0,0,0,.4); width: 12px; height: 12px; text-align: center; cursor: pointer; line-height: 11px; font-weight: medium; font-size: 20pt; } .fa-plus:before { content: ""\2b""; } .plus:hover, .minus:hover { background: #F0F0F0; } #pagination { display: flex; flex-direction: row; background-color: white; display: flex; position: absolute; bottom: 0; left: 0; right: 0; justify-content: center; background: #fafafa; box-shadow: -1px 1px 13px rgba(0,0,0,.4); } .arrow-right { height: 10px; width: 50px; border: 0; } .arrow-right i { height: 100%; width: 100%; text-align: center; font-size: 20pt; color: black; } .arrow-right:hover { border: 0; } .arrow-left:hover { border: 0; } .arrow-left { height: 10px; width: 50px; border: 0; } .arrow-left i { height: 100%; width: 100%; text-align: center; font-size: 20pt; color: black; } .arrow-first { padding-top: 3px; height: 10px; width: 50px; border: 0; } .arrow-first i { height: 100%; width: 100%; text-align: center; font-size: 15pt; color: black; } .arrow-first:hover { border: 0; } .arrow-last { padding-top: 3px; height: 10px; width: 50px; border: 0; } .arrow-last i { height: 100%; width: 100%; text-align: center; font-size: 15pt; color: black; } .arrow-last:hover { border: 0; } .counter { height: 30px; width: 100px; text-align: center; font-size: 14pt; padding-top: 2px; } #partContainer{ display: none; } .card { background: #fff; width: 2in; height: 1in; position: relative; overflow: hidden; } #save { background: #a6a6a6; width: 80px; font-size: 12px; color: white; margin-left: 15px; } #edit { background: green; width: 80px; font-size: 12px; color: white; margin-left: 5px; } #editMode { background: green; color: white; } .bold { font-weight: bold; } .italic { font-style: italic; } .underline { text-decoration: underline; } @media print { body { margin: 0; padding: 0; } #container { display: none; } #printable { all: unset; display: none; } #partContainer { display: block; } #pagination { display: none; } .wrap { display: none; } #editMode { display: none !important; } #mapZoom { display: none; } #canvas { all: unset; } .selected { box-shadow: none; } #editMode { display: none; } }",2023-04-20 16:40:15.687000,Resizable part labels with QR code,Part QR Code Label,,30,4,part-qr-code-label,0