Implement JQHTML function cache ID system and fix bundle compilation Implement underscore prefix for system tables Fix JS syntax linter to support decorators and grant exception to Task system SPA: Update planning docs and wishlists with remaining features SPA: Document Navigation API abandonment and future enhancements Implement SPA browser integration with History API (Phase 1) Convert contacts view page to SPA action Convert clients pages to SPA actions and document conversion procedure SPA: Merge GET parameters and update documentation Implement SPA route URL generation in JavaScript and PHP Implement SPA bootstrap controller architecture Add SPA routing manual page (rsx:man spa) Add SPA routing documentation to CLAUDE.md Phase 4 Complete: Client-side SPA routing implementation Update get_routes() consumers for unified route structure Complete SPA Phase 3: PHP-side route type detection and is_spa flag Restore unified routes structure and Manifest_Query class Refactor route indexing and add SPA infrastructure Phase 3 Complete: SPA route registration in manifest Implement SPA Phase 2: Extract router code and test decorators Rename Jqhtml_Component to Component and complete SPA foundation setup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
3.4 KiB
Executable File
RSpade Spa System
Overview
The RSpade Spa system enables client-side routing for authenticated areas of applications using the JQHTML component framework.
Core Classes
Spa_Action
Base class for Spa pages/routes. Each action represents a distinct page in the application.
Example:
class Users_View_Action extends Spa_Action {
static route = '/users/:user_id';
static layout = 'Frontend_Layout';
on_create() {
console.log(this.args.user_id); // URL parameter from route
}
}
Spa_Layout
Persistent wrapper component containing navigation, header, footer, etc. Layouts have a content area where actions render.
Example:
class Frontend_Layout extends Spa_Layout {
on_create() {
// Initialize layout structure
// Create navigation, header, footer
// Define content area for actions
}
}
Spa
Main Spa application class that initializes the router and manages navigation between actions.
Spa_Router
Core routing engine adapted from JQHTML framework. Handles URL matching, parameter extraction, and navigation.
Discovery
Spa actions are discovered during manifest build using:
Manifest::is_js_subclass_of('Spa_Action')
No filename conventions required - any class extending Spa_Action is automatically registered.
URL Generation
PHP:
$url = Rsx::SpaRoute('Users_View_Action', ['user_id' => 123]);
// Returns: "/users/123"
JavaScript:
const url = Rsx.SpaRoute('Users_View_Action', {user_id: 123, tab: 'posts'});
// Returns: "/users/123?tab=posts"
Architecture
Bootstrap Flow
- User requests Spa route (e.g.,
/users/123) - Dispatcher detects Spa route in manifest
- Server renders
spa_bootstrap.blade.phpwith bundle - Client initializes Spa application
- Router matches URL to action
- Layout renders with action inside
Navigation Flow
- User clicks link or calls
Rsx.SpaRoute() - Router matches URL to action class
- Current action destroyed (if exists)
- New action instantiated with URL parameters
- Action renders within persistent layout
- Browser history updated
Implementation Status
Phase 1: Foundation Setup - ✅ COMPLETE
- Directory structure created
- Placeholder files in place
- Router code copied from JQHTML export
Phase 2+: See /var/www/html/docs.dev/Spa_INTEGRATION_PLAN.md
Directory Structure
/system/app/RSpade/Core/Jqhtml_Spa/
├── CLAUDE.md # This file
├── Spa_Bootstrap.php # Server-side bootstrap handler
├── Spa_Parser.php # Parse JS files for action metadata
├── Spa_Manifest.php # Manifest integration helper
├── spa_bootstrap.blade.php # Bootstrap blade layout
├── Spa_Router.js # Core router (from JQHTML)
├── Spa.js # Spa application base class
├── Spa_Layout.js # Layout base class
└── Spa_Action.js # Action base class
Notes
- Spa routes are auth-only (no SEO concerns)
- Server does not render Spa pages (client-side only)
- Actions live alongside PHP controllers in feature directories
- Controllers provide Ajax endpoints, actions provide UI
- Layouts persist across action navigation (no re-render)
- Component renamed from
ComponenttoComponent(legacy alias maintained)