Version 26.04.07
New Features
Mail Proxy and Email Queue
- A
message_to_sendqueue table stores outgoing emails together with their sending status. A dedicated dashboard lets operators monitor the queue in real time. - A mail-proxy integration layer routes messages through the queue, using the
message_to_sendformula as the single gatekeeper that decides whether a message is actually sent. - The new architecture decouples email generation from delivery, making retry logic and auditing straightforward.
GnrListener – event-driven handler system
- A new
GnrListenerclass (gnr.app.gnrlistener) provides a declarative, database-backed publish/subscribe mechanism. - Handlers are registered with the
@listendecorator and are auto-discovered at start-up both at module level and on package classes. - An optional thread-pool executor enables parallel handler execution for high-throughput workloads.
- Notification payloads are automatically enriched with
user,page_id, andtsfields and serialised withtoTypedJSON. - The polling loop has been delegated to the adapter layer, keeping the core listener free of database-specific code.
Centralised Error Handler
- A new centralised
errorHandler(#677) replaces the scattered per-page error handling. - Errors are broadcast via
pkgBroadcastso every open page is notified simultaneously. - Toast notifications provide immediate, non-intrusive feedback.
- A traceback viewer allows developers to inspect the full Python stack trace directly in the browser.
REST API Dispatcher (_api)
- A new
_apidispatcher has been added to the web layer, providing first-class routing for REST API endpoints without requiring a dedicated WSGI application.
ExpandBox Widget
- A new
expandboxwidget based on the HTML5/
elements has been added to the grouplet system. It provides zero-JavaScript collapsible sections and integrates with the existing grouplet panel infrastructure.
GnrToast Improvements
- persistent — the toast stays visible until the user explicitly dismisses it.
- copyable — a copy-to-clipboard button is added to the toast body, useful for error messages or reference codes.
gnr.web.widgets Package
- A new Python package
gnr.web.widgetshas been introduced. Every widget exposes an@elementmethod that returns its Bag-based descriptor, providing a programmatic API for widget introspection and documentation generation.
Sourcerer Integration
- GenroPy now ships a built-in service adapter for Sourcerer, registered through the standard service declaration mechanism.
Improvements and Refactoring
CSS / Theme System Modernisation
- A design-token system replaces ad-hoc colour literals. All colours are now expressed through a numbered seven-step gray scale (
--gray-1…--gray-7) and semantic aliases (--border-light,--border-strong, etc.). - Border-radius values are centralised in CSS custom properties; the
--palette-*namespace has been retired in favour of the new tokens. color-mix()calls have been replaced with explicit hex values to maximise browser compatibility.- The theme selection mechanism is unified: the
GNR_CSS_THEMEenvironment variable now controls the default theme consistently in bothdefault.xmland the Dockerfile. - CSS variables have been added for
--multibutton-selected-bg,--button-in-grid-bg,--frameindex-tablist-*sizing, and thedeletingButtonspecialisation.
Grid Enhancements
- Flex grid columns now enforce an automatic minimum width so that column headers are never truncated below their natural size.
- Widget-in-cell rendering has been overhauled: text centering, the invalid-cell icon, and style-attribute conflicts have all been fixed.
- The
required_columnsparameter is now honoured in print-resource grid queries. drawFillerwidth calculation has been restored to its pre-PR #749 behaviour.
Grouplet Panel
GroupletFormnow maintains a strict datapath separation between the grouplet’s own data and the host page’s store, preventing cross-page data leaks.- The error indicator is now shown only when there are actual validation errors, not on every field change.
- The inline
_onRemotepattern has been replaced with a propergnrwdgmethod, improving reusability. - A double-load on the preference page has been eliminated.
Authentication Module
- Auth verifiers have been extracted from
gnrwebpageinto a dedicated module (#700), improving separation of concerns and making it easier to swap or extend the verification strategy.
Daemon Package
- Daemon initialisation logic has been moved into
gnr.web.daemon.service(#695, #688), reducing coupling between the CLI entry points and the runtime service objects. - The
DataCollector(register analyser) has similarly been moved out of the CLI layer.
gnrdeploy Refactoring
- The deployment helper has been refactored (#706) to separate configuration parsing from execution.
- A typo that mapped
column.typeinstead ofcolumn.dtypewas fixed as part of this work.
Siteregisters Module Organisation
- Siteregisters modules have been reorganised (#733) to follow a clearer package structure, making it easier to locate and extend individual register implementations.
Database Migration Extensions
- The
gnr db migratecommand now accepts a-e/--extensionoption with possible valuestxt,json, orsql, giving operators control over the format of generated migration scripts.
PostgreSQL Extension Handling
- The database layer now uses
CREATE EXTENSION IF NOT EXISTSinstead of the previousDROP → CREATEsequence, making migrations idempotent and safe to re-run.
Werkzeug ProxyFix
- The
ProxyFixWSGI middleware is now automatically applied when the application is running inside Kubernetes, ensuring thatREMOTE_ADDR,HTTP_HOST, and scheme headers are correctly resolved behind a reverse proxy.
Frameindex Top Hook
- The
frameindextop hook is now decorated with@customizable, allowing projects to override the default rendering without monkey-patching. functools.wrapsis applied so that the decorated function retains its original__name__.
K8S Generator
K8SGeneratornow accepts an optionalinitContainersargument for providing accessory init containers to the generated Kubernetes manifests.
Services Declarations
- Missing
nameandprotocolfields in service declarations have been added, andlast_refresh_tsavailability in new connections has been fixed.
Autoreload Browser-Open Fix
- When Werkzeug autoreload is active together with the
-o(open browser) option, the browser is now opened only once by the main monitor process, preventing duplicate tabs on every file change.
Removals and Clean-up
- Legacy Dojo 1.8 library (
dojo_libs/dojo_18) has been removed. The framework now targets a new Dojo internal fork in a non-exclusive way, coexisting with old Dojo 11. legacy_packages/gnrhas been removed.example_configuration/demo_sitehas been removed.- Dead WSGI code has been deleted (#739).
- The
name_fullfallback from preference caption resolution has been removed; callers must supply an explicit caption. - Tree branch PNG icons have been replaced by pure-CSS triangles, eliminating several image assets.
Bug Fixes
- The
sendMessagemethod now consultsmessage_to_sendas its sole gating condition, preventing duplicate sends and race conditions.
Storage / S3
S3multipart upload ETags (which contain a-suffix) are now correctly detected via alencheck rather than a fragile string scan. Themd5hashhelper returnsNonefor multipart ETags instead of raising.
CKEditor
- The
disabledvsreadOnlyregression introduced in a previous release has been fixed. Disabled CKEditor instances are now visually distinct from read-only ones.
DateTimeTextBox
DateTimeTextBoxno longer clears its value on blur when the field contains a valid date/time.
Login Form
- The
login_newUserform has been converted fromframeFormtoboxFormso that it auto-sizes correctly on all viewport sizes.
Document Store
- The custom
rpcmethodinload_documentand the handler rpcmethod chain inload_record,save_record, andsave_documenthave been restored after being lost in a previous refactoring.
Web Page
userLocalTagsnow returns a safe empty value instead ofNonewhen called from aremoteBuildercontext, preventingAttributeErrordownstream.- The
--nodebugcommand-line flag is now correctly evaluated and no longer silently ignored. - Debug-level evaluation order has been corrected so that the intended log level is applied from the very first log statement.
Record / BoxForm
- The
recordproperty has been extended to be compatible withBoxForm, removing an incompatibility introduced when grouplet panels were redesigned.
Batch Handler
- Schedulable batches that do not define a
table_script_parameters_panenow correctly show their parameters dialog (#679). - Batch handler CSS now uses
emunits and CSS custom properties for consistent scaling; the thermoline label is flex-centred.
Theme / CSS Fixes
css_themedefault value is now consistent betweendefault.xmland the Dockerfile entry point.- The theme editor has been fixed after the CSS variable renaming.
- Obsolete
--radius-*and--palette-*variable references in project and resource CSS files have been updated to the new token names. - The
framedindex_tablistnow usesmin-heightinstead ofpaddingto avoid layout collisions. hiderLayerandhiderMessagereadability has been improved.- The draft-marker ribbon position is now configurable via a
draftMarkeroption. - Duplicate CSS triangle chevrons in the mobile menu are hidden when
branchiconrightis active. - Toolbar background and
border-strongcolours have been darkened for better contrast. grouplet_chunk_boxposition: relativehas been moved from hardcoded Python into the CSS file.NumberTextBoxand other right-aligned inputs now have symmetricpadding-right.- The quickgrid toolbar
contentPanenow has a base height so it is always visible. TabContainerborder-radius is applied only to the top-right corner to preserve the visual tab-line continuation.- The linker error tooltip is now always visible and the scrollable-table header sync issue has been resolved.
- XSS sanitisation has been added to the dojo_20 toast output.
ping_semaphoreCSS visibility andTimeTextBoxpopup styling have been corrected.- The
ext_column handler mechanism now correctly supports multiple handlers on the same column (#698).
mkthresource
- Cross-package foreign key relation errors in
mkthresourcehave been fixed (#684).
Wizard / Formlet
- Wizard
onLoadingof the main form has been fixed. - Formlet fields now correctly display error, focus, and disabled visual states.
Preferences
- The preference page no longer triggers a double load on initialisation.
GroupletFormpreference indicator now shows only on error conditions.
Miscellaneous
_th_mixinResourcenow operates in safe mode for tables that have noth_resource, and multidomain error URLs are handled correctly (#716).display: flexhas been removed fromcellContentto restore correct template grid column widths.inline-flexis now used for formbuilder cells inside toolbars.- Minor hider background fix removing an unwanted box shadow.