Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1586 kcai request enhance qr filter to support external barcode scanner input #1594

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions app/components/assets/assets-index/advanced-filters/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,35 @@ export function getAvailableColumns(
return true;
});
}

/**
* Extracts the QR ID from a URL or returns the original value if it's not a URL
* Removes any query parameters and returns the last path segment
*
* @example
* localhost:3000/qr/abc123?hello=world -> abc123
* https://example.com/abc123 -> abc123
* abc123 -> abc123
*
* @param value - The input value (URL or QR ID)
* @returns The extracted QR ID or original value
*/
export function extractQrIdFromValue(value: string): string {
try {
// Try to parse as URL first
const url = new URL(value);

// Remove leading and trailing slashes and split path
const pathParts = url.pathname.split("/").filter(Boolean);

// Get the last part of the path (if exists)
if (pathParts.length > 0) {
return pathParts[pathParts.length - 1];
}

return value;
} catch (e) {
// If URL parsing fails, return original value
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,25 @@ import DynamicDropdown from "~/components/dynamic-dropdown/dynamic-dropdown";
import DynamicSelect from "~/components/dynamic-select/dynamic-select";
import Input from "~/components/forms/input";

import { CheckIcon, ChevronRight, PlusIcon } from "~/components/icons/library";
import {
CheckIcon,
ChevronRight,
HelpIcon,
PlusIcon,
} from "~/components/icons/library";
import { Button } from "~/components/shared/button";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "~/components/shared/tooltip";
import type { AssetIndexLoaderData } from "~/routes/_layout+/assets._index";
import { useHints } from "~/utils/client-hints";
import { adjustDateToUTC, isDateString } from "~/utils/date-fns";
import { tw } from "~/utils/tw";
import { resolveTeamMemberName } from "~/utils/user";
import { extractQrIdFromValue } from "./helpers";
import type { Filter } from "./schema";
import { userFriendlyAssetStatus } from "../../asset-status-badge";

Expand Down Expand Up @@ -156,6 +168,63 @@ export function ValueField({
switch (filter.type) {
case "string":
case "text":
if (filter.name === "qrId") {
return (
<div className={tw("flex w-full md:w-auto")}>
<div className="relative flex-1">
<Input
{...commonInputProps}
type="text"
value={filter.value as string}
onChange={(e) => {
setFilter(e.target.value);
}}
placeholder={placeholder(filter.operator)}
onKeyUp={(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
setTimeout(() => {
// Assert the target as HTMLInputElement to access value
const input = e.target as HTMLInputElement;
const cleanValue = extractQrIdFromValue(input.value);
setFilter(cleanValue);
// Create a new keyboard event for submitOnEnter
submitOnEnter(e as React.KeyboardEvent<HTMLInputElement>);
}, 10);
}
}}
error={error}
name={fieldName}
/>
{!["contains", "containsAny", "matchesAny"].includes(
filter.operator
) ? (
<TooltipProvider delayDuration={100}>
<Tooltip>
<TooltipTrigger asChild>
<i className="absolute right-3.5 top-1/2 flex -translate-y-1/2 cursor-pointer text-gray-400 hover:text-gray-700">
<HelpIcon />
</i>
</TooltipTrigger>
<TooltipContent side="bottom" className="z-[9999999]">
<div className="max-w-[260px] sm:max-w-[320px]">
<h6 className="mb-1 text-xs font-semibold text-gray-700">
Barcode scanner ready
</h6>
<p className="text-xs font-medium text-gray-500">
This fields supports barcode scanners. Simply place
your cursor in the field and scan a Shelf QR code with
your barcode scanner. The value will be automatically
filled in for you.
</p>
</div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
) : null}
</div>
</div>
);
}
return (
<Input
{...commonInputProps}
Expand Down
Loading