a7d5efc764
The self-service API-token UI was inconsistent across all 3 apps (sso-manager-node/proxy used a card grid with Edit/Rotate/Revoke and a description field; jump-host used a bare table with no Edit action, no description field anywhere in the UI, and icon-only buttons -- even though its model and PUT route already fully supported both). jump-host is first since it needed the least backend work (none -- description and the PUT handler already existed, just unexposed) and the most view work, proving the pattern before porting it to proxy/sso-manager-node. - Card grid (jq-repeat="apiTokenCard") replacing the table, matching sso-manager-node's exact template: name + truncated token-id, optional description, a <dl> of Token ID/Created/Last used/Expires, and labeled Edit/Rotate/Revoke buttons. - New Edit modal (app.modal, footer shows "Created by X on Y" via the token's existing created_by/created_on) -- net-new UI on top of the already-existing PUT /:id route. - Create modal gained a Description field and now uses app.modal.footerButtons() for its Cancel/Create pair. - Standardized status badges on Bootstrap 5's text-bg-* classes. - Bumped @simpleworkjs/frontend to ^0.2.6 (footer/footerButtons support; this app was still on ^0.2.5) and added the missing app.apiToken.update() client wrapper (list/add/remove/rotate already existed). Found and fixed a real bug along the way: the planned "flash a checkmark on copy" touch (porting sso-manager-node's copyField pattern) silently does nothing once FontAwesome replaces <i> icons with inline <svg> -- there's no <i> left to swap classes on. Renamed the existing copySshCommand() (already used by the Quick Jump feature, toast-based, unaffected by that FA behavior) to copyFieldValue() and reused it for the token-reveal copy button instead of introducing a second, broken copy mechanism. Verified live: card grid renders with truncated token ID; Edit modal shows real created-by/on data, saves a description change, and the card refreshes; Create modal's new description field round-trips; secret-reveal copy button fires the toast correctly for a real (non-programmatic) click.