Skip to content

Conversation

@IMB11
Copy link
Member

@IMB11 IMB11 commented Jan 16, 2026

Summary

  • Standardizes the content management layout into a single shared ContentPageLayout component used by both the app frontend (Mods.vue) and hosting frontend (content.vue), eliminating duplicated UI code
  • Introduces a ContentManagerContext dependency injection provider that decouples platform-specific API logic from the shared layout
  • Gates the new v1 hosting content API (with bulk operations) behind a useV1ContentTabAPI feature flag, allowing the old v0 file-based API to remain as the default for now

Content page layout (ContentPageLayout.vue)

Previously, the app's Mods.vue and hosting's content.vue each maintained their own implementations of the content management UI (search, filters, sorting, bulk actions, modpack card, empty states, confirmation modals, etc.). This PR extracts all of that into a single ContentPageLayout component in @modrinth/ui (~774 lines).

The layout consumes its data and actions entirely through dependency injection rather than props, so platform-specific pages only need to provide their handlers via provideContentManager() and then render <ContentPageLayout />.

Shared composables were also extracted into packages/ui/src/composables/content/:

  • useContentSearch - fuzzy search via Fuse.js
  • useContentFilters - dynamic filter pills (by type, updates, disabled)
  • useContentSelection - multi-select state
  • useBulkOperation - progress tracking with navigation guards
  • useChangingItems - per-item loading states

Dependency injection (ContentManagerContext)

A new DI provider at packages/ui/src/providers/content-manager.ts defines the contract between ContentPageLayout and its platform-specific implementations. The context includes:

  • Required: items, loading, error, refresh, toggleEnabled, deleteItem, browse, uploadFiles, mapToTableItem
  • Optional (platform-specific): bulkDeleteItems, bulkEnableItems, bulkDisableItems (hosting v1 only), updateItem, bulkUpdateItem, hasUpdateSupport (app only), shareItems, getOverflowOptions, uploadState, modpack actions

This means the app's Mods.vue provides Tauri-backed handlers with update/share/export support, while hosting's content.vue provides API-backed handlers with optional bulk operations - all feeding into the same layout.

Feature flags (v0/v1 content API)

A useV1ContentTabAPI feature flag in apps/frontend/src/composables/featureFlags.ts controls which hosting content API is used:

  • v0 (default): File-based operations via archon.content_v0 - individual toggle/delete calls that rename files with .disabled suffix
  • v1 (flag-enabled): Database-backed operations via archon.content_v1 - supports bulk enable/disable/delete endpoints, modpack unlinking, and the new addon model

The hosting content.vue page maintains dual query instances (only one enabled at a time) and conditionally provides bulk operation handlers to the layout only when v1 is active. The flag is passed as a prop from the page wrapper: <ServersManageContentPage :use-v1-api="flags.useV1ContentTabAPI" />.

@IMB11 IMB11 requested a review from a team January 16, 2026 10:38
@IMB11 IMB11 added website Relates to Modrinth.com web frontend frontend Involves work from the frontend team labels Jan 16, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 16, 2026

@IMB11 IMB11 force-pushed the cal/content-tab-rewrite-hosting branch 5 times, most recently from 54f0a60 to e70cd2c Compare January 29, 2026 18:00
@IMB11 IMB11 marked this pull request as ready for review February 11, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend Involves work from the frontend team website Relates to Modrinth.com web frontend

Development

Successfully merging this pull request may close these issues.

2 participants