Skip to content

Commit e1079b0

Browse files
feat: success toast with htmx trigger response
1 parent 92c0896 commit e1079b0

File tree

6 files changed

+112
-29
lines changed

6 files changed

+112
-29
lines changed

pkg/htmx/event.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package htmx
2+
3+
import (
4+
"encoding/json"
5+
"net/http"
6+
)
7+
8+
// Event
9+
10+
type Event struct {
11+
Key string
12+
Value any
13+
}
14+
15+
type Events []Event
16+
17+
func NewEventString(key string) Event {
18+
return Event{
19+
Key: key,
20+
}
21+
}
22+
23+
func NewEvent(key string, value any) Event {
24+
return Event{
25+
Key: key,
26+
Value: value,
27+
}
28+
}
29+
30+
func MultipleEvents(events ...Event) Events {
31+
return events
32+
}
33+
34+
func (e Event) String() string {
35+
if e.Value == nil {
36+
return e.Key
37+
}
38+
39+
slug := make(map[string]any)
40+
slug[e.Key] = e.Value
41+
42+
b, _ := json.Marshal(slug)
43+
return string(b)
44+
}
45+
46+
func (es Events) String() string {
47+
slug := make(map[string]any)
48+
for _, e := range es {
49+
if e.Value == nil {
50+
slug[e.Key] = ""
51+
} else {
52+
slug[e.Key] = e.Value
53+
}
54+
}
55+
56+
b, _ := json.Marshal(slug)
57+
return string(b)
58+
}
59+
60+
func (e Event) FromBody() string {
61+
return string(e.Key) + " from:body"
62+
}
63+
64+
func (e Event) SetTrigger(w http.ResponseWriter) {
65+
SetTrigger(w, e.String())
66+
}
67+
68+
func (e Event) SetTriggerAfterSettle(w http.ResponseWriter) {
69+
SetTriggerAfterSettle(w, e.String())
70+
}
71+
72+
func (e Event) SetTriggerAfterSwap(w http.ResponseWriter) {
73+
SetTriggerAfterSwap(w, e.String())
74+
}
75+
76+
func (es Events) SetTrigger(w http.ResponseWriter) {
77+
SetTrigger(w, es.String())
78+
}
79+
80+
func (es Events) SetTriggerAfterSettle(w http.ResponseWriter) {
81+
SetTriggerAfterSettle(w, es.String())
82+
}
83+
84+
func (es Events) SetTriggerAfterSwap(w http.ResponseWriter) {
85+
SetTriggerAfterSwap(w, es.String())
86+
}

pkg/htmx/htmx.go

-22
Original file line numberDiff line numberDiff line change
@@ -93,39 +93,17 @@ func SetReselect(w http.ResponseWriter) {
9393
w.Header().Set("HX-Reselect", "true")
9494
}
9595

96-
type Event string
97-
98-
// FromBody is used on the client side in the hx-trigger HTML attribute.
99-
func (e Event) FromBody() string {
100-
return string(e) + " from:body"
101-
}
102-
10396
// SetTrigger events as soon as the response is received.
10497
func SetTrigger(w http.ResponseWriter, event string) {
10598
w.Header().Set("HX-Trigger", event)
10699
}
107100

108-
// SetTrigger events as soon as the response is received.
109-
func (e Event) SetTrigger(w http.ResponseWriter) {
110-
SetTrigger(w, string(e))
111-
}
112-
113101
// SetTriggerAfterSettle events after the settling step.
114102
func SetTriggerAfterSettle(w http.ResponseWriter, event string) {
115103
w.Header().Set("HX-Trigger-After-Settle", event)
116104
}
117105

118-
// SetTriggerAfterSettle events after the settling step.
119-
func (e Event) SetTriggerAfterSettle(w http.ResponseWriter) {
120-
SetTriggerAfterSettle(w, string(e))
121-
}
122-
123106
// SetTriggerAfterSwap events after the swap step.
124107
func SetTriggerAfterSwap(w http.ResponseWriter, event string) {
125108
w.Header().Set("HX-Trigger-After-Swap", event)
126109
}
127-
128-
// SetTriggerAfterSwap events after the swap step.
129-
func (e Event) SetTriggerAfterSwap(w http.ResponseWriter) {
130-
SetTriggerAfterSwap(w, string(e))
131-
}

web/events/events.go

+8-6
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22
package events
33

44
import (
5-
"fmt"
6-
75
"github.com/ItsNotGoodName/smtpbridge/pkg/htmx"
86
)
97

10-
const (
11-
EnvelopeCreated htmx.Event = "envelope-created"
12-
RetentionPolicyRun htmx.Event = "retention-policy-run"
8+
var (
9+
EnvelopeCreated htmx.Event = htmx.NewEventString("envelope-created")
10+
RetentionPolicyRun htmx.Event = htmx.NewEventString("retention-policy-run")
1311
)
1412

1513
func CSRFToken(csrfToken string) htmx.Event {
16-
return htmx.Event(fmt.Sprintf(`{ "csrfToken": "%s" }`, csrfToken))
14+
return htmx.NewEvent("csrfToken", csrfToken)
15+
}
16+
17+
func ToastSuccess(toast string) htmx.Event {
18+
return htmx.NewEvent("toast", toast)
1719
}

web/pages/pages.go

-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,6 @@ func EnvelopeCreate(ct Controller, app core.App) http.HandlerFunc {
282282
handleErr(w, r, err, form)
283283
return
284284
}
285-
286285
helpers.Tracer(app, r).Trace(ctx, trace.ActionEnvelopeCreated, trace.WithEnvelope(id))
287286

288287
events.EnvelopeCreated.SetTrigger(w)

web/pages/pages_endpoint.go

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/ItsNotGoodName/smtpbridge/internal/models"
88
"github.com/ItsNotGoodName/smtpbridge/pkg/htmx"
99
c "github.com/ItsNotGoodName/smtpbridge/web/components"
10+
"github.com/ItsNotGoodName/smtpbridge/web/events"
1011
"github.com/ItsNotGoodName/smtpbridge/web/forms"
1112
"github.com/ItsNotGoodName/smtpbridge/web/helpers"
1213
"github.com/ItsNotGoodName/smtpbridge/web/routes"
@@ -262,6 +263,7 @@ func EndpointTest(ct Controller, app core.App) http.HandlerFunc {
262263
return
263264
}
264265

266+
events.ToastSuccess("Sent test envelope.").SetTrigger(w)
265267
w.WriteHeader(http.StatusNoContent)
266268
})
267269
}

web/src/main.ts

+16
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ document.body.addEventListener('htmx:afterRequest', function(evt: any) {
4343
}
4444
})
4545

46+
document.body.addEventListener("toast", function(evt: any) {
47+
const content = document.createElement("div")
48+
content.textContent = evt.detail.value
49+
content.className = "flex-1"
50+
51+
Toastify({
52+
node: content,
53+
duration: 3000,
54+
close: true,
55+
className: "alert alert-success flex flex-row",
56+
gravity: "bottom",
57+
position: "center",
58+
stopOnFocus: true,
59+
}).showToast();
60+
})
61+
4662
// ------------- Shoelace
4763

4864
// 24 Kb to format dates in local time

0 commit comments

Comments
 (0)