⬡ Lacelium
⌘K
Version 2.x ▾

Quick start

This site already loads the proxy script globally. On a custom page, ensure /assets/maintenance/maintenance-modal.js is loaded (it lazy-loads the core scripts when you first open a modal).

1) Call a helper

Use one of the convenience helpers for common actions.

2) Or call open()

Use open() when you need to choose the mode dynamically.

// The only required fields are table + mode.
// For edit/view/delete you must also pass id (or rowIndex).
MaintenanceModal.open({
  table: 'm_module_type',
  mode: 'edit',
  id: '1665231610866'
});

API reference

Global object

Available as window.MaintenanceModal. All methods return a Promise.

// Proxy (always present if maintenance-modal.js is loaded)
MaintenanceModal.ensureReady(): Promise<void>
MaintenanceModal.open(options): Promise<void>
MaintenanceModal.add(table): Promise<void>
MaintenanceModal.view(table, id): Promise<void>
MaintenanceModal.edit(table, id): Promise<void>
MaintenanceModal.remove(table, id): Promise<void>

open(options) options

  • table (string, required): The maintenance module table name (example: m_module_type).
  • mode (string): add/create, view, edit, delete/remove. Default is view.
  • id (string|number): Required for view/edit/delete if you don’t provide rowIndex.
  • rowIndex (number): Optional alternative to id when you already know the index in the cached records list.
  • type (string): Alias for mode (the core accepts either).
  • trigger (Element): Proxy-only. The button/link to show as “loading” while scripts load. Defaults to document.activeElement if it’s an element.
  • loadingText (string): Proxy-only. Default is Opening….

Convenience helpers

// Add (create)
await MaintenanceModal.add('m_module_type');

// View
await MaintenanceModal.view('m_module_type', '1665231610866');

// Edit
await MaintenanceModal.edit('m_module_type', '1665231610866');

// Delete (shows a confirm flow)
await MaintenanceModal.remove('m_module_type', '1665231610866');

How it works (important details)

  • Lazy loading: The proxy loads /assets/maintenance/api.js and /assets/maintenance/maintenance.js on demand.
  • Trigger loading state: When you call a method from a focused button/link, the proxy sets aria-busy, disables the trigger, and (optionally) swaps the text until the modal fires shown.bs.modal.
  • Modal DOM is auto-created: If #maintenance-modal / #maintenance-confirm-modal do not exist, the core script creates and appends them to document.body.
  • Record resolution: For view/edit/delete, the core tries to find the record in its cached list; if it can’t, it calls /api/maintenance/{table}/{id} and temporarily appends the record for the modal session.
  • Bootstrap optional: If Bootstrap’s JS (window.bootstrap.Modal) is available it is used; otherwise a small fallback controller shows/hides the modal and still emits shown.bs.modal/hidden.bs.modal events.

Rich text fields

If a field is rendered as <textarea data-field-type="rich-text">, the modal upgrades it to a lightweight editor (toolbar + contenteditable) and keeps the textarea in sync.

Proxy vs direct core scripts

There are two supported ways to enable Maintenance modals. Use the proxy for “any page” integration; use direct core scripts when you’re building a dedicated Maintenance screen and want the scripts available immediately.

Option A: Proxy (recommended for most pages)

  • Load: Only /assets/maintenance/maintenance-modal.js.
  • Behavior: Lazy-loads api.js + maintenance.js on first use.
  • UX: Supports trigger + loadingText to show “Opening…” on the clicked button.
  • Best for: Front/back pages that just need “open a modal” without maintaining the full Maintenance UI.
<script src="/assets/maintenance/maintenance-modal.js" defer></script>

<button type="button" onclick="MaintenanceModal.edit('m_module_type', '1665231610866')">
  Edit
</button>

Option B: Direct core scripts (Maintenance screens)

  • Load: /assets/maintenance/api.js and /assets/maintenance/maintenance.js (in that order).
  • Behavior: No lazy-loading; window.MaintenanceModal is defined by the core and has __ready: true.
  • UX note: Proxy-only options (trigger, loadingText) are not used by the core.
  • Best for: The Maintenance admin pages that also render the list UI and need the whole toolkit.
<script src="/assets/maintenance/api.js"></script>
<script src="/assets/maintenance/maintenance.js"></script>

// Now MaintenanceModal is ready immediately.
MaintenanceModal.open({ table: 'm_module_type', mode: 'view', id: '1665231610866' });

Backend requirements

  • Make sure the Maintenance API is accessible under /api/maintenance.
  • The modal fetches module metadata and records on demand (and may fetch a single record by id if it isn’t in the current cache).
  • The REST client used by the core supports: config, modules, list, get, create, update, delete, form.
// Endpoints used by the built-in MaintenanceAPI client
GET    /api/maintenance/config
GET    /api/maintenance/modules
GET    /api/maintenance/{table}
GET    /api/maintenance/{table}/{id}
GET    /api/maintenance/{table}/form
POST   /api/maintenance/{table}
PUT    /api/maintenance/{table}/{id}
DELETE /api/maintenance/{table}/{id}

Troubleshooting

  • “Missing Table” / “Unknown module selected”: The table you passed doesn’t exist in the Maintenance modules list returned by the backend.
  • “Record Missing”: The record wasn’t in the cached list and the GET /api/maintenance/{table}/{id} call failed (or returned { error: ... }).
  • Nothing happens on click: Check that MaintenanceModal exists in the browser console and that /assets/maintenance/maintenance-modal.js is loading without 404s.