Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2

appview/pages: list webhook deliveries in repo settings

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.org>

authored by anirudh.fi and committed by tangled.org f7ac5765 137098c6

+166 -6
+21 -5
appview/pages/pages.go
··· 965 965 } 966 966 967 967 type RepoWebhooksSettingsParams struct { 968 - LoggedInUser *oauth.MultiAccountUser 969 - RepoInfo repoinfo.RepoInfo 970 - Active string 971 - Tab string 972 - Webhooks []models.Webhook 968 + LoggedInUser *oauth.MultiAccountUser 969 + RepoInfo repoinfo.RepoInfo 970 + Active string 971 + Tab string 972 + Webhooks []models.Webhook 973 + WebhookDeliveries map[int64][]models.WebhookDelivery 973 974 } 974 975 975 976 func (p *Pages) RepoWebhooksSettings(w io.Writer, params RepoWebhooksSettingsParams) error { 976 977 params.Active = "settings" 977 978 params.Tab = "hooks" 978 979 return p.executeRepo("repo/settings/hooks", w, params) 980 + } 981 + 982 + type WebhookDeliveriesListParams struct { 983 + LoggedInUser *oauth.MultiAccountUser 984 + RepoInfo repoinfo.RepoInfo 985 + Webhook *models.Webhook 986 + Deliveries []models.WebhookDelivery 987 + } 988 + 989 + func (p *Pages) WebhookDeliveriesList(w io.Writer, params WebhookDeliveriesListParams) error { 990 + tpl, err := p.parse("repo/settings/fragments/webhookDeliveries") 991 + if err != nil { 992 + return err 993 + } 994 + return tpl.ExecuteTemplate(w, "repo/settings/fragments/webhookDeliveries", params) 979 995 } 980 996 981 997 type RepoIssuesParams struct {
+74
appview/pages/templates/repo/settings/fragments/webhookDeliveries.html
··· 1 + {{define "repo/settings/fragments/webhookDeliveries"}} 2 + <div class="flex flex-col gap-4"> 3 + <div class="flex items-center justify-between"> 4 + <h3 class="text-lg font-bold uppercase text-sm">Recent Deliveries</h3> 5 + <button 6 + type="button" 7 + onclick="this.closest('[popover]').hidePopover()" 8 + class="btn text-sm flex items-center gap-1" 9 + > 10 + {{ i "x" "size-4" }} close 11 + </button> 12 + </div> 13 + 14 + <div class="text-sm text-gray-600 dark:text-gray-400"> 15 + <span class="font-mono break-all">{{ .Webhook.Url }}</span> 16 + </div> 17 + 18 + {{ if .Deliveries }} 19 + <div class="flex flex-col divide-y divide-gray-200 dark:divide-gray-700 border border-gray-200 dark:border-gray-700 rounded max-h-[60vh] overflow-y-auto"> 20 + {{ range .Deliveries }} 21 + <details class="group"> 22 + <summary class="p-4 hover:bg-gray-50 dark:hover:bg-gray-800 cursor-pointer list-none"> 23 + <div class="flex items-center gap-2 mb-2"> 24 + {{ if .Success }} 25 + <span class="inline-flex items-center gap-1 px-2 py-1 text-xs rounded bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200"> 26 + {{ i "circle-check" "size-3" }} 27 + {{ .ResponseCode }} 28 + </span> 29 + {{ else }} 30 + <span class="inline-flex items-center gap-1 px-2 py-1 text-xs rounded bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"> 31 + {{ i "circle-x" "size-3" }} 32 + {{ if .ResponseCode }}{{ .ResponseCode }}{{ else }}failed{{ end }} 33 + </span> 34 + {{ end }} 35 + <span class="text-xs text-gray-500 dark:text-gray-400 font-mono"> 36 + {{ .DeliveryId }} 37 + </span> 38 + <span class="ml-auto text-xs text-gray-400 dark:text-gray-500 group-open:rotate-180 transition-transform"> 39 + {{ i "chevron-down" "size-4" }} 40 + </span> 41 + </div> 42 + <div class="text-sm text-gray-700 dark:text-gray-300 mb-1"> 43 + <span class="font-semibold">Event:</span> {{ .Event }} 44 + </div> 45 + <div class="text-xs text-gray-500 dark:text-gray-400"> 46 + {{ .CreatedAt.Format "2006-01-02 15:04:05 MST" }} 47 + </div> 48 + </summary> 49 + 50 + <div class="px-4 pb-4 pt-2 bg-gray-50 dark:bg-gray-800/50"> 51 + <div class="flex flex-col gap-3 text-sm"> 52 + <div class="flex flex-col gap-2"> 53 + <h5 class="font-semibold text-gray-700 dark:text-gray-300">Request Body</h5> 54 + <pre class="bg-white dark:bg-gray-900 p-3 rounded text-xs overflow-x-auto border border-gray-200 dark:border-gray-700">{{ .RequestBody }}</pre> 55 + </div> 56 + 57 + {{ if .ResponseBody }} 58 + <div class="flex flex-col gap-2"> 59 + <h5 class="font-semibold text-gray-700 dark:text-gray-300">Response Body</h5> 60 + <pre class="bg-white dark:bg-gray-900 p-3 rounded text-xs overflow-x-auto border border-gray-200 dark:border-gray-700">{{ .ResponseBody }}</pre> 61 + </div> 62 + {{ end }} 63 + </div> 64 + </div> 65 + </details> 66 + {{ end }} 67 + </div> 68 + {{ else }} 69 + <div class="flex items-center justify-center p-8 text-gray-500 dark:text-gray-400 border border-gray-200 dark:border-gray-700 rounded"> 70 + No deliveries yet 71 + </div> 72 + {{ end }} 73 + </div> 74 + {{end}}
+71 -1
appview/pages/templates/repo/settings/hooks.html
··· 82 82 </div> 83 83 {{ end }} 84 84 </div> 85 + 85 86 {{ if $.RepoInfo.Roles.IsOwner }} 86 - <div class="flex items-center"> 87 + <div class="flex items-center mt-2"> 87 88 <label class="flex items-center gap-2 cursor-pointer"> 88 89 <input 89 90 type="checkbox" ··· 96 95 <span class="text-sm">Active</span> 97 96 </label> 98 97 </div> 98 + {{ end }} 99 + 100 + <!-- Recent Deliveries --> 101 + {{ $deliveries := index $.WebhookDeliveries .Id }} 102 + {{ if $deliveries }} 103 + <div class="mt-3 border-t border-gray-200 dark:border-gray-700 pt-3"> 104 + <div class="flex items-center justify-between mb-2"> 105 + <h4 class="text-sm font-semibold text-gray-700 dark:text-gray-300 uppercase">Recent Deliveries</h4> 106 + </div> 107 + <div class="flex flex-col gap-2"> 108 + {{ range $deliveries }} 109 + <div class="flex items-center gap-3 text-xs p-2 bg-gray-50 dark:bg-gray-800 rounded"> 110 + {{ if .Success }} 111 + <span class="inline-flex items-center gap-1 px-2 py-0.5 rounded bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200"> 112 + {{ i "circle-check" "size-3" }} 113 + {{ .ResponseCode }} 114 + </span> 115 + {{ else }} 116 + <span class="inline-flex items-center gap-1 px-2 py-0.5 rounded bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"> 117 + {{ i "circle-x" "size-3" }} 118 + {{ if .ResponseCode }}{{ .ResponseCode }}{{ else }}failed{{ end }} 119 + </span> 120 + {{ end }} 121 + <span class="flex-1 font-mono text-gray-600 dark:text-gray-400 truncate"> 122 + {{ .DeliveryId }} 123 + </span> 124 + <span class="text-gray-500 dark:text-gray-400"> 125 + {{ .Event }} 126 + </span> 127 + <span class="text-gray-500 dark:text-gray-400 whitespace-nowrap"> 128 + {{ .CreatedAt.Format "Jan 02, 15:04" }} 129 + </span> 130 + </div> 131 + {{ end }} 132 + </div> 133 + <div class="mt-2"> 134 + <button 135 + class="btn text-xs flex items-center gap-1" 136 + hx-get="/{{ $.RepoInfo.FullName }}/settings/hooks/{{ .Id }}/deliveries" 137 + hx-target="#webhook-deliveries-modal-{{ .Id }}" 138 + hx-swap="innerHTML" 139 + popovertarget="webhook-deliveries-modal-{{ .Id }}" 140 + popovertargetaction="toggle" 141 + > 142 + {{ i "list" "size-3" }} 143 + show all 144 + </button> 145 + </div> 146 + </div> 147 + {{ else }} 148 + <div class="mt-3 border-t border-gray-200 dark:border-gray-700 pt-3"> 149 + <div class="text-xs text-gray-500 dark:text-gray-400 text-center py-2"> 150 + No deliveries yet 151 + </div> 152 + </div> 153 + {{ end }} 154 + 155 + <!-- Deliveries Modal --> 156 + <div 157 + id="webhook-deliveries-modal-{{ .Id }}" 158 + popover 159 + class="bg-white w-full sm:w-[50rem] dark:bg-gray-800 p-6 max-h-dvh overflow-y-auto rounded border border-gray-200 dark:border-gray-700 drop-shadow dark:text-white backdrop:bg-gray-400/50 dark:backdrop:bg-gray-800/50" 160 + > 161 + <div class="flex items-center justify-center p-4"> 162 + {{ i "loader-circle" "size-6 animate-spin" }} 163 + </div> 164 + </div> 165 + 166 + {{ if $.RepoInfo.Roles.IsOwner }} 99 167 <div 100 168 id="edit-webhook-modal-{{.Id}}" 101 169 popover