diff --git a/.travis.yml b/.travis.yml
index fdbcecd..71d6790 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -34,7 +34,6 @@ env:
- BASE_HREF=/
- DEPLOY_URL=/
- HOME_ROUTE=home
- - IRB_URL=http://localhost:5001/
- PORT0=4200
- PRODUCTION=false
script:
@@ -42,7 +41,7 @@ script:
deploy:
provider: script
- script: bash ./deploy.sh sartography/cr-connect-frontend
+ script: bash ./deploy.sh sartography/uva-covid19-testing-kiosk
on:
all_branches: true
condition: $TRAVIS_BRANCH =~ ^(dev|testing|demo|training|staging|master|rrt\/.*)$
diff --git a/package-lock.json b/package-lock.json
index 555051d..0777884 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3790,6 +3790,15 @@
"requires": {
"p-try": "^2.0.0"
}
+ },
+ "serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
}
}
},
@@ -10404,7 +10413,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "dev": true,
"requires": {
"safe-buffer": "^5.1.0"
}
@@ -10951,8 +10959,7 @@
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safe-regex": {
"version": "1.1.0",
@@ -11165,10 +11172,9 @@
}
},
"serialize-javascript": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
- "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
- "dev": true,
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
+ "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
"requires": {
"randombytes": "^2.1.0"
}
@@ -12351,6 +12357,15 @@
"p-try": "^2.0.0"
}
},
+ "serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -13499,6 +13514,17 @@
"terser": "^4.1.2",
"webpack-sources": "^1.4.0",
"worker-farm": "^1.7.0"
+ },
+ "dependencies": {
+ "serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ }
}
},
"to-regex-range": {
diff --git a/package.json b/package.json
index 107c4f3..99af80a 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,7 @@
"ngx-qrcode-svg": "^2.0.0",
"rfdc": "^1.1.4",
"rxjs": "~6.6.3",
+ "serialize-javascript": "^5.0.1",
"tslib": "^2.0.0",
"zone.js": "~0.10.3"
},
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 76fb535..2a24fc7 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -5,10 +5,12 @@ import {FlexLayoutModule} from '@angular/flex-layout';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatButtonModule} from '@angular/material/button';
import {MatCardModule} from '@angular/material/card';
+import {MatOptionModule} from '@angular/material/core';
import {MAT_FORM_FIELD_DEFAULT_OPTIONS, MatFormFieldModule} from '@angular/material/form-field';
import {MatIconModule} from '@angular/material/icon';
import {MatInputModule} from '@angular/material/input';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
+import {MatSelectModule} from '@angular/material/select';
import {MatToolbarModule} from '@angular/material/toolbar';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {FormlyModule} from '@ngx-formly/core';
@@ -70,7 +72,10 @@ export function getBaseHref(platformLocation: PlatformLocation): string {
MatIconModule,
MatFormFieldModule,
QRCodeSVGModule,
- AppRoutingModule, // <-- This line MUST be last (https://angular.io/guide/router#module-import-order-matters)
+ AppRoutingModule,
+ MatOptionModule,
+ MatSelectModule,
+ // <-- This line MUST be last (https://angular.io/guide/router#module-import-order-matters)
],
providers: [
{provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: {appearance: 'outline'}},
diff --git a/src/app/config/defaults.ts b/src/app/config/defaults.ts
index 88a3e5b..d343455 100644
--- a/src/app/config/defaults.ts
+++ b/src/app/config/defaults.ts
@@ -1,31 +1,60 @@
-import {AppDefaults} from '../interfaces/appDefaults.interface';
-import {LabelLayout, LabelLayoutType} from '../interfaces/labelLayout';
-
-// Default form field and data values
-export const defaults: AppDefaults = {
- countsCollection: 'counts', // Name of collection for Line Counts in Firebase.
- samplesCollection: 'samples', // Name of collection for Line Counts in Firebase.
- dateEncodedFormat: 'yyyyMMddHHmm', // Format for dates when encoded in IDs for database records.
- dateDisplayFormat: 'MM/dd/yyyy, hh:mm aa', // Format for dates when displayed to user.
- numCopies: 3, // Default number of copies of labels to print. Can be overridden by user setting.
- labelLayout: 'round_32mm_1up' as LabelLayoutType, // Which label layout to use for printing. Can be overridden by user setting.
- locationId: '0000', // Default location ID. Can be overridden by user setting.
- lineCountRegex: /^[\d]{4}-[\d]{12}$/, // ID format for Line Count records.
- qrCodeRegex: /^[\d]{9}-[a-zA-Z]+-[\d]{12}-[\d]{4}$/, // ID format for QR Code records.
- barCodeNumLength: 9, // Number of digits in Bar Code.
- barCodeRegex: /^[\d]{14}$|^[\d]{9}$/, // Pattern for Bar Code data. Scanned barcodes will be either 9 or 14 digits long.
- // Manually-entered ID numbers will be exactly 9 digits long.
- initialsLength: 5,
- initialsRegex: /^[a-zA-Z]{2,5}$/,
-};
+import createClone from 'rfdc';
+import serializeJs from 'serialize-javascript';
+import {AppDefaults, AppDefaultsOptions} from '../interfaces/appDefaults.interface';
+import {LabelLayout} from '../interfaces/labelLayout.interface';
export const labelLayouts = {
round_32mm_1up: new LabelLayout({
+ name: '32mm Round Label - 1up',
+ type: 'round_32mm_1up',
numCols: 1,
columnGap: 0,
}),
round_32mm_2up: new LabelLayout({
+ name: '32mm Round Label - 2up',
+ type: 'round_32mm_2up',
numCols: 2,
columnGap: 1.3,
}),
};
+
+// Default form field and data values
+export const defaults: AppDefaults = new AppDefaults({
+ barCodeNumLength: 9, // Number of digits in Bar Code.
+ barCodeRegExp: /^[\d]{14}$|^[\d]{9}$/, // Pattern for Bar Code data. Scanned barcodes will be either 9 or 14 digits long. Manually-entered ID numbers will be exactly 9 digits long.
+ countsCollection: 'counts', // Name of collection for Line Counts in Firebase.
+ 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: 5,
+ initialsRegExp: /^[a-zA-Z]{2,5}$/,
+ labelLayout: labelLayouts.round_32mm_1up, // 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.
+ 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.
+ samplesCollection: 'samples', // Name of collection for Line Counts in Firebase.
+});
+
+export const getSettings = (): AppDefaults => {
+ const storedSettings = localStorage.getItem('settings');
+
+ if (storedSettings) {
+ // tslint:disable-next-line:no-eval
+ return new AppDefaults(eval(`(${storedSettings})`));
+ } else {
+ localStorage.setItem('settings', serializeJs(defaults));
+ return defaults;
+ }
+};
+
+export const saveSettings = (newSettings: AppDefaultsOptions): AppDefaults => {
+ const settings: AppDefaults = createClone()(getSettings());
+
+ Object.keys(newSettings).forEach(k => {
+ settings[k] = newSettings[k];
+ });
+
+ localStorage.setItem('settings', serializeJs(settings));
+ return getSettings();
+};
diff --git a/src/app/interfaces/appDefaults.interface.ts b/src/app/interfaces/appDefaults.interface.ts
index 1623dd0..751d9c5 100644
--- a/src/app/interfaces/appDefaults.interface.ts
+++ b/src/app/interfaces/appDefaults.interface.ts
@@ -1,17 +1,51 @@
-import {LabelLayoutType} from './labelLayout';
+import {LabelLayout} from './labelLayout.interface';
-export interface AppDefaults {
- countsCollection: string;
- samplesCollection: string;
- dateEncodedFormat: string;
- dateDisplayFormat: string;
- numCopies: number;
- labelLayout: LabelLayoutType;
- locationId: string;
- lineCountRegex: RegExp;
- qrCodeRegex: RegExp;
- barCodeRegex: RegExp;
- barCodeNumLength: number;
- initialsRegex: RegExp;
- initialsLength: number;
+export interface AppDefaultsOptions {
+ barCodeNumLength?: number;
+ barCodeRegExp?: RegExp | string;
+ countsCollection?: string;
+ dateDisplayFormat?: string;
+ dateEncodedFormat?: string;
+ initialsLength?: number;
+ initialsRegExp?: RegExp | string;
+ labelLayout?: LabelLayout;
+ lineCountRegExp?: RegExp | string;
+ locationId?: string;
+ locationIdRegExp?: RegExp | string;
+ numCopies?: number;
+ qrCodeRegExp?: RegExp | string;
+ samplesCollection?: string;
+}
+
+export class AppDefaults {
+ barCodeNumLength: number;
+ barCodeRegExp: RegExp;
+ countsCollection: string;
+ dateDisplayFormat: string;
+ dateEncodedFormat: string;
+ initialsLength: number;
+ initialsRegExp: RegExp;
+ labelLayout: LabelLayout;
+ lineCountRegExp: RegExp;
+ locationId: string;
+ locationIdRegExp: RegExp;
+ numCopies: number;
+ qrCodeRegExp: RegExp;
+ samplesCollection: string;
+
+ constructor(options: AppDefaultsOptions) {
+ console.log('options', options);
+ const keys = Object.keys(options);
+ keys.forEach(k => {
+ if (k.includes('RegExp')) {
+ if (typeof options[k] === 'string') {
+ this[k] = new RegExp(options[k]);
+ } else {
+ this[k] = options[k];
+ }
+ } else {
+ this[k] = options[k];
+ }
+ });
+ }
}
diff --git a/src/app/interfaces/labelLayout.ts b/src/app/interfaces/labelLayout.interface.ts
similarity index 70%
rename from src/app/interfaces/labelLayout.ts
rename to src/app/interfaces/labelLayout.interface.ts
index 68ba560..0aa9ffc 100644
--- a/src/app/interfaces/labelLayout.ts
+++ b/src/app/interfaces/labelLayout.interface.ts
@@ -1,6 +1,6 @@
-export declare type LabelLayoutType = 'round_32mm_1up' | 'round_32mm_2up';
-
export interface LayoutOptions {
+ type?: string;
+ name?: string;
units?: string;
pointsPerUnit?: number;
labelSize?: number;
@@ -17,6 +17,8 @@ export interface LayoutOptions {
}
export class LabelLayout {
+ type = 'round_32mm_1up';
+ name = '32mm Round Label - 1up';
units = 'mm';
pointsPerUnit = 0.3528;
labelSize = 28.6;
@@ -32,18 +34,10 @@ export class LabelLayout {
numCopies = 1;
constructor(private options: LayoutOptions) {
- this.units = options.units || this.units;
- this.pointsPerUnit = options.pointsPerUnit || this.pointsPerUnit;
- this.marginSize = options.marginSize || this.marginSize;
- this.labelSize = options.labelSize || this.labelSize;
- this.numCols = options.numCols || this.numCols;
- this.columnGap = options.columnGap || this.columnGap;
- this.sideTextWidth = options.sideTextWidth || this.sideTextWidth;
- this.sideTextTop = options.sideTextTop || this.sideTextTop;
- this.sideTextMargin = options.sideTextMargin || this.sideTextMargin;
- this.topTextMargin = options.topTextMargin || this.topTextMargin;
- this.bottomTextMargin = options.bottomTextMargin || this.bottomTextMargin;
- this.fontSizePt = options.fontSizePt || this.fontSizePt;
+ const keys = Object.keys(options);
+ keys.forEach(k => {
+ this[k] = options[k];
+ });
}
get dimensions() {
diff --git a/src/app/print/print.component.ts b/src/app/print/print.component.ts
index 97987b5..5da95cb 100644
--- a/src/app/print/print.component.ts
+++ b/src/app/print/print.component.ts
@@ -43,7 +43,7 @@ export class PrintComponent implements OnInit {
}
get columns() {
- return Array(defaults.labelLayout === 'round_32mm_2up' ? 2 : 1).fill('');
+ return Array(defaults.labelLayout.type === 'round_32mm_2up' ? 2 : 1).fill('');
}
ngOnInit(): void {
diff --git a/src/app/sample/sample.component.html b/src/app/sample/sample.component.html
index 12f4d9e..031e0d3 100644
--- a/src/app/sample/sample.component.html
+++ b/src/app/sample/sample.component.html
@@ -18,16 +18,6 @@
type="text"
[formControl]="barCodeFormControl"
>
-
settings works!
+