Each device now migrates on the day of its date tag instead of on a
looping 24-hour clock: earlier days are finished, today's devices go
through backup and restore during working hours, later days haven't
started. The few that don't finish have a cause the dashboard shows
(broken client, broken WMI, low disk, a USMT error, unreachable PC).
A simulated team keeps two weeks of working days tagged. During working
hours it adds devices, reschedules or drops one, tags stuck PCs with
their problem, then fixes them and moves them to a new day; each morning
finished days are closed out and a new day is scheduled. Actions print
in the worker terminal as [Team] lines. Settings live in Demo.Team.
The visitor sandbox now keeps per-tag edits laid over the live roster,
so the team's changes keep showing around a visitor's own edits.
Overview calendar: today is a filled badge on the date number, so it no
longer looks like the selected day (outline plus tint).
The popup text now scrolls inside the card while the buttons stay at the
bottom, so phone visitors see 'Explore the dashboard' right away (it goes
first and full width on narrow screens). The card height uses dvh so the
top edge isn't cut off behind a phone's address bar.
- Jump sheet: Top / Middle / Bottom with the Card fields arrows; the Jump
button uses the same bold arrows.
- Container timezone defaults to America/Chicago (TZ in Dockerfile/compose).
- Demo worker follows its own business hours (Demo.BusinessHours, default
06:00-21:00 every day) with the midnight pitstop; the simulated cycle in
the browser shows the real worker's next run.
- Worker publishes the rows swept so far every few seconds (LivePublishSeconds)
with a DataVersion stamp; the dashboard reloads on each new version, so
tables, the Overview and open dialogs update mid-cycle. Shared files are
written to a temp file and swapped in, so readers never see half a file.
- Phones / tablets: one Filter & sort button opens a column list instead of a
row of chips, on every table.
- Details: a wrapped Simple / Advanced toggle sits on the left.
- Card fields: fixed-height dialog; field list and add list share it evenly.
Articles get their own address (shareable, back/forward work); the list is
searchable by title and text, shows the article count, and is grouped into
Applications and Troubleshooting & Guides via a hidden category line set
from the editor. PDF export lays out at page width with page breaks, a title
block and page numbers; Print uses the browser's vector print. Inline code
is a pill that glows blue on hover, blockquotes no longer squeeze, and
GitHub-style [!NOTE] alerts render. [[Badge]] syntax inside code spans is
left alone.
Worker: pings every tracked device on a presence sweep (hourly in business
hours plus midnight) and records last online; inventory reports whether a
device was found in AD and SCCM; monitors from WmiMonitorID; snapshots of
the last reachable state replace "Cached"; newly tracked devices are swept
and published first; totals count source devices only; per-type timing in
Worker-State.
Front end: details dialog shows presence, reasons instead of N/A,
"Waiting for worker...", monitors and snapshot times, and refreshes in
place; Custom View gains Days Offline, Last Online, Found In and monitor
columns; manual pair changes show immediately; sync dialog shows timing by
type. Custom View gets a large scrollbar; "Exactly ticked" filter.
- Custom View header now uses the browser's sticky positioning like the
other tables, so it no longer lags or bounces while scrolling. Because a
sideways-scrolling box prevents sticky headers, the table is clipped and
shifted sideways by a scrollbar pinned to the bottom of the window
(shown only when the columns are wider than the page; trackpad,
shift+wheel and touch swipes drive it too)
- Custom View header on one line like the other tables: drag grip, name,
the combined sort/filter dropdown and copy icon (remove on hover)
- Workbench stack text boxes size to their contents on load and when the
page is shown, not only while typing
- Demo sandbox waits for the worker's first sweep after a container
restart instead of treating every device as unknown
Filters (web/excel-filter.js), modeled on Excel's AutoFilter:
- Every column header gets a dropdown: Sort A to Z / Z to A, Clear Filter
From "<column>", Search, a checkbox list of the column's values with
(Select All) and (Blanks), OK / Cancel. Values come from rows passing
the other columns' filters; filters on several columns combine. Tags
and software lists are split into individual items.
- The button shows a funnel when filtered and an arrow when sorted, and a
"Clear filters (n)" button appears beside the group's copy buttons
- Replaces the old per-column filter row (which also removes the gap
between header and filter rows); hooks the existing filter passes so
global search, counts and worker re-renders keep working
- Menus are fixed-position on <body>, so sticky headers and neighbouring
tables can't cover them; on phones they open as a bottom sheet
- Workbench stacks get the same menus (sorting done client-side)
- Custom View's filter icon opens the same menu
Layout:
- Sticky headers use separated borders so no hairline gap opens
- Phones/tablets: a sticky bar of column chips (with active counts and
"Clear all") opens the filter menus
- Custom View fills the page like the other views on desktop; it still
scrolls sideways when wide, with its header pinned under the group header
- Custom View on phones/tablets: a "Card fields" sheet to choose, order
and remove the fields shown on each card
Demo: first visit puts 6 PCs (one per migration stage) on the Workbench.
Sideways-scrolling tables only showed a few of the 11 columns at a time on
a phone or iPad. Below 1100px (where the nav already collapses) each row
now renders as a card: the device as the title and every other column as
a labelled line, one card per row on phones and two or more on tablets.
- web/mobile.js copies column names onto cells (data-label) for the cards
and re-applies them as the dashboard re-renders; no-op on wide screens
- Column filters fold behind a "Show filters" button with an active count
- Custom View keeps its sort/filter header as a strip of chips
- Terminal: Follow and the "your actions (simulated)" legend move into the
terminal window's title bar; tabs read "Server" / "Worker" on phones, so
LIVE, the legend and Follow are all visible on small screens
- Replace the text triangle with an SVG chevron so it centers with the label
- Make the "your actions (simulated)" legend dot the same yellow as the
markers on simulated lines
- When live worker output was held back during a visitor's simulated
cycle, print a divider before flushing it so the jump is explained
Remove all environment-specific data and make the dashboard adoptable
anywhere, then add a demo that runs the real PowerShell services.
- Strip cached device data, internal knowledge-base articles and
screenshots, server/site names and the old project notes; replace the
knowledge base with generic sample articles and diagrams
- Move every environment value into Config/usmt-dash.psd1
- Route all infrastructure access in the worker and Get-Software.ps1
through a provider (Providers/SCCM.ps1), with a config-driven asset
inventory view instead of a hard-coded custom class
- Add Providers/Demo.ps1: a deterministic simulated fleet whose
migrations progress in real time, and Demo/New-DemoData.ps1 to seed it
- Server: -Demo makes the API read-only; add get-config and get-logs;
serve static files only from web/, Documentation/ and an allowlist of
Data/ files with a path-traversal guard; gzip large responses
- Mirror both services' console output to Data/Logs via a Write-Host
proxy, and add a terminal panel to the dashboard that streams it
- Demo sandbox (web/demo/demo.js): visitor changes to tags, articles and
images are kept in the visitor's browser and echoed in the terminals;
nothing a visitor does reaches the server
- Vendor marked, highlight.js and html2pdf.js instead of loading CDNs
- Dockerfile and compose file for hosting the demo (Coolify-ready)