Add import method dialog with file upload and paste options

Replace direct file picker trigger with a modal offering two import
methods: file upload and paste JSON content. Uses a textarea instead
of navigator.clipboard.readText() to avoid browser permission prompts.
Also centers both import dialogs and updates spec for clipboard import.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-03-27 14:43:22 +01:00
parent fba83bebd6
commit 4969ed069b
4 changed files with 200 additions and 17 deletions

View File

@@ -25,18 +25,19 @@ A DM has set up an encounter (combatants, HP, initiative, conditions) and wants
### Story IE-2 — Import encounter from file (Priority: P1)
A DM receives a `.json` file from another DM (or from their own earlier export) and wants to load it. They click an import button, select the file, and the application replaces the current state with the imported data.
A DM receives a `.json` file from another DM (or from their own earlier export) and wants to load it. They click an import button, choose an import method (file upload or clipboard paste), and the application replaces the current state with the imported data.
**Why this priority**: Import completes the core value proposition — without it, export is just a read-only backup. Both are needed for the feature to be useful.
**Independent Test**: Can be tested by importing a valid `.json` file and verifying the encounter, undo/redo history, and player characters are replaced with the imported data.
**Independent Test**: Can be tested by importing a valid `.json` file (or pasting valid JSON from the clipboard) and verifying the encounter, undo/redo history, and player characters are replaced with the imported data.
**Acceptance Scenarios**:
1. **Given** the current encounter is empty, **When** the user selects a valid exported `.json` file, **Then** the application loads the imported encounter, undo/redo history, and player characters without any confirmation prompt.
2. **Given** the current encounter has combatants, **When** the user selects a valid `.json` file, **Then** a confirmation dialog appears warning that the current encounter will be replaced.
3. **Given** the confirmation dialog is shown, **When** the user confirms, **Then** the current encounter, undo/redo history, and player characters are replaced with the imported data.
4. **Given** the confirmation dialog is shown, **When** the user cancels, **Then** the current state remains unchanged.
1. **Given** the user clicks the import action, **Then** a dialog appears offering two import methods: file upload and clipboard paste.
2. **Given** the current encounter is empty, **When** the user imports valid encounter data (via file or clipboard), **Then** the application loads the imported encounter, undo/redo history, and player characters without any confirmation prompt.
3. **Given** the current encounter has combatants, **When** the user imports valid encounter data, **Then** a confirmation dialog appears warning that the current encounter will be replaced.
4. **Given** the confirmation dialog is shown, **When** the user confirms, **Then** the current encounter, undo/redo history, and player characters are replaced with the imported data.
5. **Given** the confirmation dialog is shown, **When** the user cancels, **Then** the current state remains unchanged.
---
@@ -53,6 +54,7 @@ A DM accidentally selects a wrong file (a non-JSON file, a corrupted export, or
1. **Given** the user selects a non-JSON file (e.g., an image), **When** the import attempts to parse it, **Then** a user-facing error message is shown and the current state is unchanged.
2. **Given** the user selects a JSON file with missing required fields, **When** the import validates it, **Then** a user-facing error message is shown and the current state is unchanged.
3. **Given** the user selects a JSON file with a valid top-level structure but individual combatants with invalid fields (e.g., negative HP, unknown condition IDs), **When** the import validates it, **Then** invalid fields on otherwise valid combatants are dropped/defaulted (same as localStorage rehydration), but if the top-level structure is malformed (missing `encounter` key, wrong types), the file is rejected with an error message.
4. **Given** the user chooses clipboard import but the clipboard is empty or contains non-JSON text, **Then** a user-facing error message is shown and the current state is unchanged.
---
@@ -70,7 +72,7 @@ A DM accidentally selects a wrong file (a non-JSON file, a corrupted export, or
- **FR-001**: The system MUST provide an export action accessible from the UI that downloads the full application state as a `.json` file.
- **FR-002**: The exported file MUST contain the current encounter (combatants and turn/round state), undo/redo stacks, and player character templates.
- **FR-003**: The exported file MUST use a human-readable filename that includes context (e.g., date or encounter info).
- **FR-004**: The system MUST provide an import action accessible from the UI that opens a file picker for `.json` files.
- **FR-004**: The system MUST provide an import action accessible from the UI that lets the user choose between uploading a `.json` file or pasting from the clipboard.
- **FR-005**: On import, the system MUST replace the current encounter, undo/redo history, and player characters with the imported data.
- **FR-006**: The system MUST show a confirmation dialog before importing if the current encounter is non-empty (has at least one combatant).
- **FR-007**: The system MUST validate imported data using the same rules applied when loading from localStorage — invalid fields are cleaned or dropped, structurally malformed files are rejected entirely.