xmr-remote-nodes/internal/handler/views/partial_datatable.templ
Christian Ditaputratama 98dcdfa94a
feat: Do not push query strings to URL #155
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.
2024-11-07 01:20:50 +07:00

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>
}