feat: mobile-first MinIO file browser playground #2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "1-mobile-first-file-browser-playground"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Five-page vanilla HTML/CSS/JS prototype replacing the unusable stock MinIO Console on mobile. Uses mock S3 data with real bucket names. All pages are mobile-first with 44px tap targets, pal-e-playground design tokens, and no build step.
Changes
style.css-- All styles with design tokens from pal-e-playground (Atkinson Hyperlegible,--radius: 6px,--max-width: 48rem), responsive card grid, file list, thumbnail grid, upload zone, progress bars, metadata table, confirmation dialogapp.js-- Mock S3 data for 3 buckets (assets, postgres-wal, tf-state-backups) with nested prefixes, page routing viadata-pageattribute, utility functions for formatting bytes/dates, simulated upload progress animationindex.html-- Bucket list landing page with card grid (1-col mobile, 2-col desktop)browse.html-- Object browser with breadcrumb navigation, prefix-based folder drill-down, image thumbnail grid, file list with icons/metadatapreview.html-- Full-size image viewer with pinch-zoom support viatouch-actionupload.html-- File upload with tap-to-select (triggers camera/gallery on mobile), drag-and-drop, animated progress barsdetail.html-- File metadata table (bucket, key, size, type, modified, ETag), download button, delete with confirmation dialogassets/.gitkeep-- Placeholder for sample images directoryReview Checklist
@media (min-width: 600px)desktop enhancementsTest Plan
python3 -m http.server 8080Related
plan-pal-e-platformSelf-Review
Reviewed all 8 files against the acceptance criteria from #1.
Verified
:activestates for taptouch-action: pan-x pan-y pinch-zoom--color-bg,--color-text,--color-border,--radius: 6pxmax-width: 48remcontainer on all pagespython3 -m http.server 8080node -c, CSS braces balanced (96/96), HTML parsed cleanNo Issues Found
Code is clean. All acceptance criteria met. Ready for manual phone review.
PR #2 Review
DOMAIN REVIEW
Tech stack: Vanilla HTML/CSS/JS playground -- no frameworks, no build step. Reviewed against pal-e-playground design system conventions and mobile-first accessibility criteria.
Design tokens -- Correct.
--color-bg,--color-text,--color-border,--radius: 6px,--max-width: 48rem,--font-body: 'Atkinson Hyperlegible'all present and match the pal-e-playground system.Mobile-first CSS -- Correct. Base styles target mobile, with
@media (min-width: 600px)used for desktop enhancements (card grid 2-col, thumbnail grid 4-col, action-bar row layout). No desktop-first breakpoints detected.44px minimum tap targets -- Verified across interactive elements:
.breadcrumb a--min-height: 44pxwith padding.bottom-nav a--min-height: 48px.card--min-height: 44px.file-item a--min-height: 44px.btn--min-height: 44px.upload-zone--min-height: 120px.thumb-item a--min-height: 44pxNo hover-dependent UI -- Confirmed. All interactive states use
:activeinstead of:hover. The--color-link-hovertoken exists but is only referenced in:activerules.Safe area insets -- Bottom nav uses
env(safe-area-inset-bottom)for notched devices. Good.Font loading --
@font-facedeclarations usefont-display: swapand load from Google Fonts CDN via direct woff2 URLs. This avoids the render-blocking Google Fonts stylesheet. Good approach.Page routing -- Uses
data-pageattribute on<body>with aDOMContentLoadedswitch. Clean pattern for multi-page vanilla JS.Mock data -- Uses real bucket names (
assets,postgres-wal,tf-state-backups) matching actual infrastructure. SVG placeholder images are generated inline viadata:image/svg+xmlURIs. No external dependencies.Accessibility positives:
aria-labelon nav elements, file lists, upload zone, metadata table, dialogaria-hidden="true"on decorative iconsaria-current="page"on active nav itemsrole="dialog",aria-modal="true",aria-labelledbyon delete confirmationrole="button"andtabindex="0"on upload zone with keyboard event handling (Enter/Space).sr-onlyclass for visually hidden file inputlang="en"on all HTML elementsBLOCKERS
None.
This is a static playground with mock data only. The standard BLOCKER criteria are evaluated as follows:
bucket,key,prefix) are inserted intoinnerHTMLvia template literals without HTML escaping. In a production app this would be an XSS blocker. In a playground with mock data and no real backend, this is a nit (see below) -- the pattern should be corrected before any production promotion.NITS
XSS pattern in innerHTML (style, not security for playground):
bucket,key, andprefixfrom URL params are interpolated directly intoinnerHTMLwithout escaping. Example inrenderObjectBrowser():The
hrefis properlyencodeURIComponent-encoded, but the text content${bucket}is raw. A simpleescapeHtml()utility would fix this. Flag for correction before any production promotion.Inline
onclickhandler indetail.html:All other event handlers are properly attached via
addEventListenerinapp.js. This one should follow the same pattern for consistency.Inline
styleattributes indetail.htmlandbrowse.html: The preview section and thumbnail container use inline styles (style="display: none; margin-bottom: 1.5rem;", inline styles on the preview link/image). These should be CSS classes for consistency with the rest of the codebase.Dialog focus trap missing: The delete confirmation dialog has correct ARIA attributes but no focus trap. Pressing Tab can move focus behind the overlay. For a playground this is minor; for production,
focusTrapDialog()logic would be needed.Redundant variable assignment in
renderObjectBrowser():Both branches of the ternary are identical. Simplify to
const name = getFileName(obj.key);.Escape key for dialog: The delete dialog can be dismissed by clicking the overlay backdrop but not by pressing Escape. Adding an Escape key handler would improve keyboard accessibility.
Upload nav link hardcoded to
assetsbucket: The bottom nav upload link is hardcoded toupload.html?bucket=assetson every page. When browsingpostgres-walortf-state-backups, tapping Upload navigates to the assets bucket context. This could be confusing.Missing
## Relatedsection in PR body: The SOP template calls for## Summary,## Changes,## Test Plan,## Related. The PR has Summary, Changes, and a Review Checklist (reasonable substitute for Test Plan), but no Related section referencing the plan slug.SOP COMPLIANCE
1-mobile-first-file-browsermatches issue #1PROCESS OBSERVATIONS
## Relatedsection is a minor process gap.VERDICT: APPROVED
The implementation meets all acceptance criteria from issue #1. Five mobile-first pages with proper design tokens, accessible markup, 44px tap targets, no hover-dependent UI, and clean vanilla JS architecture. The nits above (XSS escaping pattern, inline onclick, redundant ternary, missing Related section) should be tracked as discovered scope for correction before any production promotion of this pattern.