mirror of
https://github.com/ditatompel/xmr-remote-nodes.git
synced 2025-01-08 05:52:10 +07:00
Christian Ditaputratama
98dcdfa94a
Slightly increase user browsing privacy by not pushing query strings to browser URL. By using this method, the browser history stay on the main page and filter query strings not recorded. Note: This approach is experimental. Only tested on Firefox and Chromium browser.
158 lines
5.2 KiB
Text
158 lines
5.2 KiB
Text
package views
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/ditatompel/xmr-remote-nodes/internal/paging"
|
|
"slices"
|
|
)
|
|
|
|
var availablePages = []int{5, 10, 20, 50, 100}
|
|
|
|
templ DtRowPerPage(url, hxTarget string, rowsPerPage int, q interface{}) {
|
|
<div class="max-w-sm space-y-3">
|
|
<select
|
|
name="limit"
|
|
id="dt_limit"
|
|
class="py-2 px-3 pe-9 block bg-neutral-900 border-neutral-700 rounded-lg text-sm focus:border-orange-400 focus:ring-orange-400"
|
|
autocomplete="off"
|
|
hx-get={ fmt.Sprintf("%s?%s", url, paging.EncodedQuery(q, []string{"limit"})) }
|
|
hx-trigger="change"
|
|
hx-push-url="false"
|
|
hx-target={ hxTarget }
|
|
hx-swap="outerHTML"
|
|
>
|
|
<option disabled>CHOOSE</option>
|
|
for _, page := range availablePages {
|
|
<option
|
|
value={ fmt.Sprintf("%d", page) }
|
|
selected?={ page == rowsPerPage }
|
|
>{ fmt.Sprintf("%d", page) }</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
}
|
|
|
|
templ DtRefreshInterval(url, hxTarget, interval string, q interface{}) {
|
|
<div class="inline-flex gap-x-2 items-center">
|
|
<div>Auto refresh:</div>
|
|
<div class="max-w-sm space-y-3">
|
|
<select
|
|
name="refresh"
|
|
id="dt_refresh"
|
|
class="py-2 px-3 pe-9 block text-sm text-neutral-400 bg-neutral-900 border-neutral-700 rounded-lg focus:border-orange-400 focus:ring-orange-400"
|
|
autocomplete="off"
|
|
hx-get={ fmt.Sprintf("%s?%s", url, paging.EncodedQuery(q, []string{"refresh"})) }
|
|
hx-trigger="change"
|
|
hx-push-url="false"
|
|
hx-target={ hxTarget }
|
|
hx-swap="outerHTML"
|
|
>
|
|
<option value="">off</option>
|
|
for _, v := range refreshIntevals {
|
|
<option value={ v } selected?={ v == interval }>{ v }</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
if slices.Contains(refreshIntevals, interval) {
|
|
<div
|
|
hx-get={ fmt.Sprintf("%s?%s", url, paging.EncodedQuery(q, []string{""})) }
|
|
hx-push-url="false"
|
|
hx-target={ hxTarget }
|
|
hx-trigger={ fmt.Sprintf("every %s", interval) }
|
|
hx-swap="outerHTML"
|
|
></div>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
templ DtReload(url, hxTarget string, q interface{}) {
|
|
<button
|
|
class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-bold rounded-full border border-transparent bg-orange-600 text-white hover:bg-orange-500 focus:outline-none"
|
|
hx-get={ fmt.Sprintf("%s?%s", hxTarget, paging.EncodedQuery(q, []string{""})) }
|
|
hx-push-url="false"
|
|
hx-target={ hxTarget }
|
|
hx-swap="outerHTML"
|
|
>
|
|
<svg class="flex-shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg>
|
|
Reload
|
|
</button>
|
|
}
|
|
|
|
// Sort TH table
|
|
//
|
|
// URL: Where the URL to get the results is
|
|
// HxTarget: Where the results will be displayed
|
|
// Title: The title of the column
|
|
// ExpectedSort: The expected sort, used to determine the sort direction indicator
|
|
// SortBy: The current sort by
|
|
// SortDir: The current sort direction
|
|
// Q: The current query
|
|
templ DtThSort(url, hxTarget, title, expectedSort, sortBy, sortDir string, q interface{}) {
|
|
if expectedSort == sortBy && sortDir== "asc" {
|
|
<th
|
|
scope="col"
|
|
class="cursor-pointer"
|
|
hx-push-url="false"
|
|
hx-target={ hxTarget }
|
|
hx-swap="outerHTML"
|
|
hx-get={ fmt.Sprintf("%s?sort_by=%s&sort_direction=desc&%s", url, expectedSort, paging.EncodedQuery(q, []string{"sort_by", "sort_direction"})) }
|
|
>{ title } ▾</th>
|
|
} else if expectedSort == sortBy && sortDir== "desc" {
|
|
<th
|
|
scope="col"
|
|
class="cursor-pointer"
|
|
hx-push-url="false"
|
|
hx-target={ hxTarget }
|
|
hx-swap="outerHTML"
|
|
hx-get={ string(templ.URL(fmt.Sprintf("%s?sort_by=%s&sort_direction=asc&%s", url, expectedSort, paging.EncodedQuery(q, []string{"sort_by", "sort_direction"})))) }
|
|
>{ title } ▴</th>
|
|
} else {
|
|
<th
|
|
scope="col"
|
|
class="cursor-pointer"
|
|
hx-push-url="false"
|
|
hx-target={ hxTarget }
|
|
hx-swap="outerHTML"
|
|
hx-get={ string(templ.URL(fmt.Sprintf("%s?sort_by=%s&sort_direction=desc&%s", url, expectedSort, paging.EncodedQuery(q, []string{"sort_by", "sort_direction"})))) }
|
|
>{ title } ▴▾</th>
|
|
}
|
|
}
|
|
|
|
templ DtRowCount(currentPage, rowsPerPage, totalRows int) {
|
|
<div>
|
|
<p class="text-sm">
|
|
if totalRows <= 0 {
|
|
No entries found
|
|
} else {
|
|
<b>{ fmt.Sprintf("%d", (rowsPerPage * currentPage) - rowsPerPage + 1) }</b>
|
|
if rowsPerPage * currentPage > totalRows {
|
|
- <b>{ fmt.Sprintf("%d", totalRows) }</b>
|
|
} else {
|
|
- <b>{ fmt.Sprintf("%d", rowsPerPage * currentPage) }</b>
|
|
}
|
|
<b>/ { fmt.Sprintf("%d", totalRows) }</b>
|
|
}
|
|
</p>
|
|
</div>
|
|
}
|
|
|
|
templ DtPagination(url, hxTarget string, q interface{}, p paging.Pagination) {
|
|
<div>
|
|
<nav class="pagination inline-flex gap-x-2">
|
|
for _, page := range p.Pages {
|
|
if page == -1 {
|
|
<button class="cursor-not-allowed" disabled>...</button>
|
|
} else if page == p.CurrentPage {
|
|
<button class="active" disabled>{ fmt.Sprintf("%d", page) }</button>
|
|
} else {
|
|
<button
|
|
hx-get={ fmt.Sprintf("%s?%s&page=%d", url, paging.EncodedQuery(q, []string{"page"}), page) }
|
|
hx-push-url="false"
|
|
hx-target={ hxTarget }
|
|
hx-swap="outerHTML"
|
|
>{ fmt.Sprintf("%d", page) }</button>
|
|
}
|
|
}
|
|
</nav>
|
|
</div>
|
|
}
|