Skip to content

feat: Import existing Plist/JSON configurations #8

@dernerl

Description

@dernerl

📥 Feature Request: Import Plist/JSON Configurations

Problem

Currently, users need to manually recreate their existing Microsoft Edge Managed Favorites configurations from scratch. This is time-consuming and error-prone when modifying existing deployments.

Proposed Solution

Add an Import feature that allows users to load existing configuration files:

  • JSON files (from GPO/Intune Settings Catalog)
  • Plist files (from macOS Configuration Profiles/Intune)

This would enable users to:

  • ✅ Edit existing configurations easily
  • ✅ Migrate from manual JSON/Plist editing to the GUI
  • ✅ Make incremental changes to deployed configs
  • ✅ Avoid starting from scratch

Implementation Ideas

1. UI Integration

  • Add "Import" button in Toolbar (next to "Add Favorite"/"Add Folder")
    • Icon: square.and.arrow.down or arrow.down.doc
    • Keyboard Shortcut: CMD+I or CMD+O
  • File picker with filters:
    • .json for JSON files
    • .plist for Plist files
    • Both formats selectable

2. Import Logic

// Pseudo-code
func importConfiguration(from url: URL) throws {
    let data = try Data(contentsOf: url)
    
    if url.pathExtension == "json" {
        let favorites = try parseJSON(data)
        importToDatabase(favorites)
    } else if url.pathExtension == "plist" {
        let favorites = try parsePlist(data)
        importToDatabase(favorites)
    }
}

3. Parsing Requirements

JSON Format:

[
  { "toplevel_name": "Company Links" },
  {
    "name": "Work Folder",
    "children": [
      { "name": "GitHub", "url": "https://github.com" }
    ]
  },
  { "name": "Google", "url": "https://google.com" }
]

Plist Format:

<dict>
  <key>ManagedFavorites</key>
  <array>
    <dict>
      <key>toplevel_name</key>
      <string>Company Links</string>
    </dict>
    <dict>
      <key>children</key>
      <array>...</array>
      <key>name</key>
      <string>Work Folder</string>
    </dict>
  </array>
</dict>

4. Data Mapping

  • Extract toplevel_name and update ViewModel
  • Parse root-level favorites (no parent)
  • Parse folders and their children
  • Assign order based on array position
  • Generate UUIDs for id and parentID

5. User Flow

  1. User clicks "Import" button (or CMD+I)
  2. File picker opens (filter: .json, .plist)
  3. User selects file
  4. App parses and validates file
  5. Options:
    • Replace all - Clear existing favorites and import
    • Merge - Add imported items to existing ones
    • Preview - Show what will be imported before confirming
  6. Import completes with success/error message

6. Error Handling

  • ❌ Invalid JSON/Plist format
  • ❌ Missing required fields (name, url)
  • ❌ Unsupported structure (e.g., nested folders > 1 level)
  • ❌ File read errors
  • Show user-friendly error alerts with recovery suggestions

Additional Features

Optional Enhancements:

  • 🔄 Drag & Drop - Drop .json/.plist files onto app window
  • 🔍 Validation - Show warnings for invalid URLs or names
  • 📋 Preview Dialog - Display what will be imported before confirming
  • ⚙️ Import Options in Settings:
    • Default behavior (replace vs. merge)
    • Auto-assign order values
    • Handle duplicate names/URLs

Benefits

  • 🚀 Faster workflow for IT admins
  • 📝 Easier config modifications
  • 🔄 Seamless migration from manual editing
  • ✅ Reduces errors when updating existing deployments

Technical Notes

  • Use NSOpenPanel for file picker
  • JSONDecoder for JSON parsing
  • PropertyListSerialization for Plist parsing
  • SwiftData for importing into database
  • Consider ViewModel method: importFavorites(from url: URL, mode: ImportMode)

Priority

Medium - Valuable feature for users with existing configurations, but app is fully functional without it.

Related Issues


Acceptance Criteria:

  • Import button in Toolbar with keyboard shortcut
  • File picker supporting .json and .plist
  • Correct parsing of both formats
  • Support for flat lists and folder hierarchies
  • Extract and apply toplevel_name
  • Replace or merge import modes
  • Error handling with user-friendly messages
  • Imported data persists via SwiftData
  • Unit tests for parser logic

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions