-
Notifications
You must be signed in to change notification settings - Fork 0
feat(settings): add backup & restore UI and import/export logic #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Add a Settings component providing Backup & Restore functionality for synced user settings. Implement exportSettings to serialize current rankings, quick bangs, and bang aliases into a JSON file and trigger a download. Implement importSettings to accept a JSON file, validate its structure, and apply contained rankings, quick_bangs, and bang_aliases to storage with error handling and user feedback. Wire the new Settings component into the main page navigation. Rename the lucide-solid Settings icon import to SettingsIcon to avoid naming conflict with the component. Provide transient success/error status messages that auto-clear after a few seconds. Validate backup format and handle malformed input with a clear error message.
Deploying searchtuner with
|
| Latest commit: |
edf70bb
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://1c1e8a5e.searchtuner.pages.dev |
| Branch Preview URL: | https://backup-support.searchtuner.pages.dev |
|
| Filename | Overview |
|---|---|
| apps/extension/src/entrypoints/pages/components/Settings.tsx | Added backup/restore UI with export and import functionality. Critical validation bugs allow arrays to pass object type checks for rankings and bang_aliases, and version validation is too permissive. |
| apps/extension/src/entrypoints/pages/main.tsx | Wired Settings component into navigation and renamed icon import to avoid naming conflict. Clean implementation with no issues. |
Sequence Diagram
sequenceDiagram
participant User
participant Settings as Settings Component
participant Browser as Browser Storage
participant FileSystem as File System
alt Export Settings
User->>Settings: Click "Export Settings"
Settings->>Browser: Get syncedRankings()
Browser-->>Settings: rankings data
Settings->>Browser: Get quickBangsData()
Browser-->>Settings: quick_bangs data
Settings->>Browser: Get bangAliasesData()
Browser-->>Settings: bang_aliases data
Settings->>Settings: Create SyncSettingsBackup object
Settings->>Settings: JSON.stringify with formatting
Settings->>Settings: Create Blob and download link
Settings->>FileSystem: Trigger download
FileSystem-->>User: searchtuner-backup-YYYY-MM-DD.json
end
alt Import Settings
User->>Settings: Click "Import Settings"
Settings->>User: Open file picker
User->>Settings: Select JSON file
Settings->>FileSystem: Read file content
FileSystem-->>Settings: JSON text
Settings->>Settings: JSON.parse backup
Settings->>Settings: Validate version and data structure
alt Validation passes
Settings->>Browser: setValue(rankings) if present
Settings->>Browser: setValue(quick_bangs) if present
Settings->>Browser: setValue(bang_aliases) if present
Browser-->>Settings: Success
Settings->>User: Show success message (3s)
else Validation fails
Settings->>User: Show error message (5s)
end
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 files reviewed, 3 comments
| } | ||
|
|
||
| // Import each setting if present | ||
| if (backup.data.rankings && typeof backup.data.rankings === "object") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: typeof === "object" also returns true for arrays, allowing [] to be imported as rankings which should be an object.
| if (backup.data.rankings && typeof backup.data.rankings === "object") { | |
| if (backup.data.rankings && typeof backup.data.rankings === "object" && !Array.isArray(backup.data.rankings)) { |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/extension/src/entrypoints/pages/components/Settings.tsx
Line: 73:73
Comment:
**logic:** `typeof === "object"` also returns true for arrays, allowing `[]` to be imported as rankings which should be an object.
```suggestion
if (backup.data.rankings && typeof backup.data.rankings === "object" && !Array.isArray(backup.data.rankings)) {
```
How can I resolve this? If you propose a fix, please make it concise.| if ( | ||
| backup.data.bang_aliases && | ||
| typeof backup.data.bang_aliases === "object" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: typeof === "object" also returns true for arrays, allowing [] to be imported as bang_aliases which should be an object.
| if ( | |
| backup.data.bang_aliases && | |
| typeof backup.data.bang_aliases === "object" | |
| if ( | |
| backup.data.bang_aliases && | |
| typeof backup.data.bang_aliases === "object" && | |
| !Array.isArray(backup.data.bang_aliases) | |
| ) { |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/extension/src/entrypoints/pages/components/Settings.tsx
Line: 81:83
Comment:
**logic:** `typeof === "object"` also returns true for arrays, allowing `[]` to be imported as bang_aliases which should be an object.
```suggestion
if (
backup.data.bang_aliases &&
typeof backup.data.bang_aliases === "object" &&
!Array.isArray(backup.data.bang_aliases)
) {
```
How can I resolve this? If you propose a fix, please make it concise.|
|
||
| // Validate backup structure | ||
| if ( | ||
| !backup.version || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Version check is too loose - accepts any truthy version number instead of specifically validating version 1.
| !backup.version || | |
| backup.version !== 1 || |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/extension/src/entrypoints/pages/components/Settings.tsx
Line: 65:65
Comment:
**logic:** Version check is too loose - accepts any truthy version number instead of specifically validating version 1.
```suggestion
backup.version !== 1 ||
```
How can I resolve this? If you propose a fix, please make it concise.829abd3 to
edf70bb
Compare
Add a Settings component providing Backup & Restore functionality for
synced user settings. Implement exportSettings to serialize current
rankings, quick bangs, and bang aliases into a JSON file and trigger a
download. Implement importSettings to accept a JSON file, validate its
structure, and apply contained rankings, quick_bangs, and bang_aliases
to storage with error handling and user feedback.
Wire the new Settings component into the main page navigation. Rename
the lucide-solid Settings icon import to SettingsIcon to avoid naming
conflict with the component.
Provide transient success/error status messages that auto-clear after a
few seconds. Validate backup format and handle malformed input with a
clear error message.