aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/index/index.go8
-rw-r--r--pkg/site/site.go8
-rw-r--r--web/command/handler/delete.go57
-rw-r--r--web/command/html/delete.go58
-rw-r--r--web/command/html/flags.go3
-rw-r--r--web/command/html/home.go19
-rw-r--r--web/command/html/site.go10
-rw-r--r--web/command/html/style.css12
-rw-r--r--web/mux.go2
9 files changed, 171 insertions, 6 deletions
diff --git a/pkg/index/index.go b/pkg/index/index.go
index f3dc00d..f741708 100644
--- a/pkg/index/index.go
+++ b/pkg/index/index.go
@@ -55,6 +55,14 @@ func (s *SiteIndex) AddSite(site *site.Site) {
s.updateSiteIndexes()
}
+func (s *SiteIndex) RemoveSite(name string) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ delete(s.sites, name)
+ s.updateSiteIndexes()
+}
+
func (s *SiteIndex) UpdateSiteIndexes() {
s.mu.Lock()
defer s.mu.Unlock()
diff --git a/pkg/site/site.go b/pkg/site/site.go
index 704c34d..82f25ad 100644
--- a/pkg/site/site.go
+++ b/pkg/site/site.go
@@ -8,6 +8,7 @@ import (
"path"
"path/filepath"
"regexp"
+ "slices"
"strings"
"time"
@@ -92,6 +93,10 @@ func (s *Site) UpdateVersion(newVersion string) error {
return os.Symlink(newVersion, currentVersionPath)
}
+func (s *Site) DeleteDataOnDisk() error {
+ return os.RemoveAll(s.Path)
+}
+
func (s *Site) GetAllVersions() ([]string, error) {
entries, err := os.ReadDir(s.Path)
@@ -116,6 +121,9 @@ func (s *Site) GetAllVersions() ([]string, error) {
}
}
+ slices.Sort(versions)
+ slices.Reverse(versions)
+
return versions, err
}
diff --git a/web/command/handler/delete.go b/web/command/handler/delete.go
new file mode 100644
index 0000000..f95e278
--- /dev/null
+++ b/web/command/handler/delete.go
@@ -0,0 +1,57 @@
+package handler
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/LMBishop/scrapbook/pkg/config"
+ "github.com/LMBishop/scrapbook/pkg/index"
+ "github.com/LMBishop/scrapbook/web/command/html"
+ . "maragu.dev/gomponents"
+ ghttp "maragu.dev/gomponents/http"
+)
+
+func GetDelete(index *index.SiteIndex) func(http.ResponseWriter, *http.Request) {
+ return ghttp.Adapt(func(w http.ResponseWriter, r *http.Request) (Node, error) {
+ siteName := r.PathValue("site")
+ if siteName == "" {
+ return html.ErrorPage("Unknown site: " + siteName), nil
+ }
+ site := index.GetSite(siteName)
+ if site == nil {
+ return html.ErrorPage("Unknown site: " + siteName), nil
+ }
+
+ return html.DeletePage("", "", siteName), nil
+ })
+}
+
+func PostDelete(mainConfig *config.MainConfig, index *index.SiteIndex) func(http.ResponseWriter, *http.Request) {
+ return ghttp.Adapt(func(w http.ResponseWriter, r *http.Request) (Node, error) {
+ siteName := r.PathValue("site")
+ if siteName == "" {
+ return html.ErrorPage("Unknown site: " + siteName), nil
+ }
+ site := index.GetSite(siteName)
+ if site == nil {
+ return html.ErrorPage("Unknown site: " + siteName), nil
+ }
+
+ err := r.ParseForm()
+ if err != nil {
+ return html.DeletePage("", fmt.Errorf("Could not parse form: %w", err).Error(), siteName), nil
+ }
+
+ if r.FormValue("delete") != "on" {
+ return html.DeletePage("", "You need to check the box to continue", siteName), nil
+ }
+
+ err = site.DeleteDataOnDisk()
+ if err != nil {
+ return html.DeletePage("", fmt.Errorf("Error occurred during data deletion: %w", err).Error(), siteName), nil
+ }
+ index.RemoveSite(siteName)
+
+ return html.DeletePage(fmt.Sprintf("Successfully deleted site %s", siteName), "", siteName), nil
+ })
+}
diff --git a/web/command/html/delete.go b/web/command/html/delete.go
new file mode 100644
index 0000000..a2059f5
--- /dev/null
+++ b/web/command/html/delete.go
@@ -0,0 +1,58 @@
+package html
+
+import (
+ "fmt"
+
+ . "maragu.dev/gomponents"
+ . "maragu.dev/gomponents/html"
+)
+
+func DeletePage(success, err string, siteName string) Node {
+ return page("Delete "+siteName,
+ H1(Text("Delete "+siteName)),
+
+ If(success != "", Group{
+ alertSuccess(success),
+ Div(
+ Class("control-group group-right"),
+ navButton("OK", "/"),
+ ),
+ }),
+
+ If(success == "", Group{
+ If(err != "", alertError(err)),
+
+ Form(
+ Method("post"),
+
+ FieldSet(
+ Legend(Text("Delete")),
+ Span(
+ Input(
+ ID("delete"),
+ Name("delete"),
+ Type("checkbox"),
+ ),
+ Label(
+ For("delete"),
+ Text(fmt.Sprintf("Really delete site %s?", siteName)),
+ ),
+ ),
+ Span(
+ Class("form-help"),
+ Text("Check the box to confirm deletion. Data on disk (including all site versions) will be deleted. This action is irreversible."),
+ ),
+ ),
+
+ Div(
+ Class("control-group group-right"),
+ navButton("Go back", fmt.Sprintf("/site/%s/", siteName)),
+ Input(
+ Type("submit"),
+ Value("Submit"),
+ ),
+ ),
+ ),
+ }),
+ )
+}
diff --git a/web/command/html/flags.go b/web/command/html/flags.go
index a7fb99f..728b415 100644
--- a/web/command/html/flags.go
+++ b/web/command/html/flags.go
@@ -52,6 +52,7 @@ func FlagsPage(success, err string, siteName string, flags config.SiteFlag) Node
ID("tls"),
Name("tls"),
Type("checkbox"),
+ Disabled(),
If(flags&config.FlagTLS != 0, Checked()),
),
Label(
@@ -69,6 +70,7 @@ func FlagsPage(success, err string, siteName string, flags config.SiteFlag) Node
ID("index"),
Name("index"),
Type("checkbox"),
+ Disabled(),
If(flags&config.FlagIndex != 0, Checked()),
),
Label(
@@ -86,6 +88,7 @@ func FlagsPage(success, err string, siteName string, flags config.SiteFlag) Node
ID("password"),
Name("password"),
Type("checkbox"),
+ Disabled(),
If(flags&config.FlagPassword != 0, Checked()),
),
Label(
diff --git a/web/command/html/home.go b/web/command/html/home.go
index b9d585c..5dc236a 100644
--- a/web/command/html/home.go
+++ b/web/command/html/home.go
@@ -33,7 +33,13 @@ func HomePage(siteIndex *index.SiteIndex) Node {
Text("Actions"),
),
},
+
Map(siteIndex.GetSites(), func(site *site.Site) Node {
+ status := site.EvaluateSiteStatus()
+ good := false
+ if status == "live" {
+ good = true
+ }
return Group{
Span(
Class("name"),
@@ -42,8 +48,9 @@ func HomePage(siteIndex *index.SiteIndex) Node {
If(site.SiteConfig.Host != "", Span(Text(fmt.Sprintf("on %s", site.SiteConfig.Host)))),
),
Span(
- Class("status"),
- Text(site.EvaluateSiteStatus()),
+ If(good, Class("status text-good")),
+ If(!good, Class("status text-bad")),
+ Text(status),
),
Span(
Class("flags"),
@@ -57,6 +64,12 @@ func HomePage(siteIndex *index.SiteIndex) Node {
}),
),
- navButton("Create new", "/create"),
+ If(len(siteIndex.GetSites()) == 0, alert("There are no sites to display", "")),
+
+ Div(
+ Class("control-group group-right"),
+
+ navButton("Create new", "/create"),
+ ),
)
}
diff --git a/web/command/html/site.go b/web/command/html/site.go
index 7da9dc0..b3e0cc1 100644
--- a/web/command/html/site.go
+++ b/web/command/html/site.go
@@ -24,9 +24,8 @@ func SitePage(mainConfig *config.MainConfig, site *site.Site) Node {
Div(
Class("control-group"),
- navButton("Upload new version", "upload"),
- navButton("Set flags", "flags"),
navButton("Change host", "host"),
+ navButton("Set flags", "flags"),
navButton("Delete site", "delete"),
),
),
@@ -64,6 +63,11 @@ func SitePage(mainConfig *config.MainConfig, site *site.Site) Node {
}
}),
),
+ Div(
+ Class("control-group group-right"),
+
+ navButton("Upload new version", "upload"),
+ ),
}),
H2(Text("Information")),
@@ -72,6 +76,8 @@ func SitePage(mainConfig *config.MainConfig, site *site.Site) Node {
P(Text("Data directory on system: "), Code(Text(site.Path))),
+ Br(),
+
navButton("Go back", "/"),
)
}
diff --git a/web/command/html/style.css b/web/command/html/style.css
index fbefaa1..e8db90c 100644
--- a/web/command/html/style.css
+++ b/web/command/html/style.css
@@ -126,6 +126,8 @@ a:hover, button:hover, input[type=submit]:hover, button:active, a:active, input[
}
.sites-table > .actions, .versions-table > .actions {
+ display: flex;
+ gap: 0.5rem;
justify-self: flex-end;
}
@@ -149,7 +151,7 @@ a:hover, button:hover, input[type=submit]:hover, button:active, a:active, input[
}
.versions-table > .date > .current {
- color: #2ECC40;
+ color: #0dbe22;
font-size: smaller;
font-style: italic;
}
@@ -170,4 +172,12 @@ a:hover, button:hover, input[type=submit]:hover, button:active, a:active, input[
.alert.error {
background-color: #ffcccb;
border: 1px solid #ff6666;
+}
+
+.text-good {
+ color: #0dbe22;
+}
+
+.text-bad {
+ color: #c02020;
} \ No newline at end of file
diff --git a/web/mux.go b/web/mux.go
index 439eaa0..e3ad8d4 100644
--- a/web/mux.go
+++ b/web/mux.go
@@ -25,6 +25,8 @@ func NewMux(cfg *config.MainConfig, siteIndex *index.SiteIndex, authenticator *a
mux.HandleFunc("POST /site/{site}/flags", middleware.MustAuthenticate(authenticator, handler.PostFlags(cfg, siteIndex)))
mux.HandleFunc("GET /site/{site}/host", middleware.MustAuthenticate(authenticator, handler.GetHost(siteIndex)))
mux.HandleFunc("POST /site/{site}/host", middleware.MustAuthenticate(authenticator, handler.PostHost(cfg, siteIndex)))
+ mux.HandleFunc("GET /site/{site}/delete", middleware.MustAuthenticate(authenticator, handler.GetDelete(siteIndex)))
+ mux.HandleFunc("POST /site/{site}/delete", middleware.MustAuthenticate(authenticator, handler.PostDelete(cfg, siteIndex)))
return mux
}