Monorepo for Tangled

appview: allows a default knot to be selected from knots available to the user

Signed-off-by: Will Andrews <will7989@hotmail.com>

+49 -28
+13 -5
appview/knots/knots.go
··· 81 81 return 82 82 } 83 83 84 + availableKnots, err := k.Enforcer.GetKnotsForUser(user.Did()) 85 + if err != nil { 86 + k.Logger.Error("failed to fetch available knots for user", "err", err) 87 + w.WriteHeader(http.StatusInternalServerError) 88 + return 89 + } 90 + 84 91 defaultKnot := "" 85 92 profile, err := db.GetProfile(k.Db, user.Did()) 86 93 if err != nil { ··· 91 98 } 92 99 93 100 k.Pages.Knots(w, pages.KnotsParams{ 94 - LoggedInUser: user, 95 - Registrations: registrations, 96 - Tabs: knotsTabs, 97 - Tab: "knots", 98 - DefaultKnot: defaultKnot, 101 + LoggedInUser: user, 102 + Registrations: registrations, 103 + Tabs: knotsTabs, 104 + Tab: "knots", 105 + AvailableKnots: availableKnots, 106 + DefaultKnot: defaultKnot, 99 107 }) 100 108 } 101 109
+6 -5
appview/pages/pages.go
··· 417 417 } 418 418 419 419 type KnotsParams struct { 420 - LoggedInUser *oauth.MultiAccountUser 421 - Registrations []models.Registration 422 - Tabs []map[string]any 423 - Tab string 424 - DefaultKnot string 420 + LoggedInUser *oauth.MultiAccountUser 421 + Registrations []models.Registration 422 + Tabs []map[string]any 423 + Tab string 424 + AvailableKnots []string 425 + DefaultKnot string 425 426 } 426 427 427 428 func (p *Pages) Knots(w io.Writer, params KnotsParams) error {
+21 -17
appview/pages/templates/knots/index.html
··· 64 64 {{ end }} 65 65 66 66 {{ define "default-knot" }} 67 - <section class="rounded w-full flex flex-col gap-2"> 68 - <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300">default knot</h2> 69 - <select id="default-knot" name="default-knot" 70 - class="p-1 max-w-64 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700" 71 - hx-post="/profile/default-knot" 72 - hx-swap="none" 73 - name="default-knot"> 74 - <option value="" > 75 - Choose a default Knot 76 - </option> 77 - <option value="knot1.tangled.sh" {{if eq $.DefaultKnot "knot1.tangled.sh"}}selected{{end}} > 78 - knot1.tangled.sh 79 - </option> 80 - {{ range $registration := .Registrations }} 81 - <option value="{{ .Domain }}" class="py-1" {{if eq $.DefaultKnot .Domain}}selected{{end}}> 82 - {{ .Domain }} 67 + <section class="rounded w-full flex flex-col gap-2"> 68 + <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300">default knot</h2> 69 + <form hx-post="/profile/default-knot" class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch"> 70 + <select 71 + id="default-knot" 72 + name="default-knot" 73 + required 74 + class="p-1 max-w-64 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"> 75 + {{/* For some reason, we can't use an empty string in a <select> in all scenarios unless it is preceded by a disabled select?? No idea, could just be a Firefox thing? */}} 76 + <option value="[[none]]" class="py-1" {{ if not $.DefaultKnot }}selected{{ end }}> 77 + Choose a default knot 78 + </option> 79 + {{ range $.AvailableKnots }} 80 + <option value="{{ . }}" class="py-1" {{ if eq . $.DefaultKnot }}selected{{ end }}> 81 + {{ . }} 83 82 </option> 84 83 {{ end }} 85 84 </select> 86 - </section> 85 + <button class="btn flex gap-2 items-center" type="submit"> 86 + {{ i "check" "size-4" }} 87 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 88 + </button> 89 + </form> 90 + </section> 87 91 {{ end }} 88 92 89 93 {{ define "register" }}
+9 -1
appview/state/profile.go
··· 633 633 return 634 634 } 635 635 636 - profile.DefaultKnot = r.Form.Get("default-knot") 636 + defaultKnot := r.Form.Get("default-knot") 637 + 638 + if defaultKnot == "[[none]]" { // see pages/templates/knots/index.html for more info on why we use this value 639 + defaultKnot = "" 640 + } 641 + 642 + profile.DefaultKnot = defaultKnot 637 643 638 644 tx, err := s.db.BeginTx(r.Context(), nil) 639 645 if err != nil { ··· 646 652 log.Println("failed to update profile", err) 647 653 return 648 654 } 655 + 656 + s.pages.HxRefresh(w) 649 657 } 650 658 651 659 func (s *State) updateProfile(profile *models.Profile, w http.ResponseWriter, r *http.Request) {