show = false} transition:fade>
-
+
{#if title}
{title}
@@ -55,7 +56,6 @@
}
.inner {
- max-width: 80vw;
max-height: 80vh;
background-color: #fff;
margin-left: auto;
diff --git a/frontend/src/organisms/addressbar/createhostmodal.svelte b/frontend/src/organisms/addressbar/createhostmodal.svelte
new file mode 100644
index 0000000..1bfa6c2
--- /dev/null
+++ b/frontend/src/organisms/addressbar/createhostmodal.svelte
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
diff --git a/frontend/src/organisms/addressbar/hostmodal.svelte b/frontend/src/organisms/addressbar/hostmodal.svelte
index ace8ae0..31fb4b2 100644
--- a/frontend/src/organisms/addressbar/hostmodal.svelte
+++ b/frontend/src/organisms/addressbar/hostmodal.svelte
@@ -1,44 +1,83 @@
-
+
+ {#if error}
+
+ Oops! {error}
+
+ {/if}
{#if Object.keys(hosts).length}
+ {:else}
+ createHostModalOpen = true} />
{/if}
+
+
diff --git a/frontend/src/organisms/addressbar/index.svelte b/frontend/src/organisms/addressbar/index.svelte
index 147cc95..07a4602 100644
--- a/frontend/src/organisms/addressbar/index.svelte
+++ b/frontend/src/organisms/addressbar/index.svelte
@@ -27,7 +27,7 @@
-
+
diff --git a/frontend/wailsjs/go/app/App.d.ts b/frontend/wailsjs/go/app/App.d.ts
index 565b178..faa3623 100755
--- a/frontend/wailsjs/go/app/App.d.ts
+++ b/frontend/wailsjs/go/app/App.d.ts
@@ -4,6 +4,8 @@ import {app} from '../models';
import {primitive} from '../models';
import {map[string]app} from '../models';
+export function AddHost(arg1:string):Promise
;
+
export function DropCollection(arg1:string,arg2:string,arg3:string):Promise;
export function DropDatabase(arg1:string,arg2:string):Promise;
@@ -24,6 +26,8 @@ export function OpenConnection(arg1:string):Promise>;
export function OpenDatabase(arg1:string,arg2:string):Promise>;
+export function RemoveHost(arg1:string):Promise;
+
export function RemoveItems(arg1:string,arg2:string,arg3:string,arg4:string,arg5:boolean):Promise;
export function UpdateItems(arg1:string,arg2:string,arg3:string,arg4:string):Promise;
diff --git a/frontend/wailsjs/go/app/App.js b/frontend/wailsjs/go/app/App.js
index 6885d66..e330223 100755
--- a/frontend/wailsjs/go/app/App.js
+++ b/frontend/wailsjs/go/app/App.js
@@ -2,6 +2,10 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
+export function AddHost(arg1) {
+ return window['go']['app']['App']['AddHost'](arg1);
+}
+
export function DropCollection(arg1, arg2, arg3) {
return window['go']['app']['App']['DropCollection'](arg1, arg2, arg3);
}
@@ -42,6 +46,10 @@ export function OpenDatabase(arg1, arg2) {
return window['go']['app']['App']['OpenDatabase'](arg1, arg2);
}
+export function RemoveHost(arg1) {
+ return window['go']['app']['App']['RemoveHost'](arg1);
+}
+
export function RemoveItems(arg1, arg2, arg3, arg4, arg5) {
return window['go']['app']['App']['RemoveItems'](arg1, arg2, arg3, arg4, arg5);
}
diff --git a/go.mod b/go.mod
index 3f3efc0..1ccb228 100644
--- a/go.mod
+++ b/go.mod
@@ -4,24 +4,14 @@ go 1.18
require github.com/wailsapp/wails/v2 v2.3.1
-require (
- github.com/golang/snappy v0.0.1 // indirect
- github.com/klauspost/compress v1.13.6 // indirect
- github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
- github.com/rogpeppe/go-internal v1.9.0 // indirect
- github.com/xdg-go/pbkdf2 v1.0.0 // indirect
- github.com/xdg-go/scram v1.1.1 // indirect
- github.com/xdg-go/stringprep v1.0.3 // indirect
- github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
- golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
-)
-
require (
github.com/bep/debounce v1.2.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
- github.com/google/uuid v1.1.2 // indirect
+ github.com/golang/snappy v0.0.1 // indirect
+ github.com/google/uuid v1.1.2
github.com/imdario/mergo v0.3.12 // indirect
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
+ github.com/klauspost/compress v1.13.6 // indirect
github.com/labstack/echo/v4 v4.9.0 // indirect
github.com/labstack/gommon v0.3.1 // indirect
github.com/leaanthony/go-ansi-parser v1.0.1 // indirect
@@ -29,17 +19,24 @@ require (
github.com/leaanthony/slicer v1.5.0 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
+ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 // indirect
github.com/pkg/errors v0.9.1 // indirect
+ github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/samber/lo v1.27.1 // indirect
github.com/tkrajina/go-reflector v0.5.5 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
github.com/wailsapp/mimetype v1.4.1 // indirect
+ github.com/xdg-go/pbkdf2 v1.0.0 // indirect
+ github.com/xdg-go/scram v1.1.1 // indirect
+ github.com/xdg-go/stringprep v1.0.3 // indirect
+ github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
go.mongodb.org/mongo-driver v1.11.1
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
+ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/text v0.3.7 // indirect
)
diff --git a/internal/app/host.go b/internal/app/host.go
deleted file mode 100644
index d5d2dff..0000000
--- a/internal/app/host.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package app
-
-import (
- "context"
- "errors"
- "fmt"
- "time"
-
- "github.com/wailsapp/wails/v2/pkg/runtime"
- "go.mongodb.org/mongo-driver/mongo"
- mongoOptions "go.mongodb.org/mongo-driver/mongo/options"
-)
-
-type Host struct {
- Name string `json:"name"`
- URI string `json:"uri"`
-}
-
-var hosts = map[string]Host{
- "localhost": {Name: "Localhost", URI: "mongodb://localhost:27017"},
- "tig": {Name: "cmdb.myinfra.nl"},
- "vbt": {Name: "vbtverhuurmakelaars.nl"},
-}
-
-func (a *App) Hosts() map[string]Host {
- return hosts
-}
-
-func (a *App) connectToHost(hostKey string) (*mongo.Client, context.Context, func(), error) {
- h := hosts[hostKey]
- if len(h.URI) == 0 {
- runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
- Type: runtime.InfoDialog,
- Title: "Invalid uri",
- Message: "You haven't specified a valid uri for the selected host.",
- })
- return nil, nil, nil, errors.New("invalid uri")
- }
-
- client, err := mongo.NewClient(mongoOptions.Client().ApplyURI(h.URI))
-
- if err != nil {
- fmt.Println(err.Error())
- runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
- Type: runtime.ErrorDialog,
- Title: "Could not connect",
- Message: "Failed to establish a connection with " + h.Name,
- })
- return nil, nil, nil, errors.New("could not establish a connection with " + h.Name)
- }
-
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
- client.Connect(ctx)
- return client, ctx, func() {
- client.Disconnect(ctx)
- cancel()
- }, nil
-}
diff --git a/internal/app/hosts.go b/internal/app/hosts.go
new file mode 100644
index 0000000..5cf4077
--- /dev/null
+++ b/internal/app/hosts.go
@@ -0,0 +1,190 @@
+package app
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "time"
+
+ "github.com/google/uuid"
+ "github.com/wailsapp/wails/v2/pkg/runtime"
+ "go.mongodb.org/mongo-driver/mongo"
+ mongoOptions "go.mongodb.org/mongo-driver/mongo/options"
+)
+
+// {
+// "3b7e3926-03ce-4407-bc3f-85ed2f01ee42": {
+// "name": "Localhost",
+// "uri": "mongodb://localhost:27017"
+// }
+// }
+
+type Host struct {
+ Name string `json:"name"`
+ URI string `json:"uri"`
+}
+
+func updateHostsFile(newData map[string]Host) error {
+ filePath, err := appDataFilePath("hosts.json")
+ if err != nil {
+ return err
+ }
+
+ jsonData, err := json.MarshalIndent(newData, "", "\t")
+ if err != nil {
+ return err
+ }
+
+ err = ioutil.WriteFile(filePath, jsonData, os.ModePerm)
+ return err
+}
+
+func (a *App) Hosts() (map[string]Host, error) {
+ filePath, err := appDataFilePath("hosts.json")
+ if err != nil {
+ fmt.Println(err.Error())
+ return nil, err
+ }
+
+ jsonData, err := ioutil.ReadFile(filePath)
+ if err != nil {
+ // It's ok if the file cannot be opened, for example if it is not accessible.
+ // Therefore no error is returned.
+ fmt.Println(err.Error())
+ return make(map[string]Host, 0), nil
+ }
+
+ if len(jsonData) == 0 {
+ return make(map[string]Host, 0), nil
+ } else {
+ var hosts map[string]Host
+ err = json.Unmarshal(jsonData, &hosts)
+
+ if err != nil {
+ fmt.Println(err.Error())
+ return nil, errors.New("host.json file contains malformatted JSON data")
+ }
+ return hosts, nil
+ }
+}
+
+func (a *App) AddHost(jsonData string) error {
+ hosts, err := a.Hosts()
+ if err != nil {
+ runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
+ Type: runtime.InfoDialog,
+ Title: "Could not retrieve hosts",
+ })
+ return errors.New("could not retrieve existing host list")
+ }
+
+ var newHost Host
+ err = json.Unmarshal([]byte(jsonData), &newHost)
+ if err != nil {
+ runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
+ Type: runtime.InfoDialog,
+ Title: "Malformed JSON",
+ })
+ return errors.New("could not retrieve existing host list")
+ }
+
+ id, err := uuid.NewRandom()
+ if err != nil {
+ runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
+ Type: runtime.InfoDialog,
+ Title: "Failed to generate a UUID",
+ })
+ return errors.New("could not generate a UUID")
+ }
+
+ fmt.Println(hosts)
+
+ hosts[id.String()] = newHost
+ err = updateHostsFile(hosts)
+ if err != nil {
+ runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
+ Type: runtime.InfoDialog,
+ Title: "Could not update host list",
+ })
+ return errors.New("could not update host list")
+ }
+
+ return nil
+}
+
+func (a *App) RemoveHost(key string) error {
+ hosts, err := a.Hosts()
+ if err != nil {
+ runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
+ Type: runtime.InfoDialog,
+ Title: "Could not retrieve hosts",
+ })
+ return errors.New("could not retrieve existing host list")
+ }
+
+ sure, _ := runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
+ Title: "Confirm",
+ Message: "Are you sure you want to remove " + key + "?",
+ Buttons: []string{"Yes", "No"},
+ DefaultButton: "Yes",
+ CancelButton: "No",
+ })
+ if sure != "Yes" {
+ return errors.New("operation aborted")
+ }
+
+ delete(hosts, key)
+ err = updateHostsFile(hosts)
+
+ if err != nil {
+ runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
+ Type: runtime.InfoDialog,
+ Title: "Could not update host list",
+ })
+ return errors.New("could not update host list")
+ }
+ return nil
+}
+
+func (a *App) connectToHost(hostKey string) (*mongo.Client, context.Context, func(), error) {
+ hosts, err := a.Hosts()
+ if err != nil {
+ runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
+ Type: runtime.InfoDialog,
+ Title: "Could not retrieve hosts",
+ })
+ return nil, nil, nil, errors.New("could not retrieve hosts")
+ }
+
+ h := hosts[hostKey]
+ if len(h.URI) == 0 {
+ runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
+ Type: runtime.InfoDialog,
+ Title: "Invalid uri",
+ Message: "You haven't specified a valid uri for the selected host.",
+ })
+ return nil, nil, nil, errors.New("invalid uri")
+ }
+
+ client, err := mongo.NewClient(mongoOptions.Client().ApplyURI(h.URI))
+
+ if err != nil {
+ fmt.Println(err.Error())
+ runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
+ Type: runtime.ErrorDialog,
+ Title: "Could not connect",
+ Message: "Failed to establish a connection with " + h.Name,
+ })
+ return nil, nil, nil, errors.New("could not establish a connection with " + h.Name)
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ client.Connect(ctx)
+ return client, ctx, func() {
+ client.Disconnect(ctx)
+ cancel()
+ }, nil
+}
diff --git a/internal/app/settings.go b/internal/app/settings.go
new file mode 100644
index 0000000..a4c8c56
--- /dev/null
+++ b/internal/app/settings.go
@@ -0,0 +1,37 @@
+package app
+
+import (
+ "errors"
+ "os"
+ "path/filepath"
+ "runtime"
+)
+
+func appDataDirectory() (string, error) {
+ var err error
+ homeDir, err := os.UserHomeDir()
+ prefDir := ""
+
+ switch runtime.GOOS {
+ case "windows":
+ prefDir = filepath.Join(homeDir, "/AppData/Local/Mongodup")
+ case "darwin":
+ prefDir = filepath.Join(homeDir, "/Library/Application Support/Mongodup")
+ case "linux":
+ prefDir = filepath.Join(homeDir, "/.config/Mongodup")
+ default:
+ err = errors.New("unsupported platform")
+ }
+
+ _ = os.MkdirAll(prefDir, os.ModePerm)
+ return prefDir, err
+}
+
+func appDataFilePath(filename string) (string, error) {
+ dir, err := appDataDirectory()
+ if err != nil {
+ return "", err
+ }
+ path := filepath.Join(dir, filename)
+ return path, nil
+}