DEV Community

Cover image for OpenSparrow v4.5 adds a chat shortcut on user tooltips
Tomasz
Tomasz

Posted on

OpenSparrow v4.5 adds a chat shortcut on user tooltips

OpenSparrow v4.5 adds a chat shortcut on user tooltips, a per‑page Click Statistics breakdown with date‑range filters, and a last‑edited‑by line in the Record History tab — plus a base64 logo upload that works on shared hosting with an unwritable temp dir.

A chat shortcut on every user tooltip

Every record owner and comment author tooltip now ends with a small chat button. User tooltips already went through one shared funnel (enableUserTooltips() in public/assets/js/util/user-tooltip.js), which fetches the user's contact card via api/owners.php?action=user_info and renders it through the record tooltip; the model now also carries a chat action when the target is not yourself (info.id !== window.CURRENT_USER_ID). Clicking the button dynamically imports chat-panel.js and calls openChatPanel(peer), so the messenger opens straight into that person's thread — even when no prior conversation exists (the empty thread renders and the first send creates the message). The shortcut respects the existing chat_enabled gate and simply does not appear for the self user.

Click Statistics: per‑page breakdown and date filtering

The Click Statistics admin panel gains a Pages tab: one tile per page script, each showing its icon and click count, aggregated from spw_clickstats with the same element/user filters as the Log and Top Elements tabs. The rollup is computed server‑side (GROUP BY c.page, COALESCE(c.page, '') for empty pages) and rendered as a responsive icon grid, with unknown pages labelled "Unknown page". The Log, Top Elements and Pages tabs all accept a new From/To date range, validated against a YYYY-MM-DD shape before it reaches SQL and applied as a half‑open window (created_at >= from and created_at < to + 1 day) so both bounds are inclusive.

Record History: who last edited the record

The Record History tab now shows a "Last edit" line under the owner section, answering "who edited this record and when" directly. It is read from the audit log (spw_users_log) through a new owners last_edit API action: the latest INSERT/UPDATE row for (target_table, record_id), joined to spw_users for the username and avatar. Mass edits and board/calendar moves log with record_id = null, so they correctly never appear — the line reflects edit/create-form saves only. The table and record are gated through the usual validatedTable() → require_table_access() path, so a user only sees last‑edit info for tables they can already access.

Branding logo upload that survives shared hosting

The branding logo upload moved off multipart. A shared host with an unwritable upload_tmp_dir previously failed every $_FILES upload with "No file received", because PHP writes the temp file before any userland code runs and upload_tmp_dir/sys_temp_dir are PHP_INI_SYSTEM (only settable in php.ini). The admin now reads the image with FileReader.readAsDataURL() and POSTs it as JSON base64 through php://input, so no temp directory is ever touched. The backend guards the payload length before decoding, re‑checks the decoded size against the 2 MB limit, validates the MIME via finfo::buffer(), and writes straight into public/assets/img/uploads. The $_FILES path stays as a fallback, and its error codes now map to distinct messages — including a dedicated "set upload_tmp_dir in the hosting panel" hint for UPLOAD_ERR_NO_TMP_DIR.

Also in this release

  • Demo contact fields — the CRM demo users are now seeded with first name, last name, email and phone, so the record‑history and user tooltips show full info right after install (reinstall from Admin → Demo to pick them up).
  • Audit‑log last‑edit — backed by the existing spw_users_log trail, no new table or migration is required.

Following this series?

OpenSparrow v4.4 adds one-to-one user chat, an HTTP cron trigger, and content-sized admin tables

Websites

https://opensparrow.org

Top comments (1)

Collapse
 
wrobeltomasz profile image
Tomasz •

I encourage you to join the discussion; I'll do my best to answer any questions you may have about the system.