settings: add option for website title

This commit is contained in:
Maxi Quoß
2023-01-28 16:29:32 +01:00
parent 0ef4b4ac02
commit 8f76628e15
10 changed files with 159 additions and 50 deletions

View File

@@ -38,7 +38,7 @@ Open up [http://localhost:5173/](http://localhost:5173/)
- [x] ~~theme toggle button~~
- [x] ~~add device ports to cards~~
- [ ] settings: add network scan
- [ ] settings: add option for website title
- [x] settings: add option for website title
- backend

View File

@@ -3,7 +3,6 @@ module github.com/seriousm4x/upsnap/backend
go 1.19
require (
github.com/Ullaakut/nmap/v2 v2.2.2
github.com/go-ping/ping v1.1.0
github.com/labstack/echo/v5 v5.0.0-20220201181537-ed2888cfa198
github.com/mdlayher/wol v0.0.0-20220221231636-b763a792253a
@@ -59,7 +58,6 @@ require (
github.com/mdlayher/packet v1.0.0 // indirect
github.com/mdlayher/socket v0.2.1 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/cobra v1.6.1 // indirect

View File

@@ -481,8 +481,6 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/Ullaakut/nmap/v2 v2.2.2 h1:178Ety3d8T21sF6WZxyj7QVZUhnC1tL1J+tHLLW507Q=
github.com/Ullaakut/nmap/v2 v2.2.2/go.mod h1:/6YyiW1Rgn7J6DAWCgL4CZZf6zJCFhB07PQzvjFfzLI=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -1565,7 +1563,6 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=

View File

@@ -0,0 +1,48 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("nmj3ko20gzkg8n3")
if err != nil {
return err
}
// remove
collection.Schema.RemoveField("7ehvglvv")
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("nmj3ko20gzkg8n3")
if err != nil {
return err
}
// add
del_notifications := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "7ehvglvv",
"name": "notifications",
"type": "bool",
"required": false,
"unique": false,
"options": {}
}`), del_notifications)
collection.Schema.AddField(del_notifications)
return dao.SaveCollection(collection)
})
}

View File

@@ -0,0 +1,52 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("nmj3ko20gzkg8n3")
if err != nil {
return err
}
// add
new_website_title := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "slrjkipw",
"name": "website_title",
"type": "text",
"required": false,
"unique": false,
"options": {
"min": null,
"max": null,
"pattern": ""
}
}`), new_website_title)
collection.Schema.AddField(new_website_title)
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("nmj3ko20gzkg8n3")
if err != nil {
return err
}
// remove
collection.Schema.RemoveField("slrjkipw")
return dao.SaveCollection(collection)
})
}

View File

