• v7.16.0 Stable

    gitea-actions released this 2026-09-28 09:09:46 +00:00 | 56 commits to main since this release

    Data Controller for SAS - v7.16.0

    Released 28 September 2026.

    This release makes Data Controller easier to support and safer to deploy. The frontend now reports the context of the session - browser, version, timezone, the page URL and its parameters - so a support ticket can be diagnosed from the job log rather than a round of follow-up questions. Every release now ships checksums, so a download can be verified before it is deployed into a SAS environment. The applied-filter panel also becomes readable when a filter clause runs past a single line.

    There is no security content in this release, and nothing that forces an upgrade.

    For installation / upgrade instructions, visit https://docs.datacontroller.io/


    Highlights

    Support diagnostics travel with every request

    A support ticket often opens with a question about the environment: which browser, which Data Controller build, which timezone the user is in, and which page they arrived on. Data Controller now answers those from the job log.

    The frontend sends two input tables with the startup service and with the services that run customer-provided code - the hook scripts (pre/post edit and pre/post approve hooks) and the dynamic cell dropdown programs:

    • browser_info - one row describing the session: the Data Controller page URL, the referring (embedding) document, the browser timezone and its UTC offset, the locale, the Data Controller build, the @sasjs/adapter version, and the browser family and version.
    • browser_url_vars - the page URL parameters as one row per parameter (name, value), so a SAS program reads a parameter by name rather than parsing the URL string. Parameters from both the search string and the hash query string (Angular routes carry them after the #) are included. The table is sent only when the page URL has at least one parameter.

    Turn debug on in the app and the session initialisation writes both tables to the job log:

    NOTE: MPEINIT: work.browser_url_vars:
    name=embed value=va
    NOTE: MPEINIT: work.browser_info:
    url=... referrer=... timezone=Europe/Berlin tz_offset=-120 locale=en-GB
    dc_version=7.16.0 adapter_version=4.19.0 browser=Chrome browser_version=120.0
    platform=Linux user_agent=...
    

    The tables are readable from a hook as work.browser_info / work.browser_url_vars, so a hook can adapt to the context it was called in - the embedding report, a label flag, the user's timezone. Guard with %sysfunc(exist()) before reading, because a service called directly (or by a frontend older than this feature) has neither table.

    The values are supplied by the client, so treat them as diagnostics hints and never as a security boundary.

    Which services receive the tables, the full column list, and how to read them from a hook are all in the troubleshooting documentation.

    Every release now ships checksums

    Release assets are deployed into SAS environments, so a download should be verifiable before it is used. Each release now carries a SHA256SUMS file covering every asset, and the release notes carry the one-line check:

    sha256sum --check SHA256SUMS --ignore-missing
    

    Download the assets and SHA256SUMS into the same folder and run the command; it reports OK for each file that matches. A matching checksum confirms the download is byte-for-byte the file the pipeline uploaded, which guards against a corrupted or tampered transfer. It is an integrity check, not a signature - the hashes travel in the same release as the files. The downloads documentation lists every release asset and what it is for.

    Reading a long filter clause

    The applied-filter panel above the grid was clamped to a single line, so a long or complex filter could not be read on screen. The panel is now collapsed to one line and carries a chevron that expands it to show the whole clause, wrapped, and collapses it again.

    The chevron is rendered only when the clause does not fit the collapsed line, so a short filter looks exactly as it did before. The clause is set in the monospace face the app already uses for code-like content, so a query reads as a query.

    A short filter, unchanged - shown in full, with no chevron:

    A short filter clause shown in full, with no chevron

    A long filter (a 646-character IN clause) collapsed to the chevron:

    A long filter clause collapsed to one line with a chevron

    The same clause expanded, wrapped over several lines:

    The same long filter clause expanded over several lines

    On the edit page, where the clause was previously truncated with an ellipsis - collapsed:

    The editor's filter clause collapsed with a chevron

    The same clause on the edit page, expanded in full:

    The editor's filter clause expanded in full

    Also in this release

    • A post edit hook that routes a changeset to an unregistered table now fails immediately, with a clear message. A POST_EDIT_HOOK may re-point a changeset at a different table - that is what lets an empty mirror stand in for a real one - but nothing checked the result. A hook pointing at a table with no MPE_TABLES row produced a changeset the approval screen could not process, and the failure surfaced as a syntax error rather than an explanation. The loader now validates the target while the submitter is still watching, and cancels with the table name and the reason. A hook may only route a changeset to a registered table.
    • The deploy screen no longer ships a hardcoded dcPath. The frontend template carried /tmp/dc as a default. A Viya deployment cannot necessarily write there, and because a deploy re-streams the frontend, the stale value could land in the deployed app and be passed to the control-library creation, leaving the control library somewhere the next compute session cannot see. The deploy screens already derive a platform-appropriate default and expose the path as an editable field, so the shipped default was only a hazard.
    • The sidebar sub-page label no longer shows URL parameters. A route carrying any parameter (a VA report embed always adds one) rendered as TABLES?EMBED=VA; the label now shows TABLES.
    • iOS browsers are reported correctly in the diagnostics described above.

    If you are upgrading

    Nothing in this release changes how existing tables, rules, hooks or screens behave, and no configuration change is required. The diagnostics tables are sent automatically, and only to the startup service and the services that run customer-provided code - the high-frequency viewer and metadata calls do not receive them.

    Verifying the download

    Every asset on this release is covered by the SHA256SUMS file. To verify a download, fetch SHA256SUMS from the release assets alongside the files you downloaded, then run:

    sha256sum --check SHA256SUMS --ignore-missing
    

    The command reports OK for each asset that matches. --ignore-missing lets you check just the files you downloaded rather than all of them.

    What this protects: a matching checksum confirms the asset is byte-for-byte the file this pipeline uploaded, guarding against corrupted or tampered downloads (mirrors, proxies, interrupted transfers). It is not a signature: the hashes travel in the same release as the files, so a compromise of the forge itself could alter both. Treat it as an integrity check, not a trust anchor.

    Downloads