You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Raw Item Data
│
├──> validateItemName()
│ ├─ Check not empty
│ ├─ Check length <= 200
│ └─ Trim whitespace
│
├──> normalizeQuantity()
│ ├─ Parse number
│ ├─ Check >= 0
│ ├─ Round to integer
│ └─ Default to 1 if invalid
│
├──> normalizeCategory()
│ ├─ Trim whitespace
│ ├─ Case-insensitive match
│ ├─ Check valid categories
│ └─ Default to "Other"
│
└──> Validated Item
{name, quantity, category, notes}
Error Handling Strategy
Import Process
│
├──> Parse File
│ ├─ Success ──> Continue
│ └─ Failure ──> Return error result
│
├──> Validate Structure
│ ├─ Success ──> Continue
│ └─ Failure ──> Return error result
│
├──> Process Each Item
│ ├─ Valid ──> Add to items array
│ ├─ Invalid ──> Add to errors array
│ └─ Warning ──> Add to warnings array
│
└──> Return Result
├─ success: items.length > 0
├─ items: [...valid items]
├─ errors: [...error messages]
└─ warnings: [...warning messages]
State Management
ImportList Component States
// UI State
step: 'select'|'preview'|'importing'|'complete'// Data State
importResult: ImportResult|null// Parsed import data
listName: string// User-editable name
importError: string|null// Current error message// Refs
fileInputRef: HTMLInputElement// File input element
// Used mutationcreateListFromTemplate(name: string,items: ImportedItem[],color?: string,icon?: string): Promise<string>// Creates:// 1. New list with provided name// 2. List membership for current user// 3. All imported items associated with list
Header Row: name,quantity,category,notes
Data Rows: <value>,<value>,<value>,<value>
Rules:
- First row can be header (detected by "name" or "item" presence)
- Values can be quoted for commas/special chars
- Empty values allowed (use defaults)
- List name from filename
Text Format
Format: [quantity] [x] <item name>
Examples:
- "Milk" -> name: "Milk", quantity: 1
- "2 Apples" -> name: "Apples", quantity: 2
- "3x Bananas" -> name: "Bananas", quantity: 3
Rules:
- One item per line
- Optional quantity prefix
- All items get "Other" category
- List name from filename
// listImport.tsdescribe('importFromJSON',()=>{test('valid JSON with all fields')test('JSON with missing optional fields')test('JSON with invalid categories')test('empty items array')test('malformed JSON')})describe('importFromCSV',()=>{test('CSV with header row')test('CSV without header row')test('CSV with quoted values')test('CSV with empty fields')})describe('importFromText',()=>{test('plain item names')test('items with quantity prefix')test('items with "x" notation')test('empty lines ignored')})
Integration Tests
describe('ImportList Component',()=>{test('file upload triggers parsing')test('drag-and-drop works')test('preview shows correct data')test('import creates list in store')test('success navigates to new list')test('cancel closes modal')})
E2E Tests
describe('Import Feature Flow',()=>{test('complete import flow JSON')test('complete import flow CSV')test('complete import flow TXT')test('error handling invalid file')test('partial import with errors')test('navigation after import')})