github austinginder/minn-admin v0.19.0

latest releases: v0.38.0, v0.37.0, v0.36.0...
one month ago

v0.19.0 - July 19, 2026

The storefront release. Orders stop being modal glimpses and become real pages with their own URLs, payments arrive by hand (a check in the mail is two clicks), refunds learn the order's own line items, and the Overview says out loud when the store needs you. Around the store: every site log in one viewer with a collapse-repeats mode, live posts carrying unsaved edits get a name (Modified) in the content list, Yes/No notices finally answer properly, and the post-lock story closes its last blind window with a server-side guard.

Added

  • Orders open as a full page: clicking an order now navigates to /minn-admin/orders/{id}, a real URL: linkable, refreshable and back-button friendly. The page hosts the full detail (customer and shipping, items, status, the Payment card with Record payment, refunds, WooCommerce emails, notes, subscriptions, and the customer's other orders) at full height with no inner scrollbox, the header keeps the status pill in view, and the Orders sidebar item stays lit. Every order reference navigates there: related orders on the page, a customer's order history, a subscription's parent and renewal orders, and a newly created order lands on its page too. The old modal survives as Quick view: a hover eye button on each row for one click, plus an entry on the row's right-click menu, with an Open full page action in its footer.
  • Receive payments by hand: the order modal gains a Payment card with the payment method (your enabled gateways plus a free-form Other), a transaction ID field, and a Record payment button on unpaid orders. A check arrives in the mail: pick Check payments, note the check number, record. Pending orders run through WooCommerce's own payment_complete (paid date, status move, stock and email hooks all fire); on-hold check orders, which WooCommerce's REST guard skips, get the paid stamp and processing status set explicitly, exactly as an admin would by hand. Method and transaction edits also ride the normal Save changes without touching the paid state.
  • The Overview knows when the store needs you: with WooCommerce active, a Store strip joins the dashboard under the stat cards listing the orders that need working today: awaiting payment, on hold, to fulfill and failed. Each count is a chip that lands on the Orders list pre-filtered to that status, a View orders button keeps the plain door, and an all-clear store says "All caught up" out loud instead of hiding the strip. Counts read from WooCommerce's own order counters, and the strip only renders for users who can manage orders.
  • The third state has a name: Modified. A published, scheduled or private post carrying unsaved edits (its newest autosave is newer than the version being served) now says so in the content list: an amber Modified chip beside the status, and a quiet Modified toolbar filter that shows only those posts. The state already existed, since Minn's status-aware autosave protects live posts by writing edits to revisions instead of the live copy; now it is named and filterable, backed by a minn_modified REST field and collection filter on every REST-visible post type. The editor's amber restore banner remains the way back in.
  • Site logs, all in one viewer: the System page's log viewer outgrew the single debug log. The Debug tools card now lists every log the site has: the WordPress debug log, the PHP error log when it is a separate file, and one source per WooCommerce log channel (gateway errors, transactional emails, fatal errors), each read through WooCommerce's own log controller. The full-screen viewer gains a source picker, and a collapse repeats mode that ignores digits when grouping, so ten thousand "Undefined index on line 47" repeats read as one line with a count. Clearing stays per source and only where it is safe (file logs you can write; WooCommerce retention stays on its own screen), plus a ⌘K "View site logs" command. Plugins and host mu-plugins can register their own sources through the new minn_admin_log_sources filter, documented in the author guide; Minn deliberately never guesses at web-server log paths.
  • More from this customer: the order modal lists the customer's other orders (status, total, age), found by account for registered customers and by billing email for guests. Click one to jump straight to it, or View all to open the Orders list pre-filtered to that customer.

Improved

  • Refunds grew up: the order Refund card lists the order's items with quantity steppers, so refunding two of the three mugs is two clicks. The amount computes itself (tax included) while staying hand-editable for shipping or goodwill refunds, and a Restock refunded items toggle rides WooCommerce's own restocking. The gateway checkbox names the real gateway ("Also refund via Stripe") and only appears when that gateway can actually push money back; check and manual orders say plainly that the record is manual and the money moves outside the site. Refund rows in the totals list gained when and who, plus a delete control that removes a mistaken refund record and restores the totals, with honest copy that money a gateway already sent is not pulled back. Underneath, a refund-state endpoint serves the accounting Minn could not get from wc/v3: per-line refunded quantities through WooCommerce's own bookkeeping, refunder names resolved server-side, and whether the order's gateway supports refunds.
  • The Playground demo feels like a lived-in site: the WordPress Playground blueprint now ships Koko Analytics with 65 days of seeded traffic (site totals, per-page stats and referrers, dated relative to whenever you launch it), so the Overview opens on a real Traffic chart with working day drill-downs. Code Snippets comes preloaded with three example snippets and User Switching joins the demo roster alongside Simple History, Redirection and the example adapter. Seeding runs through each plugin's own machinery (Koko's migration hook, Code Snippets' save API), and the demo continues to request the latest WordPress build Playground ships.
  • The payment picker mirrors wp-admin exactly: the method list is served by a Minn endpoint reading each gateway's computed title (the same call wp-admin's own dropdown renders and stores), so the options and the stored payment_method_title match the WooCommerce order screen byte-for-byte, even for gateways that generate their titles like Stripe. Saving without touching the method never rewrites the stored title (wp-admin's own rule).
  • The order modal's dropdowns are themed comboboxes: status, payment method and the WooCommerce email picker join the app's searchable combobox style; the last OS-drawn selects in the modal are gone.

Fixed

  • Activating a Performance Lab module no longer strands the list: turning a feature on installs and activates a real plugin, which can recycle the PHP worker and kill the very next request. The list reload after any action now replays once when its socket drops (the error card only paints if the replay also fails), and an action whose own reply dies after the server did the work proceeds to the reload instead of toasting a false failure. No more "Couldn't load this list" plus a manual refresh after activating a module.
  • Yes/No notices lost their Yes: Smash Balloon's "Are you enjoying the Instagram Feed Plugin?" notice showed fused text ("Plugin?YesNo") and only a No button, because its Yes is a literal button element the extractor never walked and notice text was flattened without element boundaries. Notice text now joins elements with spaces (and tidies punctuation), button elements join the CTA extraction in document order, and surfaced choice labels are stripped from the body by last whole-word occurrence, so a short "No" label can never eat part of the sentence. Buttons only surface when Minn can honestly answer them: a whitelisted handler, or a dismiss-shaped label. Both Instagram Feed choices now run the plugin's own consent handler from the panel, so Yes and No do exactly what they do in wp-admin.
  • A save racing a lock takeover is rejected by the server: the up-to-30-seconds between someone taking over a post and the losing session's next lock refresh used to be a blind window where the loser could still save and silently overwrite the taker's work. Minn's in-place saves now carry the post id in an X-Minn-Expect-Lock header, verified against the edit lock inside the save request itself; a save from an ousted session fails with a clear conflict error, nothing is written, and that session flips straight to the taken-over banner. Requests without the header (the block editor, other REST clients) behave exactly as before.
  • Taking a post lock back no longer risks silently reverting the other person's saves: when a lock changes hands, the winning session's copy could predate saves the other session made in the meantime, and the next save would quietly restore the stale copy. Regaining the lock now checks the server's modified stamp: a clean local copy adopts the newer saved version in place, and a copy with unsaved edits gets an amber banner naming who saved and offering Load theirs or keep working. Their work stays in revisions either way; choosing Load theirs also discards the local crash-net snapshot so the overwritten copy is never offered back.
  • The order modal no longer loses in-progress edits: its background fetches (emails, notes, related orders) re-render the modal as they land, and anything typed or picked in that window used to silently revert to saved values, with the save then persisting the reverted form. Edits now survive those refreshes, and focus returns to the field the rebuild stole it from.

Don't miss a new minn-admin release

NewReleases is sending notifications on new releases.