Revision history for Database-BI

0.003.0	Wed Aug 26 01:00:39 PM EDT 2026
    [ Enhancements ]
    - Platform and language are now detected per-request rather than read
      statically from config.  CGI::Info inspects the User-Agent header to
      select 'mobile', 'tablet', or 'web'; CGI::Lingua selects the best
      ISO 639-1 language from the Accept-Language header against the set of
      languages that have a template directory under templates/<platform>/.
      Config values (platform, language) remain as fallbacks for when a
      module is unavailable, the header is absent, or no template directory
      exists for the detected value.
    - Add "Refresh" button (↻) to the toolbar next to Export.  Pressing it
      reloads the current view from disk, picking up any changes to the
      source file(s) since the page was last loaded.  All URL state (joins,
      filters, dedup) is preserved because location.reload() reuses the
      current URL.
    - Add "Hide duplicates / Show duplicates" toggle button to the toolbar.
      When active (filled blue), duplicate rows are removed from the displayed
      table and from any CSV or SQLite export.  The button text reflects the
      current state: "Hide duplicates" when duplicates are visible, "Show
      duplicates" when they are suppressed.  State is carried in the ?d=1
      query parameter so the URL remains shareable and bookmarkable.
    - Added "Clear upload cache" button (POST /uploads/clear).
      Mojo::File->list() requires {dir => 1} to
      include subdirectories; without it the upload subdirs are silently
      skipped and the action always reports 0 files freed.

    [ Bug Fixes ]
    - Files opened via the "recently saved" section are no longer also added
      to the "recently opened" list.  The saved-section card href now carries
      a transient ?from=saved marker; the dashboard JS reads and removes it
      via history.replaceState (keeping the address bar clean) and skips the
      bi:recent write when the marker is present.
    - Recently saved files on the home page now open with a single click;
      double-click was required before, making the feature effectively
      inaccessible on touch devices and to users who did not discover the
      interaction.  Missing files (greyed-out cards) still block navigation.

0.002.0	Wed Aug 26 08:21:12 EDT 2026
    [ Enhancements ]
    - Add "Recently saved" section to the home page: the last 5 files written
      via POST /export appear as cards below "Recently opened".  Each card
      fetches /api/stat on page load -- missing files are immediately greyed
      out and their cards block navigation.  Mouseover shows saved-on date,
      last-modified time, file size, and a "File not found on disk" warning
      when the file has been moved or deleted.
    - Add "Combine data" feature (GET /combine): stack rows from two or more
      data files vertically into a unified view.  All columns from all sources
      appear as headers; cells are blank where a source file lacks that column.
      Equivalent to a SQL UNION ALL across heterogeneous schemas.
    - New "Combine data..." toolbar button (teal) sits next to "Merge data...";
      both panels are mutually exclusive (opening one closes the other).
    - Export pipeline (GET /export, POST /export) now handles c= params so
      combined views can be downloaded or saved to disk.
    - Internal helpers migrated from Sub::Private (:Private) to Sub::Protected
      (:Protected) in Dashboard.pm and DataSource.pm for correct OO dispatch
      in production (morbo/hypnotoad) without the CHECK-phase stash-deletion
      side-effect that made :Private OO calls fail at runtime.
    - "Merge data" button tooltip improved; join chip no longer shows key
      annotation for combine summaries that have no join key.

0.001.0	Tue Aug 25 08:14:37 PM EDT 2026
    - Initial CPAN release.
    - Mojolicious web application presenting arbitrary flat data files
      (CSV, PSV, XML, SQLite) as styled, sortable, reorderable HTML tables.
    - Home page card grid; filesystem browser (/browse, /open).
    - In-memory left-join engine (/join) with repeatable join steps.
    - Server-side result filters (eq, ne, contains, starts, lt, le, gt, ge,
      empty, notempty operators).
    - CSV and SQLite export via GET /export (stream download) and
      POST /export (filesystem write).
    - Drag-and-drop file upload (POST /upload).
    - JSON APIs: /api/columns, /api/dirs, /api/stat.
    - URL import: fetch and display an HTML table from any public URL
      (/import).
    - localStorage persistence for column order and sort state.
