Skip to content

Phase 0: Full frontend modernization — Laravel 12, Vite, Blade, Tiptap, design system, accessibility#3259

Open
gloriafolaron wants to merge 428 commits intomasterfrom
feature/phase-0-modernization
Open

Phase 0: Full frontend modernization — Laravel 12, Vite, Blade, Tiptap, design system, accessibility#3259
gloriafolaron wants to merge 428 commits intomasterfrom
feature/phase-0-modernization

Conversation

@gloriafolaron
Copy link
Copy Markdown
Contributor

@gloriafolaron gloriafolaron commented Feb 15, 2026

Overview

This is a ground-up modernization of Leantime's entire frontend stack. It touches 1,086 files across 310 commits — every layer from the build system to the template engine to the CSS architecture to the JavaScript runtime. The goal is to replace a decade of accumulated legacy tooling with a modern, maintainable foundation that can support Leantime's next generation of features.

This is not a cosmetic refresh. It is an infrastructure overhaul that changes how templates are authored, how styles are defined, how JavaScript is loaded, how modals work, how forms are built, and how the design system is governed — while preserving every existing feature and user-facing behavior.

By the numbers:

  • 540 PHP/Blade files changed (19,294 insertions / 13,795 deletions)
  • 184 JS files changed (8,209 insertions / 12,172 deletions)
  • 53 CSS files changed (3,674 insertions / 10,733 deletions)
  • 142 legacy template files deleted (.tpl.php, .sub.php, .inc.php)
  • 272 new Blade templates created
  • ~4 MB eliminated from initial page load (TinyMCE, jQuery UI, Bootstrap, dead libraries)

1. Build System & Framework Upgrades

Laravel 12

Upgraded from Laravel 11 to Laravel 12. Updated framework dependencies, service providers, and kernel configuration to match the new structure.

Laravel Mix → Vite

Replaced the Webpack-based Laravel Mix build with Vite. This is not just a config swap — the entire asset pipeline was restructured:

  • Converted all LESS files to standard CSS
  • Rewrote entry points to use ES module imports instead of CommonJS require()
  • Added @rollup/plugin-commonjs to handle legacy CJS libraries (jstree, DataTables, FullCalendar) that cannot be converted
  • Created a virtual jQuery module so that import $ from 'jquery' works throughout the codebase without bundling jQuery multiple times
  • Production builds now complete in ~6 seconds (down from ~45s with Webpack)
  • Source maps work correctly in development for the first time

Tailwind CSS 3.4 → 4.x

Upgraded to Tailwind v4's CSS-native configuration model:

  • Replaced tailwind.config.js with CSS-based config in resources/css/app.css
  • Changed prefix from tw- (hyphen) to tw: (colon) across every template
  • Only @tailwind components and @tailwind utilities are active (base layer disabled to avoid conflicts with existing styles)

HTMX 1.x → 2.x

Upgraded HTMX to version 2 and added the Idiomorph morphing extension for smoother DOM diffing during partial swaps. Added the head-support and preload extensions.


2. Template Migration — Legacy PHP to Blade

Complete conversion

Every legacy .tpl.php, .sub.php, and .inc.php template has been converted to Laravel Blade (.blade.php). This was done domain by domain:

  • Tickets — All main views (showAll, showKanban, showTicket) plus submodules and modal dialogs
  • Projects — All project templates including settings tabs, hub, and blueprints
  • Sprints, Settings, Users, Clients — Full conversion
  • Calendar, Comments, Files — Full conversion
  • Timesheets, Wiki — Full conversion, with wiki getting a complete 3-panel redesign
  • Canvas variants (14 domains) — All converted, leveraging the shared Canvas base
  • Ideas — Full conversion including wall and kanban views
  • Api, Connector, CsvImport, Errors, Install, Reports, Strategy — Remaining domains converted
  • Auth, TwoFA, Help — Login, reset, invite flows, 2FA verification, and help tutorials

After conversion, 142 legacy template files were deleted and the legacy template extension registration was removed from the view system. The application no longer loads or renders .tpl.php files.

Bootstrap grid class removal

After the Blade conversion, every template was scrubbed to remove Bootstrap-specific grid classes (col-md-*, row, offset-*, pull-right, clearfix) across all domains including Help, Canvas, Goalcanvas, Strategy, shared Views, and plugin templates. These were replaced with flexbox utilities or lightweight CSS shims where layout was still needed.


3. Shared Blade Component Library

