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.