Skip to content
This repository was archived by the owner on Sep 2, 2024. It is now read-only.

Commit 2be63da

Browse files
committed
added way to see form submission in the UI close #14
1 parent 65458a8 commit 2be63da

File tree

6 files changed

+218
-36
lines changed

6 files changed

+218
-36
lines changed

form.go

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010

1111
"go.mongodb.org/mongo-driver/bson"
1212
"go.mongodb.org/mongo-driver/bson/primitive"
13-
"go.mongodb.org/mongo-driver/mongo/options"
1413
)
1514

1615
func submitForm(w http.ResponseWriter, r *http.Request) {
@@ -67,47 +66,15 @@ func listForm(w http.ResponseWriter, r *http.Request) {
6766
return
6867
}
6968

70-
db := client.Database(conf.Name)
71-
72-
opt := options.Find()
73-
opt.SetLimit(100)
74-
opt.SetSort(bson.M{internal.FieldID: -1})
69+
curDB := client.Database(conf.Name)
7570

76-
filter := bson.M{}
77-
if fn := r.URL.Query().Get("name"); len(fn) > 0 {
78-
filter["form"] = fn
79-
}
71+
formName := r.URL.Query().Get("name")
8072

81-
cur, err := db.Collection("sb_forms").Find(context.Background(), filter, opt)
73+
results, err := internal.ListFormSubmissions(curDB, formName)
8274
if err != nil {
8375
http.Error(w, err.Error(), http.StatusInternalServerError)
8476
return
8577
}
86-
defer cur.Close(context.Background())
87-
88-
var results []bson.M
89-
90-
for cur.Next(context.Background()) {
91-
var result bson.M
92-
err := cur.Decode(&result)
93-
if err != nil {
94-
http.Error(w, err.Error(), http.StatusInternalServerError)
95-
return
96-
}
97-
98-
result["id"] = result["_id"]
99-
delete(result, internal.FieldID)
100-
101-
results = append(results, result)
102-
}
103-
if err := cur.Err(); err != nil {
104-
http.Error(w, err.Error(), http.StatusInternalServerError)
105-
return
106-
}
107-
108-
if len(results) == 0 {
109-
results = make([]bson.M, 1)
110-
}
11178

11279
respond(w, http.StatusOK, results)
11380
}

internal/form.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package internal
2+
3+
import (
4+
"fmt"
5+
6+
"go.mongodb.org/mongo-driver/bson"
7+
"go.mongodb.org/mongo-driver/mongo"
8+
"go.mongodb.org/mongo-driver/mongo/options"
9+
)
10+
11+
func ListFormSubmissions(db *mongo.Database, name string) ([]bson.M, error) {
12+
opt := options.Find()
13+
opt.SetLimit(100)
14+
opt.SetSort(bson.M{FieldID: -1})
15+
16+
filter := bson.M{}
17+
if len(name) > 0 {
18+
filter["form"] = name
19+
}
20+
21+
cur, err := db.Collection("sb_forms").Find(ctx, filter, opt)
22+
if err != nil {
23+
return nil, err
24+
}
25+
defer cur.Close(ctx)
26+
27+
var results []bson.M
28+
for cur.Next(ctx) {
29+
var result bson.M
30+
if err := cur.Decode(&result); err != nil {
31+
return nil, err
32+
}
33+
34+
result["id"] = result[FieldID]
35+
delete(result, FieldID)
36+
37+
results = append(results, result)
38+
}
39+
if err := cur.Err(); err != nil {
40+
return nil, err
41+
}
42+
43+
if len(results) == 0 {
44+
results = make([]bson.M, 1)
45+
}
46+
47+
return results, nil
48+
}
49+
50+
func GetForms(db *mongo.Database) ([]string, error) {
51+
pipeline := mongo.Pipeline{bson.D{{"$group", bson.D{{"_id", "$form"}}}}}
52+
cur, err := db.Collection("sb_forms").Aggregate(ctx, pipeline)
53+
if err != nil {
54+
return nil, err
55+
}
56+
defer cur.Close(ctx)
57+
58+
var names []string
59+
for cur.Next(ctx) {
60+
var form bson.M
61+
if err := cur.Decode(&form); err != nil {
62+
return nil, err
63+
}
64+
65+
names = append(names, fmt.Sprintf("%v", form[FieldID]))
66+
}
67+
68+
if err := cur.Err(); err != nil {
69+
return nil, err
70+
}
71+
72+
if len(names) == 0 {
73+
names = make([]string, 1)
74+
}
75+
76+
return names, nil
77+
}

render.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import (
66
"log"
77
"net/http"
88
"os"
9+
"strconv"
910
"strings"
11+
"time"
1012

1113
"go.mongodb.org/mongo-driver/bson"
1214
"go.mongodb.org/mongo-driver/bson/primitive"
@@ -116,6 +118,19 @@ func customFuncs() template.FuncMap {
116118
if ok {
117119
return oid.Hex()
118120
}
121+
122+
date, ok := dict[s].(time.Time)
123+
if ok {
124+
return date.Format("2006-01-02 15:04")
125+
}
126+
127+
if s == "sb_posted" {
128+
i, err := strconv.ParseInt(fmt.Sprintf("%v", dict[s]), 10, 64)
129+
if err == nil {
130+
ts := time.Unix(i/1000, 0)
131+
return ts.Format("2006-01-02 15:04")
132+
}
133+
}
119134
return fmt.Sprintf("%v", v)
120135
},
121136
}

