Documentation
¶
Overview ¶
Package view owns TableX's rendering layer: it parses the embedded html/template set once at startup, exposes a shared func map (icons, humanizers, small helpers), and renders either a full page or — for htmx requests — a fragment that swaps #page_content plus out-of-band chrome.
Index ¶
Constants ¶
const WriteTimeout = 60 * time.Second
WriteTimeout bounds a single response write: the buffered page write below, and each export chunk (the handlers' deadlineWriter references it). The server deliberately sets no global http.Server WriteTimeout — exports stream for longer than any fixed cap — so every write path bounds itself and clears the deadline afterwards, keeping the keep-alive connection clean for the next request. SetWriteDeadline is best-effort: an unsupported writer (tests' ResponseRecorder) degrades to an unbounded write.
Variables ¶
var AllowAll = Allowance{Write: true, Console: true, DDL: true}
AllowAll is the unrestricted default.
Functions ¶
func HumanBytes ¶
HumanBytes formats a byte count using IEC units (KiB, MiB, …). A negative value (our "unknown" sentinel) renders as an em dash, matching phpMyAdmin's blank stat cells. The IEC formatting itself is the shared driver.HumanBytesIEC.
Types ¶
type Allowance ¶
type Allowance struct {
// Write is set when state-changing requests are permitted at all: row edits,
// inserts, deletes. Cleared by read_only.
Write bool
// Console is set when arbitrary SQL is permitted — the SQL console and SQL
// import. Cleared by allow_console = false, and by read_only, which refuses
// them along with everything else that changes state.
Console bool
// DDL is set when schema and access-control changes are permitted: the
// structure editor, table and database operations, stored programs, accounts
// and grants. Cleared by allow_ddl = false, and by read_only.
DDL bool
}
Allowance is what this deployment permits, for the templates' benefit: the [restrict] policy in the shape a template can read.
It exists so the UI does not offer what the middleware will refuse. Hiding a button is NOT a control and is never treated as one — `internal/server` enforces every restriction on the request, keyed on the route, and goes on doing so whether or not a template consulted this. The distinction matters enough that the config type deliberately does not reach the templates: a template that could read the policy might look like it were applying it.
The fields are positive ("what you may do") rather than negative, because `{{if $.Allow.DDL}}` reads as an affordance being offered, while `{{if not $.Restrict.NoDDL}}` reads as a double negative nobody gets right.
func (Allowance) Notice ¶
Notice summarises what is withheld, for the banner. Empty when nothing is.
read_only subsumes the other two — under it nothing can be changed at all — so it is reported alone rather than as three findings that all say the same thing.
func (Allowance) Restricted ¶
Restricted reports whether anything is withheld, so the layout can say so once rather than leaving a user to infer it from missing buttons. A UI that quietly drops half its features looks broken; one that states the policy looks deliberate.
type Flash ¶
type Flash struct {
Kind string // success | error | info | warning
Message string
Detail string // optional secondary text (e.g. the offending SQL)
}
Flash is a one-shot alert (success/error/info/warning) shown above content.
type NavNode ¶
type NavNode struct {
}
NavNode is one node (database, schema, table or view) in the tree.
type NavView ¶
type NavView struct {
}
NavView backs the left navigation tree. The tree is loaded incrementally: databases render up-front; expanding a node fetches its children via htmx.
type Page ¶
type Page struct {
Title string
BodyID string // <body id> echoing phpMyAdmin's page ids
LoggedIn bool
CSRF string
Theme string // "light" | "dark"
// declaration rendered inline on <html> so the persisted sidebar width is in
// effect on the first paint (no flash of the default width before JS runs).
// It is template.CSS (trusted) only after server-side validation; empty
// otherwise.
NavWidthStyle template.CSS
// Current connection identity (when logged in).
ServerName string
Info driver.ServerInfo
Caps driver.Capabilities
// Allow mirrors the [restrict] policy so a template does not OFFER what the
// middleware would refuse. It reads alongside Caps and for the same reason:
// Caps says what the engine can do, Allow says what this deployment permits.
//
// It is not the enforcement and must never be treated as such — every
// restriction is applied to the request in internal/server/restrict.go, and
// stays applied whether or not a template consulted this. What it buys is
// only that a user is not shown a button that answers 403.
Allow Allowance
// Chrome.
Breadcrumb []Crumb
Tabs []Tab
Flashes []Flash
// NeedsEditor makes the layout load CodeMirror up front. It is 242 KB —
// well over a third of the whole asset payload — and only the SQL console
// and the import form carry a `textarea.tx-sql-editor`, so every other page
// paid for it. An htmx navigation ONTO one of those pages swaps only
// #page_content and never re-runs <head>, so app.js injects the assets on
// demand there; this flag covers the full-page render (and a no-JS client,
// which then gets a plain textarea either way).
NeedsEditor bool
// Page-specific payload.
Body any
}
Page is the data passed to every template. It carries the shared "chrome" (breadcrumb, context tabs, navigation tree, flashes, server identity) plus a page-specific Body. Handlers build a Page, set Body, and call Render.
type Renderer ¶
type Renderer struct {
// contains filtered or unexported fields
}
Renderer holds the parsed per-page template sets.
func (*Renderer) AssetVersion ¶
AssetVersion is the fingerprint templates stamp onto /static/ URLs. The server reads it to decide which requests may be cached forever.
func (*Renderer) Render ¶
Render writes a page. For htmx requests it renders the "fragment" entry (content + OOB breadcrumb/tabs/title); otherwise the full "base" shell. Output is buffered so a render error never emits half a page.
func (*Renderer) RenderNamed ¶
RenderNamed renders a specific named template within a page set (used for standalone fragments like nav-tree children). Output is buffered.