Fix horizontal scrollbar, rearrange error and copy icons in cells

This commit is contained in:
2025-03-13 00:27:36 -04:00
parent f55d35e301
commit 0f89373d11
6 changed files with 64 additions and 64 deletions

View File

@@ -1,18 +1,16 @@
# Current Issues to Address # Current Issues to Address
3. The copy down button is in the way of the validation error icon and the select open trigger - all three need to be in unique locations
4. Validation isn't happening beyond checking if a cell is required or not - needs to respect rules in import.tsx 4. Validation isn't happening beyond checking if a cell is required or not - needs to respect rules in import.tsx
* Red cell outline if cell is required and it's empty * Red cell outline if cell is required and it's empty
* Red outline + alert circle icon with tooltip if cell is NOT empty and isn't valid * Red outline + alert circle icon with tooltip if cell is NOT empty and isn't valid
5. Description column needs to have an expanded view of some sort, maybe a popover to allow for easier editing 5. Description column needs to have an expanded view of some sort, maybe a popover to allow for easier editing
* Don't distort table to make it happen * Don't distort table to make it happen
6. Need to ensure all cell's contents don't overflow the input (truncate). COO does this currently, probably more
7. The template select cell is expanding, needs to be fixed size and truncate 7. The template select cell is expanding, needs to be fixed size and truncate
8. When you enter a value in 2+ cells before validation finishes, contents from all edited cells get erased when validation finishes 8. When you enter a value in 2+ cells before validation finishes, contents from all edited cells get erased when validation finishes
9. Import dialog state not fully reset when closing? (validate data step appears scrolled to the middle of the table where I left it) 9. Import dialog state not fully reset when closing? (validate data step appears scrolled to the middle of the table where I left it)
10. UPC column doesn't need to show loading state when Item Number is being processed, only show on item number column 10. UPC column doesn't need to show loading state when Item Number is being processed, only show on item number column
11. Copy down needs to show a loading state on the cells that it will copy to 11. Copy down needs to show a loading state on the cells that it will copy to
12. Shipping restrictions/tax category should default to ID 0 if we didn't get it elsewhere 12. Shipping restrictions/tax category should default to ID 0 if we didn't get it elsewhere
14. Need a way to scroll around table if user doesn't have mouse wheel for left/right
## Do NOT change or edit ## Do NOT change or edit
@@ -23,7 +21,10 @@
## Issues already fixed - do not work on these ## Issues already fixed - do not work on these
✅FIXED 1. The red row background should go away when all cells in the row are valid and all required cells are populated ✅FIXED 1. The red row background should go away when all cells in the row are valid and all required cells are populated
✅FIXED 2. Columns alignment with header is slightly off, gets worse the further right you go ✅FIXED 2. Columns alignment with header is slightly off, gets worse the further right you go
✅FIXED 3. The copy down button is in the way of the validation error icon and the select open trigger - all three need to be in unique locations
✅FIXED 6. Need to ensure all cell's contents don't overflow the input (truncate). COO does this currently, probably more
✅FIXED 13. Header row should be sticky (both up/down and left/right) ✅FIXED 13. Header row should be sticky (both up/down and left/right)
✅FIXED 14. Need a way to scroll around table if user doesn't have mouse wheel for left/right
--------- ---------

View File

