- add helpdesk module pages, services, settings and tests
- standardize debtor list on drawer/grid contracts and robust filter drawer behavior
- add helpdesk aside panel navigation and settings visibility provider
- switch primary list slug to helpdesk/debitor and remove helpdesk/search compatibility
- include required core contract updates for list contracts and detail/drawer integration
- Add default minWidth (100px) to all grid columns via normalizeGridColumns
to prevent header truncation when data entries are short
- Fix inconsistent th heights by setting .gridjs-th-content line-height
to 24px (matching the sort button height) so sortable and non-sortable
columns render at uniform height
- Remove dead button.gridjs-sort height:15px rule (was overridden by 24px)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the dedicated "Edit"/"Open" action button column from all list
pages. Instead, wrap the primary data column (name, description, subject,
etc.) in a clickable <a> link via the new rowInteraction.linkColumn option.
Double-click, Enter-key, and click-to-focus row navigation preserved.
Pages with explicit actions config are unaffected. Address-book opts out
of auto-wrapping (linkColumn: false) and renders the link in its own
formatter to avoid nested <a> with avatar lightbox.
Also fixes pre-existing XSS in insertActionColumn (unescaped href/label)
and updates typography test for --text-page-title token change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Async component init (e.g. MultiSelect replacing <select> with hidden
inputs) mutated the DOM after the initial form state snapshot, causing
a phantom "unsaved fields" warning. Re-baseline the initial state on
structural DOM changes until the first user interaction.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DRY duplicated helpers (escapeAttr, belongsToForm, isSubmitControl,
isEditableTarget) into web/js/core/app-form-utils.js and update 7
consumers. Add aria-live="polite" to flash messages, async messages,
and search results for screen reader announcements. Add
prefers-reduced-motion support to CSS tooltips.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Session timeout redirected to /de/login?return_to=... but the remember-me
cookie was not cleared by logoutDueToSessionTimeout(). On the next request,
autoLoginFromCookie() silently re-logged the user in, causing the MintyPHP
router to resolve the login route to pages/index().php (dashboard) instead
of the login action — the intended URL redirect logic never executed.
Fix: intercept ?return_to= immediately after successful auto-login in
index.php and redirect to the sanitized route path. Also harden the login
flow with hidden return_to form fields and POST body fallback for cases
without remember-me.
Additional improvements in this commit:
- Convert stored REQUEST_URI to router-compatible path (strip leading
slash and locale prefix) via IntendedUrlService::toRoutePath()
- Consolidate duplicate CSRF data attributes into shared data-csrf-key
and data-csrf-token on <html> element
- Add tenant branding (logo) to auth pages via appAuthLogoUrl() helper
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>