Documentation
¶
Overview ¶
Package ui embeds and serves the pinned Apache Airflow 3.2.1 React SPA bundle. The control plane ships the UI in-binary (ADR 0017); the bundle is produced reproducibly by `make fetch-airflow-ui`, which extracts the dist directory from the apache/airflow:3.2.1 image. The serving contract mirrors Airflow's own FastAPI app: static files under /static and an index.html SPA fallback for every other path, with the <base href> templated per request.
Index ¶
- func Assets() fs.FS
- func Version() string
- type Server
- func (s *Server) Index(w http.ResponseWriter, basePath string)
- func (s *Server) Precompress()
- func (s *Server) SetEditorButton(on bool)
- func (s *Server) SetFavicon(url string)
- func (s *Server) SetHomeLink(label, url string)
- func (s *Server) SetInstanceName(name string)
- func (s *Server) SetLiteBanner(on bool)
- func (s *Server) SetProBanner(on bool)
- func (s *Server) SetStylesheets(urls []string)
- func (s *Server) StaticHandler() http.Handler
- func (s *Server) Version() string
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server serves the embedded Airflow 3.2.1 SPA: static assets under a prefix and an index.html fallback for client-side routes.
func NewFromFS ¶
NewFromFS builds a Server over an arbitrary asset filesystem, so tests can inject a fixture instead of the embedded bundle.
func (*Server) Index ¶
func (s *Server) Index(w http.ResponseWriter, basePath string)
Index writes the SPA shell with <base href> set to basePath, so the bundled React router resolves routes and asset URLs against the deployment root. It is the fallback for any non-static, non-API path. basePath defaults to "/".
func (*Server) Precompress ¶ added in v0.5.1
func (s *Server) Precompress()
Precompress reads and gzips every compressible file of the bundle up front, so the first browser after a restart does not pay the compression. It is meant to run in its own goroutine at startup; a request that arrives first for a file waits for that file's build instead of compressing it a second time.
func (*Server) SetEditorButton ¶
SetEditorButton toggles injection of the "IDE" button that opens the Lite web editor (/ide). It is enabled only when a workspace is configured (Lite).
func (*Server) SetFavicon ¶
SetFavicon replaces the bundle's favicon with url (#1289). Empty keeps the stock icon. Config validation limits url to http(s) or a root-relative path.
func (*Server) SetHomeLink ¶
SetHomeLink sets the operator's link back to their platform (#1290), shown on every UI page and opened in the same tab. An empty url disables it.
func (*Server) SetInstanceName ¶
SetInstanceName overrides the value used to rewrite the embedded SPA's `<title>` tag (issue #D15). Empty falls back to "Dexaflow" so the browser tab never shows the upstream "Airflow" string from the bundled fork.
func (*Server) SetLiteBanner ¶
SetLiteBanner toggles injection of the LITE overlay into the served shell. It is enabled by the Lite edition (`dexaflow lite`); the demo and production never set it.
func (*Server) SetProBanner ¶
SetProBanner toggles injection of the gold PRO overlay into the served shell. It is enabled by the Pro edition (Helm install); Lite and Demo never set it. The two edition pills are mutually exclusive in practice, but the server does not enforce that — it trusts the edition resolved upstream.
func (*Server) SetStylesheets ¶
SetStylesheets adds stylesheets every UI page loads in <head>, typically the web fonts a theme names (#1289). Config validation limits each URL as for SetFavicon.
func (*Server) StaticHandler ¶
StaticHandler serves the bundle as static files from the embedded FS. The caller mounts it with the /static prefix already stripped. Content-hashed chunks (under assets/) are marked immutable; index.html is never cached; everything else gets a short cache. Compressible assets are gzipped when the client accepts it. Missing files yield 404 (no SPA fallback here); directories are not listed.
Each file is read, hashed and gzipped once (by Precompress, or else on its first request) and served from memory afterwards with a strong ETag, so a conditional request gets a 304 and a cold one costs a copy instead of a fresh compression.