Style tweaks
This commit is contained in:
@@ -19,8 +19,7 @@ import {
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import config from "@/config"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { CheckCircle2, AlertCircle, InfoIcon, EyeIcon, EyeOffIcon, ArrowRightIcon, XIcon, FileIcon, LinkIcon } from "lucide-react"
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
|
||||
import { CheckCircle2, AlertCircle, EyeIcon, EyeOffIcon, ArrowRightIcon, XIcon, FileSpreadsheetIcon, LinkIcon, FileIcon } from "lucide-react"
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
@@ -110,7 +109,7 @@ export const MatchColumnsStep = <T extends string>({
|
||||
onBack,
|
||||
initialGlobalSelections
|
||||
}: MatchColumnsProps<T>) => {
|
||||
const dataExample = useMemo(() => data.slice(0, 3), [data]) // Show 3 sample rows
|
||||
const dataExample = useMemo(() => data.slice(0, 5), [data]) // Show 5 sample rows
|
||||
const { fields, autoMapHeaders, autoMapSelectValues, autoMapDistance, translations } = useRsi<T>()
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [columns, setColumns] = useState<Columns<T>>(
|
||||
@@ -200,8 +199,6 @@ export const MatchColumnsStep = <T extends string>({
|
||||
});
|
||||
}, [columns]);
|
||||
|
||||
// Get the first value from the sample data for a column
|
||||
|
||||
// Get mapped company value (if company is mapped to a column)
|
||||
const mappedCompanyColumn = useMemo(() => findMappedColumnForField('company'), [findMappedColumnForField]);
|
||||
const mappedCompanyValue = useMemo(() => {
|
||||
@@ -726,7 +723,7 @@ export const MatchColumnsStep = <T extends string>({
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="ghost" size="icon" className="h-8 w-8">
|
||||
<FileIcon className="h-4 w-4 text-muted-foreground" />
|
||||
<FileSpreadsheetIcon className="h-4 w-4 text-muted-foreground" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent side="right" align="start" className="w-[250px] p-0">
|
||||
@@ -865,13 +862,13 @@ export const MatchColumnsStep = <T extends string>({
|
||||
{/* Left panel - Global selections & Required fields */}
|
||||
<div className="lg:col-span-1 space-y-4">
|
||||
<div>
|
||||
<h3 className="text-lg font-medium mb-4">Global Settings</h3>
|
||||
<p className="text-sm text-muted-foreground mb-4">
|
||||
Apply these values to all imported items
|
||||
<h3 className="text-lg font-medium mb-0">Global Settings</h3>
|
||||
<p className="text-sm text-muted-foreground mb-2">
|
||||
These values will be applied to all imported items
|
||||
</p>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm font-medium">Supplier</label>
|
||||
<Select
|
||||
value={globalSelections.supplier}
|
||||
@@ -890,7 +887,7 @@ export const MatchColumnsStep = <T extends string>({
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm font-medium">Company</label>
|
||||
<Select
|
||||
value={globalSelections.company}
|
||||
@@ -916,7 +913,7 @@ export const MatchColumnsStep = <T extends string>({
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm font-medium">Line</label>
|
||||
<Select
|
||||
value={globalSelections.line}
|
||||
@@ -942,7 +939,7 @@ export const MatchColumnsStep = <T extends string>({
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm font-medium">Sub Line</label>
|
||||
<Select
|
||||
value={globalSelections.subline}
|
||||
@@ -964,22 +961,12 @@ export const MatchColumnsStep = <T extends string>({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Separator className="my-6" />
|
||||
<Separator className="my-8" />
|
||||
|
||||
{/* Required Fields Section - Updated to show source column */}
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<h3 className="text-lg font-medium">Required Fields</h3>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<InfoIcon className="h-4 w-4 text-muted-foreground" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p className="max-w-xs">Map columns to required fields or set them globally</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<h3 className="text-lg font-medium">Matched Fields</h3>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
@@ -1019,27 +1006,7 @@ export const MatchColumnsStep = <T extends string>({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats summary for column mapping */}
|
||||
<div className="mt-6 pt-4">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm">Columns total:</span>
|
||||
<span className="text-sm font-medium">{columns.length}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm">Mapped:</span>
|
||||
<span className="text-sm font-medium">{matchedColumns.length}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm">Ignored:</span>
|
||||
<span className="text-sm font-medium">{ignoredColumns.length}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm">Unmapped:</span>
|
||||
<span className="text-sm font-medium">{unmatchedColumns.length}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Right panel - Column mapping interface */}
|
||||
@@ -1075,7 +1042,7 @@ export const MatchColumnsStep = <T extends string>({
|
||||
<TableHeader className="sticky top-0 bg-muted z-10">
|
||||
<TableRow>
|
||||
<TableHead className="w-1/3">Spreadsheet Column</TableHead>
|
||||
<TableHead className="w-12 text-center">Data</TableHead>
|
||||
<TableHead className="w-12 text-center">Sample Data</TableHead>
|
||||
<TableHead className="w-12"></TableHead>
|
||||
<TableHead>Map To Field</TableHead>
|
||||
<TableHead className="w-24 text-right">Action</TableHead>
|
||||
|
||||
@@ -149,21 +149,24 @@ export const SelectHeaderStep = ({ data, onContinue, onBack }: SelectHeaderProps
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-[calc(100vh-9.5rem)]">
|
||||
<div className="px-8 py-6 bg-background">
|
||||
<h2 className="text-2xl font-semibold text-foreground">
|
||||
{translations.selectHeaderStep.title}
|
||||
</h2>
|
||||
<div className="px-8 py-6 bg-background flex justify-between items-end">
|
||||
<div>
|
||||
<h2 className="text-2xl font-semibold text-foreground">
|
||||
{translations.selectHeaderStep.title}
|
||||
</h2>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
Select the row that contains your column headers
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
onClick={discardEmptyAndDuplicateRows}
|
||||
>
|
||||
Remove Empty/Duplicates
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex-1 flex flex-col min-h-0">
|
||||
<div className="px-8 mb-4 flex justify-end">
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
onClick={discardEmptyAndDuplicateRows}
|
||||
>
|
||||
Remove Empty/Duplicates
|
||||
</Button>
|
||||
</div>
|
||||
<div className="px-8 flex-1 overflow-auto">
|
||||
<SelectHeaderTable
|
||||
data={localData}
|
||||
|
||||
@@ -40,15 +40,13 @@ export const SelectHeaderTable = ({ data, selectedRows, setSelectedRows }: Props
|
||||
|
||||
return (
|
||||
<div className="rounded-md border p-3">
|
||||
<p className="mb-2 p-2 text-sm text-muted-foreground">
|
||||
Select the row that contains your column headers
|
||||
</p>
|
||||
<div className="h-[calc(100vh-27rem)] overflow-auto">
|
||||
|
||||
<div className="h-[calc(100vh-23rem)] overflow-auto">
|
||||
<Table className="relative w-full" style={{ tableLayout: 'fixed' }}>
|
||||
<TableHeader>
|
||||
<TableRow className="grid" style={{ gridTemplateColumns }}>
|
||||
<TableHead className="sticky top-0 z-20 bg-background overflow-hidden">
|
||||
<div className="truncate">Select</div>
|
||||
|
||||
</TableHead>
|
||||
{columns.map((column) => (
|
||||
<TableHead
|
||||
|
||||
@@ -30,7 +30,14 @@ export const Steps = () => {
|
||||
const onNext = (v: StepState) => {
|
||||
history.current.push(state)
|
||||
setState(v)
|
||||
v.type !== StepType.selectSheet && setActiveStep(activeStep + 1)
|
||||
|
||||
if (v.type === StepType.validateData && 'isFromScratch' in v && v.isFromScratch) {
|
||||
// If starting from scratch, jump directly to the validation step
|
||||
const validationStepIndex = steps.indexOf('validationStep')
|
||||
setActiveStep(validationStepIndex)
|
||||
} else if (v.type !== StepType.selectSheet) {
|
||||
setActiveStep(activeStep + 1)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -4,15 +4,16 @@ import { useRsi } from "../../hooks/useRsi"
|
||||
import { DropZone } from "./components/DropZone"
|
||||
import { StepType } from "../UploadFlow"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
|
||||
type UploadProps = {
|
||||
onContinue: (data: XLSX.WorkBook, file: File) => Promise<void>
|
||||
setInitialState?: (state: { type: StepType; data: any[] }) => void
|
||||
setInitialState?: (state: { type: StepType; data: any[]; isFromScratch?: boolean }) => void
|
||||
}
|
||||
|
||||
export const UploadStep = ({ onContinue, setInitialState }: UploadProps) => {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const { translations, fields } = useRsi()
|
||||
const { translations } = useRsi()
|
||||
|
||||
const handleOnContinue = useCallback(
|
||||
async (data: XLSX.WorkBook, file: File) => {
|
||||
@@ -30,19 +31,18 @@ export const UploadStep = ({ onContinue, setInitialState }: UploadProps) => {
|
||||
}, [setInitialState])
|
||||
|
||||
return (
|
||||
<div className="p-8 flex flex-col items-center max-w-xl mx-auto">
|
||||
<h2 className="text-3xl font-semibold mb-8 text-center">{translations.uploadStep.title}</h2>
|
||||
<div className="p-8">
|
||||
<h2 className="text-3xl font-semibold mb-8 text-left">{translations.uploadStep.title}</h2>
|
||||
|
||||
<div className="w-full space-y-8">
|
||||
<div className="border rounded-lg p-6 flex flex-col items-center">
|
||||
<h3 className="text-lg font-medium mb-4">Upload spreadsheet file</h3>
|
||||
<div className="max-w-xl mx-auto w-full space-y-8">
|
||||
<div className="rounded-lg p-6 flex flex-col items-center">
|
||||
<DropZone onContinue={handleOnContinue} isLoading={isLoading} />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-center">
|
||||
<div className="bg-muted h-px w-16"></div>
|
||||
<Separator className="w-24" />
|
||||
<span className="px-3 text-muted-foreground text-sm font-medium">OR</span>
|
||||
<div className="bg-muted h-px w-16"></div>
|
||||
<Separator className="w-24" />
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center">
|
||||
|
||||
@@ -2,25 +2,25 @@ import type { DeepPartial } from "ts-essentials"
|
||||
|
||||
export const translations = {
|
||||
uploadStep: {
|
||||
title: "Upload file",
|
||||
title: "Upload File",
|
||||
manifestTitle: "Data that we expect:",
|
||||
manifestDescription: "(You will have a chance to rename or remove columns in next steps)",
|
||||
maxRecordsExceeded: (maxRecords: string) => `Too many records. Up to ${maxRecords} allowed`,
|
||||
dropzone: {
|
||||
title: "Upload .xlsx, .xls or .csv file",
|
||||
title: "Drop any .xlsx, .xls or .csv file here or click to select",
|
||||
errorToastDescription: "upload rejected",
|
||||
activeDropzoneTitle: "Drop file here...",
|
||||
buttonTitle: "Select file",
|
||||
loadingTitle: "Processing...",
|
||||
},
|
||||
selectSheet: {
|
||||
title: "Select the sheet to use",
|
||||
title: "Select Which Sheet To Use",
|
||||
nextButtonTitle: "Next",
|
||||
backButtonTitle: "Back",
|
||||
},
|
||||
},
|
||||
selectHeaderStep: {
|
||||
title: "Select header row",
|
||||
title: "Select Header Row",
|
||||
nextButtonTitle: "Next",
|
||||
backButtonTitle: "Back",
|
||||
},
|
||||
@@ -39,7 +39,7 @@ export const translations = {
|
||||
duplicateColumnWarningDescription: "Columns cannot duplicate",
|
||||
},
|
||||
validationStep: {
|
||||
title: "Validate data",
|
||||
title: "Validate Data",
|
||||
nextButtonTitle: "Next",
|
||||
backButtonTitle: "Back",
|
||||
noRowsMessage: "No data found",
|
||||
|
||||
Reference in New Issue
Block a user