A reusable component library was built in app/Views/Templates/components/ to standardize all UI elements across the application. Every hardcoded HTML form element and interactive pattern was systematically converted to use these components:

Form components

Component Replaces Key features
forms/input <input type="text|hidden|number|email|password|time"> Type variants, :bare prop for inline contexts
forms/select <select> SlimSelect integration, :bare prop, grouped options
forms/textarea <textarea> Auto-sizing, TipTap-aware (skips rich editors)
forms/checkbox <input type="checkbox"> ID generation, disabled state, label wrapping, slot support
forms/radio <input type="radio"> ID generation, disabled state, label wrapping, slot support
forms/date <input class="dates"> Flatpickr integration, date/datetime modes
forms/file <input type="file"> Uppy integration, :bare prop

UI components

Component Purpose
button All buttons and button-links with type variants (primary, secondary, danger, ghost)
pageheader Page title with icon and breadcrumb slot
tabs Tab navigation with active state
loader / loadingText Loading indicators and skeleton screens
elements/badge Status badges and labels
elements/card Content cards with glass effect support
progress Universal emboss-style progress bar
avatar User avatar display
dateInline Inline date display with icon/text toggle

The bare prop pattern

All form components support :bare="true" which outputs just the raw HTML element with no wrapper markup and no framework classes. This is essential for:

  • Title inputs that need transparent, full-width styling
  • Color picker and tag inputs that expect specific DOM structure for jQuery plugin compatibility
  • Inline form layouts with float-based label+input patterns
  • Table cell selects in filter bars and data rows
  • HTMX-attributed elements that need clean DOM

DaisyUI evaluation

DaisyUI 5 was installed and all templates were converted to use its component classes. After thorough testing, DaisyUI was reverted — the class naming conflicts with Leantime's existing design token system created more problems than it solved. The component conversions remain (Blade components are still used), but they output Bootstrap-compatible class names styled by our own CSS. The DaisyUI package remains installed for future consideration but is not actively used for production styling.


4. CSS Architecture & Design System

Design token system

The entire CSS codebase was systematically swept to replace hardcoded values with CSS custom properties. This was done in 17 numbered sweeps covering every property type:

Sweep Property What changed
1 Brand colors All hardcoded #004666, #1b75bb, etc. → var(--accent1), var(--accent2)
2 Neutral colors All hardcoded grays/whites/blacks → var(--primary-font-color), var(--secondary-background), etc.
3 Dark mode Shadows and remaining neutrals verified for dark mode rendering
4 Focus indicators focus-visible outlines added to all custom interactive elements
5 Screen reader aria-labels, aria-hidden, and form labels added throughout
6a-c Loading states role=status, sr-only text, aria-live=polite on all HTMX indicators/targets
9 Touch targets All interactive elements enforced to 44×44px minimum (WCAG 2.5.8)
10 Editor typography Tiptap editor fonts normalized to design scale
11 Border radius All hardcoded border-radiusvar(--box-radius) scale
12a-b Spacing All off-scale spacing snapped to 4px grid
13 Line height All unitless line-heights normalized to tokens
14 Transitions All transition durations normalized to tokens
15 Opacity All opacity values normalized to tokens
16 Z-index / font-size Z-index layers and remaining font-size px values tokenized
17 Box-shadow / font-weight Final shadow and weight normalization

Semantic alias layer

Added accent3 and accent4 tokens, plus semantic aliases that map purpose to value (e.g., --feedback-success, --feedback-warning). This lets themes change meaning without hunting through hundreds of property declarations.

Glass morphism

Added a tiered glass effect system with CSS custom properties:

  • --glass-blur, --glass-background, --glass-border for standard glass
  • --glass-blur-subtle tier for lighter effects on widgets and selectables
  • Applied to modals, dropdowns, tooltips, the left sidebar, and content cards
  • Dark mode values tuned independently
  • Hardcoded blur values in the Tiptap editor tokenized

Typography

Added Hanken Grotesk as the new default font family, with fallbacks to Roboto and system fonts. All font-size, font-weight, and line-height values across the CSS codebase were normalized to use the design token scale.

Design system naming (v3)

Implemented a comprehensive naming convention pass (Phases 0–5) to make all CSS custom properties consistent and predictable. This renamed tokens across the entire system to follow a --{category}-{property}-{variant} pattern.


5. JavaScript Modernization

jQuery elimination