@@ -251,6 +251,33 @@ const ItemNumberCell = React.memo(({
return ( return (
<TableCell className="p-1 group relative" style={{ width: `${width}px`, minWidth: `${width}px`, maxWidth: `${width}px`, boxSizing: 'border-box' }}> <TableCell className="p-1 group relative" style={{ width: `${width}px`, minWidth: `${width}px`, maxWidth: `${width}px`, boxSizing: 'border-box' }}>
<div className={`relative ${hasError || isRequiredButEmpty ? 'border-red-500' : ''}`}> <div className={`relative ${hasError || isRequiredButEmpty ? 'border-red-500' : ''}`}>
{shouldShowErrorIcon && (
<div className="absolute right-1.5 top-1/2 -translate-y-1/2 z-20">
<ValidationIcon error={{
message: errorMessages,
level: 'error'
}} />
</div>
)}
{!shouldShowErrorIcon && copyDown && !isEmpty(displayValue) && (
<div className="absolute right-1.5 top-1/2 -translate-y-1/2 z-20 opacity-0 group-hover:opacity-100 transition-opacity">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
onClick={copyDown}
className="p-1 rounded-sm hover:bg-muted text-muted-foreground/50 hover:text-foreground"
>
<ArrowDown className="h-3.5 w-3.5" />
</button>
</TooltipTrigger>
<TooltipContent>
<p>Copy value to all cells below</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
)}
{isValidating ? ( {isValidating ? (
<div className="flex items-center justify-center gap-2"> <div className="flex items-center justify-center gap-2">
<Loader2 className="h-4 w-4 animate-spin text-blue-500" /> <Loader2 className="h-4 w-4 animate-spin text-blue-500" />
@@ -267,33 +294,6 @@ const ItemNumberCell = React.memo(({
/> />
</div> </div>
)} )}
{shouldShowErrorIcon && (
<div className="absolute right-2 top-1/2 -translate-y-1/2 z-20">
<ValidationIcon error={{
message: errorMessages,
level: 'error'
}} />
</div>
)}
{copyDown && (
<div className="absolute right-2 top-1/2 -translate-y-1/2 z-20 opacity-0 group-hover:opacity-100 transition-opacity">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
onClick={copyDown}
className="ml-1 p-1 rounded-sm hover:bg-gray-100 text-gray-500 hover:text-gray-700"
>
<ArrowDown className="h-3 w-3" />
</button>
</TooltipTrigger>
<TooltipContent>
<p>Copy value to all cells below</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
)}
</div> </div>
</TableCell> </TableCell>
); );
@@ -367,6 +367,33 @@ const ValidationCell = ({
return ( return (
<TableCell className="p-1 group relative" style={{ width: `${width}px`, minWidth: `${width}px`, maxWidth: `${width}px`, boxSizing: 'border-box' }}> <TableCell className="p-1 group relative" style={{ width: `${width}px`, minWidth: `${width}px`, maxWidth: `${width}px`, boxSizing: 'border-box' }}>
<div className={`relative ${hasError || isRequiredButEmpty ? 'border-red-500' : ''}`}> <div className={`relative ${hasError || isRequiredButEmpty ? 'border-red-500' : ''}`}>
{shouldShowErrorIcon && (
<div className="absolute right-1.5 top-1/2 -translate-y-1/2 z-20">
<ValidationIcon error={{
message: errorMessages,
level: 'error'
}} />
</div>
)}
{!shouldShowErrorIcon && copyDown && !isEmpty(value) && (
<div className="absolute right-0.5 top-1/2 -translate-y-1/2 z-20 opacity-0 group-hover:opacity-100 transition-opacity">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
onClick={copyDown}
className="p-1 rounded-full hover:bg-muted text-muted-foreground/50 hover:text-foreground"
>
<ArrowDown className="h-3.5 w-3.5" />
</button>
</TooltipTrigger>
<TooltipContent>
<p>Copy value to all cells below</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
)}
{isValidating ? ( {isValidating ? (
<div className="flex items-center justify-center gap-2"> <div className="flex items-center justify-center gap-2">
<Loader2 className="h-4 w-4 animate-spin text-blue-500" /> <Loader2 className="h-4 w-4 animate-spin text-blue-500" />
@@ -383,33 +410,6 @@ const ValidationCell = ({
/> />
</div> </div>
)} )}
{shouldShowErrorIcon && (
<div className="absolute right-2 top-1/2 -translate-y-1/2 z-20">
<ValidationIcon error={{
message: errorMessages,
level: 'error'
}} />
</div>
)}
{copyDown && (
<div className="absolute right-2 top-1/2 -translate-y-1/2 z-20 opacity-0 group-hover:opacity-100 transition-opacity">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
onClick={copyDown}
className="ml-1 p-1 rounded-sm hover:bg-gray-100 text-gray-500 hover:text-gray-700"
>
<ArrowDown className="h-3 w-3" />
</button>
</TooltipTrigger>
<TooltipContent>
<p>Copy value to all cells below</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
)}
</div> </div>
</TableCell> </TableCell>
); );

View File

@@ -1039,17 +1039,16 @@ const ValidationContainer = <T extends string>({
{/* Main table section */} {/* Main table section */}
<div className="px-8 pb-6 flex-1 min-h-0"> <div className="px-8 pb-6 flex-1 min-h-0">
<div className="rounded-md border h-full flex flex-col overflow-hidden"> <div className="rounded-md border h-full flex flex-col overflow-hidden">
<div className="flex-1 overflow-hidden"> <div className="flex-1 overflow-hidden w-full">
<div <div
ref={scrollContainerRef} ref={scrollContainerRef}
className="overflow-auto max-h-[calc(100vh-300px)] w-full" className="overflow-auto max-h-[calc(100vh-320px)] w-full"
style={{ style={{
willChange: 'transform', willChange: 'transform',
position: 'relative', position: 'relative',
WebkitOverflowScrolling: 'touch', // Improve scroll performance on Safari WebkitOverflowScrolling: 'touch', // Improve scroll performance on Safari
overscrollBehavior: 'contain', // Prevent scroll chaining overscrollBehavior: 'contain', // Prevent scroll chaining
contain: 'paint', // Improve performance for sticky elements contain: 'paint', // Improve performance for sticky elements
scrollbarWidth: 'thin' // Thinner scrollbars in Firefox
}} }}
onScroll={handleScroll} onScroll={handleScroll}
> >

View File

@@ -414,7 +414,7 @@ const MultiInputCell = <T extends string>({
</> </>
)} )}
</div> </div>
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" /> <ChevronsUpDown className="mx-2 h-4 w-4 shrink-0 opacity-50" />
</div> </div>
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>

View File

@@ -177,7 +177,7 @@ const SelectCell = <T extends string>({
<span className={isProcessing ? "opacity-70" : ""}> <span className={isProcessing ? "opacity-70" : ""}>
{displayValue} {displayValue}
</span> </span>
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" /> <ChevronsUpDown className="mr-1.5 h-4 w-4 shrink-0 opacity-50" />
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent <PopoverContent

View File

@@ -62,7 +62,7 @@ const BASE_IMPORT_FIELDS = [
description: "Universal Product Code/Barcode", description: "Universal Product Code/Barcode",
alternateMatches: ["barcode", "bar code", "jan", "ean", "upc code"], alternateMatches: ["barcode", "bar code", "jan", "ean", "upc code"],
fieldType: { type: "input" }, fieldType: { type: "input" },
width: 140, width: 145,
validations: [ validations: [
{ rule: "required", errorMessage: "Required", level: "error" }, { rule: "required", errorMessage: "Required", level: "error" },
{ rule: "unique", errorMessage: "Must be unique", level: "error" }, { rule: "unique", errorMessage: "Must be unique", level: "error" },