From cb89b5923f92ecf1b0dd1ce6b9219025cfd883af Mon Sep 17 00:00:00 2001 From: Romein van Buren Date: Sat, 24 Jun 2023 20:27:48 +0200 Subject: [PATCH] Improved error logging and dialogs --- CHANGELOG.md | 1 + internal/app/app.go | 25 +++++-- internal/app/app_menu.go | 2 +- internal/app/app_settings.go | 44 +++++++----- internal/app/collection.go | 51 +++++++++----- internal/app/collection_aggregate.go | 40 ++++++----- internal/app/collection_find.go | 28 +++++--- internal/app/collection_find_export.go | 93 +++++++++++++++++-------- internal/app/collection_find_queries.go | 43 ++++++++---- internal/app/collection_indexes.go | 34 +++++---- internal/app/collection_insert.go | 19 +++-- internal/app/collection_remove.go | 39 +++++++---- internal/app/collection_update.go | 39 +++++++---- internal/app/connection.go | 34 ++++++--- internal/app/database.go | 32 ++++++--- internal/app/database_dump.go | 22 ++++-- internal/app/hosts.go | 65 +++++++++++++---- internal/app/views.go | 41 ++++++++--- 18 files changed, 444 insertions(+), 208 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45749c7..8e0239e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * Open dump in Explorer/Finder when finished (#43). * Made it possible (again) to input loose JSON into find view inputs, i.e. `{ key: 'val' }` or `{ 'num': 2 }` besides `{ "strict": "json" }`. +* Improved error logging and dialogs. ## [v0.2.1] diff --git a/internal/app/app.go b/internal/app/app.go index 684090c..4ea2f99 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -13,7 +13,6 @@ import ( "strings" "github.com/garraflavatra/rolens/internal/ui" - "github.com/ncruces/zenity" wailsRuntime "github.com/wailsapp/wails/v2/pkg/runtime" "golang.org/x/sync/syncmap" ) @@ -107,16 +106,30 @@ func (a *App) Environment() EnvironmentInfo { } func (a *App) PurgeLogDirectory() { - err := zenity.Question("Are you sure you want to remove all logfiles?", zenity.Title("Confirm"), zenity.WarningIcon) - if err == zenity.ErrCanceled { + choice, _ := wailsRuntime.MessageDialog(a.ctx, wailsRuntime.MessageDialogOptions{ + Title: "Confirm", + Message: "Are you sure you want to remove all logfiles?", + Buttons: []string{"Yes", "Cancel"}, + DefaultButton: "Yes", + CancelButton: "Cancel", + }) + if choice != "Yes" { return } - err = os.RemoveAll(a.Env.LogDirectory) + err := os.RemoveAll(a.Env.LogDirectory) if err == nil { - zenity.Info("Successfully purged log directory.", zenity.InfoIcon) + wailsRuntime.MessageDialog(a.ctx, wailsRuntime.MessageDialogOptions{ + Title: "Success", + Message: "Successfully purged log directory", + Type: wailsRuntime.InfoDialog, + }) } else { - zenity.Error(err.Error(), zenity.Title("Encountered an error while purging log directory."), zenity.WarningIcon) + wailsRuntime.MessageDialog(a.ctx, wailsRuntime.MessageDialogOptions{ + Title: "Error while purging log directory", + Message: err.Error(), + Type: wailsRuntime.ErrorDialog, + }) } } diff --git a/internal/app/app_menu.go b/internal/app/app_menu.go index b4b2be8..f345340 100644 --- a/internal/app/app_menu.go +++ b/internal/app/app_menu.go @@ -30,7 +30,7 @@ func (a *App) Menu() *menu.Menu { aboutMenu.AddSeparator() aboutMenu.AddText("Open data directory…", nil, func(cd *menu.CallbackData) { a.ui.Reveal(a.Env.DataDirectory) }) aboutMenu.AddText("Open log directory…", nil, func(cd *menu.CallbackData) { a.ui.Reveal(a.Env.LogDirectory) }) - aboutMenu.AddText("Purge logs", nil, func(cd *menu.CallbackData) { a.PurgeLogDirectory() }) + aboutMenu.AddText("Purge logs…", nil, func(cd *menu.CallbackData) { a.PurgeLogDirectory() }) aboutMenu.AddSeparator() aboutMenu.AddText("Quit Rolens", keys.CmdOrCtrl("q"), func(cd *menu.CallbackData) { wailsRuntime.Quit(a.ctx) }) diff --git a/internal/app/app_settings.go b/internal/app/app_settings.go index b8fb123..561dcfe 100644 --- a/internal/app/app_settings.go +++ b/internal/app/app_settings.go @@ -6,7 +6,6 @@ import ( "os" "path" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" ) @@ -34,20 +33,20 @@ func (a *App) Settings() Settings { if err != nil { // It's ok if the file cannot be opened, for example if it is not accessible. // Therefore no error is returned. - runtime.LogInfo(a.ctx, "Cannot open settings.json:") - runtime.LogInfo(a.ctx, err.Error()) + runtime.LogInfof(a.ctx, "Cannot open settings.json: %s", err.Error()) return s } if len(jsonData) == 0 { return s } else { - err = json.Unmarshal(jsonData, &s) - - if err != nil { - runtime.LogWarning(a.ctx, "Cannot unmarshal settings.json:") - runtime.LogWarning(a.ctx, err.Error()) - zenity.Warning("Could not retrieve application settings, using defaults!", zenity.WarningIcon) + if err := json.Unmarshal(jsonData, &s); err != nil { + runtime.LogWarningf(a.ctx, "Cannot unmarshal settings.json: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Settings malformed", + Message: "Could not retrieve application settings: using defaults!", + Type: runtime.WarningDialog, + }) } return s } @@ -57,26 +56,35 @@ func (a *App) UpdateSettings(jsonData string) Settings { s := a.Settings() err := json.Unmarshal([]byte(jsonData), &s) if err != nil { - runtime.LogError(a.ctx, "Malformed JSON for settings file:") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Malformed JSON"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Malformed JSON for settings file: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Settings malformed", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return s } newJson, err := json.MarshalIndent(s, "", "\t") if err != nil { - runtime.LogError(a.ctx, "Could not marshal settings into JSON:") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Malformed JSON"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Could not marshal settings into JSON: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "JSON is being awkward", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return s } filePath := path.Join(a.Env.DataDirectory, "settings.json") err = ioutil.WriteFile(filePath, newJson, os.ModePerm) if err != nil { - runtime.LogError(a.ctx, "Could not update host list:") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not update host list"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Could not update host list: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Could not update host list", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) } return s diff --git a/internal/app/collection.go b/internal/app/collection.go index ae4180c..b8a86a1 100644 --- a/internal/app/collection.go +++ b/internal/app/collection.go @@ -3,7 +3,6 @@ package app import ( "fmt" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" "go.mongodb.org/mongo-driver/bson" ) @@ -23,8 +22,7 @@ func (a *App) OpenCollection(hostKey, dbKey, collKey string) (result OpenCollect command := bson.M{"collStats": collKey} err = client.Database(dbKey).RunCommand(ctx, command).Decode(&result.Stats) if err != nil { - runtime.LogWarning(a.ctx, "Could not retrieve collection stats for "+collKey) - runtime.LogWarning(a.ctx, err.Error()) + runtime.LogWarningf(a.ctx, "Could not retrieve collection stats for %s: %s", collKey, err.Error()) result.StatsError = err.Error() } @@ -45,9 +43,12 @@ func (a *App) RenameCollection(hostKey, dbKey, collKey, newCollKey string) bool } err = client.Database("admin").RunCommand(ctx, command).Decode(&result) if err != nil { - runtime.LogWarning(a.ctx, "Could not rename collection "+collKey) - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while renaming collection"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Could not rename collection %s: %s", collKey, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error renaming collection", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } @@ -55,8 +56,14 @@ func (a *App) RenameCollection(hostKey, dbKey, collKey, newCollKey string) bool } func (a *App) TruncateCollection(hostKey, dbKey, collKey string) bool { - err := zenity.Question("Are you sure you want to remove all items from "+collKey+"?", zenity.Title("Confirm"), zenity.WarningIcon) - if err == zenity.ErrCanceled { + choice, _ := runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Confirm", + Message: "Are you sure you want to remove all items in " + collKey + "?", + Buttons: []string{"Yes", "Cancel"}, + DefaultButton: "Yes", + CancelButton: "Cancel", + }) + if choice != "Yes" { return false } @@ -68,9 +75,12 @@ func (a *App) TruncateCollection(hostKey, dbKey, collKey string) bool { _, err = client.Database(dbKey).Collection(collKey).DeleteMany(ctx, bson.D{}) if err != nil { - runtime.LogWarning(a.ctx, "Could not truncate collection "+collKey) - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while truncating collection"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Could not truncate collection %s: %s", collKey, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error truncating collection", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } @@ -78,8 +88,14 @@ func (a *App) TruncateCollection(hostKey, dbKey, collKey string) bool { } func (a *App) DropCollection(hostKey, dbKey, collKey string) bool { - err := zenity.Question("Are you sure you want to drop "+collKey+"?", zenity.Title("Confirm"), zenity.WarningIcon) - if err == zenity.ErrCanceled { + choice, _ := runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Confirm", + Message: "Are you sure you want to drop " + collKey + "?", + Buttons: []string{"Yes", "Cancel"}, + DefaultButton: "Yes", + CancelButton: "Cancel", + }) + if choice != "Yes" { return false } @@ -91,9 +107,12 @@ func (a *App) DropCollection(hostKey, dbKey, collKey string) bool { err = client.Database(dbKey).Collection(collKey).Drop(ctx) if err != nil { - runtime.LogWarning(a.ctx, "Could not drop collection "+collKey) - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while dropping collection"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Could not drop collection %s: %s", collKey, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error dropping collection", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } diff --git a/internal/app/collection_aggregate.go b/internal/app/collection_aggregate.go index 74ef37f..06dbf1e 100644 --- a/internal/app/collection_aggregate.go +++ b/internal/app/collection_aggregate.go @@ -2,9 +2,7 @@ package app import ( "encoding/json" - "fmt" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" @@ -14,17 +12,23 @@ import ( func (a *App) Aggregate(hostKey, dbKey, collKey, pipelineJson, settingsJson string) { var settings *options.AggregateOptions if err := json.Unmarshal([]byte(settingsJson), &settings); err != nil { - runtime.LogError(a.ctx, "Could not parse aggregation settings:") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Couldn't parse aggregation settings"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Could not parse aggregation settings: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Couldn't parse aggregation settings", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return } var pipeline mongo.Pipeline if err := bson.UnmarshalExtJSON([]byte(pipelineJson), true, &pipeline); err != nil { - runtime.LogWarning(a.ctx, "Could not parse aggregation pipeline:") - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Couldn't parse aggregation pipeline"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Could not parse aggregation pipeline: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Couldn't parse aggregation pipeline", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return } @@ -37,19 +41,23 @@ func (a *App) Aggregate(hostKey, dbKey, collKey, pipelineJson, settingsJson stri cursor, err := client.Database(dbKey).Collection(collKey).Aggregate(ctx, pipeline, settings) if err != nil { - runtime.LogWarning(a.ctx, "Could not get aggregation cursor:") - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Couldn't get aggregation cursor"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Could not get aggregation cursor: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Couldn't get aggregation cursor", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return } var results []bson.M if err := cursor.All(ctx, &results); err != nil { - runtime.LogInfo(a.ctx, "Error while running aggregation pipeline:") - runtime.LogInfo(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while running aggregation pipeline"), zenity.ErrorIcon) + runtime.LogInfof(a.ctx, "Error while running aggregation pipeline: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error while running aggregation pipeline", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return } - - fmt.Println(results) } diff --git a/internal/app/collection_find.go b/internal/app/collection_find.go index f643983..2b2a986 100644 --- a/internal/app/collection_find.go +++ b/internal/app/collection_find.go @@ -3,7 +3,6 @@ package app import ( "encoding/json" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" "go.mongodb.org/mongo-driver/bson" mongoOptions "go.mongodb.org/mongo-driver/mongo/options" @@ -29,9 +28,9 @@ func (a *App) FindItems(hostKey, dbKey, collKey, formJson string) (result FindIt err := json.Unmarshal([]byte(formJson), &form) if err != nil { - runtime.LogError(a.ctx, "Could not parse find form:") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not parse form"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Could not parse find form: %s", err.Error()) + result.ErrorTitle = "Could not parse form" + result.ErrorDescription = err.Error() return } @@ -109,8 +108,7 @@ func (a *App) FindItems(hostKey, dbKey, collKey, formJson string) (result FindIt for _, r := range results { marshalled, err := bson.MarshalExtJSON(r, true, true) if err != nil { - runtime.LogError(a.ctx, "Failed to marshal find BSON:") - runtime.LogError(a.ctx, err.Error()) + runtime.LogErrorf(a.ctx, "Failed to marshal find BSON: %s", err.Error()) result.ErrorTitle = "Failed to marshal JSON" result.ErrorDescription = err.Error() return @@ -125,14 +123,22 @@ func (a *App) UpdateFoundDocument(hostKey, dbKey, collKey, idJson, newDocJson st var id bson.M if err := bson.UnmarshalExtJSON([]byte(idJson), true, &id); err != nil { runtime.LogWarningf(a.ctx, "Could not parse find/update query: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Couldn't parse update query"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error parsing update query", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } var newDoc bson.M if err := bson.UnmarshalExtJSON([]byte(newDocJson), true, &newDoc); err != nil { runtime.LogWarningf(a.ctx, "Could not parse new find/update document: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Couldn't parse document"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error parsing document", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } @@ -144,7 +150,11 @@ func (a *App) UpdateFoundDocument(hostKey, dbKey, collKey, idJson, newDocJson st if _, err := client.Database(dbKey).Collection(collKey).ReplaceOne(ctx, id, newDoc); err != nil { runtime.LogInfof(a.ctx, "Error while replacing document: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Unable to replace document"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error replacing document", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } diff --git a/internal/app/collection_find_export.go b/internal/app/collection_find_export.go index e4ea737..078a355 100644 --- a/internal/app/collection_find_export.go +++ b/internal/app/collection_find_export.go @@ -6,7 +6,6 @@ import ( "fmt" "os" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/bsontype" @@ -46,7 +45,11 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo var settings ExportSettings if err := json.Unmarshal([]byte(settingsJson), &settings); err != nil { runtime.LogWarningf(a.ctx, "Could not parse export settings: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Couldn't parse export settings!"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Couldn't parse export settings!", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } @@ -69,8 +72,11 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo view, found := views[settings.ViewKey] if !found { - zenity.Error(fmt.Sprintf("View %s is not known", settings.ViewKey), zenity.ErrorIcon) runtime.LogDebugf(a.ctx, "Export: unknown view %s", settings.ViewKey) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Message: fmt.Sprintf("View %s is not known", settings.ViewKey), + Type: runtime.ErrorDialog, + }) return false } @@ -106,19 +112,29 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo Filters: []runtime.FileFilter{fileFilter}, }) if err != nil { - zenity.Error("An error occured while choosing the export destination", zenity.ErrorIcon) runtime.LogWarningf(a.ctx, "Export: error while choosing export destination: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error while choosing export destination", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } if settings.OutFile == "" { - zenity.Error("You must specify an export destination.", zenity.ErrorIcon) runtime.LogDebug(a.ctx, "Export: no destination specified") + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Message: "Please specify ab export destination.", + Type: runtime.ErrorDialog, + }) return false } if _, err := os.Stat(settings.OutFile); err == nil { - zenity.Error(fmt.Sprintf("File %s already exists, export aborted.", settings.OutFile), zenity.ErrorIcon) runtime.LogDebugf(a.ctx, "Export: destination %s already exists", settings.OutFile) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Message: fmt.Sprintf("File %s already exists, export aborted.", settings.OutFile), + Type: runtime.ErrorDialog, + }) return false } @@ -126,7 +142,11 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo if settings.Contents != ExportContentsAll { if err = bson.UnmarshalExtJSON([]byte(settings.QueryJson), true, &query); err != nil { runtime.LogDebugf(a.ctx, "Invalid find query (exporting): %s", settings.QueryJson) - zenity.Error(err.Error(), zenity.Title("Invalid query"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Invalid query", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } } @@ -137,8 +157,6 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo } defer close() - pgr, _ := zenity.Progress(zenity.Title("Performing export…")) - projection := bson.M{} if settings.ViewKey != "list" { for _, col := range view.Columns { @@ -163,14 +181,22 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo }) if err != nil { runtime.LogInfof(a.ctx, "Export: unable to get cursor while exporting: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Unable to get cursor"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Couldn't get cursor", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } file, err := os.OpenFile(settings.OutFile, os.O_CREATE|os.O_WRONLY, 0644) if err != nil { - zenity.Error(fmt.Sprintf(err.Error(), zenity.Title("Error while opening file"), settings.OutFile), zenity.ErrorIcon) runtime.LogDebugf(a.ctx, "Export: unable to open file %s", settings.OutFile) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error opening file", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } defer file.Close() @@ -192,7 +218,11 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo case ExportFormatCsv: els, err := cur.Current.Elements() if err != nil { - zenity.Error(err.Error(), zenity.Title("BSON invalid"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "BSON is invalid", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) } csvItem := make([]string, 0) @@ -228,7 +258,11 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo if err := csvWriter.Write(csvColumnKeys); err != nil { runtime.LogInfof(a.ctx, "Unable to write item %d to CSV while exporting: %s", index, err.Error()) - zenity.Error(err.Error(), zenity.Title("Unable to write item %d to CSV"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: fmt.Sprintf("Unable to write item %d to CSV", index), + Message: err.Error(), + Type: runtime.ErrorDialog, + }) } } @@ -241,7 +275,11 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo var v any if err := r.Unmarshal(&v); err != nil { - zenity.Error(err.Error(), zenity.Title(fmt.Sprintf("Unable to unmarshal field %s", k)), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: fmt.Sprintf("Unable to unmarshal field %s", k), + Message: err.Error(), + Type: runtime.ErrorDialog, + }) csvItem = append(csvItem, "") continue } @@ -254,8 +292,12 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo } if err := csvWriter.Write(csvItem); err != nil { - runtime.LogInfof(a.ctx, "Unable to write item %d to CSV while exporting: %s", index, err.Error()) - zenity.Error(err.Error(), zenity.Title("Unable to write item %d to CSV"), zenity.ErrorIcon) + runtime.LogInfof(a.ctx, "Export: Unable to write item %d to CSV while exporting: %s", index, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: fmt.Sprintf("Unable to write item %d to CSV", index), + Message: err.Error(), + Type: runtime.ErrorDialog, + }) } csvWriter.Flush() @@ -263,8 +305,12 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo case ExportFormatJsonArray, ExportFormatNdJson: itemJson, err := bson.MarshalExtJSON(cur.Current, true, false) if err != nil { - runtime.LogInfof(a.ctx, "Unable to marshal item %d to JSON while exporting: %s", index, err.Error()) - zenity.Error(err.Error(), zenity.Title("Unable to marshal item %d to JSON"), zenity.ErrorIcon) + runtime.LogInfof(a.ctx, "Export: Unable to marshal item %d to JSON while exporting: %s", index, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: fmt.Sprintf("Unable to write item %d to CSV", index), + Message: err.Error(), + Type: runtime.ErrorDialog, + }) } if (settings.Format == ExportFormatJsonArray) && (index != 0) { @@ -280,22 +326,13 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo index++ - if count != 0 && pgr != nil { - p := (float32(index) / float32(count)) * 100.0 - pgr.Value(int(p)) - } } if settings.Format == ExportFormatJsonArray { file.WriteString("]\n") } - if pgr != nil { - pgr.Complete() - pgr.Close() - } - a.ui.Reveal(settings.OutFile) - runtime.LogInfo(a.ctx, "Export succeeded") + runtime.LogInfof(a.ctx, "Export succeeded: %d items", count) return true } diff --git a/internal/app/collection_find_queries.go b/internal/app/collection_find_queries.go index 50cf591..5bfcb49 100644 --- a/internal/app/collection_find_queries.go +++ b/internal/app/collection_find_queries.go @@ -6,7 +6,6 @@ import ( "os" "path" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" ) @@ -37,8 +36,7 @@ func (a *App) SavedQueries() map[string]SavedQuery { if err != nil { // It's ok if the file cannot be opened, for example if it is not accessible. // Therefore no error is returned. - runtime.LogInfo(a.ctx, "Could not open queries.json") - runtime.LogInfo(a.ctx, err.Error()) + runtime.LogInfof(a.ctx, "Could not open queries.json: %s", err.Error()) return make(map[string]SavedQuery, 0) } @@ -49,8 +47,7 @@ func (a *App) SavedQueries() map[string]SavedQuery { err = json.Unmarshal(jsonData, &queries) if err != nil { - runtime.LogInfo(a.ctx, "queries.json file contains malformatted JSON data") - runtime.LogInfo(a.ctx, err.Error()) + runtime.LogInfof(a.ctx, "queries.json file contains malformatted JSON data: %s", err.Error()) return nil } @@ -62,9 +59,12 @@ func (a *App) SaveQuery(jsonData string) string { var query SavedQuery err := json.Unmarshal([]byte(jsonData), &query) if err != nil { - runtime.LogError(a.ctx, "Add query: malformed form") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Malformed JSON"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Add query: malformed form: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Malformed JSON", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return "" } @@ -72,7 +72,11 @@ func (a *App) SaveQuery(jsonData string) string { queries[query.Name] = query err = updateQueryFile(a, queries) if err != nil { - zenity.Error(err.Error(), zenity.Title("Could not update query list"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Could not update query list", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return "" } @@ -83,7 +87,11 @@ func (a *App) RemoveQuery(queryName string) { queries := a.SavedQueries() delete(queries, queryName) if err := updateQueryFile(a, queries); err != nil { - zenity.Error(err.Error(), zenity.Title("Could not update query list"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Could not update query list", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) } } @@ -91,15 +99,22 @@ func (a *App) UpdateQueries(jsonData string) bool { var queries map[string]SavedQuery err := json.Unmarshal([]byte(jsonData), &queries) if err != nil { - runtime.LogError(a.ctx, "Update queries: malformed form") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Malformed JSON"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Update queries: malformed form: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Malformed JSON", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } err = updateQueryFile(a, queries) if err != nil { - zenity.Error(err.Error(), zenity.Title("Could not save queries"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Could not save queries", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } diff --git a/internal/app/collection_indexes.go b/internal/app/collection_indexes.go index 2167a98..a19bd2e 100644 --- a/internal/app/collection_indexes.go +++ b/internal/app/collection_indexes.go @@ -4,7 +4,6 @@ import ( "encoding/json" "math" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" @@ -25,16 +24,14 @@ func (a *App) GetIndexes(hostKey, dbKey, collKey string) (result GetIndexesResul cur, err := client.Database(dbKey).Collection(collKey).Indexes().List(ctx) if err != nil { - runtime.LogWarning(a.ctx, "Encountered an error while creating index cursor:") - runtime.LogWarning(a.ctx, err.Error()) + runtime.LogWarningf(a.ctx, "Encountered an error while creating index cursor: %s", err.Error()) result.Error = err.Error() return } err = cur.All(ctx, &result.Indexes) if err != nil { - runtime.LogWarning(a.ctx, "Encountered an error while executing index cursor:") - runtime.LogWarning(a.ctx, err.Error()) + runtime.LogWarningf(a.ctx, "Encountered an error while executing index cursor: %s", err.Error()) result.Error = err.Error() } @@ -64,9 +61,12 @@ func (a *App) CreateIndex(hostKey, dbKey, collKey, jsonData string) string { err = json.Unmarshal([]byte(jsonData), &form) if err != nil { - runtime.LogError(a.ctx, "Could not parse index JSON:") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not parse JSON"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Could not parse index JSON: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Malformed JSON", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return "" } @@ -94,9 +94,12 @@ func (a *App) CreateIndex(hostKey, dbKey, collKey, jsonData string) string { name, err := client.Database(dbKey).Collection(collKey).Indexes().CreateOne(ctx, indexModel) if err != nil { - runtime.LogWarning(a.ctx, "Encountered an error while creating index:") - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while creating index"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Encountered an error while creating index: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error creating index", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return "" } @@ -112,9 +115,12 @@ func (a *App) DropIndex(hostKey, dbKey, collKey, indexName string) bool { _, err = client.Database(dbKey).Collection(collKey).Indexes().DropOne(ctx, indexName, &options.DropIndexesOptions{}) if err != nil { - runtime.LogError(a.ctx, "Encountered an error while creating index drop cursor:") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while creating drop cursor"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Encountered an error while creating index drop cursor: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error creating drop cursor", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } diff --git a/internal/app/collection_insert.go b/internal/app/collection_insert.go index 74d03e1..9d587ca 100644 --- a/internal/app/collection_insert.go +++ b/internal/app/collection_insert.go @@ -3,7 +3,6 @@ package app import ( "strings" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" "go.mongodb.org/mongo-driver/bson" ) @@ -18,9 +17,12 @@ func (a *App) InsertItems(hostKey, dbKey, collKey, jsonData string) interface{} err := bson.UnmarshalExtJSON([]byte(jsonData), true, &data) if err != nil { - runtime.LogError(a.ctx, "Could not parse insert JSON:") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not parse JSON"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Could not parse insert JSON: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Malformed JSON", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return nil } @@ -32,9 +34,12 @@ func (a *App) InsertItems(hostKey, dbKey, collKey, jsonData string) interface{} res, err := client.Database(dbKey).Collection(collKey).InsertMany(ctx, data) if err != nil { - runtime.LogWarning(a.ctx, "Encountered an error while performing insert:") - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while performing insert"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Encountered an error while performing insert: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error performing insert", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return nil } diff --git a/internal/app/collection_remove.go b/internal/app/collection_remove.go index 4835d04..e6fa33e 100644 --- a/internal/app/collection_remove.go +++ b/internal/app/collection_remove.go @@ -3,7 +3,6 @@ package app import ( "strings" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" @@ -15,16 +14,25 @@ func (a *App) RemoveItems(hostKey, dbKey, collKey, jsonData string, many bool) i jsonData = strings.TrimSpace(jsonData) if len(jsonData) == 0 { - err := zenity.Question("Are you sure you want to drop all items in "+collKey+"?", zenity.Title("Confirm"), zenity.WarningIcon) - if err == zenity.ErrCanceled { + choice, _ := runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Confirm", + Message: "Are you sure you want to drop all items in " + collKey + "?", + Buttons: []string{"Yes", "Cancel"}, + DefaultButton: "Yes", + CancelButton: "Cancel", + }) + if choice != "Yes" { return 0 } } else { err = bson.UnmarshalExtJSON([]byte(jsonData), true, &filter) if err != nil { - runtime.LogError(a.ctx, "Could not parse remove query:") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not parse JSON"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Could not parse remove query: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Malformed JSON", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return 0 } } @@ -45,9 +53,12 @@ func (a *App) RemoveItems(hostKey, dbKey, collKey, jsonData string, many bool) i } if err != nil { - runtime.LogWarning(a.ctx, "Encountered an error while performing remove:") - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while performing remove"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Encountered an error while performing remove: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error performing remove query", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return 0 } @@ -66,10 +77,12 @@ func (a *App) RemoveItemById(hostKey, dbKey, collKey, itemId string) bool { err = client.Database(dbKey).Collection(collKey).FindOneAndDelete(ctx, filter).Err() if err != nil && err != mongo.ErrNoDocuments { - runtime.LogWarning(a.ctx, "Encountered an error while performing remove by id:") - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while performing remove"), zenity.ErrorIcon) - + runtime.LogWarningf(a.ctx, "Encountered an error while performing remove by id: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error performing remove query", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } diff --git a/internal/app/collection_update.go b/internal/app/collection_update.go index aa85e8e..03bac6d 100644 --- a/internal/app/collection_update.go +++ b/internal/app/collection_update.go @@ -3,7 +3,6 @@ package app import ( "encoding/json" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" "go.mongodb.org/mongo-driver/bson" @@ -24,9 +23,12 @@ func (a *App) UpdateItems(hostKey, dbKey, collKey string, formJson string) int64 err := json.Unmarshal([]byte(formJson), &form) if err != nil { - runtime.LogError(a.ctx, "Could not parse update form:") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not parse form"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Could not parse update form: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Malformed JSON", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return 0 } @@ -41,10 +43,12 @@ func (a *App) UpdateItems(hostKey, dbKey, collKey string, formJson string) int64 err = bson.UnmarshalExtJSON([]byte(form.Query), true, &query) if err != nil { - runtime.LogWarning(a.ctx, "Invalid update query:") - runtime.LogWarning(a.ctx, form.Query) - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Invalid update query"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Invalid update query %v: %s", form.Query, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Invalid update query", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return 0 } @@ -54,10 +58,12 @@ func (a *App) UpdateItems(hostKey, dbKey, collKey string, formJson string) int64 if err == nil { update[param.Type] = unmarshalled } else { - runtime.LogWarning(a.ctx, "Invalid update parameter value:") - runtime.LogWarning(a.ctx, param.Value) - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Invalid update query"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Invalid update parameter value %v: %s", param.Value, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Invalid update query", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return 0 } } @@ -72,9 +78,12 @@ func (a *App) UpdateItems(hostKey, dbKey, collKey string, formJson string) int64 } if err != nil { - runtime.LogWarning(a.ctx, "Encountered an error while performing update:") - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while performing update"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Encountered an error while performing update: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error performing update query", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return 0 } diff --git a/internal/app/connection.go b/internal/app/connection.go index 66d8985..96fa13e 100644 --- a/internal/app/connection.go +++ b/internal/app/connection.go @@ -5,7 +5,6 @@ import ( "errors" "time" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" @@ -24,14 +23,22 @@ func (a *App) connectToHost(hostKey string) (*mongo.Client, context.Context, fun hosts, err := a.Hosts() if err != nil { runtime.LogInfof(a.ctx, "Error while getting hosts: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while getting hosts"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error getting hosts", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return nil, nil, nil, errors.New("could not retrieve hosts") } h := hosts[hostKey] if len(h.URI) == 0 { runtime.LogInfof(a.ctx, "Invalid URI (len == 0) for host %s", hostKey) - zenity.Warning("You haven't specified a valid uri for the selected host.", zenity.Title("Invalid query"), zenity.WarningIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Invalid host information", + Message: "You haven't specified a valid uri for the selected host.", + Type: runtime.ErrorDialog, + }) return nil, nil, nil, errors.New("invalid uri") } @@ -39,7 +46,11 @@ func (a *App) connectToHost(hostKey string) (*mongo.Client, context.Context, fun if err != nil { runtime.LogWarningf(a.ctx, "Could not connect to host %s: %s", hostKey, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while connecting to "+h.Name), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error while connecting to " + h.Name, + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return nil, nil, nil, errors.New("could not establish a connection with " + h.Name) } @@ -60,24 +71,25 @@ func (a *App) OpenConnection(hostKey string) (result OpenConnectionResult) { result.Databases, err = client.ListDatabaseNames(ctx, bson.M{}) if err != nil { - runtime.LogWarning(a.ctx, "Could not retrieve database names for host "+hostKey) - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while getting databases"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Could not retrieve database names for host %s: %s", hostKey, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error getting database list", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) } command := bson.M{"serverStatus": 1} err = client.Database("admin").RunCommand(ctx, command).Decode(&result.Status) if err != nil { - runtime.LogWarning(a.ctx, "Could not retrieve server status") - runtime.LogWarning(a.ctx, err.Error()) + runtime.LogWarningf(a.ctx, "Could not retrieve server status: %s", err.Error()) result.StatusError = err.Error() } command = bson.M{"hostInfo": 1} err = client.Database("admin").RunCommand(ctx, command).Decode(&result.SystemInfo) if err != nil { - runtime.LogWarning(a.ctx, "Could not retrieve system info") - runtime.LogWarning(a.ctx, err.Error()) + runtime.LogWarningf(a.ctx, "Could not retrieve system info: %s", err.Error()) result.SystemInfoError = err.Error() } diff --git a/internal/app/database.go b/internal/app/database.go index 3fa95bc..6cd0ebe 100644 --- a/internal/app/database.go +++ b/internal/app/database.go @@ -1,7 +1,6 @@ package app import ( - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" "go.mongodb.org/mongo-driver/bson" ) @@ -22,24 +21,32 @@ func (a *App) OpenDatabase(hostKey, dbKey string) (result OpenDatabaseResult) { command := bson.M{"dbStats": 1} err = client.Database(dbKey).RunCommand(ctx, command).Decode(&result.Stats) if err != nil { - runtime.LogWarning(a.ctx, "Could not retrieve database stats for "+dbKey) - runtime.LogWarning(a.ctx, err.Error()) + runtime.LogWarningf(a.ctx, "Could not retrieve database stats for %s: %s", dbKey, err.Error()) result.StatsError = err.Error() } result.Collections, err = client.Database(dbKey).ListCollectionNames(ctx, bson.D{}) if err != nil { - runtime.LogWarning(a.ctx, "Could not retrieve collection list for db "+dbKey) - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while getting collections"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Could not retrieve collection list for db %s: %s", dbKey, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error getting collection list", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) } return } func (a *App) DropDatabase(hostKey, dbKey string) bool { - err := zenity.Question("Are you sure you want to drop "+dbKey+"?", zenity.Title("Confirm"), zenity.WarningIcon) - if err == zenity.ErrCanceled { + choice, _ := runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Confirm", + Message: "Are you sure you want to drop " + dbKey + "?", + Buttons: []string{"Yes", "Cancel"}, + DefaultButton: "Yes", + CancelButton: "Cancel", + }) + if choice != "Yes" { return false } @@ -51,9 +58,12 @@ func (a *App) DropDatabase(hostKey, dbKey string) bool { err = client.Database(dbKey).Drop(ctx) if err != nil { - runtime.LogWarning(a.ctx, "Could not drop db "+dbKey) - runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while dropping database"), zenity.ErrorIcon) + runtime.LogWarningf(a.ctx, "Could not drop db %s: %s", dbKey, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error dropping database", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } diff --git a/internal/app/database_dump.go b/internal/app/database_dump.go index 21eaf8c..7912aba 100644 --- a/internal/app/database_dump.go +++ b/internal/app/database_dump.go @@ -7,7 +7,6 @@ import ( "path" "strings" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" ) @@ -23,21 +22,32 @@ func (a *App) PerformDump(jsonData string) bool { var info DumpInfo err := json.Unmarshal([]byte(jsonData), &info) if err != nil { - runtime.LogError(a.ctx, "Could not unmarshal dump form") - runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not parse JSON"), zenity.ErrorIcon) + runtime.LogErrorf(a.ctx, "Could not unmarshal dump form: %s", err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Malformed JSON", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } hosts, err := a.Hosts() if err != nil { - zenity.Error(err.Error(), zenity.Title("Error while getting hosts"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error getting hosts", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } host := hosts[info.HostKey] if !a.Env.HasMongoDump { - zenity.Error("You need to install mongodump to perform a dump.", zenity.Title("Additional tooling required"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Additional tooling required", + Message: "You need to install mongodump to perform a dump.", + Type: runtime.ErrorDialog, + }) return false } diff --git a/internal/app/hosts.go b/internal/app/hosts.go index 6025c2b..1f220e4 100644 --- a/internal/app/hosts.go +++ b/internal/app/hosts.go @@ -8,7 +8,6 @@ import ( "path" "github.com/google/uuid" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" ) @@ -55,7 +54,11 @@ func (a *App) Hosts() (map[string]Host, error) { func (a *App) AddHost(jsonData string) string { hosts, err := a.Hosts() if err != nil { - zenity.Error(err.Error(), zenity.Title("Error while retrieving hosts"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error getting hosts", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return "" } @@ -63,21 +66,33 @@ func (a *App) AddHost(jsonData string) string { err = json.Unmarshal([]byte(jsonData), &newHost) if err != nil { runtime.LogErrorf(a.ctx, "Add host: malformed form: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not parse JSON"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Malformed JSON", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return "" } id, err := uuid.NewRandom() if err != nil { runtime.LogErrorf(a.ctx, "Add host: failed to generate a UUID: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while generating UUID"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error generating UUID", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return "" } hosts[id.String()] = newHost err = updateHostsFile(a, hosts) if err != nil { - zenity.Error(err.Error(), zenity.Title("Error while updating host list"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error updating host list", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return "" } @@ -87,7 +102,11 @@ func (a *App) AddHost(jsonData string) string { func (a *App) UpdateHost(hostKey string, jsonData string) bool { hosts, err := a.Hosts() if err != nil { - zenity.Error(err.Error(), zenity.Title("Error while getting hosts"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error getting host list", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } @@ -95,14 +114,22 @@ func (a *App) UpdateHost(hostKey string, jsonData string) bool { err = json.Unmarshal([]byte(jsonData), &host) if err != nil { runtime.LogErrorf(a.ctx, "Could not parse update host JSON: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not parse JSON"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Malformed JSON", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } hosts[hostKey] = host err = updateHostsFile(a, hosts) if err != nil { - zenity.Error(err.Error(), zenity.Title("Error while updating hosts"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error updating hosts", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } @@ -112,12 +139,22 @@ func (a *App) UpdateHost(hostKey string, jsonData string) bool { func (a *App) RemoveHost(key string) bool { hosts, err := a.Hosts() if err != nil { - zenity.Error(err.Error(), zenity.Title("Error while retrieving hosts"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error getting host list", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } - err = zenity.Question("Are you sure you want to remove "+hosts[key].Name+"?", zenity.Title("Confirm"), zenity.WarningIcon) - if err == zenity.ErrCanceled { + choice, _ := runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Confirm", + Message: "Are you sure you want to remove " + hosts[key].Name + "?", + Buttons: []string{"Yes", "Cancel"}, + DefaultButton: "Yes", + CancelButton: "Cancel", + }) + if choice != "Yes" { return false } @@ -125,7 +162,11 @@ func (a *App) RemoveHost(key string) bool { err = updateHostsFile(a, hosts) if err != nil { - zenity.Error(err.Error(), zenity.Title("Error while updating hosts"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error updating host list", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return false } diff --git a/internal/app/views.go b/internal/app/views.go index 9b7c435..27ffe65 100644 --- a/internal/app/views.go +++ b/internal/app/views.go @@ -7,7 +7,6 @@ import ( "os" "path" - "github.com/ncruces/zenity" "github.com/wailsapp/wails/v2/pkg/runtime" ) @@ -77,16 +76,14 @@ func (a *App) Views() (ViewStore, error) { if err != nil { // It's ok if the file cannot be opened, for example if it is not accessible. // Therefore no error is returned. - runtime.LogInfo(a.ctx, "views.json file cannot be opened") - runtime.LogInfo(a.ctx, err.Error()) + runtime.LogInfof(a.ctx, "views.json file cannot be opened: %s", err.Error()) return views, nil } if len(jsonData) > 0 { err = json.Unmarshal(jsonData, &views) if err != nil { - runtime.LogInfo(a.ctx, "views.json file contains malformatted JSON data") - runtime.LogInfo(a.ctx, err.Error()) + runtime.LogInfof(a.ctx, "views.json file contains malformatted JSON data: %s", err.Error()) return views, errors.New("views.json file contains malformatted JSON data") } } @@ -101,13 +98,21 @@ func (a *App) UpdateViewStore(jsonData string) error { var viewStore ViewStore err := json.Unmarshal([]byte(jsonData), &viewStore) if err != nil { - zenity.Error(err.Error(), zenity.Title("Could not parse JSON"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Malformed JSON", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return errors.New("invalid JSON") } err = updateViewStore(a, viewStore) if err != nil { - zenity.Error(err.Error(), zenity.Title("Error while updating view store"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error updating view store", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return errors.New("could not update view store") } @@ -117,12 +122,22 @@ func (a *App) UpdateViewStore(jsonData string) error { func (a *App) RemoveView(viewKey string) error { views, err := a.Views() if err != nil { - zenity.Error(err.Error(), zenity.Title("Error while getting views"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error getting views", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return errors.New("could not retrieve existing view store") } - err = zenity.Question("Are you sure you want to remove "+views[viewKey].Name+"?", zenity.Title("Confirm"), zenity.WarningIcon) - if err == zenity.ErrCanceled { + choice, _ := runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Confirm", + Message: "Are you sure you want to remove " + views[viewKey].Name + "?", + Buttons: []string{"Yes", "Cancel"}, + DefaultButton: "Yes", + CancelButton: "Cancel", + }) + if choice != "Yes" { return errors.New("operation aborted") } @@ -130,7 +145,11 @@ func (a *App) RemoveView(viewKey string) error { err = updateViewStore(a, views) if err != nil { - zenity.Error(err.Error(), zenity.Title("Error while updating view store"), zenity.ErrorIcon) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Title: "Error updating view store", + Message: err.Error(), + Type: runtime.ErrorDialog, + }) return errors.New("could not update view store") } return nil