Approximately 600 jQuery calls across all domain controllers were converted to vanilla JavaScript. This includes:

  • $(document).ready()DOMContentLoaded listeners
  • $.ajax()fetch() with proper credentials and headers
  • $('.selector').on('click')addEventListener with event delegation
  • $.each(), $.extend(), $.trim() → native equivalents
  • $(el).show/hide/toggle()classList and style.display manipulation
  • $(el).val(), .text(), .html().value, .textContent, .innerHTML

jQuery UI removal

  • Datepicker → Flatpickr (lighter, more customizable, better mobile support)
  • Sortable → SortableJS (modern drag-and-drop with nested list support)
  • Tabs → Vanilla JS tabsController (reads data-tab-target attributes)
  • Custom nestedSortable rewritten to use SortableJS internally

Other library replacements

Removed Replaced with Rationale
jQuery Growl Vanilla toast utility No jQuery dependency, CSS custom property theming
Chosen.js SlimSelect Modern, accessible, smaller bundle
nyroModal Native <dialog> + modalManager.js Browser-native, no jQuery, frosted-glass backdrop
simpleColorPicker SlimSelect-based picker Consistent with other select patterns
jquery.alerts Removed (unused) Dead code

Domain JS lazy-loading

Instead of loading all 46 domain JS files on every page (~110 KB), the build now uses import.meta.glob to split them into individual chunks. Only the active module's scripts are loaded:

  • The page's $module variable determines which domain JS to fetch
  • An hx-boost domain JS reloader automatically loads the correct scripts when SPA-style HTMX navigation changes the active module
  • 17 canvas controllers were consolidated into a shared factory, eliminating 16 near-identical files

Performance impact

Eliminated approximately 4 MB from the initial page load:

  • TinyMCE 5.10.9: 3.6 MB (replaced by Tiptap at ~480 KB)
  • jQuery UI: ~400 KB
  • Bootstrap CSS/JS: ~300 KB
  • Dead libraries (nyroModal, jquery.alerts, Chosen CSS/JS, Growl): ~200 KB
  • Domain JS (deferred): ~110 KB moved to lazy loading

6. Rich Text Editor — TinyMCE → Tiptap

The monolithic TinyMCE editor (3.6 MB, version 5.10.9 with ~20 custom plugins) was replaced with a modern Tiptap-based editor built on ProseMirror:

Features

  • Slash commands — Type / for a command palette (headings, lists, code blocks, tables, etc.)
  • @mentions — Type @ to search and mention users
  • Column layouts — Multi-column content blocks
  • Math rendering — KaTeX integration for mathematical notation
  • Code blocks — Syntax-highlighted code with language selection
  • Tables — Full table editing with add/remove rows and columns
  • Mobile-responsive toolbar — Apple-like floating toolbar that adapts to screen size

Three editor variants

  • Complex (wiki) — Full toolbar, slash commands, mentions, columns, math
  • Simple (comments, descriptions) — Basic formatting, links, lists
  • Notes — Minimal variant for sticky notes

Integration

  • All Blade templates updated to use Tiptap instead of TinyMCE
  • HTMX-aware — properly re-initializes after partial swaps
  • Scoped CSS prevents editor styles from leaking into the page

7. Modal System — nyroModal → Native Dialog

Replaced the jQuery-based nyroModal plugin with a modern modal system built on the browser's native <dialog> element:

modalManager.js

  • Opens ticket modals, article dialogs, and other content as <dialog> overlays
  • Fetches content via fetch(), injects into the dialog, and manages lifecycle
  • Frosted-glass backdrop using CSS backdrop-filter: blur(12px) with 50% opacity overlay
  • Re-initializes modal handlers after hx-boost SPA navigation
  • Handles form submissions inside modals, including FormData with submit button values
  • Hash-based URL routing (#/tickets/showTicket/123) for deep-linkable modals

Migration scope

  • All $.nmManual() and $.nyroModal() calls converted
  • All Bootstrap <div class="modal fade"> patterns converted
  • All data-dismiss="modal" attributes removed
  • All jQuery(...).modal('show'|'hide') calls eliminated

8. HTMX & SPA Navigation

hx-boost navigation

Added hx-boost="true" to the main content area, enabling SPA-like navigation where clicking links swaps just the page content instead of doing a full page reload. This includes:

  • A loading indicator during navigation transitions
  • Automatic domain JS reloading when the active module changes
  • Proper hx-target and hx-select attributes to prevent the target inheritance bug (where child HTMX elements inherit the parent's swap target and accidentally replace the entire page)

HTMX fixes

  • Fixed hx-select inheritance — added explicit targets to all HTMX elements inside .primaryContent to prevent the .rightpanel ancestor's swap target from being inherited
  • Added aria-live="polite" to all HTMX swap target containers for screen reader announcements
  • Re-activated inert <script> tags after DOMParser innerHTML swaps (HTMX strips script tags by default)

9. Accessibility Improvements

Systematic accessibility improvements applied across the entire application:

Category Changes
Touch targets All interactive elements (buttons, links, checkboxes, radios, menu items) enforced to 44×44px minimum per WCAG 2.5.8
Focus indicators focus-visible outlines added to all custom interactive elements (cards, clickable divs, icon buttons)
Screen reader aria-labels added to all icon-only buttons and links, aria-hidden="true" on decorative icons
Form labels All form inputs associated with labels via for/id attributes
Loading states All loading indicators have role="status" and sr-only descriptive text
HTMX regions All HTMX swap targets have aria-live="polite" for dynamic content announcements
Keyboard navigation Custom clickable elements (cards, kanban items) made keyboard-accessible with tabindex="0" and Enter/Space handlers
Zoom Removed maximum-scale=1 from viewport meta tag to allow user zoom (WCAG 1.4.4)
Priority indicators Added aria-labels to color-only priority border ticket cards

10. Mobile & Responsive Improvements

Change Details
Viewport units All 100vh replaced with 100dvh (dynamic viewport height) for correct mobile browser behavior
Table overflow Added horizontal scroll wrappers around all data tables that were breaking on mobile
Fixed widths Replaced hardcoded pixel widths with responsive max-width values
Modal breakpoints Added responsive sizing so modals don't overflow on small screens
Dashboard grid Added responsive breakpoints for the GridStack widget dashboard
Performance Replaced transition: all with specific property transitions to prevent layout thrashing on mobile

11. Page-Specific Fixes & Polish

Timesheets

  • Modernized toolbar from float-based layout to flexbox
  • Added inline editing to My Timesheets list view
  • Fixed filter icon, data loading, and dropdown rendering
  • Moved "Add Hours" button to right side of toolbar
  • Added visual hierarchy to list view (dimmed dates, types, zero-hour entries)
  • Constrained project/ticket selector widths in week view
  • Fixed total alignment and empty ticket messaging
  • Transaction safety and timezone handling improvements

Calendar

  • Replaced float-based toolbar with flexbox
  • Built scrollable day selector with 5-week date range
  • Fixed dashboard calendar widget rendering under Vite
  • Restored drag-and-drop from todo widget to calendar
  • Fixed duplicate events when dragging
  • Aligned day selector with grid columns, added event tooltips

Wiki

  • Complete redesign with modern 3-panel Tiptap layout
  • Activity feed integration
  • Fixed double-escaping in Blade template

Notes

  • Fixed inline editing, pin refresh, grid layout on HTMX navigation
  • Resolved Packery layout, TipTap scoping, and HTMX conflicts
  • Right-aligned filter controls, fixed scroll behavior

Dashboard & Widgets

  • Fixed widget headers, dropdowns, resize handles, subtitle styling
  • Repaired My ToDos filter and group-by HTMX interactions
  • Allowed dropdown menus to overflow widget boundaries
  • Aligned group-by labels with radio buttons
  • Tightened ToDos row layout
  • Fixed filter icon and widget action promotion timing

Project Settings

  • Used bare inputs for budget fields to avoid full-width stretch
  • Marked selects as required
  • Bare label inputs on status settings, fixed Add Status icon
  • Bare role inputs on Team tab, fixed HTML link rendering
  • Aligned To-Do Status Settings into proper column grid
  • Fixed SlimSelect double borders and Tiptap not rendering

Kanban

  • Added SortableJS bridge for drag-and-drop (replacing jQuery UI sortable)
  • Fixed recurring icon overflow and filter bar auto-opening

Admin & Settings

  • Polished company section page layouts
  • Fixed auth settings toggle layout
  • Added missing jQuery UI tabs initialization for company settings

Plugins / Apps Page

  • Redesigned from stacked vertical ticketBox cards to horizontal flex layout
  • Plugin image left, content center (name, version, vendor, description), controls right
  • Updated skeleton loading states to match new horizontal card layout
  • Cleaned up marketplace category headers (h1 → h5, removed inline borders)
  • Simplified control wrappers for both installed and marketplace plugins

Other fixes

  • Fixed Gantt chart initialization and timeline tab rendering
  • Fixed milestone loaders inheriting wrong HTMX targets
  • Fixed reports MySQL CAST compatibility (INTEGER → SIGNED)
  • Fixed Uppy file upload timing under Vite module loading
  • Fixed canvas controller ordering and eager-load domain JS
  • Fixed tagsInput strict-mode error and SlimSelect re-init crash
  • Fixed various Blade parsing and template rendering issues
  • Fixed login/install page rendering without Bootstrap

12. Submodule Updates

The app/Plugins/ submodule was updated throughout to keep plugins compatible with the modernization changes:

  • Migrated tw- prefix to tw: for Tailwind v4
  • Converted plugin templates to Blade where needed (PgmPro, Llamadorian cleanup)
  • Applied bare prop conversions to plugin form components
  • Fixed Notes header layout, filter rows, sort/search positioning
  • Fixed AdvancedAuth HTMX compatibility
  • Applied Pomodoro timer styling and drag-and-drop support
  • Applied flagged-items token sweep and code style fixes
  • Strategy/program settings fixes

Known Remaining Work

Bootstrap patterns still present

Pattern Files Notes
data-toggle="dropdown" ~39 Converting dropdownPill + inlineSelect shared components cascades to ~30 consumers
.nav-tabs / .nav-pills ~2 Left sidebar menu + ticket submenu
.alert.alert-* ~9 Mostly Plugins/Billing; component exists
.label.label-* ~9 Badge component exists
.btn-group ~10 Component exists, internal class still Bootstrap-named
.form-group ~15 Layout-only, low priority

Other

  • A few secretInput inline date pickers were intentionally skipped (specialized transparent styling)
  • The marketplace API is currently experiencing availability issues (unrelated to this PR — external service timeout)

Test Plan

Core Navigation

  • Dashboard loads, widgets render, GridStack drag-and-drop works
  • Left sidebar navigation works, icons display correctly
  • hx-boost SPA navigation transitions smoothly between pages
  • Domain JS loads correctly when navigating between different modules

Tickets & Kanban

  • Ticket list view renders with proper table styling
  • Kanban board renders, cards drag between columns via SortableJS
  • Ticket modal opens as dialog overlay with frosted-glass backdrop
  • Quick-add works from both list and kanban views
  • Ticket title input renders as large transparent field

Projects

  • Project hub renders with working HTMX client filter
  • Project settings — all tabs render (General, Status, Team, Budget)
  • All form fields work: date pickers, selects, checkboxes, color pickers
  • Blueprint creation flow works

Timesheets

  • Week view renders with proper column alignment
  • List view renders with inline editing
  • Filter bar works, Add Hours button is accessible
  • Totals calculate and display correctly

Calendar

  • Month view renders via FullCalendar
  • Day selector scrolls and highlights today
  • Drag-and-drop from todo widget to calendar works
  • Event creation modal opens correctly

Wiki

  • 3-panel layout renders (sidebar, content, activity)
  • Tiptap editor loads with full toolbar
  • Slash commands and @mentions work
  • Article creation/editing saves correctly

Notes

  • Notes grid renders with Packery layout
  • Inline title editing works
  • Pin/unpin refreshes correctly
  • TipTap editor initializes in note cards

Canvas / Goals

  • All 14 canvas variants render correctly
  • Card creation, editing, and drag-and-drop work
  • Goal canvas with its custom service layer works

Forms & Components

  • All form components render correctly (input, select, textarea, checkbox, radio, date, file)
  • :bare prop produces clean, unwrapped output
  • SlimSelect initializes on all select elements
  • Flatpickr initializes on all date inputs

Editor

  • Tiptap loads in all three variants (complex, simple, notes)
  • Slash commands open command palette
  • @mentions search and insert correctly
  • Tables, code blocks, and column layouts work
  • Editor re-initializes after HTMX partial swaps

Modals

  • Ticket modal opens/closes correctly
  • Frosted-glass backdrop renders
  • Form submission inside modals works
  • Modal re-initializes after hx-boost navigation

Admin & Settings

  • Account settings — all tabs render, theme settings work
  • Company settings — all sections accessible, tabs initialize
  • Auth settings — toggle layout renders correctly
  • Apps page (My Apps) — horizontal card layout, enable/disable/remove links work
  • Apps page (Marketplace) — horizontal cards with "Learn More" buttons (when API is available)

Visual & Responsive

  • Dark mode renders correctly on all pages
  • Mobile responsive — sidebar collapses, tables scroll, modals resize
  • Glass effects render on modals, dropdowns, sidebar
  • All design tokens resolve correctly (no broken var() references)

Accessibility

  • Tab navigation reaches all interactive elements
  • Screen reader announces loading states and dynamic content
  • All icon-only buttons have accessible labels
  • Touch targets are at least 44×44px
  • Page is zoomable (no maximum-scale restriction)

cc @marcelfolaron

🤖 Generated with Claude Code

@gloriafolaron gloriafolaron requested a review from a team as a code owner February 15, 2026 20:36
@gloriafolaron gloriafolaron requested review from marcelfolaron and removed request for a team February 15, 2026 20:36
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Feb 15, 2026

CLA assistant check
All committers have signed the CLA.

@gloriafolaron
Copy link
Copy Markdown
Contributor Author

gloriafolaron commented Feb 16, 2026

Update: Timesheets, Menu Icons, and UI Polish

@marcelfolaron — new batch of changes pushed, summary below.

New in this push (19 commits)

Timesheets

  • Inline editing for My Timesheets list view (click-to-edit hours, project/ticket selectors)
  • Fixed list view save, validation, total alignment, and empty ticket message
  • Constrained project/ticket selector widths and aligned week view total
  • Fixed list view filter icon and data loading

UI Polish

  • Fixed filter bar layout with flexbox and proper label stacking
  • Increased table row height and toolbar-to-header spacing
  • Fixed active column color and aligned timesheet dropdowns
  • Made active column body cells transparent to match card background
  • Scoped today indicator to header cell only with rounded outline

Menu

  • Fixed missing icons in left sidebar nav items
  • Removed duplicate icon rendering in nav item template
  • Added strategy overview menu language keys

@gloriafolaron gloriafolaron changed the title Phase 0 modernization: modal layout fixes and UI polish Phase 0 modernization: modal layout, UI polish, and settings fixes Feb 16, 2026
@gloriafolaron gloriafolaron changed the title Phase 0 modernization: modal layout, UI polish, and settings fixes Phase 0 modernization: Bootstrap removal, Blade components, Vite migration, Tiptap editor Feb 18, 2026
gloriafolaron and others added 21 commits February 19, 2026 16:40
…aisyUI to Bootstrap

Replace tw:/DaisyUI classes with Bootstrap equivalents in project hub,
project cards, user management, client details, and company settings
templates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…endar from DaisyUI to Bootstrap

Replace tw:/DaisyUI classes with Bootstrap equivalents in dashboard
widgets, welcome panel, head menu, project selector, stopwatch,
timesheets, and calendar export templates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…es from DaisyUI to Bootstrap

Replace tw:/DaisyUI classes with Bootstrap equivalents in canvas
elements, goal dashboard, idea dialogs, strategy boards, wiki dialogs,
comments, and file browser templates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…DaisyUI to Bootstrap

Replace tw:/DaisyUI classes with Bootstrap equivalents in login,
user invites, API keys, integrations, onboarding help steps, and
plugin marketplace templates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s files

nyroModal library was removed but CSS selectors targeting .nyroModalCont
remained in tiptap-editor.css and theme dark.css files. Also deletes
unused Less files (main.less, app.less) that referenced removed libraries
and were not part of the Vite build pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… quickadd.less

Remove orphaned .nyroModalCloseButton mobile rule (native dialog handles
its own close button). Delete quickadd.less — duplicate of quickadd.css
with minor differences, not part of the build pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Regenerated CSS bundles with nyroModal selectors removed from
tiptap-editor, mobile, and theme dark.css source files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete loading.css (120KB), loading-btn.css (4KB), switchery.min.css,
and jquery.ui.css — all confirmed unused. Remove ld-ext-right spinner
classes from 3 blade templates (save buttons on user profile, project
details, company settings). Saves ~125KB of dead CSS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…omains

Remove superseded .tpl.php templates from all 15 canvas variant domains
(Cpcanvas, Dbmcanvas, Eacanvas, Emcanvas, Insightscanvas, Lbmcanvas,
Leancanvas, Minempathycanvas, Obmcanvas, Retroscanvas, Riskscanvas,
Sbcanvas, Smcanvas, Sqcanvas, Swotcanvas). Each domain's 5 files
(showCanvas, canvasDialog, canvasComment, delCanvas, delCanvasItem) have
verified Blade equivalents that are already active.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… 11 other domains

Remove superseded .tpl.php templates: Ideas (5), Wiki (6), Connector (8),
Clients (5), Errors (4), Files (2), Comments (1), Api (3), TwoFA (2),
Install (2), CsvImport (1), Reports (1), Strategy (1). All have verified
Blade equivalents that are already active.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add success, warning type variants to both button components. Consolidate
danger/error aliases. Add ghost, transparent mappings to button-dropdown
for parity with the main button component.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite .row and .col-* definitions as clean flexbox without vendor
prefixes. Fix column widths to correct 12-column percentages (8.333%
instead of the old incorrect 8.555%). Remove unused push-*, pull-*,
and offset-* grid utilities (zero template references). Add proper
responsive breakpoints for col-sm-*, col-lg-* alongside existing col-md-*.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
View/sort/search filters moved from above the page title to a properly
aligned actions bar on the same line as the title.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@marcelfolaron marcelfolaron requested review from Copilot and removed request for marcelfolaron February 22, 2026 22:12
marcelfolaron and others added 30 commits April 4, 2026 16:38
The fourth stat card label ('Goals you are contributing to') wraps to
multiple lines while shorter labels fit on one line, causing visual
inconsistency. Adding whitespace-nowrap with text-ellipsis overflow
to the big-number-box component ensures all stat card labels render
at a consistent single-line height.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ing is accessible

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Submenus stayed collapsed when navigating to pages within them (e.g.,
Ideas under THINK, Company Settings under Administration). This fixes
two issues: (1) moves the visual state assignment inside the else block
to prevent an undefined $submenuState from overwriting the 'always'
case, and (2) adds logic to check if any submenu child matches the
current module+action and forces the submenu open if so.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…i translations

The global __() helper race condition: Laravel's helpers.php defines __()
before Leantime's app/helpers.php loads (Composer autoload order), so
Leantime's version never registers. Laravel's __() calls
app('translator')->get(), which should resolve to Leantime's Language
class. The LanguageServiceProvider used alias() for this binding, but
a direct singleton is more robust against deferred provider overrides.

Also share $tpl via View::share() in Template::display() so the
template instance is available in all Blade views (layouts, components).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…font

All 7 chip-select templates referenced 'material-symbols-rounded' but the
CSS bundle only includes the @font-face for 'Material Symbols Outlined',
causing icon names to render as literal text. Changed to
'material-symbols-outlined' to match icon.blade.php and the loaded font.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…timesheetsController

These functions are called from jQuery.ready() so the DOM is already loaded.
The nested DOMContentLoaded listeners never fire, preventing DataTable
initialization on the users and timesheets pages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… initializes

initMilestoneTable() selects via jQuery('.ticketTable') but the milestone
templates only had 'dataTable' from the component — missing 'ticketTable'
caused silent init failure, losing sort indicators, Export/Columns buttons,
and hidden column defaults.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dule load

The inline script in showAllMilestonesOverview.blade.php called
leantime.ticketsController methods outside jQuery(document).ready(),
but entry-app.js loads as a deferred ES module. This caused the
controller to be undefined when the inline script executed. Moving
all controller calls inside jQuery(document).ready() ensures the
module has registered before the calls run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…mission

Conditionally render hx-post/hx-trigger/hx-swap/hx-vals only when ticketId
is present, preventing 400 errors on new ticket forms. Add hx-include="this"
so HTMX only sends the chip's own value instead of the entire parent form,
fixing 'Unknown column saveTicket' SQL errors on existing ticket pages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The get() method only returned a Response for the 'game=snake' query
parameter. Without it, get() returned null, causing the Frontcontroller
to access an uninitialized $response property and trigger a fatal error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…les empty message misplacement

The table.blade.php component already wraps the default slot in <tbody>,
so the explicit <tbody></tbody> in showAll.blade.php created a duplicate.
DataTables inserted its "Nothing found!" message into the first (empty)
tbody while data rows rendered in the second, making the empty message
always visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…full page injection

When a ticket cannot be found, the error path was calling display() which
renders a full HTML page. This response gets injected into #ticketContent
via jQuery.get, causing duplicate page chrome. Changed to displayPartial()
in both GET and POST handlers for consistency with the success path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ink being unclickable

Add pointer-events:none to .timerContainer so it doesn't intercept clicks
on chip-selects inside it, with pointer-events:auto on direct children.
Change kanbanCardContent and h4 overflow from hidden to visible and set
h4 a to display:inline-block so the title link renders with proper dimensions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t overflow into title

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…button visibility leak

The Blade button component renders fileupload-exists buttons as
<a class="btn btn-primary fileupload-exists"> whose forms.css rule
`body a.btn.btn-primary` (specificity 0,2,2) overrides the bootstrap-fileupload
hide rule `.fileupload-new .fileupload-exists` (specificity 0,2,0), causing
Save/Remove buttons to be visible in the default no-file-selected state.
Bump specificity to (0,3,0) with `.fileupload.fileupload-new .fileupload-exists`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…element in table view

Pass size=sm and noText=true to the milestone progress HTMX endpoint so
the table column renders a slim progress bar instead of the full card-style
progress with text labels that resembled a toggle switch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…MX partial templates

The HTMX partial had hardcoded English strings for 'My Favorites' and
'All Assigned Projects' that lost emoji formatting and i18n after refresh.
Added text.my_favorites key and replaced hardcoded strings with __() calls
in both templates for consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded strings in showProject.blade.php (archive status message),
showMy.blade.php (Save button, timezone tooltip texts) with proper __() calls
and add corresponding keys to en-US.ini.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…line

The title column's data-search was incorrectly set to the status label
name (copy-paste from the status column), causing DataTables search to
match status text instead of the actual ticket title.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…L IDs

When the same ticket appears in multiple contexts (kanban board + detail panel),
the timerContainer elements get duplicate IDs. Append uniqid() to each
timerContainer ID across all templates to ensure uniqueness. HTMX self-refresh
uses hx-target="this" so is unaffected by the ID change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Notes plugin exists in the OSS codebase but its menu entry was only
injected via plugin event listener. Move the menu item into the core
personal menu structure at index 10 (between Project Hub and Timesheets)
and add proper i18n keys.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…iles

The text.no_blueprints_yet translation value contained a trailing <br/>
in 42 language files (all except en-US.ini). Since the Blade template
renders this with {{ }} (escaped output), the <br/> appeared as visible
literal text instead of a line break. The template already has proper
<br /> tags for spacing, so the HTML in translations was unnecessary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…icket

The NewTicket controller always used displayPartial() which rendered the
modal template without the application shell. Now it checks for HTMX/AJAX
requests and only uses the partial for those; direct navigation gets the
full-page newTicket.blade.php with proper layout. Also removed the
inline visibility:hidden style from the modal template tabs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…h 13 columns

The showMyList page was an inline-editing form with 7 columns and no
pagination. The reference design is a read-only DataTables reporting view
with 13 columns (ID, Date, Hours, Plan Hours, Difference, Ticket, Project,
Employee, Type, Description, Invoiced, MGR Approval, Paid), Export/Columns
buttons, and pagination.

- Rewrote template to use DataTables with all 13 columns, matching showAll pattern
- Added Export (CSV) and Columns visibility buttons
- Added pagination via DataTables (100 entries per page)
- Removed inline editing form, new entry row, and Save button
- Simplified controller by removing save logic (no longer needed)
- Removed unused ProjectService and TicketService dependencies
- Removed "Overview" subtitle from page header
- Added initMyTimesheetsTable JS function for the new table

Resolves: fix-039, timesheets-showMyList-001, timesheets-showMyList-002,
timesheets-showMyList-007, timesheets-showMyList-008, timesheets-showMyList-009

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…log input width

When dialog fragments using the blank layout are accessed directly (not via
AJAX/HTMX), they now get a proper HTML wrapper with the app's CSS loaded.
AJAX requests continue to receive bare fragments as before. Also adds an
inline width:100% fallback on the boardDialog text input for when Tailwind
classes aren't available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…plate

When /tickets/showTicket is accessed without an ID, the 400 error page
displayed raw i18n keys (e.g. 'headlines.bad_request') instead of
readable text. This adds hardcoded English fallbacks so the template
renders correctly even when the Language service hasn't fully loaded
the ini translations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The '// All To-Dos' subtitle dropdown in the timelineHeader submodule
was conditionally hidden when no sprints existed, unlike ticketHeader
which always shows the dropdown. Removed the @if guard so the dropdown
is always visible on Roadmap and Calendar pages, matching the reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…users page

Add left padding to gantt-wrapper so the first month label is fully
visible, and set flex-initial on users maincontentinner so it sizes
to content instead of stretching to fill the viewport.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants