mirror of
https://github.com/sartography/uva-covid19-testing-frontend.git
synced 2025-03-03 16:40:57 +00:00
Adds rectangular label layouts with support for DataMatrix Rectangular Extension 2D barcodes.
This commit is contained in:
parent
5d75e93c07
commit
fa86d296f6
@ -29,6 +29,11 @@
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
],
|
||||
"allowedCommonJsDependencies": [
|
||||
"bwip-js",
|
||||
"qrcode",
|
||||
"serialize-javascript"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
|
5
package-lock.json
generated
5
package-lock.json
generated
@ -2959,6 +2959,11 @@
|
||||
"integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=",
|
||||
"dev": true
|
||||
},
|
||||
"bwip-js": {
|
||||
"version": "2.0.11",
|
||||
"resolved": "https://registry.npmjs.org/bwip-js/-/bwip-js-2.0.11.tgz",
|
||||
"integrity": "sha512-8hAwUM+5FrGguKRaFi2QxKF9SxQM4fAfTy5TVAkeBODH6Eq3Q8MMEoBN+ymIBxiGKL+wNHB1Z1pv5f9oWGLUKQ=="
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
||||
|
@ -35,6 +35,7 @@
|
||||
"@angular/router": "~11.0.0-next.2",
|
||||
"@ngx-formly/core": "^5.8.0",
|
||||
"@ngx-formly/material": "^5.8.0",
|
||||
"bwip-js": "^2.0.11",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"ngx-qrcode-svg": "^2.0.0",
|
||||
"rfdc": "^1.1.4",
|
||||
|
@ -31,6 +31,7 @@ import {ApiService} from './services/api.service';
|
||||
import {CacheService} from './services/cache.service';
|
||||
import {SettingsService} from './services/settings.service';
|
||||
import {SettingsComponent} from './settings/settings.component';
|
||||
import { BarcodeDataMatrixComponent } from './barcode-data-matrix/barcode-data-matrix.component';
|
||||
|
||||
/**
|
||||
* This function is used internal to get a string instance of the `<base href="" />` value from `index.html`.
|
||||
@ -60,6 +61,7 @@ export function getBaseHref(platformLocation: PlatformLocation): string {
|
||||
PrintLayoutComponent,
|
||||
SampleComponent,
|
||||
SettingsComponent,
|
||||
BarcodeDataMatrixComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
|
@ -0,0 +1,2 @@
|
||||
<canvas id="barcodeCanvas"></canvas>
|
||||
<div id="err"></div>
|
@ -0,0 +1,4 @@
|
||||
#barcodeCanvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { BarcodeDataMatrixComponent } from './barcode-data-matrix.component';
|
||||
|
||||
describe('BarcodeDataMatrixComponent', () => {
|
||||
let component: BarcodeDataMatrixComponent;
|
||||
let fixture: ComponentFixture<BarcodeDataMatrixComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ BarcodeDataMatrixComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BarcodeDataMatrixComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
35
src/app/barcode-data-matrix/barcode-data-matrix.component.ts
Normal file
35
src/app/barcode-data-matrix/barcode-data-matrix.component.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import bwipjs from 'bwip-js';
|
||||
import {AppDefaults} from '../models/appDefaults.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-barcode-data-matrix',
|
||||
templateUrl: './barcode-data-matrix.component.html',
|
||||
styleUrls: ['./barcode-data-matrix.component.scss']
|
||||
})
|
||||
export class BarcodeDataMatrixComponent implements OnInit {
|
||||
@Input() format: string;
|
||||
@Input() value: string;
|
||||
@Input() settings: AppDefaults;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.renderBarcode();
|
||||
}
|
||||
|
||||
renderBarcode(): void {
|
||||
bwipjs.toCanvas('barcodeCanvas', {
|
||||
bcid: this.format,
|
||||
text: this.value,
|
||||
scale: 2,
|
||||
width: this.settings.labelLayout.labelWidth,
|
||||
height: this.settings.labelLayout.labelHeight,
|
||||
includetext: false,
|
||||
textalign: 'center',
|
||||
version: '8x96',
|
||||
padding: this.settings.labelLayout.marginSize,
|
||||
});
|
||||
}
|
||||
}
|
@ -4,16 +4,37 @@ import {LabelLayout} from '../models/labelLayout.interface';
|
||||
export const labelLayouts = {
|
||||
round_32mm_1up: new LabelLayout({
|
||||
name: '32mm Round Label - 1up',
|
||||
barcodeType: 'qrcode',
|
||||
type: 'round_32mm_1up',
|
||||
numCols: 1,
|
||||
columnGap: 0,
|
||||
}),
|
||||
round_32mm_2up: new LabelLayout({
|
||||
name: '32mm Round Label - 2up',
|
||||
barcodeType: 'qrcode',
|
||||
type: 'round_32mm_2up',
|
||||
numCols: 2,
|
||||
columnGap: 3.4,
|
||||
}),
|
||||
rectangular_lg: new LabelLayout({
|
||||
name: '2in x 1.25in Rectangular Label',
|
||||
barcodeType: 'qrcode',
|
||||
type: 'rectangular_lg',
|
||||
numCols: 1,
|
||||
columnGap: 0,
|
||||
labelWidth: 38,
|
||||
labelHeight: 38,
|
||||
}),
|
||||
rectangular_sm: new LabelLayout({
|
||||
name: '96mm x 15mm Rectangular Label',
|
||||
barcodeType: 'datamatrixrectangularextension',
|
||||
type: 'rectangular_sm',
|
||||
numCols: 1,
|
||||
columnGap: 0,
|
||||
labelWidth: 96,
|
||||
labelHeight: 8,
|
||||
marginSize: 4,
|
||||
}),
|
||||
};
|
||||
|
||||
export const defaultOptions: AppDefaultsOptions = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="label-layout">
|
||||
<div class="label-layout" [ngStyle]="pageStyle">
|
||||
<div class="date">{{dateCreated | date:'yyMMdd'}}{{initials}}</div>
|
||||
<div class="time">
|
||||
T<br />
|
||||
@ -6,9 +6,18 @@
|
||||
{{dateCreated | date:'mm'}}
|
||||
</div>
|
||||
<qrcode-svg
|
||||
*ngIf="settings.labelLayout.barcodeType === 'qrcode'"
|
||||
[value]="qrCodeValue"
|
||||
errorCorrectionLevel="H"
|
||||
[ngStyle]="labelStyle"
|
||||
></qrcode-svg>
|
||||
<app-barcode-data-matrix
|
||||
*ngIf="settings.labelLayout.barcodeType !== 'qrcode'"
|
||||
[value]="qrCodeValue"
|
||||
[format]="settings.labelLayout.barcodeType"
|
||||
[ngStyle]="labelStyle"
|
||||
[settings]="settings"
|
||||
></app-barcode-data-matrix>
|
||||
<div class="location">
|
||||
L<br />
|
||||
{{settings.locationId.slice(0, 2)}}<br />
|
||||
|
@ -13,9 +13,9 @@
|
||||
position: relative;
|
||||
width: 24.6mm;
|
||||
height: 24.6mm;
|
||||
border: 2mm solid white;
|
||||
border: 2mm solid transparent;
|
||||
border-radius: 100%;
|
||||
background-color: white;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
right: 0;
|
||||
}
|
||||
|
||||
qrcode-svg {
|
||||
qrcode-svg, app-barcode-data-matrix {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {createQrCodeValue} from '../_util/qrCode';
|
||||
import {AppDefaults} from '../models/appDefaults.interface';
|
||||
import {CssStyle} from '../models/cssStyle.interface';
|
||||
import {SettingsService} from '../services/settings.service';
|
||||
|
||||
@Component({
|
||||
@ -13,9 +14,27 @@ export class LabelLayoutComponent implements OnInit {
|
||||
@Input() barCode: string;
|
||||
@Input() initials: string;
|
||||
settings: AppDefaults;
|
||||
pageStyle: CssStyle;
|
||||
labelStyle: CssStyle;
|
||||
|
||||
constructor(private settingsService: SettingsService) {
|
||||
this.settings = this.settingsService.getSettings();
|
||||
const d = this.settings.labelLayout.dimensions;
|
||||
|
||||
this.pageStyle = {
|
||||
width: d.pageWidth,
|
||||
height: d.pageHeight
|
||||
};
|
||||
|
||||
this.labelStyle = {
|
||||
width: d.labelWidth,
|
||||
height: d.labelHeight,
|
||||
marginTop: `-${this.settings.labelLayout.labelHeight / 2}mm`,
|
||||
marginLeft: `-${this.settings.labelLayout.labelWidth / 2}mm`,
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
get qrCodeValue(): string {
|
||||
|
1
src/app/models/cssStyle.interface.ts
Normal file
1
src/app/models/cssStyle.interface.ts
Normal file
@ -0,0 +1 @@
|
||||
export interface CssStyle { [klass: string]: any; }
|
@ -1,9 +1,11 @@
|
||||
export interface LayoutOptions {
|
||||
barcodeType?: string;
|
||||
type?: string;
|
||||
name?: string;
|
||||
units?: string;
|
||||
pointsPerUnit?: number;
|
||||
labelSize?: number;
|
||||
labelWidth?: number;
|
||||
labelHeight?: number;
|
||||
marginSize?: number;
|
||||
numCols?: number;
|
||||
columnGap?: number;
|
||||
@ -17,11 +19,13 @@ export interface LayoutOptions {
|
||||
}
|
||||
|
||||
export class LabelLayout {
|
||||
barcodeType = 'qrcode';
|
||||
type = 'round_32mm_1up';
|
||||
name = '32mm Round Label - 1up';
|
||||
units = 'mm';
|
||||
pointsPerUnit = 0.3528;
|
||||
labelSize = 28.6;
|
||||
labelHeight = 28.6;
|
||||
labelWidth = 28.6;
|
||||
marginSize = 1.7;
|
||||
numCols = 1;
|
||||
columnGap = 4;
|
||||
@ -45,8 +49,10 @@ export class LabelLayout {
|
||||
bottomTextMargin: this._toUnits(this.bottomTextMargin),
|
||||
columnGap: this._toUnits(this.columnGap),
|
||||
fontSize: this._toUnits(this.fontSize),
|
||||
labelSize: this._toUnits(this.labelSize),
|
||||
labelSizeWithMargins: this._toUnits(this.labelSizeWithMargins),
|
||||
labelWidth: this._toUnits(this.labelWidth),
|
||||
labelWidthWithMargins: this._toUnits(this.labelWidthWithMargins),
|
||||
labelHeight: this._toUnits(this.labelHeight),
|
||||
labelHeightWithMargins: this._toUnits(this.labelHeightWithMargins),
|
||||
marginWidth: this._toUnits(this.marginSize),
|
||||
pageHeight: this._toUnits(this.pageHeight),
|
||||
pageWidth: this._toUnits(this.pageWidth),
|
||||
@ -57,16 +63,20 @@ export class LabelLayout {
|
||||
};
|
||||
}
|
||||
|
||||
get labelSizeWithMargins(): number {
|
||||
return (this.labelSize + (this.marginSize * 2));
|
||||
get labelWidthWithMargins(): number {
|
||||
return (this.labelWidth + (this.marginSize * 2));
|
||||
}
|
||||
|
||||
get labelHeightWithMargins(): number {
|
||||
return (this.labelHeight + (this.marginSize * 2));
|
||||
}
|
||||
|
||||
get pageWidth(): number {
|
||||
return (this.labelSizeWithMargins * this.numCols);
|
||||
return (this.labelWidthWithMargins * this.numCols);
|
||||
}
|
||||
|
||||
get pageHeight(): number {
|
||||
return (this.labelSizeWithMargins * this.numCopies);
|
||||
return (this.labelHeightWithMargins * this.numCopies);
|
||||
}
|
||||
|
||||
get fontSize(): number {
|
||||
|
BIN
src/assets/bwip-fonts/Inconsolata.otf
Normal file
BIN
src/assets/bwip-fonts/Inconsolata.otf
Normal file
Binary file not shown.
BIN
src/assets/bwip-fonts/OCRA7.ttf
Normal file
BIN
src/assets/bwip-fonts/OCRA7.ttf
Normal file
Binary file not shown.
BIN
src/assets/bwip-fonts/OCRB7.ttf
Normal file
BIN
src/assets/bwip-fonts/OCRB7.ttf
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user