From 82974d2d7a7b4fc198b012350f39d863cd84ad54 Mon Sep 17 00:00:00 2001 From: Aaron Louie Date: Mon, 16 Nov 2020 16:38:55 -0500 Subject: [PATCH] Shortens data stored in CODE128. Increases length of initials to accommodate UVA computing ids. Removes old home component and syncs data on Scan Barcode screen. --- src/app/_util/qrCode.ts | 19 +++++++-- src/app/app-routing.module.spec.ts | 2 - src/app/app-routing.module.ts | 1 - src/app/app.module.ts | 2 - src/app/config/defaults.ts | 5 ++- src/app/home/home.component.html | 27 ------------ src/app/home/home.component.scss | 3 -- src/app/home/home.component.spec.ts | 41 ------------------- src/app/home/home.component.ts | 41 ------------------- .../rectangle-code128.component.svg | 6 +-- .../label-layout/label-layout.component.ts | 4 +- src/app/models/labelLayout.interface.ts | 2 + src/app/print/print.component.ts | 4 +- src/app/sample/sample.component.html | 2 +- src/app/sample/sample.component.spec.ts | 28 ++++++++++--- src/app/sample/sample.component.ts | 33 ++++++++++++++- src/app/settings/settings.component.html | 6 +-- src/app/settings/settings.component.ts | 23 +++++++++-- src/app/testing/environment.mock.ts | 4 ++ 19 files changed, 110 insertions(+), 143 deletions(-) delete mode 100644 src/app/home/home.component.html delete mode 100644 src/app/home/home.component.scss delete mode 100644 src/app/home/home.component.spec.ts delete mode 100644 src/app/home/home.component.ts diff --git a/src/app/_util/qrCode.ts b/src/app/_util/qrCode.ts index 940de94..f2b92d5 100644 --- a/src/app/_util/qrCode.ts +++ b/src/app/_util/qrCode.ts @@ -1,11 +1,22 @@ import {formatDate} from '@angular/common'; -export const createQrCodeValue = (barCode: string, initials: string, dateCreated: Date, locationId: string): string => { +export const createQrCodeValue = ( + barCode: string, + initials: string, + dateCreated: Date, + locationId: string, + delimiter = '-', + barcodeType: string +): string => { + const is1D = barcodeType === 'code128'; + const locId = is1D ? locationId.slice(2, 4) : locationId; + const dateFormat = is1D ? 'yyMMdd' : 'yyyyMMddHHmm'; + const valArray = [ barCode, initials.toUpperCase(), - formatDate(dateCreated, 'yyyyMMddHHmm', 'en-us'), - locationId, + formatDate(dateCreated, dateFormat, 'en-us'), + locId, ]; - return valArray.join('-'); + return valArray.join(delimiter); }; diff --git a/src/app/app-routing.module.spec.ts b/src/app/app-routing.module.spec.ts index e03028d..98776af 100644 --- a/src/app/app-routing.module.spec.ts +++ b/src/app/app-routing.module.spec.ts @@ -22,7 +22,6 @@ import {FormlyMaterialModule} from '@ngx-formly/material'; import {routes} from './app-routing.module'; import {AppComponent} from './app.component'; import {FooterComponent} from './footer/footer.component'; -import {HomeComponent} from './home/home.component'; import {NavbarComponent} from './navbar/navbar.component'; import {MockEnvironment} from './testing/environment.mock'; @@ -38,7 +37,6 @@ describe('Router: App', () => { declarations: [ AppComponent, FooterComponent, - HomeComponent, NavbarComponent, ], imports: [ diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index f281a2d..785511a 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -2,7 +2,6 @@ import {NgModule} from '@angular/core'; import {RouterModule, Routes} from '@angular/router'; import {ThisEnvironment} from '../environments/environment.injectable'; import {CountComponent} from './count/count.component'; -import {HomeComponent} from './home/home.component'; import {PrintComponent} from './print/print.component'; import {SampleComponent} from './sample/sample.component'; import {SettingsComponent} from './settings/settings.component'; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 6bb96c7..9b0d486 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -21,7 +21,6 @@ import {AppComponent} from './app.component'; import {BarcodeSvgDirective} from './barcode-svg/barcode-svg.directive'; import {CountComponent} from './count/count.component'; import {FooterComponent} from './footer/footer.component'; -import {HomeComponent} from './home/home.component'; import {CircleQRcodeDoubleComponent} from './label-layout/formats/circle-qrcode-double/circle-qrcode-double.component'; import {CircleQRcodeSingleComponent} from './label-layout/formats/circle-qrcode-single/circle-qrcode-single.component'; import {RectangleCode128Component} from './label-layout/formats/rectangle-code128/rectangle-code128.component'; @@ -60,7 +59,6 @@ export function getBaseHref(platformLocation: PlatformLocation): string { CircleQRcodeSingleComponent, CountComponent, FooterComponent, - HomeComponent, LabelLayoutComponent, LoadingComponent, NavbarComponent, diff --git a/src/app/config/defaults.ts b/src/app/config/defaults.ts index 854f13c..d5b786d 100644 --- a/src/app/config/defaults.ts +++ b/src/app/config/defaults.ts @@ -22,6 +22,7 @@ export const labelLayouts = { id: 'rectangle_code128', pageWidth: 54, pageHeight: 34, + delimiter: '', }), rectangle_datamatrix: new LabelLayout({ name: '2in x 1.25in Rectangular Label - DataMatrix', @@ -41,11 +42,11 @@ export const defaultOptions: AppDefaultsOptions = { dateDisplayFormat: 'MM/dd/yyyy, hh:mm aa', // Format for dates when displayed to user. dateEncodedFormat: 'yyyyMMddHHmm', // Format for dates when encoded in IDs for database records. initialsLength: 6, - initialsRegExp: /^[a-zA-Z]{2,6}$/, + initialsRegExp: /^[a-zA-Z0-9]{2,6}$/, labelLayout: labelLayouts.circle_qrcode_single, // Which label layout to use for printing. Can be overridden by user setting. lineCountRegExp: /^[\d]{4}-[\d]{12}$/, // ID format for Line Count records. locationId: '0000', // Default location ID. Can be overridden by user setting. - locationIdRegExp: /^[\d]{4}$/, // ID format for Line Count records. + locationIdRegExp: /^[\d]{1,4}$/, // ID format for Line Count records. numCopies: 1, // Default number of copies of labels to print. // Can be overridden by user setting. qrCodeRegExp: /^[\d]{9}-[a-zA-Z]+-[\d]{12}-[\d]{4}$/, // ID format for QR Code records. diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html deleted file mode 100644 index 11e7528..0000000 --- a/src/app/home/home.component.html +++ /dev/null @@ -1,27 +0,0 @@ -
-
- - -
-
diff --git a/src/app/home/home.component.scss b/src/app/home/home.component.scss deleted file mode 100644 index a743d8a..0000000 --- a/src/app/home/home.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn-xl { - width: 100%; -} diff --git a/src/app/home/home.component.spec.ts b/src/app/home/home.component.spec.ts deleted file mode 100644 index b1978af..0000000 --- a/src/app/home/home.component.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import {APP_BASE_HREF} from '@angular/common'; -import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; -import {async, ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing'; -import {ApiService} from '../services/api.service'; -import {CacheService} from '../services/cache.service'; -import {MockEnvironment} from '../testing/environment.mock'; - -import { HomeComponent } from './home.component'; - -describe('HomeComponent', () => { - let component: HomeComponent; - let fixture: ComponentFixture; - let httpMock: HttpTestingController; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ HomeComponent ], - imports: [ - HttpClientTestingModule, - ], - providers: [ - ApiService, - CacheService, - {provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, - {provide: APP_BASE_HREF, useValue: '/'}, - ], - }) - .compileComponents(); - })); - - beforeEach(() => { - httpMock = TestBed.inject(HttpTestingController); - fixture = TestBed.createComponent(HomeComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts deleted file mode 100644 index 67459c4..0000000 --- a/src/app/home/home.component.ts +++ /dev/null @@ -1,41 +0,0 @@ -import {Component, OnInit} from '@angular/core'; -import {ApiService} from '../services/api.service'; -import {CacheService} from '../services/cache.service'; - -@Component({ - selector: 'app-home', - templateUrl: './home.component.html', - styleUrls: ['./home.component.scss'] -}) -export class HomeComponent implements OnInit { - - constructor( - private cacheService: CacheService, - private apiService: ApiService, - ) { - } - - ngOnInit(): void { - const cachedRecords = this.cacheService.getRecords(); - let numSuccess = 0; - if (cachedRecords && cachedRecords.length > 0) { - cachedRecords.forEach(r => { - this.apiService.addSample(r).subscribe(() => { - numSuccess++; - console.log('cachedRecords', cachedRecords); - console.log('numSuccess', numSuccess); - - if (numSuccess === cachedRecords.length) { - console.log('Cache cleared.'); - this.cacheService.clearCache(); - } - }, error => { - console.log('Cannot connect to server. Cache not cleared.'); - }); - }); - } else { - console.log('No cached records to upload.'); - } - } - -} diff --git a/src/app/label-layout/formats/rectangle-code128/rectangle-code128.component.svg b/src/app/label-layout/formats/rectangle-code128/rectangle-code128.component.svg index 85290fa..957a483 100644 --- a/src/app/label-layout/formats/rectangle-code128/rectangle-code128.component.svg +++ b/src/app/label-layout/formats/rectangle-code128/rectangle-code128.component.svg @@ -35,10 +35,10 @@ + [width]="188" + transform="scale(0.08625)"/> diff --git a/src/app/label-layout/label-layout.component.ts b/src/app/label-layout/label-layout.component.ts index 1085a63..360d564 100644 --- a/src/app/label-layout/label-layout.component.ts +++ b/src/app/label-layout/label-layout.component.ts @@ -35,7 +35,9 @@ export class LabelLayoutComponent implements OnInit { this.sample.student_id, this.sample.initials, this.sample.date, - this.sample.location + this.sample.location, + this.settings.labelLayout.delimiter, + this.settings.labelLayout.barcodeType, ); this.sample.barcode = this.barcodeValue; diff --git a/src/app/models/labelLayout.interface.ts b/src/app/models/labelLayout.interface.ts index 57a45d8..e6da243 100644 --- a/src/app/models/labelLayout.interface.ts +++ b/src/app/models/labelLayout.interface.ts @@ -7,6 +7,7 @@ export interface LayoutOptions { pageWidth?: number; numCols?: number; numCopies?: number; + delimiter?: string; } export class LabelLayout { @@ -18,6 +19,7 @@ export class LabelLayout { pageWidth = 32; numCols = 1; numCopies = 1; + delimiter = '-'; constructor(private options: LayoutOptions) { if (options) { diff --git a/src/app/print/print.component.ts b/src/app/print/print.component.ts index caaf5cd..7899d6d 100644 --- a/src/app/print/print.component.ts +++ b/src/app/print/print.component.ts @@ -77,7 +77,9 @@ export class PrintComponent implements AfterViewInit { this.barCode, this.initials, this.dateCreated, - this.settings.locationId + this.settings.locationId, + this.settings.labelLayout.delimiter, + this.settings.labelLayout.barcodeType, ); const newSample: Sample = { diff --git a/src/app/sample/sample.component.html b/src/app/sample/sample.component.html index 1c64a68..717e5c3 100644 --- a/src/app/sample/sample.component.html +++ b/src/app/sample/sample.component.html @@ -24,7 +24,7 @@ Please enter exactly 9 or 14 digits. - Initials + Initials or 6-character UVA Computing ID { let component: SampleComponent; let fixture: ComponentFixture; const mockRouter = {navigate: jasmine.createSpy('navigate')}; + let httpMock: HttpTestingController; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ SampleComponent ], + declarations: [ + SampleComponent + ], imports: [ + HttpClientTestingModule, MatButtonModule, MatCardModule, MatFormFieldModule, MatIconModule, MatInputModule, NoopAnimationsModule, + ReactiveFormsModule, ], providers: [ + {provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, + {provide: APP_BASE_HREF, useValue: '/'}, {provide: Router, useValue: mockRouter}, + ApiService, + CacheService, + SettingsService, ] - }) - .compileComponents(); + }).compileComponents(); }); beforeEach(() => { + httpMock = TestBed.inject(HttpTestingController); fixture = TestBed.createComponent(SampleComponent); component = fixture.componentInstance; fixture.detectChanges(); diff --git a/src/app/sample/sample.component.ts b/src/app/sample/sample.component.ts index c5f99fe..d30d460 100644 --- a/src/app/sample/sample.component.ts +++ b/src/app/sample/sample.component.ts @@ -1,9 +1,13 @@ -import {AfterViewInit, ChangeDetectorRef, Component, ViewChild} from '@angular/core'; +import {APP_BASE_HREF} from '@angular/common'; +import {AfterViewInit, ChangeDetectorRef, Component, Inject, OnInit, ViewChild} from '@angular/core'; import {FormControl, Validators} from '@angular/forms'; import {MatButton} from '@angular/material/button'; import {MatInput} from '@angular/material/input'; import {Params, Router} from '@angular/router'; import {AppDefaults} from '../models/appDefaults.interface'; +import {AppEnvironment} from '../models/appEnvironment.interface'; +import {ApiService} from '../services/api.service'; +import {CacheService} from '../services/cache.service'; import {SettingsService} from '../services/settings.service'; @@ -12,7 +16,7 @@ import {SettingsService} from '../services/settings.service'; templateUrl: './sample.component.html', styleUrls: ['./sample.component.scss'] }) -export class SampleComponent implements AfterViewInit { +export class SampleComponent implements OnInit, AfterViewInit { settings: AppDefaults; barCodeFormControl: FormControl; initialsFormControl: FormControl; @@ -24,6 +28,8 @@ export class SampleComponent implements AfterViewInit { private router: Router, private changeDetector: ChangeDetectorRef, private settingsService: SettingsService, + private cacheService: CacheService, + private apiService: ApiService ) { this.settings = this.settingsService.getSettings(); this.barCodeFormControl = new FormControl('', [ @@ -65,6 +71,29 @@ export class SampleComponent implements AfterViewInit { return !(this.barCodeFormControl.valid && this.initialsFormControl.valid); } + ngOnInit(): void { + const cachedRecords = this.cacheService.getRecords(); + let numSuccess = 0; + if (cachedRecords && cachedRecords.length > 0) { + cachedRecords.forEach(r => { + this.apiService.addSample(r).subscribe(() => { + numSuccess++; + console.log('cachedRecords', cachedRecords); + console.log('numSuccess', numSuccess); + + if (numSuccess === cachedRecords.length) { + console.log('Cache cleared.'); + this.cacheService.clearCache(); + } + }, error => { + console.log('Cannot connect to server. Cache not cleared.'); + }); + }); + } else { + console.log('No cached records to upload.'); + } + } + ngAfterViewInit() { this.barCodeInput.focus(); this.changeDetector.detectChanges(); diff --git a/src/app/settings/settings.component.html b/src/app/settings/settings.component.html index e2906d6..40a1bc4 100644 --- a/src/app/settings/settings.component.html +++ b/src/app/settings/settings.component.html @@ -15,12 +15,12 @@ This field is required. - Please enter exactly 4 digits. + Please enter a number between 1 and 4 digits long. Label layout @@ -39,7 +39,7 @@ {{layout.name}}
- + diff --git a/src/app/settings/settings.component.ts b/src/app/settings/settings.component.ts index a279b39..c557652 100644 --- a/src/app/settings/settings.component.ts +++ b/src/app/settings/settings.component.ts @@ -8,6 +8,7 @@ import {AppDefaults} from '../models/appDefaults.interface'; import {LabelLayout} from '../models/labelLayout.interface'; import {Sample} from '../models/sample.interface'; import {SettingsService} from '../services/settings.service'; +import createClone from 'rfdc'; @Component({ selector: 'app-settings', @@ -70,7 +71,7 @@ export class SettingsComponent implements AfterViewInit { this.settingsService.saveSettings({ labelLayout: labelLayouts[this.labelLayoutFormControl.value], numCopies: this.numCopiesFormControl.value, - locationId: this.locationIdFormControl.value, + locationId: this.locationIdFormControl.value.toString().padStart(4, '0'), }); this.router.navigate(['/']); } @@ -81,7 +82,7 @@ export class SettingsComponent implements AfterViewInit { this.fakeSample = { barcode: '', student_id: '123456789', - initials: 'ABCDE', + initials: 'ABC9Z', date: new Date(), location: this.settings.locationId, }; @@ -90,7 +91,9 @@ export class SettingsComponent implements AfterViewInit { this.fakeSample.student_id, this.fakeSample.initials, this.fakeSample.date, - this.fakeSample.location + this.fakeSample.location, + '-', + 'datamatrix', ); this.fakeSample.barcode = this.fakeBarcodeValue; @@ -99,4 +102,18 @@ export class SettingsComponent implements AfterViewInit { selectLabelLayout(layout: LabelLayout) { this.labelLayoutFormControl.patchValue(layout); } + + sampleForLayout(layout: LabelLayout) { + const sample: Sample = createClone()(this.fakeSample); + sample.barcode = createQrCodeValue( + sample.student_id, + sample.initials, + sample.date, + sample.location, + layout.delimiter, + layout.barcodeType, + ); + + return sample; + } } diff --git a/src/app/testing/environment.mock.ts b/src/app/testing/environment.mock.ts index bbecec1..0ed8eac 100644 --- a/src/app/testing/environment.mock.ts +++ b/src/app/testing/environment.mock.ts @@ -7,4 +7,8 @@ export class MockEnvironment implements AppEnvironment { api = 'apiRoot'; title = 'Mock Title'; googleAnalyticsKey = 'SOME_KEY'; + + constructor() { + console.log('MockEnvironment constructor'); + } }