Files
marketplaces/docs/GLOBAL-SPRINT-PLAN.md
sdarbinyan 55b379bd6d
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
fix: manifest-aware layout picker, real carousel items-per-page, hero arrows/swipe/2-panel
Sprint E: homepage section editor now filters the layout-strategy picker
to each widget's widget-manifest.json supportedLayouts instead of always
showing all 5 strategies. columns field gated to widgets that read it
(hero, product-collection carousel).

Sprint F: closes client bug report (no items-per-page control, hero
carousel not manually/automatically scrollable, no 1-2 slide big-carousel
option). Product carousel item width now driven by layout.columns
(reused, was already editable but dead). Hero widget gains prev/next
arrows, touch swipe, and 1-2 panel mode via the same field.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 19:25:34 +04:00

11 KiB

Global Sprint Plan — "Coming Soon" Stub Closure

Supersedes docs/COMING-SOON-AUDIT.md §5 sprint breakdown. One consolidated tracker for the four stub-closure sprints. Approved decisions (from AskUserQuestion): Reports/Settings ship as minimal real pages (not fake data, not empty shells); Documentation/Help nav uses an external-link approach; docs/COMING-SOON-AUDIT.md is deleted once all sprints land, folded into docs/KNOWN-ISSUES.md. Profile control constraint: login/logout only — no dropdown, no account links.

Sprint A — Profile menu (storefront header)

  • i18n: header.login / header.logout keys in en/ru/hy (translations.ts type already updated)
  • header.component.ts: inject AuthService, expose isAuthenticated, add login()/logout()
  • header.component.ts: import TelegramLoginComponent
  • header.component.html: profile control gated by headerConfig().showProfile, login/logout only, <app-telegram-login /> rendered once
  • SCSS matches existing header button conventions (reused .platform-ux-btn, no new SCSS needed)

What shipped: Header profile control wired to the customer AuthService (Telegram QR login). Gated by headerConfig().showProfile (already a real toggle in Project Editor, previously dead). Logged-out shows a login button (user icon), logged-in shows a logout button (logOut icon) — no dropdown, no account links, per the explicit constraint.

Sprint B — Admin Reports page

  • admin-reports-page.component.ts/.html/.scss (mirrors admin-analytics-page structure), reuses AdminAnalyticsFacade
  • Report cards: Sales, Top Products, Marketplace Health
  • CSV export wired to existing facade export methods / existing download helper (same Blob pattern as admin-analytics-page.component.ts)
  • Route backoffice/reports in app.routes.ts, i18n keys adminShell.pages.reports.* + new adminReports.* block
  • Remove comingSoon: true from reports nav entry

What shipped: Minimal real Reports page with 3 cards (Sales, Top Products, Marketplace Health), each showing a live summary from AdminAnalyticsFacade and a CSV export button. Orders card was scoped out — see final report for why (reuse would require mutating a shared singleton facade's pagination state).

Sprint C — Admin Settings page

  • AdminPreferencesService (density signal, localStorage-backed, key adminPreferences.density.v1)
  • admin-layout.component applies admin-density-compact class to #admin-content shell wrapper
  • admin-settings-page.component.ts/.html/.scss — density toggle (app-toggle), auto-persists on change, no separate Save button
  • Route backoffice/settings, i18n keys adminShell.pages.settings.* + adminSettings.* block
  • Remove comingSoon: true from nav entry AND dashboard shortcut; shortcut route → ['backoffice','settings']
  • Compact-density CSS rule added to the shared app-table component stylesheet (.admin-density-compact .app-table th/td) — applies to every admin list page built on app-table (orders, products, categories, etc.), not just one

What shipped: Genuinely real, backend-independent UI density preference. No maintenance-mode toggle built (explicitly deferred per docs/NEXT_PHASE.md Phase 4).

Sprint D — Documentation / Help nav

  • Help: mailto: using existing supportEmail read path (UiRuntimeFacade.contactEmail(), same one header.component.ts already uses for bootstrap.branding.supportEmail)
  • AdminNavLink gains optional externalHref?: string; nav renderer renders <a> branch (bottom nav)
  • Documentation: added tenant.documentationUrl?: string to TenantConfig, populated mock with https://docs.marketplace.local
  • help/documentation resolved dynamically in admin-layout.component.ts (navBottom computed) — real <a> when bootstrap data present, static comingSoon: true entries kept as defensive fallback for the (currently unreachable, since mock always has both fields) case where the backend omits them

What shipped: Both Help and Documentation wired to real external links, not just Help. comingSoon: true remains in admin-nav.model.ts source as a fallback flag only — it is overridden to false at render time whenever bootstrap actually has the data, which it does today.

Sprint E — Widget layout config correctness (manifest-aware editor)

Root cause confirmed 2026-08-05: widget-manifest.json already declares supportedLayouts per widget type (hero[hero, split], categories[grid], product-collection[carousel, grid]), but homepage-section.component.ts's layoutStrategyPickerOptions is a static 5-option list (stack/grid/hero/carousel/split) shown identically for every homepage section regardless of which widget backs it — it never reads the manifest. The columns field (homepage-section.component.html:49) is shown for every section too, but no widget component reads layout.columns — it is currently dead everywhere.

  • homepage-section.component.ts: resolve each section's widget type (via its bound widget id → widget-registry/manifest lookup) and filter layoutStrategyPickerOptions down to that widget's supportedLayouts before rendering the picker
  • Hide/disable the columns field for any section whose resolved widget doesn't consume it (only product-collection and, after Sprint F, hero will)
  • No behavior change for widgets that already worked (categories/recently-viewed/footer-nav keep their single valid layout, picker just stops offering the other 4 nonsensically)

What shipped: homepage-section.component.ts now injects WidgetManifestService, resolves each section's manifest entry directly by section.type (confirmed identical to the manifest type key — no separate widget-id lookup needed), and derives layoutOptionsFor(section) by filtering the static option list down to that entry's supportedLayouts. A stale/unsupported saved strategy value is appended back into the options list rather than dropped, so app-visual-layout-picker never renders with no active card. showColumnsFor(section) gates the columns field to the two componentKeys that actually read it (hero always, product-collection only in carousel strategy — grid mode ignores it). One correction to the plan's assumption: recently-viewed's actual manifest entry declares supportedLayouts: ["stack", "grid", "carousel"] (3 options, not 1) — the picker now correctly reflects that per the manifest rather than the plan's guess.

Confirmed real, reported by a client, not fixed anywhere: neither carousel widget has an "items/slides per page" concept. Design: reuse the existing (currently dead) layout.columns field rather than inventing a new one — it is already editable in the Homepage section editor once Sprint E gates it to the right widgets.

  • ProductCarouselWidgetComponent: read section.layout.columns (default 4, min 1) to size .catalog-product-shell width as a fraction of the scroller instead of the hardcoded 220px — gives real "items per page" control, arrows/scroll logic unchanged (already works)
  • HeroWidgetComponent: add manual prev/next arrows (parity with the product carousel's arrow buttons) in addition to the existing dots — closes "not scrollable manually"
  • HeroWidgetComponent: add swipe/drag (pointer events) support for touch — closes "not scrollable manually" on mobile
  • HeroWidgetComponent: support layout.columns = 1 or 2 to show one or two slide panels at once ("big carousel one or two slides per page") — 2-panel mode shows the active slide plus the next one side by side
  • Verify autoplay (props.autoplay, already exists, editor toggle already exists per widgets-section.component.html:61) still functions correctly alongside the new manual controls (manual interaction should not fight the autoplay timer — reset/pause timer on manual nav, matching common carousel UX)
  • i18n: any new aria-labels for the new hero arrows (reuse common.previousProducts/common.nextProducts keys if wording fits, or add common.previousSlide/common.nextSlide)

What shipped: ProductCarouselWidgetComponent sets --items-per-page as a CSS custom property ([style.--items-per-page]) driven by itemsPerPage() (default 4, min 1, floored), and .catalog-product-shell width is now calc((100% - (var(--items-per-page, 4) - 1) * var(--space-md, 16px)) / var(--items-per-page, 4)) instead of a fixed 220px. HeroWidgetComponent gained prev/next arrow buttons (same circular/bordered visual language as the product carousel's arrows), touch-event swipe (same threshold-based approach as cart.component.ts's onSwipeStart, 50px threshold, left swipe = next, right swipe = prev), and 2-panel support via layout.columns (defaults to 1; columns === 2 shows the active slide plus the next one side by side, falling back to 1 panel when there's only one slide total). All manual navigation (arrows, swipe, dots) routes through the existing goTo(), which already clears+restarts the autoplay timer, so no duplicate timer logic was needed. New i18n keys common.previousSlide / common.nextSlide added to translations.ts, en.ts, ru.ts, hy.ts.

Verification: npx tsc --noEmit and npx ng build --configuration=development both clean. Visually verified in the browser preview (ng serve on port 4200) by temporarily patching the embedded home-page sections in src/assets/mock/bootstrap/bootstrap.json (the actual runtime source for /src/assets/mock/bootstrap/homepage.json is a separate, unused-by-this-route file) to columns: 2 + a second slide for hero and columns: 3 for the product carousel, confirming via DOM/computed-style inspection: hero rendered 2 slide panels with 2 working arrows, arrow clicks and simulated touch swipe both advanced/reversed the active dot correctly, and the carousel's --items-per-page CSS var read 3 with each .catalog-product-shell measuring ~348px (vs. the fixed 1110px/220px before). All temporary mock-data edits were reverted afterward (git checkout) — bootstrap.json and homepage.json are unchanged in the final diff. The Sprint E manifest-aware picker itself could only be verified by code inspection, not live in the browser — /edit/:section requires Telegram admin login, which cannot be completed in this environment.

Housekeeping

  • Delete docs/COMING-SOON-AUDIT.md
  • Fold summary into docs/KNOWN-ISSUES.md "Fixed (this cycle)"; remove the HeaderConfig.showProfile dead-toggle entry from "Open"
  • Update docs/BACKEND.md (tenant.documentationUrl field added §1.3; no docs/backend/BACKEND-INTEGRATION.md exists in this repo)
  • npm run barry -- validate (clean, only pre-existing unrelated warnings)
  • Typecheck touched files (tsc --noEmit + full ng build both clean)