Skip to content

Feature/import wizard new upload step#84

Merged
ManukMinasyan merged 47 commits into3.xfrom
feature/import-wizard-new-upload-step
Jan 23, 2026
Merged

Feature/import wizard new upload step#84
ManukMinasyan merged 47 commits into3.xfrom
feature/import-wizard-new-upload-step

Conversation

@ManukMinasyan
Copy link
Copy Markdown
Contributor

No description provided.

…ing upload

Add new import wizard with these key features:
- SQLite-based storage per import session (no main DB bloat)
- LazyCollection streaming for memory-efficient CSV processing
- Parent-child Livewire architecture with @event and $parent patterns
- Deferred store creation (only on user commitment)
- Performance: 47ms for 10K rows, ~50KB memory usage

Implementation status:
- Phase 1 (Core Storage): ImportStore + ImportRow complete
- Phase 2 (Upload Step): UploadStep with streaming complete
- Phase 3+ (Mapping, Review, Preview): Placeholders ready
- Fix ImportRow to use snake_case column names matching database schema
- Add AsCollection cast for raw_data, validation, corrections columns
- Simplify getFinalData() using Collection::merge()
- Fix UploadStep to use 'raw_data' key instead of 'data' (silent failure bug)
- Add SQLite trigger to enforce raw_data is never null/empty
- Extract WithImportStore trait to reduce duplication in step components
- Add Data classes: ColumnMapping, MatchableField, RelationshipMatch
- Add RowMatchAction enum for create/update/skip actions
introduce framework-agnostic importer classes that define fields,
relationships, and matching strategies for each entity type. includes
base importer with shared logic and entity-specific importers for
company, people, opportunity, task, and note.
- fix hover states with visible contrast against page background
- apply filament border radius patterns (rounded-xl for panels)
- disable relationships that are already mapped to other columns
- make isRelationshipMapped public for blade access
- add autofocus to dropdown search input on open
- simplify submenu layout with inline checkmark
- enhance preview panel with 20 rows and header badge
- create field-select.blade.php with self-contained alpine state
- add full keyboard navigation (tab, enter, space, arrows, escape)
- add aria roles and labels for accessibility
- emit events for field/relationship selection and clearing
- simplify mapping-step.blade.php from 370 to 120 lines
- parent handles livewire calls via event listeners
Add min-h-0 and overflow-hidden to flex containers to allow proper
height constraint propagation. This ensures the preview panel scrolls
internally rather than causing page-level scrolling.
…dling

- Convert step containers to flex columns with proper height distribution
- Add overflow handling and scrollable areas for mapping rows
- Consistent navigation section styling across all steps
- Increase preview values from 20 to 50 in mapping step
- Add validation for sort field/direction to prevent SQL injection
- Add validation for filter values with allowlist
- Add ESCAPE clause to SQLite LIKE queries for proper wildcard handling
- Add clearFilters() method to consolidate filter reset
- Add wire:key to filter buttons for proper Livewire reconciliation
- Remove unused hasMoreValues property
Add self-contained document-level click listener that closes the
dropdown when clicking outside. Enables coordination with other
dropdowns without requiring a shared event protocol.
…and subtle invalid row styling

- Add DateFormat enum for parsing/formatting dates (ISO, European, American)
- Implement date column handling with user-selectable format per column
- Add choice field handling with case-insensitive matching
- Extract value row partials for date, choice, text, and skipped states
- Update select-menu component to support borderless mode and event dispatching
- Use subtle invalid row styling: neutral borders with warning icon indicator
- Document all decisions and bug fixes in DECISIONS.md
…ervice

- add ValueValidator service for centralized field validation
- add ImportDateRule and ImportChoiceRule custom validation rules
- remove ColumnAnalysisResult data class, use ImportField directly
- simplify ReviewStep by removing redundant columnAnalyses state
- add translation support for validation error messages
- use ValidationService from custom-fields for rule extraction
- fix FQCN usage to use imported class names
…pages

- Add ImportPeople, ImportOpportunities, ImportNotes pages
- Rename import pages to use {resource}/import URL pattern:
  - companies/import, people/import, tasks/import, etc.
- Rename ImportCompaniesNew -> ImportCompanies, ImportTasksNew -> ImportTasks
- Remove import wizard tests temporarily (to be rewritten)
- Clean up Pest.php helper functions
- Refactor ColumnMapping -> ColumnData, remove unused support classes
Copilot AI review requested due to automatic review settings January 23, 2026 19:38
@ManukMinasyan ManukMinasyan merged commit c6c8e1a into 3.x Jan 23, 2026
0 of 8 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new upload step for the import wizard, replacing the previous implementation with a more streamlined approach using SQLite-based storage instead of Filament's built-in import models.

Changes:

  • Replaced Filament's native import system with a custom SQLite-based storage solution
  • Introduced new service provider and Livewire components for the refactored wizard
  • Removed legacy models, jobs, and infrastructure classes
  • Updated configuration to use simpler settings

Reviewed changes

Copilot reviewed 113 out of 141 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Store/ImportRow.php New Eloquent model for SQLite-based import row storage
src/Livewire/Steps/UploadStep.php New upload step component with streaming CSV processing
src/ImportWizardNewServiceProvider.php New service provider for the refactored wizard
src/Enums/ImportEntityType.php New enum for mapping entity types to importers
src/Importers/* New importer classes replacing Filament's import column system
resources/views/* New Blade views for the refactored wizard UI
config/import-wizard.php Simplified configuration

->take($this->maxRows())
->map(function (array $row) use (&$rowCount): array {
return [
'row_number' => ++$rowCount + 1,
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The row number calculation is incorrect. Using ++$rowCount + 1 will result in row numbers starting at 2 instead of 1 (when $rowCount is 0, it becomes 1, then adds 1 to get 2). Either use ++$rowCount or $rowCount + 1 before incrementing.

Suggested change
'row_number' => ++$rowCount + 1,
'row_number' => ++$rowCount,

Copilot uses AI. Check for mistakes.
{{-- Navigation --}}
<div class="flex items-center justify-between pt-4 mt-6 border-t border-gray-200 dark:border-gray-700 pb-1">
<a
href="{{ url()->getPublicUrl('documentation/import') }}"
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method getPublicUrl() does not exist on the URL facade. Use url('documentation/import') directly instead.

Suggested change
href="{{ url()->getPublicUrl('documentation/import') }}"
href="{{ url('documentation/import') }}"

Copilot uses AI. Check for mistakes.
{
return match ($this) {
self::Company => 'Company',
self::People => 'Person',
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent singular form for People entity. The entity is 'People' but the singular is 'Person', which may cause confusion. Consider using 'People' for both plural and singular to maintain consistency with the entity naming convention used elsewhere in the codebase.

Suggested change
self::People => 'Person',
self::People => 'People',

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants