Files
hermes-config/skills/self-hosting/shop-pro-quote/references/settings-field-addition-pattern.md
T
2026-07-12 10:17:17 -04:00

4.4 KiB
Raw Blame History

Adding a New Site Configuration Setting

When adding a single new setting to the Site Configuration modal, you MUST update 6 places across the codebase. Missing any one will cause silent failures.

Checklist (ordered, follow exactly)

1. settings.js — Add default value

// In the `let appSettings = { ... }` block (~line 8)
notifyBeforePromised: 0,   // 0 = off, 15/30/60 = minutes before promised time

2. settings.js — Populate form on load (populateSiteSettingsForm)

// ~line 244
setValue('notify-before-promised', appSettings.notifyBeforePromised, 0);

Use setChecked() for checkboxes/toggles, setValue() for selects/inputs.

3. settings.js — Save handler (setupUnifiedSiteSettingsModalHandlers) ×2

There are TWO save handlers that must both read the new field:

// ~line 277 (inside setupUnifiedSiteSettingsModalHandlers)
appSettings.notifyBeforePromised = parseInt(document.getElementById('notify-before-promised')?.value ?? '0');

// ~line 1008 (window.saveSiteSettings bridge — repair-orders inline onclick)
appSettings.notifyBeforePromised = parseInt(document.getElementById('notify-before-promised')?.value ?? '0');

Use replace_all=true when patching since the two blocks are identical.

4. settings.js — Auto-save binding (attachSiteSettingsAutoSave)

// ~line 559
bind('notify-before-promised', 'change', (el) => appSettings.notifyBeforePromised = parseInt(el.value || '0'));

Use 'change' for selects, 'change' for checkboxes.

5. settings.js — Realtime sync (subscribeToRealtimeSettings)

// ~line 677
setIfSafe('notify-before-promised', String(appSettings.notifyBeforePromised ?? 0));

Use String() for value fields, !! + 'checked' for checkbox fields.

6. ALL FOUR HTML pages — Add the form control

  • repair-orders.html — inside #site-settings-modal → Notifications card
  • appointments.html — inside #site-settings-modal → Notifications card
  • customers.html — inside #site-settings-modal → Notifications card
  • index.html — inside #site-settings-modal → Notifications card

All four pages need the identical HTML block. Find the Critical Alerts toggle section and add the new control right after it, before the closing </div> of the Notifications card.

Template for a select dropdown:

<div>
    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Setting Label</label>
    <p class="text-xs text-gray-500 dark:text-gray-400 mb-2">Help text explaining the setting</p>
    <select id="setting-id" class="w-full p-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 focus:ring-2 focus:ring-purple-500 focus:outline-none">
        <option value="0">Off</option>
        <option value="15">15 minutes before</option>
        <option value="30">30 minutes before</option>
        <option value="60">1 hour before</option>
    </select>
</div>

Template for a toggle switch:

<div class="flex items-center justify-between">
    <div>
        <label class="text-sm font-medium text-gray-700 dark:text-gray-300">Toggle Label</label>
        <p class="text-xs text-gray-500 dark:text-gray-400">Help text</p>
    </div>
    <label class="toggle-switch">
        <input type="checkbox" id="toggle-id">
        <span class="slider"></span>
    </label>
</div>

Verification

After all changes, verify with curl:

# settings.js should have 6 references (default, populate, save×2, auto-save, realtime)
curl -sk https://localhost/settings.js | grep -c 'newFieldName'

# Each page should have exactly 1 reference (the element)
for page in repair-orders.html appointments.html customers.html index.html; do
  echo "$page: $(curl -sk https://localhost/$page | grep -c 'element-id')"
done

Common mistakes

  • Forgetting the second save handler: window.saveSiteSettings (the bridge at file end) is a DUPLICATE of the handler inside setupUnifiedSiteSettingsModalHandlers. Both must read the new field.
  • Missing a page: All 4 pages use the same settings.js backend, so the form control must exist on all 4 or getElementById returns null.
  • Wrong bind event type: Use 'change' for selects and checkboxes, not 'input'.
  • HTML ID mismatch: The id attribute in HTML must exactly match the document.getElementById() call in JS.