Improve JS enum_val() with caching and single-value lookup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-12-26 00:45:41 +00:00
parent 1abbac58e7
commit a289eecf0f
2 changed files with 36 additions and 20 deletions

View File

@@ -403,33 +403,45 @@ class Database_BundleIntegration extends BundleIntegration_Abstract
} }
// Generate enum value getter with Proxy for maintaining order // Generate enum value getter with Proxy for maintaining order
$content .= " static {$column}_enum_val() {\n"; $content .= " static __{$column}_enum_val = null;\n";
$content .= " const data = {};\n"; $content .= " static {$column}_enum_val(enum_value) {\n";
$content .= " const order = [];\n"; $content .= " if (!this.__{$column}_enum_val) {\n";
$content .= " const data = {};\n";
$content .= " const order = [];\n";
// Generate the sorted entries // Generate the sorted entries
foreach ($enum_values as $value => $props) { foreach ($enum_values as $value => $props) {
$value_json = json_encode($value); $value_json = json_encode($value);
$props_json = json_encode($props, JSON_UNESCAPED_SLASHES); $props_json = json_encode($props, JSON_UNESCAPED_SLASHES);
$content .= " data[{$value_json}] = {$props_json};\n"; $content .= " data[{$value_json}] = {$props_json};\n";
$content .= " order.push({$value_json});\n"; $content .= " order.push({$value_json});\n";
} }
$content .= " // Return Proxy that maintains sort order for enumeration\n"; $content .= " // Cache Proxy that maintains sort order for enumeration\n";
$content .= " return new Proxy(data, {\n"; $content .= " this.__{$column}_enum_val = new Proxy(data, {\n";
$content .= " ownKeys() {\n"; $content .= " ownKeys() {\n";
$content .= " return order.map(String);\n"; $content .= " return order.map(String);\n";
$content .= " },\n"; $content .= " },\n";
$content .= " getOwnPropertyDescriptor(target, prop) {\n"; $content .= " getOwnPropertyDescriptor(target, prop) {\n";
$content .= " if (prop in target) {\n"; $content .= " if (prop in target) {\n";
$content .= " return {\n"; $content .= " return {\n";
$content .= " enumerable: true,\n"; $content .= " enumerable: true,\n";
$content .= " configurable: true,\n"; $content .= " configurable: true,\n";
$content .= " value: target[prop]\n"; $content .= " value: target[prop]\n";
$content .= " };\n"; $content .= " };\n";
$content .= " }\n";
$content .= " }\n"; $content .= " }\n";
$content .= " });\n";
$content .= " }\n";
$content .= " if (enum_value !== undefined) {\n";
$content .= " const result = this.__{$column}_enum_val[enum_value];\n";
$content .= " if (!result) {\n";
$content .= " console.error(`Invalid enum value '\${enum_value}' for {$column}`);\n";
$content .= " return null;\n";
$content .= " }\n"; $content .= " }\n";
$content .= " });\n"; $content .= " return result;\n";
$content .= " }\n";
$content .= " return this.__{$column}_enum_val;\n";
$content .= " }\n\n"; $content .= " }\n\n";
// Generate enum_select() - Selectable items for dropdowns (respects selectable: false) // Generate enum_select() - Selectable items for dropdowns (respects selectable: false)

View File

@@ -937,8 +937,8 @@ Integer-backed enums with model-level mapping to constants, labels, and custom p
class Project_Model extends Rsx_Model_Abstract { class Project_Model extends Rsx_Model_Abstract {
public static $enums = [ public static $enums = [
'status_id' => [ 'status_id' => [
1 => ['constant' => 'STATUS_ACTIVE', 'label' => 'Active', 'badge' => 'bg-success'], 1 => ['constant' => 'STATUS_ACTIVE', 'label' => 'Active', 'badge' => 'bg-success', 'order' => 1],
2 => ['constant' => 'STATUS_ARCHIVED', 'label' => 'Archived', 'selectable' => false], 2 => ['constant' => 'STATUS_ARCHIVED', 'label' => 'Archived', 'selectable' => false, 'order' => 99],
], ],
]; ];
} }
@@ -949,6 +949,10 @@ echo $project->status_label; // "Active"
echo $project->status_badge; // "bg-success" (custom property) echo $project->status_badge; // "bg-success" (custom property)
``` ```
**Special properties**:
- `order` - Sort position in dropdowns (default: 0, lower first)
- `selectable` - Include in dropdown options (default: true). Non-selectable items excluded from `field_enum_select()` but still shown if current value.
**Migration:** Use BIGINT for enum columns, TINYINT(1) for booleans. Run `rsx:migrate:document_models` after adding enums. **Migration:** Use BIGINT for enum columns, TINYINT(1) for booleans. Run `rsx:migrate:document_models` after adding enums.
### Model Fetch ### Model Fetch