PageSourceSearch

https://smrtbld.ai/js/pages/settings/utils.js

js smrtbld.ai collected 2026-10-05 15:09:15 UTC 2,778 bytes, 79 lines download raw bytes

1/**
2 * Settings - Shared Utilities
3 * Helper functions used across all settings tab modules.
4 *
5 * String formatting (formatPhoneNumber) lives in utils/string-format.js — this
6 * file re-exports it for backward compat. Generic state-render lives in
7 * utils/state-views.js; generic busy-button lives in utils/dom.js
8 * (runWithBusyButton). `saveWithButton` here is a thin settings-flavored
9 * wrapper around runWithBusyButton that adds a "Saved" success toast.
10 */
11
12import { runWithBusyButton } from '../../utils/dom.js';
13import { showLoading as showStateLoading, showError as showStateError } from '../../utils/state-views.js';
14import { formatPhoneNumber } from '../../utils/string-format.js';
15
16// Re-export so existing callers (notifications.js) don't need to change.
17export { formatPhoneNumber };
18
19/**
20 * Get trimmed value from an input element by ID
21 */
22export function getValue(id) {
23    const el = document.getElementById(id);
24    return el?.value?.trim() || '';
25}
26
27/**
28 * Close/clear a modal container
29 */
30export function closeModal(container) {
31    if (container) container.innerHTML = '';
32}
33
34/**
35 * Show the settings-flavored loading state.
36 * Delegates to state-views via the templateId escape hatch so we get
37 * afterRender + lifecycle for free while keeping the bespoke template.
38 */
39export function showLoading(container) {
40    showStateLoading(container, { templateId: '#tpl-settings-loading' });
41}
42
43/**
44 * Show the settings-flavored error state with a "Reload Page" button.
45 * Delegates to state-views; wires the reload button afterward since the
46 * bespoke template uses [data-action="reload-page"] (not state-views'
47 * standard [data-action="retry"]).
48 */
49export function showError(container, title, message) {
50    showStateError(container, {
51        templateId: '#tpl-settings-error',
52        data: { title, message },
53    });
54    container?.querySelector('[data-action="reload-page"]')
55        ?.addEventListener('click', () => location.reload());
56}
57
58/**
59 * Run a settings save with the canonical busy-button choreography plus a
60 * success toast. Mirrors runWithBusyButton's contract — returns the operation's
61 * resolved value (or undefined on error/abort).
62 *
63 * @param {HTMLElement} button - The save button element
64 * @param {() => Promise<any>} operation - The async save work
65 * @returns {Promise<any|undefined>}
66 */
67export async function saveWithButton(button, operation) {
68    return runWithBusyButton(button, 'Saving...', async () => {
69        const result = await operation();
70        window.showToast?.('Saved', 'success', {
71            description: 'Your changes have been saved',
72        });
73        return result;
74    }, {
75        errorTitle: 'Save failed',
76        errorLogPrefix: '[Settings Save]',
77        resetOnSuccess: true,
78    });
79}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.