@@ -4,7 +4,6 @@ import (
"log"
"net/http"
"os"
"strconv"
"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase"
@@ -130,7 +129,7 @@ func importSettings() error {
settings = settingsRecords[0]
}
// set ping interval and notification settings. priority:
// set ping interval settings. priority:
// 1st: env var
// 2nd: database entry
// 3rd: default values
@@ -141,31 +140,20 @@ func importSettings() error {
if os.Getenv("UPSNAP_INTERVAL") != "" {
interval = os.Getenv("UPSNAP_INTERVAL")
}
notifications := true
if settings.GetBool("notifications") {
notifications = settings.GetBool("notifications")
}
if os.Getenv("UPSNAP_NOTIFICATIONS") != "" {
notificationsParsed, err := strconv.ParseBool(os.Getenv("UPSNAP_NOTIFICATIONS"))
if err != nil {
return err
} else {
notifications = notificationsParsed
}
}
// save settings to db
settings.Set("interval", interval)
settings.Set("notifications", notifications)
if scanRange := os.Getenv("UPSNAP_SCAN_RANGE"); scanRange != "" {
settings.Set("scan_range", scanRange)
}
if scanRange := os.Getenv("UPSNAP_WEBSITE_TITLE"); scanRange != "" {
settings.Set("website_title", scanRange)
}
if err := App.Dao().SaveRecord(settings); err != nil {
return err
}
logger.Info.Println("Ping interval set to", interval)
logger.Info.Println("Notifications set to", notifications)
return nil
}

View File

@@ -4,7 +4,6 @@
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
<title>UpSnap</title>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" class="h-100">

View File

@@ -1,14 +1,46 @@
<script>
import { page } from '$app/stores';
import { theme } from '@stores/theme';
import { pocketbase } from '@stores/pocketbase';
import { faSun, faMoon, faCircleHalfStroke, faBrush } from '@fortawesome/free-solid-svg-icons';
import Fa from 'svelte-fa';
import { onMount } from 'svelte';
let pb;
let website_title = '';
onMount(async () => {
pocketbase.subscribe((conn) => {
pb = conn;
});
const result = await pb.collection('settings').getList(1, 1);
website_title = result.items[0].website_title;
pb.collection('settings').subscribe('*', function (e) {
website_title = e.record.website_title;
document.title = website_title;
});
});
</script>
<svelte:head>
{#if website_title !== ''}
<title>{website_title}</title>
{:else}
<title>UpSnap</title>
{/if}
</svelte:head>
<nav class="navbar navbar-expand">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<img src="/favicon.png" alt="UpSnap" width="30" height="30" />
<img
src="/favicon.png"
alt="UpSnap"
width="30"
height="30"
class:me-2={website_title !== ''}
/>{website_title ? website_title : ''}
</a>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">

View File

@@ -1,9 +1,9 @@
<script>
import { onMount } from 'svelte';
import Navbar from '@components/Navbar.svelte';
import Transition from '@components/Transition.svelte';
import { page } from '$app/stores';
import { theme } from '@stores/theme';
import Navbar from '@components/Navbar.svelte';
import Transition from '@components/Transition.svelte';
let preferesDark;

View File

@@ -50,10 +50,7 @@
if (settings.interval === '') {
settings.interval = '@every 3s';
}
await pb.collection('settings').update(settings.id, {
interval: settings.interval,
notifications: settings.notifications
});
await pb.collection('settings').update(settings.id, settings);
clearTimeout(timeout);
timeout = setTimeout(() => {
buttons.settings.state = 'none';
@@ -159,6 +156,19 @@
bind:value={settings.interval}
/>
</div>
<h3 class="my-3">Website title</h3>
<p>Set the website title in the navbar.</p>
<div class="input-group mb-3">
<span class="input-group-text" id="website-title">Title</span>
<input
type="text"
class="form-control"
placeholder="e.g. 'UpSnap'"
aria-label="Website title"
aria-describedby="website-title"
bind:value={settings.website_title}
/>
</div>
</div>
<div class="col-md-6">
<div class="callout callout-info m-0">
@@ -178,23 +188,9 @@
</div>
</div>
</div>
<h3 class="my-3">Notifications</h3>
<p>Show toast notifications in the bottom right corner.</p>
<div class="form-check form-switch">
<label class="form-check-label" for="settings-notifications"
>Enable notifications</label
>
<input
class="form-check-input"
type="checkbox"
id="settings-notifications"
role="switch"
bind:checked={settings.notifications}
/>
</div>
<button
type="submit"
class="btn btn-secondary mt-3"
class="btn btn-secondary"
class:btn-success={buttons.settings.state === 'success' ? true : false}
class:btn-warning={buttons.settings.state === 'waiting' ? true : false}
class:btn-danger={buttons.settings.state === 'failed' ? true : false}
@@ -219,17 +215,16 @@
</p>
<div class="callout callout-danger fw-bold">This will wipe the existing database!</div>
<input
class="form-control"
placeholder="Username"
aria-label="Username"
aria-describedby="addon-wrapping"
class="form-control mb-3"
aria-label="Restore"
aria-describedby="Restore"
type="file"
accept=".json"
bind:files
/>
<button
type="button"
class="btn btn-secondary mt-3"
class="btn btn-secondary"
class:btn-success={buttons.restore.state === 'success' ? true : false}
class:btn-warning={buttons.restore.state === 'waiting' ? true : false}
class:btn-danger={buttons.restore.state === 'failed' ? true : false}