Files
rspade_system/storage-broken/rsx-tmp/babel_88541583ec1c5f505db952afb075ee53.js
root 78553d4edf Fix code quality violations for publish
Remove unused blade settings pages not linked from UI
Convert remaining frontend pages to SPA actions
Convert settings user_settings and general to SPA actions
Convert settings profile pages to SPA actions
Convert contacts and projects add/edit pages to SPA actions
Convert clients add/edit page to SPA action with loading pattern
Refactor component scoped IDs from $id to $sid
Fix jqhtml comment syntax and implement universal error component system
Update all application code to use new unified error system
Remove all backwards compatibility - unified error system complete
Phase 5: Remove old response classes
Phase 3-4: Ajax response handler sends new format, old helpers deprecated
Phase 2: Add client-side unified error foundation
Phase 1: Add server-side unified error foundation
Add unified Ajax error response system with constants

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 04:35:01 +00:00

118 lines
15 KiB
JavaScript
Executable File

"use strict";
/**
* Rsx_Tabs
*
* Tab container component with form-aware error handling integration.
* See rsx_tabs.jqhtml for full documentation.
*
* JavaScript Responsibilities:
* - Builds tab navigation dynamically from registered Rsx_Tab children
* - Manages tab activation and switching behavior
* - Persists active tab to URL hash for bookmarking
* - Integrates with form validation to show error badges on tabs
* - Auto-switches to first tab with errors on validation failure
* - Provides API for parent forms to report validation errors
*/
class Rsx_Tabs extends Component {
on_create() {
this.tabs = []; // Registered Rsx_Tab components
this.active_tab_id = null;
this.form = null;
}
on_ready() {
// Find parent form if it exists
this.form = this.closest('.Rsx_Form');
// Build tab navigation from registered tabs
this._build_nav();
// Restore active tab from URL hash or activate first tab
const hash = window.location.hash;
if (hash) {
const tab_id = hash.substring(1);
this.activate_tab(tab_id);
} else if (this.tabs.length > 0) {
this.activate_tab(this.tabs[0].args.id);
}
// Persist active tab to URL hash
const that = this;
this.$sid('nav').on('click', 'a[data-bs-toggle="tab"]', function (e) {
const tab_id = $(e.currentTarget).data('tab-id');
window.location.hash = '#' + tab_id;
});
}
register_tab(tab_component) {
this.tabs.push(tab_component);
}
_build_nav() {
const $nav = this.$sid('nav');
$nav.empty();
for (let i = 0; i < this.tabs.length; i++) {
const tab = this.tabs[i];
const is_active = i === 0 ? 'active' : '';
const $li = $(`
<li class="nav-item" role="presentation">
<a class="nav-link ${is_active}"
data-bs-toggle="tab"
href="#${tab.args.id}"
data-tab-id="${tab.args.id}"
aria-selected="${i === 0 ? 'true' : 'false'}"
role="tab">
${tab.args.icon ? `<i class="${tab.args.icon}"></i> ` : ''}
${tab.args.label}
<span class="badge bg-danger ms-2" style="display: none;" data-error-badge="${tab.args.id}">0</span>
</a>
</li>
`);
$nav.append($li);
}
}
activate_tab(tab_id) {
// Find the tab
const tab = this.tabs.find(t => t.args.id === tab_id);
if (!tab) return;
// Remove active show from all tab panes
for (let t of this.tabs) {
t.$.removeClass('active show');
}
// Add active show to the selected tab pane
tab.$.addClass('active show');
// Update Bootstrap tab navigation
this.$sid('nav').find('a[data-bs-toggle="tab"]').removeClass('active').attr('aria-selected', 'false');
this.$sid('nav').find('a[data-tab-id="' + tab_id + '"]').addClass('active').attr('aria-selected', 'true');
this.active_tab_id = tab_id;
}
handle_validation_errors(errors) {
// Count errors per tab
const tab_errors = {};
for (let tab of this.tabs) {
const error_count = tab.count_errors(errors);
tab_errors[tab.args.id] = error_count;
// Update badge
const $badge = this.$sid('nav').find(`[data-error-badge="${tab.args.id}"]`);
if (error_count > 0) {
$badge.text(error_count).show();
} else {
$badge.hide();
}
}
// Find first tab with errors
const first_errored_tab = this.tabs.find(t => tab_errors[t.args.id] > 0);
// Switch to first errored tab if not currently on an errored tab
if (first_errored_tab && tab_errors[this.active_tab_id] === 0) {
this.activate_tab(first_errored_tab.args.id);
}
}
clear_error_badges() {
this.$sid('nav').find('[data-error-badge]').hide();
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSc3hfVGFicyIsIkpxaHRtbF9Db21wb25lbnQiLCJvbl9jcmVhdGUiLCJ0YWJzIiwiYWN0aXZlX3RhYl9pZCIsImZvcm0iLCJvbl9yZWFkeSIsImNsb3Nlc3QiLCJfYnVpbGRfbmF2IiwiaGFzaCIsIndpbmRvdyIsImxvY2F0aW9uIiwidGFiX2lkIiwic3Vic3RyaW5nIiwiYWN0aXZhdGVfdGFiIiwibGVuZ3RoIiwiYXJncyIsImlkIiwidGhhdCIsIiRpZCIsIm9uIiwiZSIsIiQiLCJjdXJyZW50VGFyZ2V0IiwiZGF0YSIsInJlZ2lzdGVyX3RhYiIsInRhYl9jb21wb25lbnQiLCJwdXNoIiwiJG5hdiIsImVtcHR5IiwiaSIsInRhYiIsImlzX2FjdGl2ZSIsIiRsaSIsImljb24iLCJsYWJlbCIsImFwcGVuZCIsImZpbmQiLCJ0IiwicmVtb3ZlQ2xhc3MiLCJhZGRDbGFzcyIsImF0dHIiLCJoYW5kbGVfdmFsaWRhdGlvbl9lcnJvcnMiLCJlcnJvcnMiLCJ0YWJfZXJyb3JzIiwiZXJyb3JfY291bnQiLCJjb3VudF9lcnJvcnMiLCIkYmFkZ2UiLCJ0ZXh0Iiwic2hvdyIsImhpZGUiLCJmaXJzdF9lcnJvcmVkX3RhYiIsImNsZWFyX2Vycm9yX2JhZGdlcyJdLCJzb3VyY2VzIjpbInJzeC90aGVtZS9jb21wb25lbnRzL2Zvcm1zL3JzeF90YWJzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUnN4X1RhYnNcbiAqXG4gKiBUYWIgY29udGFpbmVyIGNvbXBvbmVudCB3aXRoIGZvcm0tYXdhcmUgZXJyb3IgaGFuZGxpbmcgaW50ZWdyYXRpb24uXG4gKiBTZWUgcnN4X3RhYnMuanFodG1sIGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogSmF2YVNjcmlwdCBSZXNwb25zaWJpbGl0aWVzOlxuICogLSBCdWlsZHMgdGFiIG5hdmlnYXRpb24gZHluYW1pY2FsbHkgZnJvbSByZWdpc3RlcmVkIFJzeF9UYWIgY2hpbGRyZW5cbiAqIC0gTWFuYWdlcyB0YWIgYWN0aXZhdGlvbiBhbmQgc3dpdGNoaW5nIGJlaGF2aW9yXG4gKiAtIFBlcnNpc3RzIGFjdGl2ZSB0YWIgdG8gVVJMIGhhc2ggZm9yIGJvb2ttYXJraW5nXG4gKiAtIEludGVncmF0ZXMgd2l0aCBmb3JtIHZhbGlkYXRpb24gdG8gc2hvdyBlcnJvciBiYWRnZXMgb24gdGFic1xuICogLSBBdXRvLXN3aXRjaGVzIHRvIGZpcnN0IHRhYiB3aXRoIGVycm9ycyBvbiB2YWxpZGF0aW9uIGZhaWx1cmVcbiAqIC0gUHJvdmlkZXMgQVBJIGZvciBwYXJlbnQgZm9ybXMgdG8gcmVwb3J0IHZhbGlkYXRpb24gZXJyb3JzXG4gKi9cbmNsYXNzIFJzeF9UYWJzIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLnRhYnMgPSBbXTsgLy8gUmVnaXN0ZXJlZCBSc3hfVGFiIGNvbXBvbmVudHNcbiAgICAgICAgdGhpcy5hY3RpdmVfdGFiX2lkID0gbnVsbDtcbiAgICAgICAgdGhpcy5mb3JtID0gbnVsbDtcbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gRmluZCBwYXJlbnQgZm9ybSBpZiBpdCBleGlzdHNcbiAgICAgICAgdGhpcy5mb3JtID0gdGhpcy5jbG9zZXN0KCcuUnN4X0Zvcm0nKTtcblxuICAgICAgICAvLyBCdWlsZCB0YWIgbmF2aWdhdGlvbiBmcm9tIHJlZ2lzdGVyZWQgdGFic1xuICAgICAgICB0aGlzLl9idWlsZF9uYXYoKTtcblxuICAgICAgICAvLyBSZXN0b3JlIGFjdGl2ZSB0YWIgZnJvbSBVUkwgaGFzaCBvciBhY3RpdmF0ZSBmaXJzdCB0YWJcbiAgICAgICAgY29uc3QgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuICAgICAgICBpZiAoaGFzaCkge1xuICAgICAgICAgICAgY29uc3QgdGFiX2lkID0gaGFzaC5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlX3RhYih0YWJfaWQpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFicy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlX3RhYih0aGlzLnRhYnNbMF0uYXJncy5pZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQZXJzaXN0IGFjdGl2ZSB0YWIgdG8gVVJMIGhhc2hcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIHRoaXMuJGlkKCduYXYnKS5vbignY2xpY2snLCAnYVtkYXRhLWJzLXRvZ2dsZT1cInRhYlwiXScsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBjb25zdCB0YWJfaWQgPSAkKGUuY3VycmVudFRhcmdldCkuZGF0YSgndGFiLWlkJyk7XG4gICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaGFzaCA9ICcjJyArIHRhYl9pZDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmVnaXN0ZXJfdGFiKHRhYl9jb21wb25lbnQpIHtcbiAgICAgICAgdGhpcy50YWJzLnB1c2godGFiX2NvbXBvbmVudCk7XG4gICAgfVxuXG4gICAgX2J1aWxkX25hdigpIHtcbiAgICAgICAgY29uc3QgJG5hdiA9IHRoaXMuJGlkKCduYXYnKTtcbiAgICAgICAgJG5hdi5lbXB0eSgpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50YWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCB0YWIgPSB0aGlzLnRhYnNbaV07XG4gICAgICAgICAgICBjb25zdCBpc19hY3RpdmUgPSBpID09PSAwID8gJ2FjdGl2ZScgOiAnJztcblxuICAgICAgICAgICAgY29uc3QgJGxpID0gJChgXG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibmF2LWl0ZW1cIiByb2xlPVwicHJlc2VudGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibmF2LWxpbmsgJHtpc19hY3RpdmV9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgZGF0YS1icy10b2dnbGU9XCJ0YWJcIlxuICAgICAgICAgICAgICAgICAgICAgICBocmVmPVwiIyR7dGFiLmFyZ3MuaWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10YWItaWQ9XCIke3RhYi5hcmdzLmlkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgIGFyaWEtc2VsZWN0ZWQ9XCIke2kgPT09IDAgPyAndHJ1ZScgOiAnZmFsc2UnfVwiXG4gICAgICAgICAgICAgICAgICAgICAgIHJvbGU9XCJ0YWJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7dGFiLmFyZ3MuaWNvbiA/IGA8aSBjbGFzcz1cIiR7dGFiLmFyZ3MuaWNvbn1cIj48L2k+IGAgOiAnJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICR7dGFiLmFyZ3MubGFiZWx9XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLWRhbmdlciBtcy0yXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiIGRhdGEtZXJyb3ItYmFkZ2U9XCIke3RhYi5hcmdzLmlkfVwiPjA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgYCk7XG5cbiAgICAgICAgICAgICRuYXYuYXBwZW5kKCRsaSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhY3RpdmF0ZV90YWIodGFiX2lkKSB7XG4gICAgICAgIC8vIEZpbmQgdGhlIHRhYlxuICAgICAgICBjb25zdCB0YWIgPSB0aGlzLnRhYnMuZmluZCgodCkgPT4gdC5hcmdzLmlkID09PSB0YWJfaWQpO1xuICAgICAgICBpZiAoIXRhYikgcmV0dXJuO1xuXG4gICAgICAgIC8vIFJlbW92ZSBhY3RpdmUgc2hvdyBmcm9tIGFsbCB0YWIgcGFuZXNcbiAgICAgICAgZm9yIChsZXQgdCBvZiB0aGlzLnRhYnMpIHtcbiAgICAgICAgICAgIHQuJC5yZW1vdmVDbGFzcygnYWN0aXZlIHNob3cnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBhY3RpdmUgc2hvdyB0byB0aGUgc2VsZWN0ZWQgdGFiIHBhbmVcbiAgICAgICAgdGFiLiQuYWRkQ2xhc3MoJ2FjdGl2ZSBzaG93Jyk7XG5cbiAgICAgICAgLy8gVXBkYXRlIEJvb3RzdHJhcCB0YWIgbmF2aWdhdGlvblxuICAgICAgICB0aGlzLiRpZCgnbmF2JykuZmluZCgnYVtkYXRhLWJzLXRvZ2dsZT1cInRhYlwiXScpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKS5hdHRyKCdhcmlhLXNlbGVjdGVkJywgJ2ZhbHNlJyk7XG4gICAgICAgIHRoaXMuJGlkKCduYXYnKVxuICAgICAgICAgICAgLmZpbmQoJ2FbZGF0YS10YWItaWQ9XCInICsgdGFiX2lkICsgJ1wiXScpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICAgICAgICAuYXR0cignYXJpYS1zZWxlY3RlZCcsICd0cnVlJyk7XG5cbiAgICAgICAgdGhpcy5hY3RpdmVfdGFiX2lkID0gdGFiX2lkO1xuICAgIH1cblxuICAgIGhhbmRsZV92YWxpZGF0aW9uX2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgLy8gQ291bnQgZXJyb3JzIHBlciB0YWJcbiAgICAgICAgY29uc3QgdGFiX2Vycm9ycyA9IHt9O1xuXG4gICAgICAgIGZvciAobGV0IHRhYiBvZiB0aGlzLnRhYnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yX2NvdW50ID0gdGFiLmNvdW50X2Vycm9ycyhlcnJvcnMpO1xuICAgICAgICAgICAgdGFiX2Vycm9yc1t0YWIuYXJncy5pZF0gPSBlcnJvcl9jb3VudDtcblxuICAgICAgICAgICAgLy8gVXBkYXRlIGJhZGdlXG4gICAgICAgICAgICBjb25zdCAkYmFkZ2UgPSB0aGlzLiRpZCgnbmF2JykuZmluZChgW2RhdGEtZXJyb3ItYmFkZ2U9XCIke3RhYi5hcmdzLmlkfVwiXWApO1xuICAgICAgICAgICAgaWYgKGVycm9yX2NvdW50ID4gMCkge1xuICAgICAgICAgICAgICAgICRiYWRnZS50ZXh0KGVycm9yX2NvdW50KS5zaG93KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICRiYWRnZS5oaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIGZpcnN0IHRhYiB3aXRoIGVycm9yc1xuICAgICAgICBjb25zdCBmaXJzdF9lcnJvcmVkX3RhYiA9IHRoaXMudGFicy5maW5kKCh0KSA9PiB0YWJfZXJyb3JzW3QuYXJncy5pZF0gPiAwKTtcblxuICAgICAgICAvLyBTd2l0Y2ggdG8gZmlyc3QgZXJyb3JlZCB0YWIgaWYgbm90IGN1cnJlbnRseSBvbiBhbiBlcnJvcmVkIHRhYlxuICAgICAgICBpZiAoZmlyc3RfZXJyb3JlZF90YWIgJiYgdGFiX2Vycm9yc1t0aGlzLmFjdGl2ZV90YWJfaWRdID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlX3RhYihmaXJzdF9lcnJvcmVkX3RhYi5hcmdzLmlkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNsZWFyX2Vycm9yX2JhZGdlcygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ25hdicpLmZpbmQoJ1tkYXRhLWVycm9yLWJhZGdlXScpLmhpZGUoKTtcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU1BLFFBQVEsU0FBU0MsZ0JBQWdCLENBQUM7RUFDcENDLFNBQVNBLENBQUEsRUFBRztJQUNSLElBQUksQ0FBQ0MsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQ2hCLElBQUksQ0FBQ0MsYUFBYSxHQUFHLElBQUk7SUFDekIsSUFBSSxDQUFDQyxJQUFJLEdBQUcsSUFBSTtFQUNwQjtFQUVBQyxRQUFRQSxDQUFBLEVBQUc7SUFDUDtJQUNBLElBQUksQ0FBQ0QsSUFBSSxHQUFHLElBQUksQ0FBQ0UsT0FBTyxDQUFDLFdBQVcsQ0FBQzs7SUFFckM7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