view

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 12 Imported by: 0

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

View Source
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

View Source
var AllowAll = Allowance{Write: true, Console: true, DDL: true}

AllowAll is the unrestricted default.

Functions

func HumanBytes

func HumanBytes(n int64) string

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.

func HumanInt

func HumanInt(n int64) string

HumanInt formats an integer with thousands separators; negative renders as an em dash (unknown).

func IsHTMX

func IsHTMX(r *http.Request) bool

IsHTMX reports whether the request is an htmx-driven partial swap.

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

func (a Allowance) Notice() string

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

func (a Allowance) Restricted() bool

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 Crumb

type Crumb struct {
	Label  string
	URL    string
	Icon   string
	Active bool
}

Crumb is one item in the Server » Database » Table breadcrumb.

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 struct {
	Kind       string // database | schema | table | view
	Name       string
	Label      string
	Icon       string
	Href       string // navigation target (browse/structure)
	LoadURL    string // htmx URL to load children lazily
	Expandable bool
	Expanded   bool
	Active     bool
	IsSystem   bool
	IsError    bool // a non-navigable leaf shown when children couldn't be loaded
	Children   []NavNode
}

NavNode is one node (database, schema, table or view) in the tree.

type NavView struct {
	Databases []NavNode
}

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"

	// NavWidthStyle is a pre-validated `--tx-nav-width:<n>px` custom-property
	// 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
	Nav        *NavView
	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.

func NewPage

func NewPage(title string) *Page

NewPage returns a Page seeded with sensible defaults.

type Renderer

type Renderer struct {
	// contains filtered or unexported fields
}

Renderer holds the parsed per-page template sets.

func New

func New(fsys fs.FS) (*Renderer, error)

New parses all templates from fsys (the embedded web FS) and loads icons.

func (*Renderer) AssetVersion

func (r *Renderer) AssetVersion() string

AssetVersion is the fingerprint templates stamp onto /static/ URLs. The server reads it to decide which requests may be cached forever.

func (*Renderer) Render

func (r *Renderer) Render(w http.ResponseWriter, req *http.Request, page string, data *Page) error

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

func (r *Renderer) RenderNamed(w http.ResponseWriter, page, tmpl string, data any) error

RenderNamed renders a specific named template within a page set (used for standalone fragments like nav-tree children). Output is buffered.

type Tab

type Tab struct {
	Key    string
	Label  string
	URL    string
	Icon   string
	Active bool
}

Tab is one context tab in the #topmenu bar.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL