Skip to content

Commit

Permalink
Single tx page
Browse files Browse the repository at this point in the history
  • Loading branch information
heppu committed Apr 27, 2024
1 parent 32ff2d9 commit a0c2447
Show file tree
Hide file tree
Showing 10 changed files with 846 additions and 79 deletions.
33 changes: 33 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Store interface {
Search(filter string) ([]model.Event, error)
CachedStats(model.StatsRange) model.Stats
Events() <-chan model.Event
TxInfo(id string) (model.TxInfo, error)
}

type API struct {
Expand All @@ -42,6 +43,7 @@ func New(s Store, b *Broadcaster) (*API, error) {
}

a.r.HandleFunc("GET /", a.index)
a.r.HandleFunc("GET /tx/{tx}", a.txPage)
a.r.HandleFunc("GET /api/v1/stream", a.stream)
a.r.HandleFunc("GET /api/v1/stats", a.stats)
a.r.HandleFunc("GET /api/v1/events", a.table)
Expand Down Expand Up @@ -69,6 +71,37 @@ func (a *API) index(w http.ResponseWriter, r *http.Request) {
}
}

func (a *API) txPage(w http.ResponseWriter, r *http.Request) {
tx := r.PathValue("tx")
txInfo, err := a.s.TxInfo(tx)
if err != nil {
http.Error(w, "tx not found", http.StatusNotFound)
return
}

if r.Header.Get("Hx-Request") == "true" {
w.Header().Set("HX-Push-Url", r.URL.EscapedPath())
if err := templates.Tx(txInfo).Render(r.Context(), w); err != nil {
slog.Error("failed to render TxInfo", slog.Any("err", err))
}
return
}

// nolint:errcheck
if pusher, ok := w.(http.Pusher); ok {
pusher.Push("/assets/style.css", nil)
pusher.Push("/assets/htmx.min.js", nil)
pusher.Push("/assets/sse.js", nil)
pusher.Push("/assets/Inter-Regular.ttf", nil)
pusher.Push("/assets/Inter-Bold.ttf", nil)
pusher.Push("/assets/Inter-SemiBold.ttf", nil)
}

if err := templates.TxPage(txInfo).Render(r.Context(), w); err != nil {
slog.Error("failed to render TxPage", slog.Any("err", err))
}
}

func (a *API) stats(w http.ResponseWriter, r *http.Request) {
sr, err := model.ParseStatsRange(r.URL.Query().Get("range"))
if err != nil {
Expand Down
195 changes: 194 additions & 1 deletion api/assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -624,13 +624,173 @@ input:checked+.slider:before {
background: #b556ff;
}


#tx-container {
display: flex;
flex-direction: column;
margin-bottom: auto;
}

#tx-info {
display: flex;
flex-direction: column;
margin-bottom: auto;
}

#tx-top,
#tx-bottom {
display: flex;
flex-direction: row;
width: 50%;
}

#tx-top {
margin-right: 5px;
}

#tx-bottom {
margin-left: 5px;
}

.tx-info-header {
font-weight: 600;
font-size: 13px;
line-height: 16px;
margin: 10px;
}

#tx-info-blocks {
display: flex;
flex-direction: row;
}

#tx-state-block {
display: flex;
flex-direction: column;
width: 50%;
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0px;
margin-right: 5px;
}

#tx-state-block>div {
display: flex;
background: #EEEEEE;
border-radius: 100px;
flex-grow: 1;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 20px;
line-height: 24px;
}

#tx-current-state {
margin-bottom: 10px;
}

.tx-id-block {
display: flex;
flex-direction: column;
border: 1px solid #EEEEEE;
border-radius: 2px;
width: 50%;
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0px;
}

.tx-id-block:nth-child(1) {
margin-right: 5px;
}

.tx-id-block:nth-child(2) {
margin-left: 5px;
}

.tx-id-block-wrap {
padding: 20px;
display: flex;
flex-direction: column;
}

.tx-id-block-value {
display: flex;
word-break: break-all;
font-weight: 400;
font-size: 15px;
line-height: 18px;
width: 100%;
margin-bottom: 40px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
}

.tx-id-block-bottom {
display: flex;
flex-direction: row;
margin-top: auto;
}

.tx-id-block-header {
display: flex;
font-weight: 700;
font-size: 20px;
line-height: 24px;
margin-right: auto;
}

.tx-id-block-copy {
display: flex;
align-items: center;
padding: 0px 5px;
background: #EEEEEE;
border-radius: 40px;
max-height: 20px;
cursor: pointer;
width: fit-content;
}

.tx-id-block-copy svg {
width: 20px;
height: 20px;
}

#tx-log {
display: none;
}

.tx-log-events {}

.tx-log-row {}

.tx-log-state {}

.tx-log-id {}

.tx-log-timestamp {}

body.dark .tx-id-block-copy,
body.dark .tx-id-block-cop,
body.dark #tx-state-block>div {
background-color: #333333;
}

body.dark .tx-id-block-copy svg path {
fill: #FFFFFF
}

@media (max-width: 1500px) {
.number-title {
word-spacing: 1000px;
}
}

@media (max-width: 1200px) {
@media (max-width: 1246px) {
#stats {
height: 246px;
}
Expand All @@ -652,6 +812,19 @@ input:checked+.slider:before {
order: 1;
margin-right: auto;
}

.tx-id-block-bottom {
display: flex;
flex-direction: column-reverse;
}

.tx-id-block-copy {
margin-top: 38px;
}

.tx-id-block-header {
margin-top: 10px;
}
}

@media (max-width: 800px) {
Expand Down Expand Up @@ -759,6 +932,26 @@ input:checked+.slider:before {
min-width: 0px;
}

.tx-id-block-value {
margin-bottom: 10px;
}

#tx-info-blocks {
flex-direction: column;
}

#tx-top {
width: 100%;
margin-bottom: 5px;
}

#tx-bottom {
width: 100%;
margin-top: 5px;
margin-left: 0px;
}


#footer {
flex-direction: column;
height: auto;
Expand Down
2 changes: 2 additions & 0 deletions api/broadcaster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,10 @@ type MockStore struct {
searchResult []model.Event
searchErr error
events chan model.Event
txInfo model.TxInfo
}

func (m *MockStore) TxInfo(string) (model.TxInfo, error) { return m.txInfo, nil }
func (m *MockStore) CachedStats(model.StatsRange) model.Stats { return m.stats }
func (m *MockStore) Events() <-chan model.Event { return m.events }
func (m *MockStore) Search(string) ([]model.Event, error) { return m.searchResult, m.searchErr }
Loading

0 comments on commit a0c2447

Please sign in to comment.