server.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ func Start(dbHost, port string) {
145145
http.Handle("/ui/db/save", middleware.Chain(http.HandlerFunc(webUI.dbSave), stdRoot...))
146146
http.Handle("/ui/db/del/", middleware.Chain(http.HandlerFunc(webUI.dbDel), stdRoot...))
147147
http.Handle("/ui/db/", middleware.Chain(http.HandlerFunc(webUI.dbDoc), stdRoot...))
148+
http.Handle("/ui/forms", middleware.Chain(http.HandlerFunc(webUI.forms), stdRoot...))
149+
http.Handle("/ui/forms/del/", middleware.Chain(http.HandlerFunc(webUI.formDel), stdRoot...))
148150
http.HandleFunc("/", webUI.login)
149151

150152
log.Fatal(http.ListenAndServe(":"+port, nil))

templates/forms.html

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{{ template "head" .}}
2+
3+
<body>
4+
{{template "navbar" .}}
5+
6+
<div class="container p-6">
7+
<h2 class="title is-2">
8+
Form submissions
9+
</h2>
10+
<p class="subtitle is-5">
11+
<div class="dropdown is-active" x-data="{isOpen: false}">
12+
<div class="dropdown-trigger">
13+
<button @click="isOpen = !isOpen" class="button" aria-haspopup="true" aria-controls="dropdown-menu">
14+
<span>
15+
{{if .Data.FormName}}
16+
{{.Data.FormName}}
17+
{{else}}
18+
All forms
19+
{{end}}
20+
</span>
21+
<span class="icon is-small">
22+
<i class="fas fa-angle-down" aria-hidden="true"></i>
23+
</span>
24+
</button>
25+
</div>
26+
<div x-show="isOpen" class="dropdown-menu" id="dropdown-menu" role="menu">
27+
<div class="dropdown-content">
28+
<a href="/ui/forms" class="dropdown-item">
29+
All forms
30+
</a>
31+
{{range .Data.Forms}}
32+
<a href="/ui/forms?fn={{.}}" class="dropdown-item">
33+
{{.}}
34+
</a>
35+
{{end}}
36+
</div>
37+
</div>
38+
</div>
39+
<span class="pl-3">filter for a specifics form</span>
40+
</p>
41+
42+
{{range .Data.Entries}}
43+
<div class="box py-3">
44+
<div class="columns is-multiline">
45+
<div class="column">
46+
<a href='/ui/forms/del/{{getField "id" .}}' class="delete"
47+
onclick="return confirm('Are you sure you want to delete this form submission?\n\nThis is irreversible.')">
48+
</a>
49+
</div>
50+
{{$doc := .}}
51+
{{range $key, $val := .}}
52+
{{if eq $key "id"}}
53+
{{else}}
54+
<div class="column">
55+
<strong>{{$key}}</strong><br />
56+
{{getField $key $doc}}
57+
</div>
58+
{{end}}
59+
{{end}}
60+
</div>
61+
</div>
62+
{{end}}
63+
</div>
64+
</body>
65+
66+
{{template "foot"}}

ui.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,58 @@ func (ui) readColumnNames(docs []interface{}) []string {
319319

320320
return columns
321321
}
322+
323+
func (x ui) forms(w http.ResponseWriter, r *http.Request) {
324+
conf, _, err := middleware.Extract(r, false)
325+
if err != nil {
326+
renderErr(w, r, err)
327+
return
328+
}
329+
330+
formName := r.URL.Query().Get("fn")
331+
332+
curDB := client.Database(conf.Name)
333+
334+
forms, err := internal.GetForms(curDB)
335+
if err != nil {
336+
renderErr(w, r, err)
337+
return
338+
}
339+
340+
entries, err := internal.ListFormSubmissions(curDB, formName)
341+
if err != nil {
342+
renderErr(w, r, err)
343+
return
344+
}
345+
346+
var data = new(struct {
347+
FormName string
348+
Forms []string
349+
Entries []bson.M
350+
})
351+
352+
data.FormName = formName
353+
data.Forms = forms
354+
data.Entries = entries
355+
356+
render(w, r, "forms.html", data, nil)
357+
}
358+
359+
func (x ui) formDel(w http.ResponseWriter, r *http.Request) {
360+
conf, auth, err := middleware.Extract(r, true)
361+
if err != nil {
362+
renderErr(w, r, err)
363+
return
364+
}
365+
366+
curDB := client.Database(conf.Name)
367+
368+
id := getURLPart(r.URL.Path, 4)
369+
370+
if _, err := x.base.Delete(auth, curDB, "sb_forms", id); err != nil {
371+
renderErr(w, r, err)
372+
return
373+
}
374+
375+
http.Redirect(w, r, "/ui/forms", http.StatusSeeOther)
376+
}

0 commit comments

Comments
 (0)