Documentation
¶
Index ¶
- Constants
- func AdminHomeURL(r *http.Request) string
- func Breadcrumbs(breadcrumbs []Breadcrumb) hb.TagInterface
- func Endpoint(r *http.Request) string
- func ErrorAlert(message string) string
- func ErrorPopup(errorMessage string) hb.TagInterface
- func FlashError(flashRedirect FlashRedirectFunc, w http.ResponseWriter, r *http.Request, ...) string
- func FlashSuccess(flashRedirect FlashRedirectFunc, w http.ResponseWriter, r *http.Request, ...) string
- func JSEscapeString(s string) string
- func Layout(w http.ResponseWriter, r *http.Request, webpageTitle, webpageHtml string, ...) string
- func SuccessPopup(successMessage string) hb.TagInterface
- func SuccessPopupWithRedirect(successMessage string, redirectUrl string, redirectSeconds int) hb.TagInterface
- func URL(endpoint string, controller string, params map[string]string) string
- func URLR(r *http.Request, controller string, params map[string]string) string
- func UserAdminURL(r *http.Request) string
- func UserHomeURL(r *http.Request) string
- func VueLoaderScript() hb.TagInterface
- type Breadcrumb
- type Country
- type FlashRedirectFunc
- type GeoResolverInterface
- type Links
- func (l *Links) Home(params map[string]string) string
- func (l *Links) UserCreate(params map[string]string) string
- func (l *Links) UserDelete(params map[string]string) string
- func (l *Links) UserImpersonate(params map[string]string) string
- func (l *Links) UserManager(params map[string]string) string
- func (l *Links) UserUpdate(params map[string]string) string
- type OnUserImpersonateFunc
- type OnUserSearchFunc
- type OnUserUpdatedFunc
- type SearchCombine
- type SearchCondition
- type SearchField
- type SearchOp
- type Timezone
- type UiBase
- func (u UiBase) FlashRedirect() FlashRedirectFunc
- func (u UiBase) GeoResolver() GeoResolverInterface
- func (u UiBase) Layout(w http.ResponseWriter, r *http.Request, webpageTitle, webpageHtml string, ...) string
- func (u UiBase) Logger() *slog.Logger
- func (u UiBase) OnUserImpersonate() OnUserImpersonateFunc
- func (u UiBase) OnUserSearch() OnUserSearchFunc
- func (u UiBase) OnUserUpdated() OnUserUpdatedFunc
- func (u UiBase) UserPiiSeal() UserPiiSealFunc
- func (u UiBase) UserPiiUnseal() UserPiiUnsealFunc
- func (u UiBase) UserStore() userstore.StoreInterface
- func (u UiBase) UsersPiiUnseal() UsersPiiUnsealFunc
- type UiConfig
- type UiInterface
- type UserPiiSealFunc
- type UserPiiUnsealFunc
- type UsersPiiUnsealFunc
Constants ¶
const ( CONTROLLER_USER_MANAGER = "user-manager" CONTROLLER_USER_CREATE = "user-create" CONTROLLER_USER_DELETE = "user-delete" CONTROLLER_USER_UPDATE = "user-update" CONTROLLER_USER_IMPERSONATE = "user-impersonate" )
Controller names used in the ?controller= query parameter
const CatchAll = "/*"
CatchAll is the catch-all route suffix
const ERROR_LOGGER_IS_NIL = "logger cannot be nil"
const ERROR_USER_STORE_IS_NIL = "user store cannot be nil"
Error messages
const KeyAdminHomeURL = "admin_home_url"
const KeyEndpoint = "endpoint"
Context keys for config values injected by Handle()
const KeyUserAdminURL = "user_admin_url"
const KeyUserHomeURL = "user_home_url"
const VueLoaderJS = `` /* 479-byte string literal not displayed */
VueLoaderJS is a JavaScript snippet that defines loadVueIfNeeded(). It checks whether Vue is already loaded (e.g. by the layout) and, if not, loads it from the CDN dynamically before invoking the callback.
Every controller that needs Vue includes this snippet once (via the layout or directly). Component JS files then wrap their mount call in:
loadVueIfNeeded((err) => {
if (err) { console.error('Vue load failed:', err); return; }
const { createApp } = Vue;
const el = document.getElementById('my-app');
if (el) createApp(MyApp).mount('#my-app');
});
This avoids double-loading Vue when the layout already provides it.
Variables ¶
This section is empty.
Functions ¶
func AdminHomeURL ¶
AdminHomeURL returns the admin home URL from request context
func Breadcrumbs ¶
func Breadcrumbs(breadcrumbs []Breadcrumb) hb.TagInterface
Breadcrumbs renders a breadcrumb navigation from the given items
func ErrorAlert ¶
ErrorAlert returns an inline HTML error alert for the given message. This replaces the former ToFlashError flash-message pattern, which required a cache store and a /flash route handler that did not exist in the standalone module.
func ErrorPopup ¶
func ErrorPopup(errorMessage string) hb.TagInterface
ErrorPopup returns a SweetAlert2 error popup tag.
func FlashError ¶
func FlashError(flashRedirect FlashRedirectFunc, w http.ResponseWriter, r *http.Request, message, redirectURL string, seconds int) string
FlashError performs a flash redirect for an error message. If flashRedirect is nil, it falls back to a plain http.Redirect.
func FlashSuccess ¶
func FlashSuccess(flashRedirect FlashRedirectFunc, w http.ResponseWriter, r *http.Request, message, redirectURL string, seconds int) string
FlashSuccess performs a flash redirect for a success message. If flashRedirect is nil, it falls back to a plain http.Redirect.
func JSEscapeString ¶
JSEscapeString escapes a string for safe embedding inside a JavaScript single-quoted string literal. It escapes backslash, single quote, and newlines so that user-supplied values (e.g. user IDs from URL params) cannot break out of the string context.
func Layout ¶
func Layout(w http.ResponseWriter, r *http.Request, webpageTitle, webpageHtml string, options struct { Styles []string StyleURLs []string Scripts []string ScriptURLs []string }) string
Layout is the default layout renderer. It builds a complete HTML page using hb.NewWebpage() with Bootstrap + Vue CDN, matching the blogadmin/shopadmin pattern. If a FuncLayout is provided in AdminOptions, it takes precedence over this default.
func SuccessPopup ¶
func SuccessPopup(successMessage string) hb.TagInterface
SuccessPopup returns a SweetAlert2 success popup tag.
func SuccessPopupWithRedirect ¶
func SuccessPopupWithRedirect(successMessage string, redirectUrl string, redirectSeconds int) hb.TagInterface
SuccessPopupWithRedirect returns a SweetAlert2 success popup with an optional redirect. If redirectUrl is empty, no redirect is configured.
func URL ¶
URL builds a URL for the given endpoint and controller with params. The controller is placed in the params map under the "controller" key. The params map is copied before mutation (does not modify caller's map).
func UserAdminURL ¶
UserAdminURL returns the user admin base URL from request context
func UserHomeURL ¶
UserHomeURL returns the user home URL from request context. Used by the impersonate controller to redirect after a successful impersonation.
func VueLoaderScript ¶
func VueLoaderScript() hb.TagInterface
VueLoaderScript returns the loadVueIfNeeded definition as an hb.Tag so controllers can inject it into their container divs. This ensures the guard is available even when a host project provides a custom FuncLayout that does not include VueLoaderJS.
Types ¶
type Breadcrumb ¶
Breadcrumb represents a single breadcrumb navigation item
type FlashRedirectFunc ¶
type FlashRedirectFunc func(w http.ResponseWriter, r *http.Request, messageType, message, redirectURL string, seconds int) string
FlashRedirectFunc redirects the user with a flash message. Host projects that have a flash-message system (cache store + /flash route) provide this callback so useradmin can surface messages across redirects. If nil, useradmin falls back to a plain http.Redirect and the message is dropped.
messageType is one of "error", "success", "info", "warning".
type GeoResolverInterface ¶ added in v0.2.0
type GeoResolverInterface interface {
// Countries returns all countries.
Countries(ctx context.Context) ([]Country, error)
// Timezones returns timezones for the given country code. The
// country code is optional — pass no argument or an empty string
// when no country is selected; implementations should return an
// empty list in that case.
Timezones(ctx context.Context, countryCode ...string) ([]Timezone, error)
}
GeoResolverInterface provides countries and timezones. The host implements this against whatever geo data source it uses (dracory/geostore, a static list, an external API, etc.).
type Links ¶
type Links struct {
// contains filtered or unexported fields
}
Links provides URL helpers for useradmin controllers. The base URL is read from request context (injected by Handle()), not hardcoded. This follows the blogadmin/shopadmin pattern.
func NewLinks ¶
NewLinks creates a Links helper with the given base URL. If baseURL is empty, defaults to "/admin/users".
func NewLinksFromRequest ¶
NewLinksFromRequest creates a Links helper using the user admin URL from the request context.
func (*Links) UserCreate ¶
UserCreate builds the URL for the user create controller
func (*Links) UserDelete ¶
UserDelete builds the URL for the user delete controller
func (*Links) UserImpersonate ¶
UserImpersonate builds the URL for the user impersonate controller
func (*Links) UserManager ¶
UserManager builds the URL for the user manager controller
type OnUserImpersonateFunc ¶ added in v0.2.0
OnUserImpersonateFunc is an optional callback invoked when an admin impersonates a user. The host owns the auth mechanism — it can create a session record and set a cookie, issue a JWT, or anything else. When nil, impersonation is disabled.
type OnUserSearchFunc ¶ added in v0.2.0
type OnUserSearchFunc func(ctx context.Context, conditions []SearchCondition) ([]string, error)
OnUserSearchFunc is an optional callback for custom user search. The host receives a list of conditions and applies whatever logic it wants (blind index, Elasticsearch, etc.). When nil, useradmin falls back to userstore query-based search.
type OnUserUpdatedFunc ¶ added in v0.2.0
OnUserUpdatedFunc is an optional callback invoked after a user is updated. The host can load the user by ID and react to whatever changed (blind index rebuild, audit log, notifications, etc.). When nil, the callback is skipped.
type SearchCombine ¶ added in v0.2.0
type SearchCombine string
SearchCombine defines how a condition combines with the previous one. The first condition's CombineWith is ignored.
const ( SearchAnd SearchCombine = "AND" SearchOr SearchCombine = "OR" )
type SearchCondition ¶ added in v0.2.0
type SearchCondition struct {
// Field is the user field to filter on.
Field SearchField
// Op is the comparison operator.
Op SearchOp
// Value is the value to compare against.
Value string
// CombineWith specifies how this condition combines with the
// previous one. Defaults to AND. Ignored for the first condition.
CombineWith SearchCombine
}
SearchCondition is a single filter criterion passed to OnUserSearch.
type SearchField ¶ added in v0.2.0
type SearchField string
SearchField constants identify the user fields that can be filtered.
const ( SearchFieldFirstName SearchField = "first_name" SearchFieldLastName SearchField = "last_name" SearchFieldEmail SearchField = "email" SearchFieldPhone SearchField = "phone" SearchFieldBusinessName SearchField = "business_name" )
type SearchOp ¶ added in v0.2.0
type SearchOp string
SearchOp defines the comparison operator for a SearchCondition.
type Timezone ¶ added in v0.2.0
type Timezone struct {
Code string
}
Timezone is a single timezone entry returned by GeoResolverInterface.
type UiBase ¶
type UiBase struct {
UserStoreField userstore.StoreInterface
GeoResolverField GeoResolverInterface
LoggerField *slog.Logger
OnUserImpersonateField OnUserImpersonateFunc
OnUserSearchField OnUserSearchFunc
OnUserUpdatedField OnUserUpdatedFunc
UserPiiSealField UserPiiSealFunc
UserPiiUnsealField UserPiiUnsealFunc
UsersPiiUnsealField UsersPiiUnsealFunc
FlashRedirectField FlashRedirectFunc
LayoutField func(w http.ResponseWriter, r *http.Request, webpageTitle, webpageHtml string, options struct {
Styles []string
StyleURLs []string
Scripts []string
ScriptURLs []string
}) string
}
UiBase is a base struct that implements shared.UiInterface. Subcontroller ui structs can embed this to get all the accessor methods for free, following the blogadmin/shopadmin pattern.
func (UiBase) FlashRedirect ¶
func (u UiBase) FlashRedirect() FlashRedirectFunc
func (UiBase) GeoResolver ¶ added in v0.2.0
func (u UiBase) GeoResolver() GeoResolverInterface
func (UiBase) OnUserImpersonate ¶ added in v0.2.0
func (u UiBase) OnUserImpersonate() OnUserImpersonateFunc
func (UiBase) OnUserSearch ¶ added in v0.2.0
func (u UiBase) OnUserSearch() OnUserSearchFunc
func (UiBase) OnUserUpdated ¶ added in v0.2.0
func (u UiBase) OnUserUpdated() OnUserUpdatedFunc
func (UiBase) UserPiiSeal ¶ added in v0.2.0
func (u UiBase) UserPiiSeal() UserPiiSealFunc
func (UiBase) UserPiiUnseal ¶ added in v0.2.0
func (u UiBase) UserPiiUnseal() UserPiiUnsealFunc
func (UiBase) UserStore ¶
func (u UiBase) UserStore() userstore.StoreInterface
func (UiBase) UsersPiiUnseal ¶ added in v0.2.0
func (u UiBase) UsersPiiUnseal() UsersPiiUnsealFunc
type UiConfig ¶
type UiConfig struct {
UserStore userstore.StoreInterface
GeoResolver GeoResolverInterface
Logger *slog.Logger
// OnUserImpersonate is optional — when nil, the impersonate
// button is hidden and the impersonate route is not registered.
OnUserImpersonate OnUserImpersonateFunc
// OnUserSearch is an optional callback for custom user search
// (e.g. blind index, Elasticsearch). When nil, useradmin falls
// back to userstore query-based search.
OnUserSearch OnUserSearchFunc
// OnUserUpdated is an optional callback invoked after a user is
// updated. The host can use it to trigger side effects (blind
// index rebuild, audit log, notifications, etc.). When nil, the
// callback is skipped.
OnUserUpdated OnUserUpdatedFunc
// UserPiiSeal transforms a user from display representation to
// storage representation (e.g. tokenize, encrypt PII). Optional —
// when nil, the user is stored as-is (plain text).
UserPiiSeal UserPiiSealFunc
// UserPiiUnseal transforms a user from storage representation to
// display representation (e.g. detokenize, decrypt PII). Optional —
// when nil, the user is used as-is (plain text).
UserPiiUnseal UserPiiUnsealFunc
// UsersPiiUnseal is the batch version of UserPiiUnseal. It allows
// the host to unseal all users in a single call for efficiency.
// Optional — when nil, useradmin falls back to UserPiiUnseal per
// user (or plain text when that is also nil).
UsersPiiUnseal UsersPiiUnsealFunc
// FlashRedirect redirects with a flash message. Optional — when
// nil, plain http.Redirect is used.
FlashRedirect FlashRedirectFunc
// Layout is the layout renderer callback.
Layout func(w http.ResponseWriter, r *http.Request, webpageTitle, webpageHtml string, options struct {
Styles []string
StyleURLs []string
Scripts []string
ScriptURLs []string
}) string
}
UiConfig holds the dependencies passed to subcontroller UI factories. This follows the blogadmin/shopadmin pattern.
UserStore, GeoResolver, and Logger are required for core controllers. OnUserImpersonate is optional — when nil, the impersonate button is hidden and the impersonate route is not registered. OnUserSearch is optional — when nil, useradmin falls back to userstore query-based search. OnUserUpdated is optional — when nil, the callback is skipped. UserPiiSeal/UserPiiUnseal/UsersPiiUnseal are optional — when nil, user fields are treated as plain text.
Authentication and authorization are the host's responsibility — gate the routes with middleware before they reach useradmin.
type UiInterface ¶
type UiInterface interface {
UserStore() userstore.StoreInterface
GeoResolver() GeoResolverInterface
Logger() *slog.Logger
OnUserImpersonate() OnUserImpersonateFunc
OnUserSearch() OnUserSearchFunc
OnUserUpdated() OnUserUpdatedFunc
UserPiiSeal() UserPiiSealFunc
UserPiiUnseal() UserPiiUnsealFunc
UsersPiiUnseal() UsersPiiUnsealFunc
FlashRedirect() FlashRedirectFunc
Layout(w http.ResponseWriter, r *http.Request, webpageTitle, webpageHtml string, options struct {
Styles []string
StyleURLs []string
Scripts []string
ScriptURLs []string
}) string
}
UiInterface defines the methods every subcontroller UI must implement. This follows the blogadmin/shopadmin pattern.
type UserPiiSealFunc ¶ added in v0.2.0
type UserPiiSealFunc func(ctx context.Context, user userstore.UserInterface) (userstore.UserInterface, error)
UserPiiSealFunc transforms a user from display representation to storage representation (e.g. tokenize, encrypt, mask PII fields). The host owns the mechanism. When nil, the user is stored as-is (plain text).
type UserPiiUnsealFunc ¶ added in v0.2.0
type UserPiiUnsealFunc func(ctx context.Context, user userstore.UserInterface) (userstore.UserInterface, error)
UserPiiUnsealFunc transforms a user from storage representation to display representation (e.g. detokenize, decrypt, reveal PII fields). The host owns the mechanism. When nil, the user is used as-is (plain text).
type UsersPiiUnsealFunc ¶ added in v0.2.0
type UsersPiiUnsealFunc func(ctx context.Context, users []userstore.UserInterface) ([]userstore.UserInterface, error)
UsersPiiUnsealFunc is the batch version of UserPiiUnsealFunc. It allows the host to unseal all users in a single vault batch call for efficiency. When nil, useradmin falls back to calling UserPiiUnsealFunc per user (or plain text when that is also nil).