Skip to content

Commit

Permalink
added some barcode scanning fixes which only presented in MS Edge, se…
Browse files Browse the repository at this point in the history
…nding the wrong part type to the backend.
  • Loading branch information
replaysMike committed Feb 19, 2023
1 parent dcc7261 commit e4bf046
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 14 deletions.
30 changes: 30 additions & 0 deletions Binner/Binner.Web/ClientApp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Binner/Binner.Web/ClientApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"smooth-scroll": "^16.1.3",
"tiny-slider": "^2.9.4",
"underscore": "^1.13.6",
"use-sound": "^4.0.1",
"uuid": "^9.0.0",
"yarn": "^1.22.19"
},
Expand Down
5 changes: 5 additions & 0 deletions Binner/Binner.Web/ClientApp/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { Settings } from "./pages/Settings";
import { OhmsLawCalculator } from "./pages/tools/OhmsLawCalculator";
import { ResistorColorCodeCalculator } from "./pages/tools/ResistorColorCodeCalculator";
import { VoltageDividerCalculator } from "./pages/tools/VoltageDividerCalculator";
import { BarcodeScanner } from "./pages/tools/BarcodeScanner";
import { Help } from './pages/help/Home';
import { Scanning } from './pages/help/Scanning';
import { ApiIntegrations } from './pages/help/ApiIntegrations';
Expand Down Expand Up @@ -85,6 +86,10 @@ export default class App extends Component {
path="/tools/voltagedivider"
element={<VoltageDividerCalculator />}
/>
<Route
path="/tools/barcodescanner"
element={<BarcodeScanner />}
/>
<Route exact path="/help" element={<Help />} />
<Route path="/help/scanning" element={<Scanning />} />
<Route path="/help/api-integrations" element={<ApiIntegrations />} />
Expand Down
23 changes: 20 additions & 3 deletions Binner/Binner.Web/ClientApp/src/components/BarcodeScannerInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,15 @@ export function BarcodeScannerInput({listening, minInputLength, onReceived, help
const processBarcodeInformation = (e, value) => {
let barcodeType = "code128";
let parsedValue = {};
let gsDetected = false;
let rsDetected = false;
if (value.startsWith("[)>")) {
// 2D DotMatrix barcode. Process into value.
barcodeType = "datamatrix";
parsedValue = parseDataMatrix(value);
const parseResult = parseDataMatrix(value);
parsedValue = parseResult.value;
gsDetected = parseResult.gsDetected;
rsDetected = parseResult.rsDetected;
} else {
// 1D barcode
parsedValue = value.replace("\n", "").replace("\r", "");
Expand All @@ -89,7 +94,9 @@ export function BarcodeScannerInput({listening, minInputLength, onReceived, help
return {
type: barcodeType,
value: parsedValue,
rawValue: value
rawValue: value,
rsDetected,
gsDetected
};
};

Expand All @@ -102,6 +109,8 @@ export function BarcodeScannerInput({listening, minInputLength, onReceived, help
const expectedFormatNumber = 6; /** 22z22 barcode */
const controlChars = ["P", "1P", "P1", "K", "1K", "10K", "11K", "4L", "Q", "11Z", "12Z", "13Z", "20Z"];

let gsCodePresent = false;
let rsCodePresent = false;
let formatNumber = "";
let buffer = "";
let i;
Expand All @@ -111,6 +120,7 @@ export function BarcodeScannerInput({listening, minInputLength, onReceived, help
if (buffer === header) {
if (value.charCodeAt(i + 1) === rsCharCode) {
// read the character after the RS token (sometimes not present)
rsCodePresent = true;
formatNumberIndex = i + 2;
} else {
formatNumberIndex = i + 1;
Expand Down Expand Up @@ -143,6 +153,9 @@ export function BarcodeScannerInput({listening, minInputLength, onReceived, help
if (gsLine.length > 0)
gsLines.push(gsLine);

if (gsLines.length > 0)
gsCodePresent = true;

// console.log('gsLines', gsLines);

for (i = 0; i < gsLines.length; i++) {
Expand Down Expand Up @@ -206,7 +219,11 @@ export function BarcodeScannerInput({listening, minInputLength, onReceived, help
break;
}
}
return parsedValue;
return {
value: parsedValue,
gsDetected: gsCodePresent,
rsDetected: rsCodePresent
};
};

const scannerDebounced = useMemo(() => debounce(onReceivedBarcodeInput, BufferTimeMs), []);
Expand Down
32 changes: 22 additions & 10 deletions Binner/Binner.Web/ClientApp/src/pages/Inventory.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ export function Inventory(props) {
bulkScanIsOpenRef.current = bulkScanIsOpen;
const scannedPartsRef = useRef();
scannedPartsRef.current = scannedParts;
const partTypesRef = useRef();
partTypesRef.current = partTypes;

useEffect(() => {
const partNumberStr = props.params.partNumber;
Expand All @@ -174,12 +176,14 @@ export function Inventory(props) {
}, [props.params.partNumber]);

const fetchPartMetadata = async (input, part) => {
if (partTypesRef.current.length === 0)
console.error("There are no partTypes! This shouldn't happen and is a bug.");
Inventory.infoAbortController.abort();
Inventory.infoAbortController = new AbortController();
setLoadingPartMetadata(true);
setPartMetadataIsSubscribed(false);
try {
const response = await fetchApi(`part/info?partNumber=${input}&partTypeId=${part.partTypeId}&mountingTypeId=${part.mountingTypeId}`, {
const response = await fetchApi(`part/info?partNumber=${input}&partTypeId=${part.partTypeId || "0"}&mountingTypeId=${part.mountingTypeId || "0"}`, {
signal: Inventory.infoAbortController.signal
});
const data = response.data;
Expand All @@ -196,7 +200,7 @@ export function Inventory(props) {

const suggestedPart = infoResponse.parts[0];
// populate the form with data from the part metadata
if(!isEditing) setPartFromMetadata(metadataParts, suggestedPart, partTypes);
if(!isEditing) setPartFromMetadata(metadataParts, suggestedPart);
} else {
// no part metadata available
setPartMetadataIsSubscribed(true);
Expand All @@ -217,7 +221,7 @@ export function Inventory(props) {
}
};

const searchDebounced = useMemo(() => debounce(fetchPartMetadata, 1000), [partTypes, part]);
const searchDebounced = useMemo(() => debounce(fetchPartMetadata, 1000), []);

const onUploadSubmit = async (uploadFiles, type) => {
setUploading(true);
Expand Down Expand Up @@ -388,7 +392,12 @@ export function Inventory(props) {
// scan single part
if (cleanPartNumber) {
setPartMetadataIsSubscribed(false);
const newPart = {...part, partNumber: cleanPartNumber, quantity: input.value.quantity || "1"};
const newPart = {...part,
partNumber: cleanPartNumber,
quantity: input.value.quantity || "1",
partTypeId: -1,
mountingTypeId: -1,
};
setPart(newPart);
localStorage.setItem("viewPreferences", JSON.stringify({ ...viewPreferences, lastQuantity: newPart.quantity }));
setShowBarcodeBeingScanned(false);
Expand Down Expand Up @@ -702,15 +711,15 @@ export function Inventory(props) {
updatedPart[control.name] = control.value;
switch (control.name) {
case "partNumber":
if (updatedPart.partNumber && updatedPart.partNumber.length > 0) searchDebounced(updatedPart.partNumber, updatedPart);
if (updatedPart.partNumber && updatedPart.partNumber.length > 0) searchDebounced(updatedPart.partNumber, updatedPart, partTypes);
break;
case "partTypeId":
localStorage.setItem("viewPreferences", JSON.stringify({ ...viewPreferences, lastPartTypeId: control.value }));
if (updatedPart.partNumber && updatedPart.partNumber.length > 0) searchDebounced(updatedPart.partNumber, updatedPart);
if (updatedPart.partNumber && updatedPart.partNumber.length > 0) searchDebounced(updatedPart.partNumber, updatedPart, partTypes);
break;
case "mountingTypeId":
localStorage.setItem("viewPreferences", JSON.stringify({ ...viewPreferences, lastMountingTypeId: control.value }));
if (updatedPart.partNumber && updatedPart.partNumber.length > 0) searchDebounced(updatedPart.partNumber, updatedPart);
if (updatedPart.partNumber && updatedPart.partNumber.length > 0) searchDebounced(updatedPart.partNumber, updatedPart, partTypes);
break;
case "lowStockThreshold":
localStorage.setItem("viewPreferences", JSON.stringify({ ...viewPreferences, lowStockThreshold: control.value }));
Expand Down Expand Up @@ -739,11 +748,14 @@ export function Inventory(props) {
await fetchApi(`part/print?partNumber=${part.partNumber}&generateImageOnly=false`, { method: "POST" });
};

const setPartFromMetadata = (metadataParts, suggestedPart, partTypes) => {
const setPartFromMetadata = (metadataParts, suggestedPart) => {
if (partTypesRef.current.length === 0)
console.error("There are no partTypes! This shouldn't happen and is a bug.");

const entity = { ...part };
const mappedPart = {
partNumber: suggestedPart.basePartNumber,
partTypeId: getPartTypeId(suggestedPart.partType, partTypes),
partTypeId: getPartTypeId(suggestedPart.partType, partTypesRef.current),
mountingTypeId: suggestedPart.mountingTypeId,
packageType: suggestedPart.packageType,
keywords: suggestedPart.keywords && suggestedPart.keywords.join(" ").toLowerCase(),
Expand Down Expand Up @@ -812,7 +824,7 @@ export function Inventory(props) {
};

const handleChooseAlternatePart = (e, part, partTypes) => {
setPartFromMetadata(metadataParts, part, partTypes);
setPartFromMetadata(metadataParts, part);
setPartModalOpen(false);
};

Expand Down
6 changes: 6 additions & 0 deletions Binner/Binner.Web/ClientApp/src/pages/Tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ export function Tools(props) {
</Statistic.Value>
<Statistic.Label>Voltage Divider Calculator</Statistic.Label>
</Statistic>
<Statistic onClick={(e) => route(e, "/tools/barcodescanner")} style={{ cursor: "pointer" }}>
<Statistic.Value>
<Icon name="wrench" />
</Statistic.Value>
<Statistic.Label>Barcode Scanner</Statistic.Label>
</Statistic>
</Statistic.Group>
</Segment>
</div>
Expand Down
20 changes: 20 additions & 0 deletions Binner/Binner.Web/ClientApp/src/pages/tools/BarcodeScanner.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
code {
background: #f4f4f4;
border: 1px solid #ddd;
border-left: 3px solid #f36d33;
color: #666;
page-break-inside: avoid;
font-family: monospace;
font-size: 15px;
line-height: 1.6;
margin-bottom: 1.6em;
max-width: 100%;
padding: 1em 1.5em;
display: block;
word-wrap: break-word !important;
white-space: pre-line !important;
}

pre {
white-space: pre !important;
}
35 changes: 35 additions & 0 deletions Binner/Binner.Web/ClientApp/src/pages/tools/BarcodeScanner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { useState, useEffect, useMemo } from "react";
import { Link } from "react-router-dom";
import _ from "underscore";
import { Label, Button, Image, Form, Table, Segment, Dimmer, Checkbox, Loader, Popup } from "semantic-ui-react";
import { toast } from "react-toastify";
import { BarcodeScannerInput } from "../../components/BarcodeScannerInput";
import "./BarcodeScanner.css";

export function BarcodeScanner(props) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [message, setMessage] = useState(null);
const [isKeyboardListening, setIsKeyboardListening] = useState(true);
const [barcodeValue, setBarcodeValue] = useState('Waiting for input...');

// debounced handler for processing barcode scanner input
const handleBarcodeInput = (e, input) => {
// ignore single keypresses
setBarcodeValue(JSON.stringify(input, null, 2));
toast.info(`Barcode type ${input.type} received`);
};

return (
<div>
<BarcodeScannerInput onReceived={handleBarcodeInput} listening={isKeyboardListening} minInputLength={4} />
<h1>Barcode Scanner</h1>
<p>Test your barcode scanner to see what values it outputs.</p>
<Form>
<div>
<code><pre>{barcodeValue}</pre></code>
</div>
</Form>
</div>
);
}
2 changes: 1 addition & 1 deletion Binner/Library/Binner.Common/Integrations/DigikeyApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ private ICollection<Taxonomies> MapTaxonomies(string partType, MountingTypes pac
{
var taxonomies = new List<Taxonomies>();
var taxonomy = Taxonomies.None;
if (!string.IsNullOrEmpty(partType))
if (!string.IsNullOrEmpty(partType) && partType != "-1")
{
if (Enum.TryParse<Taxonomies>(partType, true, out taxonomy))
{
Expand Down

0 comments on commit e4bf046

Please sign in to comment.