Enhance refactor commands with controller-aware Route() updates and fix code quality violations
Add semantic token highlighting for 'that' variable and comment file references in VS Code extension Add Phone_Text_Input and Currency_Input components with formatting utilities Implement client widgets, form standardization, and soft delete functionality Add modal scroll lock and update documentation Implement comprehensive modal system with form integration and validation Fix modal component instantiation using jQuery plugin API Implement modal system with responsive sizing, queuing, and validation support Implement form submission with validation, error handling, and loading states Implement country/state selectors with dynamic data loading and Bootstrap styling Revert Rsx::Route() highlighting in Blade/PHP files Target specific PHP scopes for Rsx::Route() highlighting in Blade Expand injection selector for Rsx::Route() highlighting Add custom syntax highlighting for Rsx::Route() and Rsx.Route() calls Update jqhtml packages to v2.2.165 Add bundle path validation for common mistakes (development mode only) Create Ajax_Select_Input widget and Rsx_Reference_Data controller Create Country_Select_Input widget with default country support Initialize Tom Select on Select_Input widgets Add Tom Select bundle for enhanced select dropdowns Implement ISO 3166 geographic data system for country/region selection Implement widget-based form system with disabled state support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,24 @@ This separation ensures:
|
||||
|
||||
## CRITICAL RULES
|
||||
|
||||
### 🔴 RSpade Builds Automatically - NEVER RUN BUILD COMMANDS
|
||||
|
||||
**RSpade is an INTERPRETED framework** - like Python or PHP, changes are automatically detected and compiled on-the-fly. There is NO manual build step.
|
||||
|
||||
**ABSOLUTELY FORBIDDEN** (unless explicitly instructed):
|
||||
- `npm run compile` / `npm run build` - **DO NOT EXIST**
|
||||
- `bin/publish` - Creates releases for OTHER developers (not for testing YOUR changes)
|
||||
- `rsx:bundle:compile` - Bundles compile automatically in dev mode
|
||||
- `rsx:manifest:build` - Manifest rebuilds automatically in dev mode
|
||||
- ANY command with "build", "compile", or "publish"
|
||||
|
||||
**How it works**:
|
||||
1. Edit JS/SCSS/PHP files
|
||||
2. Refresh browser
|
||||
3. Changes are live (< 1 second)
|
||||
|
||||
**If you find yourself wanting to run build commands**: STOP. You're doing something wrong. Changes are already live.
|
||||
|
||||
### 🔴 Framework Updates
|
||||
|
||||
```bash
|
||||
@@ -94,6 +112,14 @@ Classes are namespacing tools. Use static unless instances needed (models, resou
|
||||
|
||||
**Correct workflow**: Edit → Save → Reload browser → See changes (< 1 second)
|
||||
|
||||
### 🔴 Trust Code Quality Rules
|
||||
|
||||
Each `rsx:check` rule has remediation text that tells AI assistants exactly what to do:
|
||||
- Some rules say "fix immediately"
|
||||
- Some rules say "present options and wait for decision"
|
||||
|
||||
AI should follow the rule's guidance precisely. Rules are deliberately written and well-reasoned.
|
||||
|
||||
---
|
||||
|
||||
## NAMING CONVENTIONS
|
||||
@@ -185,10 +211,12 @@ class Frontend_Controller extends Rsx_Controller_Abstract
|
||||
|
||||
```php
|
||||
// PHP
|
||||
Rsx::Route('User_Controller', 'show')->url(['id' => 123]);
|
||||
Rsx::Route('User_Controller', 'show', ['id' => 123]);
|
||||
Rsx::Route('User_Controller', 'show', 123); // Integer shorthand for 'id'
|
||||
|
||||
// JavaScript (identical)
|
||||
Rsx.Route('User_Controller', 'show').url({id: 123});
|
||||
Rsx.Route('User_Controller', 'show', {id: 123});
|
||||
Rsx.Route('User_Controller', 'show', 123); // Integer shorthand for 'id'
|
||||
```
|
||||
|
||||
---
|
||||
@@ -286,7 +314,11 @@ For mechanical thinkers who see structure, not visuals. Write `<User_Card>` not
|
||||
<button class="Save_Button Jqhtml_Component btn btn-primary">Save</button>
|
||||
```
|
||||
|
||||
**Interpolation**: `<%= escaped %>` | `<%== unescaped %>` | `<% javascript %>`
|
||||
**Interpolation**: `<%= escaped %>` | `<%!= unescaped %>` | `<% javascript %>`
|
||||
|
||||
**Conditional Attributes** (v2.2.162+): Apply attributes conditionally using `<% if (condition) { %>attr="value"<% } %>`
|
||||
directly in attribute context. Works with static values, interpolations, and multiple conditions per element.
|
||||
Example: `<input <% if (this.args.required) { %>required="required"<% } %> />`
|
||||
|
||||
### 🔴 CRITICAL on_load() Rules
|
||||
|
||||
@@ -314,13 +346,22 @@ class User_Card extends Jqhtml_Component {
|
||||
|
||||
### Lifecycle
|
||||
|
||||
1. **render** → Template executes, `this.data = {}` (empty)
|
||||
2. **on_render()** → Hide uninitialized UI (sync)
|
||||
3. **on_create()** → Quick setup (sync)
|
||||
1. **on_create()** → Setup default state BEFORE template (sync)
|
||||
2. **render** → Template executes with initialized state
|
||||
3. **on_render()** → Hide uninitialized UI (sync)
|
||||
4. **on_load()** → Fetch data into `this.data` (async)
|
||||
5. **on_ready()** → DOM manipulation safe (async)
|
||||
|
||||
**Double-render**: If `on_load()` modifies `this.data`, component renders twice (empty → populated).
|
||||
**on_create() now runs first** - Initialize `this.data` properties here so templates can safely reference them:
|
||||
|
||||
```javascript
|
||||
on_create() {
|
||||
this.data.rows = []; // Prevents "not iterable" errors
|
||||
this.data.loading = true; // Template can check loading state
|
||||
}
|
||||
```
|
||||
|
||||
**Double-render**: If `on_load()` modifies `this.data`, component renders twice (defaults → populated).
|
||||
|
||||
### Loading Pattern
|
||||
|
||||
@@ -372,6 +413,94 @@ For advanced topics: `php artisan rsx:man jqhtml`
|
||||
|
||||
---
|
||||
|
||||
## FORM COMPONENTS
|
||||
|
||||
Form components use the **vals() dual-mode pattern** for getting/setting values:
|
||||
|
||||
```javascript
|
||||
class My_Form extends Jqhtml_Component {
|
||||
vals(values) {
|
||||
if (values) {
|
||||
// Setter - populate form
|
||||
this.$id('name').val(values.name || '');
|
||||
this.$id('email').val(values.email || '');
|
||||
return null;
|
||||
} else {
|
||||
// Getter - extract values
|
||||
return {
|
||||
name: this.$id('name').val(),
|
||||
email: this.$id('email').val()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**: `Form_Utils.apply_form_errors(form.$, errors)` - Matches by `name` attribute.
|
||||
|
||||
---
|
||||
|
||||
## MODALS
|
||||
|
||||
**Basic dialogs**:
|
||||
```javascript
|
||||
await Modal.alert("File saved");
|
||||
if (await Modal.confirm("Delete?")) { /* confirmed */ }
|
||||
let name = await Modal.prompt("Enter name:");
|
||||
```
|
||||
|
||||
**Form modals**:
|
||||
```javascript
|
||||
const result = await Modal.form({
|
||||
title: "Edit User",
|
||||
component: "User_Form",
|
||||
component_args: {data: user},
|
||||
on_submit: async (form) => {
|
||||
const values = form.vals();
|
||||
const response = await User_Controller.save(values);
|
||||
|
||||
if (response.errors) {
|
||||
Form_Utils.apply_form_errors(form.$, response.errors);
|
||||
return false; // Keep open
|
||||
}
|
||||
|
||||
return response.data; // Close and return
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**Requirements**: Form component must implement `vals()` and include `<div $id="error_container"></div>`.
|
||||
|
||||
Details: `php artisan rsx:man modals`
|
||||
|
||||
---
|
||||
|
||||
## JQUERY EXTENSIONS
|
||||
|
||||
RSpade extends jQuery with utility methods:
|
||||
|
||||
**Element existence**: `$('.element').exists()` instead of `.length > 0`
|
||||
|
||||
**Component traversal**: `this.$.shallowFind('.Widget')` - Finds child elements matching selector that don't have another element of the same class as a parent between them and the component. Prevents selecting widgets from nested child components.
|
||||
|
||||
```javascript
|
||||
// Use case: Finding form widgets without selecting nested widgets
|
||||
this.$.shallowFind('.Form_Field').each(function() {
|
||||
// Only processes fields directly in this form,
|
||||
// not fields in nested sub-forms
|
||||
});
|
||||
```
|
||||
|
||||
**Sibling component lookup**: `$('.element').closest_sibling('.Widget')` - Searches for elements within progressively higher ancestors. Like `.closest()` but searches within ancestors instead of matching them. Stops at body tag. Useful for component-to-component communication.
|
||||
|
||||
**Form validation**: `$('form').checkValidity()` instead of `$('form')[0].checkValidity()`
|
||||
|
||||
**Click override**: `.click()` automatically calls `e.preventDefault()`. Use `.click_allow_default()` for native behavior.
|
||||
|
||||
For complete details: `php artisan rsx:man jquery`
|
||||
|
||||
---
|
||||
|
||||
## MODELS & DATABASE
|
||||
|
||||
### No Mass Assignment
|
||||
@@ -756,8 +885,9 @@ The include array auto-detects:
|
||||
|
||||
### Execution Order
|
||||
|
||||
- **First:** on_create() runs before anything else (setup state)
|
||||
- **Top-down:** render, on_render (parent before children)
|
||||
- **Bottom-up:** on_create, on_load, on_ready (children before parent)
|
||||
- **Bottom-up:** on_load, on_ready (children before parent)
|
||||
- **Parallel:** Siblings at same depth process simultaneously during on_load()
|
||||
|
||||
### this.args vs this.data
|
||||
@@ -825,6 +955,13 @@ public static function get_user_data(Request $request, array $params = [])
|
||||
}
|
||||
```
|
||||
|
||||
**Testing Ajax endpoints**: `php artisan rsx:ajax Controller action --site-id=1 --args='{"id":1}'`
|
||||
|
||||
Test endpoints behind auth/site scoping or invoke RPC calls from scripts. JSON-only output.
|
||||
- Default: Raw response
|
||||
- `--debug`: HTTP-like wrapper
|
||||
- `--show-context`: Display context before JSON
|
||||
|
||||
### Model Fetch Security
|
||||
|
||||
```php
|
||||
@@ -929,6 +1066,16 @@ console_debug('AJAX', 'Request sent', url, params);
|
||||
- **DuplicateCaseFilesRule** - Detect same-name different-case files (critical)
|
||||
- **MassAssignmentRule** - Prohibit $fillable arrays
|
||||
|
||||
### Trust the Rule Text
|
||||
|
||||
Each rule's remediation message specifies exactly how to handle violations:
|
||||
- What the problem is
|
||||
- Why it matters
|
||||
- How to fix it
|
||||
- Whether to fix autonomously or present options
|
||||
|
||||
**For AI assistants**: Follow the rule's guidance precisely. Don't override with "common sense" - the rule text is authoritative and deliberately written.
|
||||
|
||||
## MAIN_ABSTRACT MIDDLEWARE (EXPANDED)
|
||||
|
||||
### Execution Order
|
||||
|
||||
Reference in New Issue
Block a user