Fixes and updates.
This commit is contained in:
@@ -2,45 +2,33 @@
|
||||
<div id="labelMaker">
|
||||
<div class="labelOptions">
|
||||
<div>Label Size</div>
|
||||
<div><label for="labelWidth">Width (mm):</label> <input type="number" name="labelWidth" class="labelWidth input" step="0.25" value="{{labelWidth}}"/></div>
|
||||
<div><label for="labelHeight">Height (mm):</label> <input type="number" name="labelHeight" class="labelHeight input" step="0.25" value="{{labelHeight}}"/></div>
|
||||
<div><label for="labelSpacing">Spacing (in):</label> <input type="number" name="labelSpacing" class="labelSpacing input" step="0.05" value="{{labelSpacing}}"/></div>
|
||||
<div><label for="labelWidth">Width (mm):</label> <input disabled type="number" name="labelWidth" class="labelWidth input" step="0.25" value="{{labelWidth}}"/></div>
|
||||
<div><label for="labelHeight">Height (mm):</label> <input disabled type="number" name="labelHeight" class="labelHeight input" step="0.25" value="{{labelHeight}}"/></div>
|
||||
<div class="radioGroup"><input type="radio" name="labelType" value="oz8" checked><label for="labelType">8oz Label</label> <input type="radio" name="labelType" value="barcode"><label for="labelType">Barcode Only</label></div>
|
||||
|
||||
<div>Label Contents</div>
|
||||
<!-- <label for="title1YOffset">Vertical Offset:</label> <input type="number" name="title1YOffset" class="title1YOffset input" value="{{title1YOffset}}"/>-->
|
||||
<div><label for="title1">Title:</label> <input type="text" name="title1" class="title1 input" value="{{title1}}"/></div>
|
||||
<div><label for="title2">Title:</label> <input type="text" name="title2" class="title2 input" value="{{title2}}"/></div>
|
||||
<div><label for="ingredients" style="vertical-align: top">Ingredients:</label> <textarea name="ingredients" class="ingredients">{{ingredients}}</textarea></div>
|
||||
<div><label for="date">Date:</label> <input type="number" name="date" class="date input" value="{{date}}"/></div>
|
||||
<div class="labelTextControls"><label for="title1">Title:</label> <input type="text" name="title1" class="title1 input" value="{{title1}}"/></div>
|
||||
<div class="labelTextControls"><label for="title2">Title:</label> <input type="text" name="title2" class="title2 input" value="{{title2}}"/></div>
|
||||
<div class="labelTextControls"><label for="ingredients" style="vertical-align: top">Ingredients:</label> <textarea name="ingredients" class="ingredients">{{ingredients}}</textarea></div>
|
||||
<div class="labelTextControls"><label for="date">Date:</label> <input type="number" name="date" class="date input" value="{{date}}"/></div>
|
||||
<div><button name="print" class="print">Print</button></div>
|
||||
<div><button name="preview" class="preview">Preview</button></div>
|
||||
</div>
|
||||
<div class="labelContainer">
|
||||
<div class='label'>
|
||||
<!-- /images/Logo_0.8x0.73_300ppi.png-->
|
||||
<!-- <div class='barcodeContainer'><svg class='barcode' jsbarcode-format='upc' jsbarcode-value='123456789012' jsbarcode-textmargin='0' jsbarcode-fontoptions='bold' jsbarcode-margin='0' jsbarcode-width='1.5em' jsbarcode-height='10em'></svg></div>-->
|
||||
<!-- <img class="qrcode" src="">-->
|
||||
<div id="qrcode" class="qrcode"></div>
|
||||
<img class='labelLogo' alt='logo' src='/images/3x2 Label Logo BW.svg'/>
|
||||
<div class='title1'>{{title1}}</div>
|
||||
<div class='title2'>{{title2}}</div>
|
||||
<div class='ingredients'><span class='ingredientsPrefix'>Ingredients</span>: {{ingredients}}</div>
|
||||
<div class='ingredientsEnding'>*<span style='font-style: oblique'>grown by us</span> <span class='size'></span> FD1951 (<span class="date">{{date}}</span>)</div>
|
||||
<div class='instructions'>Refrigerate after opening; return jar when done</div>
|
||||
<div class='address'>18601 Hwy 128, Yorkville, CA 95494</div>
|
||||
<div class='website'>www.PetitTeton.com</div>
|
||||
</div>
|
||||
<div class="labelBackground">
|
||||
{{>PrintLabel vars=printLabelVars}}
|
||||
</div>
|
||||
<!-- <div class="canvasContainer">-->
|
||||
<!-- <!– 3x2" == 76x50mm; 300ppi == 11.81ppmm; So 3x2" == 897 x 590x. –>-->
|
||||
<!--<!– <canvas class="labelCanvas" width="{{labelPxWidthActual}}" height="{{labelPxHeightActual}}">–>-->
|
||||
<!--<!– </canvas>–>-->
|
||||
<!-- <canvas class="labelCanvas" width="{{labelPxWidth}}" height="{{labelPxHeight}}">-->
|
||||
<!-- </canvas>-->
|
||||
<!-- <div class="labelContainer">-->
|
||||
<!-- <div class='label'>-->
|
||||
<!-- <div id="qrcode" class="qrcode"></div>-->
|
||||
<!-- <img class='labelLogo' alt='logo' src='/images/3x2 Label Logo BW.svg'/>-->
|
||||
<!-- <div class='title1 labelText'>{{title1}}</div>-->
|
||||
<!-- <div class='title2 labelText'>{{title2}}</div>-->
|
||||
<!-- <div class='ingredients labelText'><span class='ingredientsPrefix'>Ingredients</span>: {{ingredients}}</div>-->
|
||||
<!-- <div class='ingredientsEnding labelText'>*<span style='font-style: oblique'>grown by us</span> <span class='size'></span> FD1951 (<span class="date">{{date}}</span>)</div>-->
|
||||
<!-- <div class='instructions labelText'>Refrigerate after opening; return jar when done</div>-->
|
||||
<!-- <div class='address labelText'>18601 Hwy 128, Yorkville, CA 95494</div>-->
|
||||
<!-- <div class='website labelText'>www.PetitTeton.com</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<div class="testImage">
|
||||
|
||||
</div>
|
||||
<div class="printableLabel"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
156
imports/ui/Label.import.styl
vendored
156
imports/ui/Label.import.styl
vendored
@@ -7,6 +7,36 @@
|
||||
|
||||
@media not print
|
||||
.labelOptions
|
||||
.radioGroup
|
||||
input[type='radio']
|
||||
-webkit-appearance none
|
||||
-moz-appearance none
|
||||
appearance none
|
||||
display inline-block
|
||||
position relative
|
||||
background-color #f1f1f1
|
||||
color #666
|
||||
height 30px
|
||||
width 30px
|
||||
border 0
|
||||
border-radius 50px
|
||||
cursor pointer
|
||||
margin-right 7px
|
||||
outline none
|
||||
input[type='radio']:hover
|
||||
background-color #f7f7f7
|
||||
input[type='radio']:checked::before
|
||||
position absolute
|
||||
font 13px/1 'Open Sans', sans-serif
|
||||
left 11px
|
||||
top 7px
|
||||
content '\02143'
|
||||
transform rotate(40deg)
|
||||
input[type='radio']:checked
|
||||
background-color #f1f1f1
|
||||
label
|
||||
position relative
|
||||
top -10px
|
||||
label
|
||||
font-family TimesNewRoman, Times New Roman, Times
|
||||
font-weight 200
|
||||
@@ -36,128 +66,10 @@
|
||||
font-size 12px
|
||||
font-weight 100
|
||||
line-height 14px
|
||||
.labelContainer
|
||||
.labelBackground
|
||||
text-align center
|
||||
width 100%
|
||||
width-min 3in
|
||||
height-min 2in
|
||||
width-min 5in
|
||||
height-min 5in
|
||||
background-color grey
|
||||
padding 20px
|
||||
.labels
|
||||
display none
|
||||
.printableLabel
|
||||
display none
|
||||
.label
|
||||
display inline-block
|
||||
width 3in
|
||||
height 2in
|
||||
.canvasContainer
|
||||
padding 10px
|
||||
background-color gray
|
||||
@media all
|
||||
.label
|
||||
position relative
|
||||
background-color white
|
||||
color black
|
||||
text-align center
|
||||
font-family TimesNewRoman, Times New Roman, Times
|
||||
//font-family Arial, Helvetica, sans-serif
|
||||
font-size .1in
|
||||
width 3in
|
||||
height 2in
|
||||
.barcodeContainer
|
||||
position absolute
|
||||
transform rotate(270deg) scale(0.7)
|
||||
right -10em
|
||||
top 7em
|
||||
.qrcode
|
||||
position absolute
|
||||
left 3px
|
||||
top 3px
|
||||
//padding: 2px
|
||||
//border: 2px solid black
|
||||
.labelLogo
|
||||
width 8em
|
||||
padding 0
|
||||
margin 0
|
||||
padding-top .15em
|
||||
margin-bottom .2em
|
||||
.labelLogo3
|
||||
width 14em
|
||||
padding 0
|
||||
margin 0
|
||||
padding-top .15em
|
||||
margin-bottom .8em
|
||||
.labelTagline
|
||||
font-size 1em
|
||||
font-weight 100
|
||||
line-height 1em
|
||||
.title1
|
||||
width 100%
|
||||
font-size 2.5em
|
||||
line-height .9em
|
||||
font-weight 800
|
||||
text-transform uppercase
|
||||
.title2
|
||||
width 100%
|
||||
font-size 1.5em
|
||||
line-height .9em
|
||||
font-weight 800
|
||||
padding-bottom .2em
|
||||
.ingredients
|
||||
width 100%
|
||||
font-size 1.2em
|
||||
font-weight 100
|
||||
line-height 1em
|
||||
min-height 2em
|
||||
.ingredientsEnding
|
||||
width 100%
|
||||
font-size 1.2em
|
||||
font-weight 100
|
||||
.instructions
|
||||
width 100%
|
||||
font-size 1.2em
|
||||
font-weight 800
|
||||
.address
|
||||
width 100%
|
||||
font-size 1.2em
|
||||
font-weight 100
|
||||
.website
|
||||
width 100%
|
||||
font-size 1.2em
|
||||
font-weight 100
|
||||
|
||||
@media print
|
||||
@page
|
||||
size 3in 2in
|
||||
margin 0
|
||||
padding 0
|
||||
.labelOptions, .labelContainer, .canvasContainer, .labelCanvas
|
||||
display none
|
||||
.printableLabel
|
||||
display block
|
||||
margin 0
|
||||
padding 0
|
||||
//.printableLabels
|
||||
// display inline-block
|
||||
// margin 0
|
||||
// padding 0
|
||||
//#labelMaker
|
||||
// display none
|
||||
//.labels
|
||||
// display block
|
||||
//.label
|
||||
// display block
|
||||
// width 3in
|
||||
// height 2in
|
||||
// //width 100%
|
||||
// //height 100%
|
||||
// page-break-after always
|
||||
// page-break-inside avoid
|
||||
.canvasContainer
|
||||
display none
|
||||
@media print
|
||||
.labelMaker
|
||||
margin 0
|
||||
padding 0
|
||||
overflow visible
|
||||
padding 20px
|
||||
@@ -8,6 +8,8 @@ import dragula from 'dragula';
|
||||
import QRCode from '/imports/util/qrcode/qrcode';
|
||||
//let QRCode = require('/imports/util/qrcode/qrcode.js');
|
||||
|
||||
import './PrintLabel.js';
|
||||
|
||||
console.log(QRCode);
|
||||
|
||||
//let {qrcode, svg2url} = require('pure-svg-code');
|
||||
@@ -20,216 +22,11 @@ console.log(QRCode);
|
||||
let PREFIX = "LabelMaker_";
|
||||
let PX_PER_MM = 300 / 25.4;
|
||||
let SCREEN_PX_PER_MM = 96 / 25.4;
|
||||
let imagePath = "/images/3x2 Label Logo BW.svg";//"/images/Logo_0.8x0.73_300ppi.png";
|
||||
|
||||
function generateLabels(title1, title2, ingredients, date, count, topSpacing, bottomSpacing) {
|
||||
//TODO: Allow logo to be removed or altered with an alternative logo for sizing fixes
|
||||
let label = "<div class='label'>" +
|
||||
"<div class='barcodeContainer'><svg class='barcode' jsbarcode-format='UPC' jsbarcode-value='123456789012' jsbarcode-textmargin='0' jsbarcode-fontoptions='bold' jsbarcode-margin='0' jsbarcode-width='2in' jsbarcode-height='10em'></svg></div>" +
|
||||
//"<div style='height: " + (topSpacing) + "in'></div>" +
|
||||
//"<img class='labelLogo' alt='logo' src='/images/PetitTetonLabelLogo_2in Width_v1.png'/>" +
|
||||
"<img class='labelLogo' alt='logo' src='" + imagePath + "'/>" +
|
||||
//"<div class='labelTagline'>We grow it. We can it.</div>" +
|
||||
"<div class='title1'>" + title1 + "</div>" +
|
||||
"<div class='title2'>" + (title2 === undefined ? "" : title2) + "</div>" +
|
||||
"<div class='ingredients'><span class='ingredientsPrefix'>Ingredients</span>:" + ingredients + "</div>" +
|
||||
"<div class='ingredientsEnding'>*<span style='font-style: oblique'>grown by us</span> <span class='size'>8oz</span> FD1951 (" + date + ")</div>" +
|
||||
"<div class='instructions'>Refrigerate after opening; return jar when done</div>" +
|
||||
"<div class='address'>18601 Hwy 128, Yorkville, CA 95494</div>" +
|
||||
"<div class='website'>www.PetitTeton.com</div>" +
|
||||
//"<div style='height: " + bottomSpacing + "in'></div>" +
|
||||
"</div>";
|
||||
let labels = "";
|
||||
|
||||
//TODO: Include bar code and identifying numbers.
|
||||
for(let i = 0; i < count; i++) {
|
||||
labels += label;
|
||||
}
|
||||
|
||||
return labels;
|
||||
}
|
||||
|
||||
function printImageOld(template, dataUrl) {
|
||||
let img = new Image();
|
||||
|
||||
img.onload = function() {
|
||||
let imageCanvas = $('.labelCanvas')[0];
|
||||
let ctx = imageCanvas.getContext('2d');
|
||||
//let threshold = 255 + 200 + 0;
|
||||
let desiredContrast = 100;
|
||||
let contrastCorrectionFactor = (259 * (desiredContrast + 255)) / (255 * (259 - desiredContrast));
|
||||
|
||||
imageCanvas.width = img.width;
|
||||
imageCanvas.height = img.height;
|
||||
//console.log("Generated image: " + img.width + ", " + img.height);
|
||||
//ctx.scale(0.25, 0.25);
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
let imageData = ctx.getImageData(0, 0, imageCanvas.width, imageCanvas.height);
|
||||
let data = imageData.data;
|
||||
|
||||
//Run three times
|
||||
for(let c = 0; c < 3; c++) {
|
||||
//Set each pixel to either black or white with the given threshold.
|
||||
for(let i = 0; i < data.length; i += 4) {
|
||||
data[i] = contrastCorrectionFactor * (data[i] - 128) + 128;
|
||||
data[i + 1] = contrastCorrectionFactor * (data[i + 1] - 128) + 128;
|
||||
data[i + 2] = contrastCorrectionFactor * (data[i + 2] - 128) + 128;
|
||||
//if(data[i] + data[i + 1] + data[i + 2] < threshold) {
|
||||
// data[i] = 0;
|
||||
// data[i + 1] = 0;
|
||||
// data[i + 2] = 0;
|
||||
//}
|
||||
//else {
|
||||
// data[i] = 255;
|
||||
// data[i + 1] = 255;
|
||||
// data[i + 2] = 255;
|
||||
//}
|
||||
data[i + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
|
||||
//Convert the canvas content to an image for printing. (cannot print a canvas?)
|
||||
//sendToPrinter(template, imageCanvas.toDataURL("image/png"));
|
||||
|
||||
//Save to disk.
|
||||
//imageCanvas.toBlob(function(blob) {
|
||||
// saveAs(blob, "label.png");
|
||||
//}, "image/png", 1);
|
||||
|
||||
//imageCanvas.toBlob(function(blob) {
|
||||
// let url = URL.createObjectURL(blob);
|
||||
// window.open(url, "_blank");
|
||||
//}, "image/png", 1);
|
||||
|
||||
//let imgData = imageCanvas.toDataURL('image/jpeg', 1.0);
|
||||
imageCanvas.toBlob(function(blob) {
|
||||
let pdf = new PDF();
|
||||
let url = URL.createObjectURL(blob);
|
||||
pdf.addImage(url, "image/png", 0, 0);
|
||||
pdf.save("label.pdf");
|
||||
}, "image/png", 1);
|
||||
};
|
||||
img.src = dataUrl;
|
||||
}
|
||||
|
||||
function printImage(template, raw, width, height) {
|
||||
let data = raw;
|
||||
//Run three times
|
||||
for(let c = 0; c < 3; c++) {
|
||||
//Set each pixel to either black or white with the given threshold.
|
||||
for(let i = 0; i < data.length; i += 4) {
|
||||
data[i] = contrastCorrectionFactor * (data[i] - 128) + 128;
|
||||
data[i + 1] = contrastCorrectionFactor * (data[i + 1] - 128) + 128;
|
||||
data[i + 2] = contrastCorrectionFactor * (data[i + 2] - 128) + 128;
|
||||
//if(data[i] + data[i + 1] + data[i + 2] < threshold) {
|
||||
// data[i] = 0;
|
||||
// data[i + 1] = 0;
|
||||
// data[i + 2] = 0;
|
||||
//}
|
||||
//else {
|
||||
// data[i] = 255;
|
||||
// data[i + 1] = 255;
|
||||
// data[i + 2] = 255;
|
||||
//}
|
||||
data[i + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
let url = URL.createObjectURL(new Blob(raw, {type: "image/png"}));
|
||||
let test = new Image();
|
||||
test.src = url;
|
||||
$('.testImage').html(test);
|
||||
}
|
||||
// Note: Not working correctly. Output seems to be at 96dpi instead of 300+dpi. Using a large image scaled down in in an Image tag seems to not print well.
|
||||
function sendToPrinter(template, dataUrl) {
|
||||
let canvasImg = new Image();
|
||||
canvasImg.onload = function() {
|
||||
//window.print();
|
||||
};
|
||||
canvasImg.src = dataUrl;
|
||||
canvasImg.style.height = template.labelHeight.get() + "mm";
|
||||
canvasImg.style.width = template.labelWidth.get() + "mm";
|
||||
$(".printableLabel").html(canvasImg);
|
||||
|
||||
//$('.printableLabel').html(img);
|
||||
window.print();
|
||||
}
|
||||
|
||||
function loadImage(url) {
|
||||
return new Promise(r => { let i = new Image(); i.onload = (() => r(i)); i.src = url; });
|
||||
}
|
||||
async function refreshLabelCanvas(template) {
|
||||
let mmWidth = template.labelWidth.get();
|
||||
let mmHeight = template.labelHeight.get();
|
||||
let title1 = template.title1.get();
|
||||
let title1Font = template.title1Font.get();
|
||||
let title1YOffset = template.title1YOffset.get();
|
||||
let title2 = template.title2.get();
|
||||
let title2Font = template.title2Font.get();
|
||||
let title2YOffset = template.title2YOffset.get();
|
||||
let ingredients = template.ingredients.get();
|
||||
let ingredientsFont = template.ingredientsFont.get();
|
||||
let ingredientsYOffset = template.ingredientsYOffset.get();
|
||||
let date = template.date.get();
|
||||
let $labelCanvas = $('.labelCanvas');
|
||||
let ctx = $labelCanvas[0].getContext('2d');
|
||||
let width = Math.floor(mmWidth * PX_PER_MM);
|
||||
let height = Math.floor(mmHeight * PX_PER_MM);
|
||||
let center = width / 2;
|
||||
|
||||
let img = await loadImage(imagePath);
|
||||
let imageWidth = 241;
|
||||
let imageHeight = 219;
|
||||
|
||||
let ingredientsY = 180;
|
||||
let ingredientsEndingY = 240;
|
||||
let instructionsY = 280;
|
||||
let addressY = 320;
|
||||
let websiteY = 380;
|
||||
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.fillRect(0,0, width, height);
|
||||
ctx.fillStyle = 'black';
|
||||
ctx.drawImage(img, center - (imageWidth / 2), 0);
|
||||
ctx.font = title1Font;
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(title1, center, title1YOffset);
|
||||
|
||||
|
||||
|
||||
////TODO: Allow logo to be removed or altered with an alternative logo for sizing fixes
|
||||
//let label = "<div class='label'>" +
|
||||
// "<div style='height: " + topSpacing + "in'></div>" +
|
||||
// //"<img class='labelLogo' alt='logo' src='/images/PetitTetonLabelLogo_2in Width_v1.png'/>" +
|
||||
// "<img class='labelLogo' alt='logo' src='/images/Logo_0.8x0.73_300ppi.png'/>" +
|
||||
// "<div class='labelTagline'>We grow it. We can it.</div>" +
|
||||
// "<div class='title1'>" + title1 + "</div>" +
|
||||
// "<div class='title2'>" + (title2 === undefined ? "" : title2) + "</div>" +
|
||||
// "<div class='ingredients'><span class='ingredientsPrefix'>Ingredients</span>:" + ingredients + "</div>" +
|
||||
// "<div class='ingredientsEnding'>*<span style='font-style: oblique'>grown by us</span> <span class='size'>8oz</span> FD1951 (" + date + ")</div>" +
|
||||
// "<div class='instructions'>Refrigerate after opening; return jar when done</div>" +
|
||||
// "<div class='address'>18601 Hwy 128, Yorkville, CA 95494</div>" +
|
||||
// "<div class='website'>www.PetitTeton.com</div>" +
|
||||
// "<div style='height: " + bottomSpacing + "in'></div>" +
|
||||
// "</div>";
|
||||
//let labels = "";
|
||||
//
|
||||
////TODO: Include bar code and identifying numbers.
|
||||
//for(let i = 0; i < count; i++) {
|
||||
// labels += label;
|
||||
//}
|
||||
//
|
||||
//return labels;
|
||||
}
|
||||
function bufferToBase64(buf) {
|
||||
var binstr = Array.prototype.map.call(buf, function (ch) {
|
||||
return String.fromCharCode(ch);
|
||||
}).join('');
|
||||
return btoa(binstr);
|
||||
}
|
||||
//let formats = {
|
||||
// "8oz Label": {logo: true, text: true, barcode: true, width: 76.2, height: 50.8, labelClass: '8oz'},
|
||||
// "Barcode Only": {logo: false, text: false, barcode: true, width: 25, height: 25, labelClass: 'barcode'}
|
||||
//};
|
||||
|
||||
Template.LabelMaker.onCreated(function() {
|
||||
this.labelWidth = new ReactiveVar(76);
|
||||
@@ -240,52 +37,29 @@ Template.LabelMaker.onCreated(function() {
|
||||
this.ingredients = new ReactiveVar("*strawberry, sugar, *espelette");
|
||||
|
||||
this.date = new ReactiveVar(19001);
|
||||
|
||||
//Session.set(PREFIX + "title1", "Strawberry");
|
||||
//Session.set(PREFIX + "title1Font", "50px Times New Roman");
|
||||
//Session.set(PREFIX + "title1YOffset", 260);
|
||||
//Session.set(PREFIX + "title2", "w/ Espelette");
|
||||
//Session.set(PREFIX + "title2Font", "40px Times New Roman");
|
||||
//Session.set(PREFIX + "title2YOffset", 340);
|
||||
//Session.set(PREFIX + "ingredients", "*strawberry, sugar, *espelette");
|
||||
//Session.set(PREFIX + "date", 19001);
|
||||
//Session.set(PREFIX + "count", 3);
|
||||
this.format = new ReactiveVar("oz8");
|
||||
});
|
||||
Template.LabelMaker.onRendered(function() {
|
||||
let template = this;
|
||||
|
||||
//Re-run this routine when ever the session variables change.
|
||||
//Tracker.autorun(function() {
|
||||
// //refreshLabelCanvas(Session.get(PREFIX + "title1"), Session.get(PREFIX + "title2"), Session.get(PREFIX + "ingredients"), Session.get(PREFIX + "date"), 1, Session.get(PREFIX + "labelSpacing"), 0);
|
||||
// refreshLabelCanvas(template);
|
||||
//});
|
||||
//
|
||||
//template.$('.labelContainer').on('DOMSubtreeModified', function() {
|
||||
// console.log("Initialized barcode");
|
||||
// //
|
||||
//});
|
||||
//JsBarcode(".barcode").init();
|
||||
|
||||
|
||||
//const svgString = qrcode({content: "1234567890", padding: 0, width: 60, height: 60, color: "#000000", background: "#FFFFFF", ecl: "L"});
|
||||
//this.$('.qrcode').attr('src', svg2url(svgString));
|
||||
|
||||
//this.$('.qrcode').attr('src', svg2url(new QRCode({content: '1234567890', width: 80, height: 80, color: "#000000", background: "#FFFFFF"}).svg()));
|
||||
|
||||
new QRCode(document.getElementById("qrcode"), {text: "1234567890", width: 60, height: 60});
|
||||
//new QRCode(document.getElementById("qrcode"), {text: "1234567890", width: 60, height: 60});
|
||||
});
|
||||
Template.LabelMaker.onDestroyed(function() {
|
||||
});
|
||||
Template.LabelMaker.events({
|
||||
'change .labelWidth': function(e, t) {
|
||||
let x = $(e.target).val();
|
||||
|
||||
t.labelWidth.set(!Number.isNaN(x) && x > 0 ? parseFloat(x) : 76);
|
||||
},
|
||||
'change .labelHeight': function(event, template) {
|
||||
let x = $(event.target).val();
|
||||
|
||||
t.labelHeight.set(!Number.isNaN(x) && x > 0 ? parseFloat(x) : 50);
|
||||
//'change .labelWidth': function(e, t) {
|
||||
// let x = $(e.target).val();
|
||||
//
|
||||
// t.labelWidth.set(!Number.isNaN(x) && x > 0 ? parseFloat(x) : 76);
|
||||
//},
|
||||
//'change .labelHeight': function(event, template) {
|
||||
// let x = $(event.target).val();
|
||||
//
|
||||
// t.labelHeight.set(!Number.isNaN(x) && x > 0 ? parseFloat(x) : 50);
|
||||
//},
|
||||
|
||||
'change input[name="labelType"]': function(e, t) {
|
||||
t.format.set($(e.target).val());
|
||||
},
|
||||
|
||||
'change .title1': function(e, t) {t.title1.set($(e.target).val());},
|
||||
@@ -302,25 +76,27 @@ Template.LabelMaker.events({
|
||||
|
||||
'change .date': function(e, t) {t.date.set(parseInt($(e.target).val()));},
|
||||
'click .preview': function(event, template) {
|
||||
let params = {};
|
||||
let _this = template;
|
||||
let format = _this.format.get();
|
||||
let title1 =_this.title1.get();
|
||||
let title2 =_this.title2.get();
|
||||
let ingredients =_this.ingredients.get();
|
||||
let date =_this.date.get();
|
||||
let params = {format, title1, title2, ingredients, date};
|
||||
|
||||
params['title1'] = "Strawberry";
|
||||
params['title2'] = "";
|
||||
params['ingredients'] = "Fairies";
|
||||
params['date'] = "1234";
|
||||
window.open('/PrintLabel?' + $.param(params));
|
||||
},
|
||||
'click .print': function(event, template) {
|
||||
let _this = template;
|
||||
let node = $('.label')[0];
|
||||
let width = _this.labelWidth.get();
|
||||
let height =_this.labelHeight.get();
|
||||
let format = _this.format.get();
|
||||
let title1 =_this.title1.get();
|
||||
let title2 =_this.title2.get();
|
||||
let ingredients =_this.ingredients.get();
|
||||
let date =_this.date.get();
|
||||
|
||||
Meteor.call('printLabels', width, height, "3x2Standard", title1, title2, ingredients, date, (error, result) => {
|
||||
//console.log("Calling print with: " + JSON.stringify({format, title1, title2, ingredients, date}));
|
||||
|
||||
Meteor.call('printLabels', format, title1, title2, ingredients, date, (error, result) => {
|
||||
if(error) {
|
||||
console.log(error);
|
||||
}
|
||||
@@ -333,81 +109,37 @@ Template.LabelMaker.events({
|
||||
}
|
||||
});
|
||||
|
||||
//dti.toBlob(node, {bgcolor: 'white'}).then(function(blob) {
|
||||
// printImage(template, blob);
|
||||
//}).catch(function(err) {
|
||||
// console.log(err);
|
||||
//});
|
||||
|
||||
//dti.toPng(node, {bgcolor: 'white'}).then(function(dataUrl) {
|
||||
// printImageOld(template, dataUrl);
|
||||
//}).catch(function(err) {
|
||||
// console.log(err);
|
||||
//});
|
||||
|
||||
|
||||
//let count = template.$('input[name="count"]').val();
|
||||
//let spacing = Session.get(PREFIX + "labelSpacing");
|
||||
//
|
||||
////count = (count === undefined || Number.isNaN(count)) ? 1 : parseInt(count);
|
||||
////
|
||||
////if(count < 1) {
|
||||
//// count = 1;
|
||||
////}
|
||||
////
|
||||
////Session.set(PREFIX + "generatedLabels", generateLabels(Session.get(PREFIX + "title1"), Session.get(PREFIX + "title2"), Session.get(PREFIX + "ingredients"), Session.get(PREFIX + "date"), count, 0, spacing));
|
||||
//
|
||||
//let $label = $('.printableLabel');
|
||||
//
|
||||
//console.log($label);
|
||||
//console.log($label.length);
|
||||
//domtoimage.toPng($label).then(function(dataUrl) {
|
||||
// console.log("A");
|
||||
// let img = new Image();
|
||||
// img.src = dataUrl;
|
||||
// $('.printableLabel').html(img);
|
||||
// //caman('.printableLabel img', function() {
|
||||
// // this.contrast(100);
|
||||
// // this.render();
|
||||
// // window.print();
|
||||
// //});
|
||||
//}).catch(function(error) {
|
||||
// console.error("failed to convert dom to image");
|
||||
// console.error(error);
|
||||
//});
|
||||
}
|
||||
});
|
||||
Template.LabelMaker.helpers({
|
||||
printLabelVars: function() { //Called to pass the values for rendering a sample label on the client. This mimics the same call to the same view when going to 'print' the label to PDF later.
|
||||
let t = Template.instance();
|
||||
|
||||
return {
|
||||
format: t.format.get(),
|
||||
title1: t.title1.get(),
|
||||
title2: t.title2.get(),
|
||||
ingredients: t.ingredients.get(),
|
||||
date: t.date.get()
|
||||
}
|
||||
},
|
||||
title1: function() {return Template.instance().title1.get();},
|
||||
title2: function() {return Template.instance().title2.get();},
|
||||
ingredients: function() {return Template.instance().ingredients.get();},
|
||||
date: function() {return Template.instance().date.get();},
|
||||
labelWidth: function() {return Template.instance().labelWidth.get();},
|
||||
labelHeight: function() {return Template.instance().labelHeight.get();},
|
||||
sampleLabel: function() {
|
||||
let t = Template.instance();
|
||||
setTimeout(function() {JsBarcode(".barcode").init();}, 500);
|
||||
return generateLabels(t.title1.get(), t.title2.get(), t.ingredients.get(), t.date.get(), 1, 0);
|
||||
},
|
||||
//canvasLabel: function() {
|
||||
// return generateLabelCanvas(Session.get(PREFIX + "title1"), Session.get(PREFIX + "title2"), Session.get(PREFIX + "ingredients"), Session.get(PREFIX + "date"), 1, Session.get(PREFIX + "labelSpacing"), 0);
|
||||
//},
|
||||
|
||||
labels: function() {
|
||||
return Session.get(PREFIX + "generatedLabels");
|
||||
},
|
||||
labelPxWidth: function() {
|
||||
//console.log("label width: " + Template.instance().labelWidth.get());
|
||||
//console.log("px_per_mm: " + PX_PER_MM);
|
||||
//console.log("labelPxWidth: " + (Template.instance().labelWidth.get() * PX_PER_MM));
|
||||
return Math.floor(Template.instance().labelWidth.get() * PX_PER_MM);
|
||||
},
|
||||
labelPxHeight: function() {
|
||||
return Math.floor(Template.instance().labelHeight.get() * PX_PER_MM);
|
||||
},
|
||||
labelPxWidthActual: function() {
|
||||
//console.log("label width: " + Template.instance().labelWidth.get());
|
||||
//console.log("px_per_mm: " + PX_PER_MM);
|
||||
//console.log("labelPxWidth: " + (Template.instance().labelWidth.get() * PX_PER_MM));
|
||||
return Math.floor(Template.instance().labelWidth.get() * SCREEN_PX_PER_MM);
|
||||
},
|
||||
labelPxHeightActual: function() {
|
||||
|
||||
@@ -2,17 +2,15 @@
|
||||
<div id="PrintLabel">
|
||||
<div class="labelContainer">
|
||||
<div class='label'>
|
||||
<!-- /images/Logo_0.8x0.73_300ppi.png-->
|
||||
<!-- <div class='barcodeContainer'><svg class='barcode' jsbarcode-format='upc' jsbarcode-value='123456789012' jsbarcode-textmargin='0' jsbarcode-fontoptions='bold' jsbarcode-margin='0' jsbarcode-width='1.5em' jsbarcode-height='10em'></svg></div>-->
|
||||
<div id="qrcode" class="qrcode" src=""></div>
|
||||
<div id="qrcode" class="qrcode"></div>
|
||||
<img class='labelLogo' alt='logo' src='/images/3x2 Label Logo BW.svg'/>
|
||||
<div class='title1'></div>
|
||||
<div class='title2'></div>
|
||||
<div class='ingredients'><span class='ingredientsPrefix'>Ingredients</span>: </div>
|
||||
<div class='ingredientsEnding'>*<span style='font-style: oblique'>grown by us</span> <span class='size'></span> FD1951 (<span class="date"></span>)</div>
|
||||
<div class='instructions'>Refrigerate after opening; return jar when done</div>
|
||||
<div class='address'>18601 Hwy 128, Yorkville, CA 95494</div>
|
||||
<div class='website'>www.PetitTeton.com</div>
|
||||
<div class='title1 labelText'></div>
|
||||
<div class='title2 labelText'></div>
|
||||
<div class='ingredients labelText'><span class='ingredientsPrefix'>Ingredients</span>: <span class="ingredientsList"></span></div>
|
||||
<div class='ingredientsEnding labelText'>*<span style='font-style: oblique'>grown by us</span> <span class='size'></span> FD1951 (<span class="date"></span>)</div>
|
||||
<div class='instructions labelText'>Refrigerate after opening; return jar when done</div>
|
||||
<div class='address labelText'>18601 Hwy 128, Yorkville, CA 95494</div>
|
||||
<div class='website labelText'>www.PetitTeton.com</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
45
imports/ui/PrintLabel.import.styl
vendored
45
imports/ui/PrintLabel.import.styl
vendored
@@ -2,44 +2,19 @@
|
||||
#PrintLabel
|
||||
.labelContainer
|
||||
text-align center
|
||||
//width 100%
|
||||
width-min 3in
|
||||
width 3in
|
||||
height-min 2in
|
||||
height 2in
|
||||
//background-color grey
|
||||
//padding 20px
|
||||
.labels
|
||||
display none
|
||||
.printableLabel
|
||||
display none
|
||||
.label
|
||||
display inline-block
|
||||
width 3in
|
||||
height 2in
|
||||
.canvasContainer
|
||||
padding 10px
|
||||
background-color gray
|
||||
|
||||
.label
|
||||
position relative
|
||||
background-color white
|
||||
color black
|
||||
text-align center
|
||||
font-family TimesNewRoman, Times New Roman, Times
|
||||
//font-family Arial, Helvetica, sans-serif
|
||||
font-size .1in
|
||||
width 3in
|
||||
height 2in
|
||||
.barcodeContainer
|
||||
position absolute
|
||||
transform rotate(270deg)
|
||||
right -4.5em
|
||||
top 5em
|
||||
.qrcode
|
||||
position absolute
|
||||
left 10px
|
||||
top 10px
|
||||
width 60px
|
||||
height 60px
|
||||
.labelLogo
|
||||
width 8em
|
||||
padding 0
|
||||
@@ -89,4 +64,18 @@
|
||||
.website
|
||||
width 100%
|
||||
font-size 1.2em
|
||||
font-weight 100
|
||||
font-weight 100
|
||||
.label.oz8
|
||||
width 76.2mm
|
||||
height 50.8mm
|
||||
.label.barcode
|
||||
width 30.5mm
|
||||
height 30.5mm
|
||||
.qrcode
|
||||
position absolute
|
||||
top 50%
|
||||
left 50%
|
||||
margin-top -30px
|
||||
margin-left -30px
|
||||
.labelText, .labelLogo
|
||||
display none
|
||||
@@ -1,11 +1,11 @@
|
||||
import './PrintLabel.html';
|
||||
import JsBarcode from 'JsBarcode';
|
||||
//import QRCode from "../util/qrcode/qrcode";
|
||||
import QRCode from '/imports/util/qrcode/qrcode';
|
||||
|
||||
//let {qrcode, svg2url} = require('pure-svg-code');
|
||||
import LabelFormats from '/imports/LabelFormats.js';
|
||||
|
||||
Template.PrintLabel.onCreated(function() {
|
||||
});
|
||||
|
||||
Template.PrintLabel.onRendered(function() {
|
||||
function getUrlVars() {
|
||||
let vars = {};
|
||||
let parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
|
||||
@@ -13,20 +13,30 @@ Template.PrintLabel.onCreated(function() {
|
||||
});
|
||||
return vars;
|
||||
}
|
||||
function setupDisplay(vars) {
|
||||
$('.label').removeClass().addClass("label " + vars.format);
|
||||
$('.title1').html(vars['title1']);
|
||||
$('.title2').html(vars['title2'] === undefined ? "" : vars['title2']);
|
||||
$('.ingredientsList').html(vars['ingredients']);
|
||||
$('.date').html(vars['date']);
|
||||
$('.size').html(vars['size']);
|
||||
}
|
||||
|
||||
this.vars = getUrlVars();
|
||||
});
|
||||
|
||||
Template.PrintLabel.onRendered(function() {
|
||||
let vars = this.vars;
|
||||
$('.title1').html(vars['title1']);
|
||||
$('.title2').html(vars['title2'] === undefined ? "" : vars['title2']);
|
||||
$('.ingredients').append(vars['ingredients']);
|
||||
$('.date').html(vars['date']);
|
||||
$('.size').html(vars['size']);
|
||||
//JsBarcode(".barcode").init();
|
||||
let _this = this;
|
||||
|
||||
//Use the reactive variables if this is being rendered as part of the client's view (a preview of what will be printed). Otherwise take the URL parameters as the vars for rendering.
|
||||
if(Blaze.getData(_this.view).vars) {
|
||||
Tracker.autorun(function() {
|
||||
let vars = Blaze.getData(_this.view).vars;
|
||||
|
||||
setupDisplay(vars);
|
||||
});
|
||||
}
|
||||
else {
|
||||
let vars = getUrlVars();
|
||||
|
||||
setupDisplay(vars);
|
||||
}
|
||||
|
||||
//const svgString = qrcode({content: "1234567890", padding: 0, width: 50, height: 50, color: "#000000", background: "#FFFFFF", ecl: "L"});
|
||||
//this.$('.qrcode').attr('src', svg2url(svgString));
|
||||
new QRCode(document.getElementById("qrcode"), {text: "1234567890", width: 60, height: 60});
|
||||
});
|
||||
@@ -11,7 +11,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="hasLabels"></th>
|
||||
<th class="name">Name {{>BatchSearch columnName='name'}}</th>
|
||||
<th class="name">Name {{>BatchSearch columnName='productId' collectionQueryColumnName='name' collection='Products' collectionResultColumnName='_id' width="90%"}}</th>
|
||||
<th class="date">Date {{>BatchDateRangeSearch columnName='date' width='90%'}}</th>
|
||||
<th class="amount">Amount</th>
|
||||
<th class="cook">Cook {{>BatchSearch columnName='cook' collectionQueryColumnName='name' collection='Workers' collectionResultColumnName='_id'}}</th>
|
||||
@@ -50,7 +50,7 @@
|
||||
{{else}}
|
||||
<td class="hasLabels noselect left"><i class="fa fa-print clickable {{hasLabelsClass}}" aria-hidden="true"></i></td>
|
||||
<td class="name noselect nonclickable left">{{name}}</td>
|
||||
<td class="date noselect nonclickable left">{{date}}</td>
|
||||
<td class="date noselect nonclickable left">{{date}} ({{jdate}})</td>
|
||||
<td class="amount noselect nonclickable left">{{amount}}</td>
|
||||
<td class="cook noselect nonclickable left">{{cook}}</td>
|
||||
<td class="canner noselect nonclickable left">{{canner}}</td>
|
||||
|
||||
10
imports/ui/Production.import.styl
vendored
10
imports/ui/Production.import.styl
vendored
@@ -44,19 +44,23 @@
|
||||
width: 100%
|
||||
> .date
|
||||
//width: auto
|
||||
min-width: 150px
|
||||
width: 180px
|
||||
min-width: 180px
|
||||
max-width: 180px
|
||||
> .amount
|
||||
//width: auto
|
||||
width: 100px
|
||||
min-width: 100px
|
||||
max-width: 100px
|
||||
> .cook
|
||||
//width: auto
|
||||
min-width: 150px
|
||||
width: 180px
|
||||
min-width: 180px
|
||||
max-width: 180px
|
||||
> .canner
|
||||
//width: auto
|
||||
min-width: 150px
|
||||
width: 180px
|
||||
min-width: 180px
|
||||
max-width: 180px
|
||||
> .comment
|
||||
width: 220px
|
||||
|
||||
@@ -126,6 +126,9 @@ Template.Batch.helpers({
|
||||
},
|
||||
isDeleted: function() {
|
||||
return this.deletedAt;
|
||||
},
|
||||
jdate: function() {
|
||||
return moment(this.date, "YYYYMMDD").format("YYDDDD");
|
||||
}
|
||||
});
|
||||
Template.Batch.events({
|
||||
@@ -157,6 +160,8 @@ Template.Batch.events({
|
||||
Template.BatchEditor.onCreated(function() {
|
||||
});
|
||||
Template.BatchEditor.onRendered(function() {
|
||||
//Not working????
|
||||
//this.$('.editorForm').validator();
|
||||
});
|
||||
Template.BatchEditor.helpers({
|
||||
name: function() {
|
||||
@@ -181,15 +186,30 @@ Template.BatchEditor.events({
|
||||
'click .editorCancel': function(event, template) {
|
||||
Session.set(PREFIX + "editedId", undefined);
|
||||
},
|
||||
'click input[type="submit"]': function(event, template) {
|
||||
event.preventDefault();
|
||||
template.$('.insertForm').data('bs.validator').validate(function(isValid) {
|
||||
if(isValid) {
|
||||
//Allow the user to edit the comment and the amount produced. Sometimes jars pop after the product cools and these things need to be recorded.
|
||||
'click .editorApply': function(event, template) {
|
||||
//template.$('.editorForm').data('bs.validator').validate(function(isValid) {
|
||||
// if(isValid) {
|
||||
let id = template.data._id;
|
||||
let amount = parseInt(template.$('input.amount').val());
|
||||
let comment = template.$('#batchEditorComment').val();
|
||||
|
||||
//TODO
|
||||
}
|
||||
});
|
||||
console.log(id + " " + amount + " " + comment);
|
||||
|
||||
if(Number.isInteger(amount) && amount > 0) {
|
||||
|
||||
Meteor.call('updateBatch', id, amount, comment, function(error) {
|
||||
if(error) sAlert.error("Failed to update the batch!\n" + error);
|
||||
else {
|
||||
sAlert.success("Production batch updated.");
|
||||
Session.set(PREFIX + "editedId", undefined);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
sAlert.error("Amount must be a number greater than zero.");
|
||||
}
|
||||
// }
|
||||
//});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
import './Products.html';
|
||||
import Batches from "../api/Batch";
|
||||
|
||||
let QUERY_LIMIT = 100;
|
||||
let QUERY_LIMIT_INCREMENT = 100;
|
||||
@@ -57,6 +58,10 @@ Template.Products.helpers({
|
||||
|
||||
dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {};
|
||||
Session.set(PREFIX + 'productCount', Meteor.collections.Products.find(dbQuery).count()); //Always get a full count.
|
||||
|
||||
//console.log("dbQuery=" + JSON.stringify(dbQuery));
|
||||
//console.log("Result Count: " + Meteor.collections.Products.find(dbQuery).count());
|
||||
|
||||
return Meteor.collections.Products.find(dbQuery, {limit: Session.get(PREFIX + "queryLimit"), skip: skipCount, sort: {name: 1}});
|
||||
},
|
||||
disableLoadMore: function() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
import './UserManagement.html';
|
||||
import '/imports/util/selectize/selectize.js'
|
||||
import '/imports/util/selectize/selectize.js';
|
||||
import Swal from 'sweetalert2';
|
||||
|
||||
let QUERY_LIMIT = 100;
|
||||
let QUERY_LIMIT_INCREMENT = 100;
|
||||
@@ -91,22 +92,36 @@ Template.User.events({
|
||||
},
|
||||
"click .userRemove": function(event, template) {
|
||||
let _this = this;
|
||||
bootbox.confirm({
|
||||
message: "Delete the user?",
|
||||
buttons: {confirm: {label: "Yes", className: 'btn-success'}, cancel: {label: "No", className: "btn-danger"}},
|
||||
callback: function(result) {
|
||||
if(result) {
|
||||
Meteor.call('deleteUser', _this._id, function(error, result) {
|
||||
if(error) {
|
||||
sAlert.error(error);
|
||||
}
|
||||
else {
|
||||
sAlert.success("User removed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
Swal({title: "Delete User", text: "Delete the user?", type: 'warning', showCancelButton: true, confirmButtonColor: '#419c2b', cancelButtonColor: '#d33', confirmButtonText: "Yes, delete it!"}).then((isConfirm) => {
|
||||
if(isConfirm) {
|
||||
Meteor.call('deleteUser', _this._id, function(error, result) {
|
||||
if(error) {
|
||||
sAlert.error(error);
|
||||
}
|
||||
else {
|
||||
sAlert.success("User removed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//bootbox.confirm({
|
||||
// message: "Delete the user?",
|
||||
// buttons: {confirm: {label: "Yes", className: 'btn-success'}, cancel: {label: "No", className: "btn-danger"}},
|
||||
// callback: function(result) {
|
||||
// if(result) {
|
||||
// Meteor.call('deleteUser', _this._id, function(error, result) {
|
||||
// if(error) {
|
||||
// sAlert.error(error);
|
||||
// }
|
||||
// else {
|
||||
// sAlert.success("User removed.");
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
//});
|
||||
}
|
||||
});
|
||||
Template.User.helpers({
|
||||
|
||||
Reference in New Issue
Block a user