From 7d92e4ec7f91677a5118c0533dce7715e6d050af Mon Sep 17 00:00:00 2001 From: "Calum H." Date: Thu, 12 Mar 2026 20:24:32 +0000 Subject: [PATCH] feat: content tab rewrite for worlds (#5136) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: base content card component * fix: tooltips + colors * feat: fix orgs * feat: base content tab internals rewrite * feat: fix invalidmodal * feat: add ContentModpackCard * fix: extract types * draft: layout * feat: unlink modal * feat: impl content tab * fix: lint * fix: toggling * temp: disable updating stuff * feat: selection v-model * feat: bulk selection * feat: mods tab rough draft * feat: use fuse.js * feat: add project combobox * clean up project combobox * feat: start install to play modal * fix: events * feat: use v-on * feat: bulk actions + fix floating action bar width * feat: figma alignments * feat: migrate toggle to tailwind * fix: row borders * feat: disabled state * feat: virtual list impl for card table based on window scroll * fix: lint * feat: virtualization + smaller contentcard items * feat: use ContentCardTable + ContentCardItems * feat: fix gap + border issues on last elm * feat: cleanup + use proper searching * fix: use TeleportOverflowMenu * fix: fallback to svg if src is invalid on avatar component * fix: storybook * feat: start on updater modal * feat: finish content updater modal * feat: i18n pass * feat: impl modal * feat(app): backend changes for content tab refactor (#5237) * feat: include_changelog=false for updater modal * fix: hash overrides * feat: update checking for modpack * feat: qa * feat: modpack content modal * fix: padding in table to match modals + tightness * fix: lint * feat: delete modal * feat: fix toggle bugs * fix: prepr * fix: duplicate messages * qa: full width search * qa: use bg-surface-1.5 * qa: animation for filter pills * qa: standardize hover colors * fix: border-[1px] is border * qa: mass de-select actually mass selecting * qa: match figma designs for floating action bar * qa: modal fixes * q: modal fixes x2 * fix: table border * qa: confirm modals * qa: modal alignment * qa: re-add stuck heading + dedupe logic * qa: dedupe virtual scrolling + remove dead components * qa: responsiveness for content table + link fixes * qa: version column link, tooltips + lint fixes * qa: instance busy protections * fix: installation freeze bug * chore: remove old mods page * refactor: deduplicate layout * chore: delete old content page(s) * qa * qa * qa * feat: sort btn - to iterate * fix: ml * feat: date added * fix: lint * fix: formatting.ts removal * feat: get_dependencies_as_content_items * qa: final QA changes * refactor: deduplicate + polish content.rs * feat: hook up content.vue with v1 * feat: hide v1 content api behind frontend feature flag * fix: query keys + copy on empty state * chore: i18n pass * feat: reimpl unlink + upload endpoint * feat: use bulk endpoints v1 * fix: lint * fix: flags * fix: responsiveness via container queries * fix: lint * qa: 1 * qa: fixes * qa: fix ssr issues with browse content * qa: header page divider * qa: modals * fix: prepr * fix: issues * fix: lint * fix: toggle v1 ff * qa: 5 * qa: delete modal copy * feat: creation flow modals (#5383) * refactor: delete content v0 usages + impl * feat: qa + fixes * feat: installing banner using state event * feat: fix modpack card bugs + filtering issues * refactor: delete backups v0 api module * feat: v1 servers GET endpoint * fix: backups * feat: swap to kyros upload v1 addon * fix: use tanstack for loader.vue * feat: finish install from discovery modal * qa: bug fixes * feat: set up installation settings * fix: lint * fix: typos * fix: bugs * fix: disable inline content * feat: content tab improvements — upload UX, installation settings, and client-only indicators Upload cancellation and navigation guard: - Add ConfirmLeaveModal that prompts when navigating away during upload - Cancel in-flight XHR uploads when user confirms leaving the page - Add beforeunload handler to warn on browser/tab close during upload - Track uploadedBytes/totalBytes in UploadState for progress display - Replace Collapsible with Transition for upload progress admonition - Show byte progress and percentage in upload banner - Clamp upload progress to prevent exceeding 100% Installation settings (server.properties): - Add KnownPropertiesFields and PropertiesFields types to Archon types - Add buildProperties() to creation flow context to collect gamemode, difficulty, seed, world type, structures, and generator settings - Pass properties through installContent on onboarding, discovery, and ServerSetupModal flows Server setup and discovery flow improvements: - Migrate ServerSetupModal from servers_v0.reinstall to content_v1.installContent - Replace loaderApiNames lookup with toApiLoader() helper - Remove eraseDataOnInstall toggle — always use soft_override: false - Simplify modpack install on discovery page to use first available version and route through creation flow modal for both onboarding and non-onboarding - Differentiate post-install navigation: content page for onboarding, loader options for existing servers Modpack update flow: - Replace updateModpack() call with installContent() using soft_override: true to support version selection in the content updater modal Client-only mod indicators: - Add environment field to AddonVersion (reuses Labrinth.Projects.v3.Environment) - Add environment to ContentItem and isClientOnly to ContentCardTableItem - Show orange TriangleAlertIcon with tooltip on client-only mods in content table - Add "Client-only" filter pill to content filtering (controlled via showClientOnlyFilter on ContentManagerContext) - Apply client-only indicators in both ContentPageLayout and ModpackContentModal Misc: - Add CLAUDE.md note about using prepr commands for lint checks - Export ConfirmLeaveModal from instances barrel * fix: piping * fix: switch content disable for linked server instances * feat: client only filter * fix: prepr * feat: hasUpdate shape update * feat: bulk update endpoint impl for content in panel * feat: websocket state impl again with new phases * fix: ws * fix: use timeout fn for sync admon + fix content card layout scroll for browsers with overflow anchor bug * fix: qa bugs * fix: lint, a11y and i18n * refactor: set up layouts folder properly * fix: linked data cache stuff + lint * feat: move installationsettings to shared layout * fix: lint * fix: issues * feat: temp fuck staging up * fix: lockfile * fix: data sync issues on loader.vue * fix: lint * Hide shader configuration files from content list (#5499) * feat: workaround search problem + split out reset * fix: qa * fix: changelog not showing on first open * fix: qa + optimistic updating improvements * fix: prepr+lint * fix: qa * feat: qa * fix: lint * fix: lint * fix: build * fix: build * fix: type errors * fix: fade and JAVA_HOME passthrough * feat: qa * feat: impl diff shit * fix: qa * fix: app qa * feat: update diff modal * fix: endpoint * fix: qa * fix: qa * fix: use bulk in modpack modal * feat: abort signal impl + fix issues * fix: diff modal trunc * feat: qa * fix: qa * feat: tooltip content tab * fix: prepr * fix: dismiss on settings btn * feat: qa * feat: dont clear handlers on disconnect * fix: lint * fix: wrangler + introduce staging-archon env file --------- Signed-off-by: Calum H. Co-authored-by: tdgao Co-authored-by: Artyom Ezri <61311568+Artezon@users.noreply.github.com> --- CLAUDE.md | 36 +- apps/app-frontend/package.json | 7 +- apps/app-frontend/src/App.vue | 105 +- .../src/components/GridDisplay.vue | 11 +- .../src/components/RowDisplay.vue | 14 +- .../src/components/ui/Breadcrumbs.vue | 173 +- .../src/components/ui/ExportModal.vue | 57 +- .../components/ui/InstanceCreationModal.vue | 662 ------ .../src/components/ui/NavTabs.vue | 3 +- .../components/ui/QuickInstanceSwitcher.vue | 36 +- .../src/components/ui/SearchCard.vue | 28 +- .../src/components/ui/URLConfirmModal.vue | 3 +- .../ui/instance_settings/GeneralSettings.vue | 18 +- .../InstallationSettings.vue | 985 ++------- .../ui/modal/ConfirmDeleteInstanceModal.vue | 78 + .../ui/modal/ConfirmModalWrapper.vue | 19 +- .../ui/modal/InstallToPlayModal.vue | 11 +- .../ui/modal/InstanceSettingsModal.vue | 28 +- .../src/components/ui/modal/ModalWrapper.vue | 19 +- .../components/ui/modal/ShareModalWrapper.vue | 14 +- .../components/ui/modal/UpdateToPlayModal.vue | 210 +- apps/app-frontend/src/helpers/cache.js | 14 + apps/app-frontend/src/helpers/pack.js | 65 - apps/app-frontend/src/helpers/pack.ts | 90 + apps/app-frontend/src/helpers/profile.js | 216 -- apps/app-frontend/src/helpers/profile.ts | 298 +++ apps/app-frontend/src/helpers/types.d.ts | 15 +- .../app-frontend/src/locales/en-US/index.json | 237 +-- apps/app-frontend/src/main.js | 4 + apps/app-frontend/src/pages/Browse.vue | 207 +- .../app-frontend/src/pages/instance/Index.vue | 18 +- apps/app-frontend/src/pages/instance/Mods.vue | 1775 +++++++---------- .../src/pages/instance/Worlds.vue | 8 +- apps/app-frontend/src/pages/library/Index.vue | 7 +- apps/app-frontend/src/pages/project/Index.vue | 23 +- .../src/providers/content-install.ts | 515 +++++ .../src/providers/server-install.ts | 368 ++++ apps/app-frontend/src/providers/setup.ts | 16 + .../src/providers/setup/creation-modal.ts | 110 + .../src/providers/setup/file-picker.ts | 32 + .../src/providers/setup/instance-import.ts | 47 + apps/app-frontend/src/providers/setup/tags.ts | 24 + apps/app-frontend/src/store/install.js | 475 +---- apps/app-frontend/src/store/state.js | 3 +- apps/app/build.rs | 7 + apps/app/src/api/cache.rs | 12 + apps/app/src/api/profile.rs | 91 + apps/app/src/api/utils.rs | 12 +- apps/frontend/.env.staging-archon | 4 + apps/frontend/nuxt.config.ts | 3 + apps/frontend/src/app.vue | 26 +- .../CreateProjectVersionModal.vue | 1 + .../ui/project-settings/CompatibilityCard.vue | 6 +- .../ui/servers/ContentVersionEditModal.vue | 558 ------ .../src/components/ui/servers/FileItem.vue | 345 ---- .../ui/servers/FileManagerError.vue | 41 - .../components/ui/servers/FileVirtualList.vue | 128 -- .../ui/servers/FilesBrowseNavbar.vue | 173 -- .../ui/servers/FilesContextMenu.vue | 104 - .../ui/servers/FilesCreateItemModal.vue | 94 - .../ui/servers/FilesDeleteItemModal.vue | 77 - .../ui/servers/FilesEditingNavbar.vue | 136 -- .../src/components/ui/servers/FilesEditor.vue | 260 --- .../ui/servers/FilesImageViewer.vue | 180 -- .../components/ui/servers/FilesLabelBar.vue | 102 - .../ui/servers/FilesMoveItemModal.vue | 80 - .../ui/servers/FilesRenameItemModal.vue | 92 - .../ui/servers/FilesUploadConflictModal.vue | 56 - .../ui/servers/FilesUploadDragAndDrop.vue | 75 - .../ui/servers/FilesUploadDropdown.vue | 335 ---- .../ui/servers/FilesUploadZipUrlModal.vue | 162 -- .../ui/servers/InstallingTicker.vue | 76 - .../ui/servers/PanelServerActionButton.vue | 19 +- .../PlatformChangeModpackVersionModal.vue | 26 +- .../ui/servers/PlatformMrpackModal.vue | 253 --- .../ui/servers/PlatformVersionSelectModal.vue | 35 +- .../src/components/ui/servers/SaveBanner.vue | 10 +- .../ui/servers/ServerInstallation.vue | 286 --- .../components/ui/servers/ServerSidebar.vue | 12 +- apps/frontend/src/composables/featureFlags.ts | 1 + .../composables/servers/modrinth-servers.ts | 287 --- .../composables/servers/modules/backups.ts | 109 - .../src/composables/servers/modules/base.ts | 15 - .../composables/servers/modules/content.ts | 37 - .../composables/servers/modules/general.ts | 201 -- .../src/composables/servers/modules/index.ts | 7 - .../composables/servers/modules/network.ts | 48 - .../composables/servers/modules/startup.ts | 27 - .../src/composables/servers/modules/ws.ts | 14 - .../composables/servers/use-server-image.ts | 131 ++ .../composables/servers/use-server-project.ts | 17 + apps/frontend/src/locales/en-US/index.json | 44 +- .../pages/[type]/[id]/settings/members.vue | 2 - apps/frontend/src/pages/collection/[id].vue | 30 +- .../src/pages/dashboard/revenue/transfers.vue | 14 +- .../src/pages/discover/[type]/index.vue | 687 ++++--- .../src/pages/hosting/manage/[id].vue | 557 ++++-- .../src/pages/hosting/manage/[id]/content.vue | 23 +- .../hosting/manage/[id]/content/index.vue | 704 ------- .../src/pages/hosting/manage/[id]/index.vue | 140 +- .../src/pages/hosting/manage/[id]/options.vue | 43 +- .../hosting/manage/[id]/options/index.vue | 39 +- .../hosting/manage/[id]/options/info.vue | 17 +- .../hosting/manage/[id]/options/loader.vue | 595 +++++- .../hosting/manage/[id]/options/network.vue | 61 +- .../manage/[id]/options/preferences.vue | 7 +- .../manage/[id]/options/properties.vue | 381 ++-- .../hosting/manage/[id]/options/startup.vue | 282 +-- apps/frontend/src/providers/setup.ts | 16 + .../src/providers/setup/file-picker.ts | 23 + .../src/providers/setup/modrinth-client.ts | 14 + .../src/providers/setup/page-context.ts | 14 + apps/frontend/src/providers/setup/tags.ts | 10 + apps/labrinth/src/routes/v3/versions.rs | 17 +- package.json | 1 + packages/api-client/src/features/node-auth.ts | 4 +- .../src/modules/archon/backups/v0.ts | 77 - .../src/modules/archon/backups/v1.ts | 88 +- .../src/modules/archon/content/v0.ts | 56 - .../src/modules/archon/content/v1.ts | 276 +++ .../api-client/src/modules/archon/index.ts | 4 +- .../src/modules/archon/options/v1.ts | 37 + .../src/modules/archon/properties/v1.ts | 40 + .../src/modules/archon/servers/v0.ts | 207 ++ .../src/modules/archon/servers/v1.ts | 36 + .../api-client/src/modules/archon/types.ts | 337 +++- packages/api-client/src/modules/index.ts | 21 +- .../src/modules/kyros/content/v1.ts | 65 + .../api-client/src/modules/kyros/files/v0.ts | 14 +- .../api-client/src/modules/labrinth/index.ts | 1 + .../api-client/src/modules/labrinth/types.ts | 11 +- .../src/modules/labrinth/versions/v2.ts | 141 ++ .../src/modules/labrinth/versions/v3.ts | 10 +- .../src/modules/launcher-meta/types.ts | 19 + .../src/modules/launcher-meta/v0.ts | 23 + .../api-client/src/modules/paper/types.ts | 9 + packages/api-client/src/modules/paper/v3.ts | 25 + .../api-client/src/modules/purpur/types.ts | 11 + packages/api-client/src/modules/purpur/v2.ts | 23 + packages/api-client/src/modules/types.ts | 3 + packages/api-client/src/platform/nuxt.ts | 17 +- packages/api-client/src/platform/tauri.ts | 12 +- .../src/platform/websocket-generic.ts | 40 +- ...9b73a6289c1a90fb0988c4f5f5f64be01c4ec.json | 20 + packages/app-lib/src/api/cache.rs | 17 + packages/app-lib/src/api/mod.rs | 13 +- packages/app-lib/src/api/pack/import/mod.rs | 7 +- packages/app-lib/src/api/pack/install_from.rs | 25 + .../app-lib/src/api/pack/install_mrpack.rs | 49 +- packages/app-lib/src/api/profile/mod.rs | 118 +- packages/app-lib/src/state/cache.rs | 178 +- .../app-lib/src/state/instances/content.rs | 887 ++++++++ packages/app-lib/src/state/instances/mod.rs | 4 + .../app-lib/src/state/legacy_converter.rs | 2 +- packages/app-lib/src/state/mod.rs | 3 + packages/app-lib/src/state/profiles.rs | 183 +- packages/assets/generated-icons.ts | 12 +- packages/assets/icons/arrow-up-down.svg | 1 + packages/assets/icons/circle-alert.svg | 17 + packages/assets/icons/pencil.svg | 16 + packages/assets/icons/text-cursor-input.svg | 19 + packages/assets/illustrations/done.svg | 19 + packages/assets/illustrations/empty-inbox.svg | 9 + packages/assets/illustrations/error.svg | 15 + .../assets/illustrations/no-connection.svg | 11 + .../assets/illustrations/no-credit-card.svg | 9 + .../assets/illustrations/no-documents.svg | 9 + packages/assets/illustrations/no-gps.svg | 12 + packages/assets/illustrations/no-images.svg | 12 + .../assets/illustrations/no-items-cart.svg | 15 + packages/assets/illustrations/no-messages.svg | 9 + .../assets/illustrations/no-search-result.svg | 14 + packages/assets/illustrations/no-tasks.svg | 10 + packages/assets/index.ts | 24 + .../tailwind/tailwind-preset.ts | 3 +- packages/ui/.prettierignore | 1 + packages/ui/.storybook/preview.ts | 20 + packages/ui/CLAUDE.md | 10 + packages/ui/index.ts | 2 +- packages/ui/package.json | 3 + packages/ui/src/components/base/Accordion.vue | 21 +- .../ui/src/components/base/Admonition.vue | 36 +- .../src/components/base/BigOptionButton.vue | 42 + packages/ui/src/components/base/Chips.vue | 14 +- .../ui/src/components/base/Collapsible.vue | 87 +- packages/ui/src/components/base/Combobox.vue | 338 ++-- .../ui/src/components/base/EmptyState.vue | 60 + .../src/components/base/FloatingActionBar.vue | 19 +- .../src/components/base/MultiStageModal.vue | 45 +- .../ui/src/components/base/ProgressBar.vue | 12 +- packages/ui/src/components/base/index.ts | 2 + .../components/CustomSetupStage.vue | 422 ++++ .../components/FinalConfigStage.vue | 191 ++ .../components/ImportInstanceStage.vue | 281 +++ .../components/ModpackStage.vue | 174 ++ .../components/SetupTypeStage.vue | 84 + .../creation-flow-context.ts | 396 ++++ .../flows/creation-flow-modal/index.vue | 90 + .../flows/creation-flow-modal/shared.ts | 3 + .../stages/custom-setup-stage.ts | 71 + .../stages/final-config-stage.ts | 59 + .../stages/import-instance-stage.ts | 41 + .../flows/creation-flow-modal/stages/index.ts | 15 + .../stages/modpack-stage.ts | 20 + .../stages/setup-type-stage.ts | 14 + packages/ui/src/components/index.ts | 1 - .../instances/ContentModpackCard.vue | 180 -- packages/ui/src/components/instances/index.ts | 19 - .../instances/modals/ContentUpdaterModal.vue | 389 ---- .../components/modal/InstallToPlayModal.vue | 111 ++ packages/ui/src/components/modal/NewModal.vue | 133 +- .../ui/src/components/modal/TabbedModal.vue | 12 +- packages/ui/src/components/modal/index.ts | 1 + .../project/card/ProjectCardStats.vue | 2 +- .../components/servers/InstallingBanner.vue | 122 ++ .../src/components/servers/ServerListing.vue | 8 +- .../components/servers/ServerSetupModal.vue | 254 +++ .../servers/backups/BackupCreateModal.vue | 3 +- .../servers/backups/BackupRenameModal.vue | 2 +- .../servers/backups/BackupRestoreModal.vue | 3 +- .../servers/content}/ContentVersionFilter.vue | 21 +- .../components/servers/files/FileNavbar.vue | 4 + .../servers/files/explorer/FileItem.vue | 73 +- .../files/explorer/FileVirtualList.vue | 75 +- .../files/explorer/TeleportOverflowMenu.vue | 10 + .../ui/src/components/servers/flows/index.ts | 11 + packages/ui/src/components/servers/index.ts | 3 + .../version/VersionChannelIndicator.vue | 30 +- packages/ui/src/composables/index.ts | 2 + packages/ui/src/composables/modal-stack.ts | 27 + packages/ui/src/composables/virtual-scroll.ts | 6 +- packages/ui/src/layouts/index.ts | 3 + .../components}/ContentCardItem.vue | 75 +- .../components}/ContentCardTable.vue | 46 +- .../components/ContentModpackCard.vue | 371 ++++ .../components/ContentSelectionBar.vue | 207 ++ .../modals/ConfirmBulkUpdateModal.vue | 98 + .../modals/ConfirmDeletionModal.vue | 107 + .../components/modals/ConfirmLeaveModal.vue | 91 + .../modals/ConfirmModpackUpdateModal.vue | 109 + .../modals/ConfirmReinstallModal.vue | 97 + .../components/modals/ConfirmRepairModal.vue | 79 + .../components/modals/ConfirmUnlinkModal.vue | 97 + .../components/modals/ContentInstallModal.vue | 460 +++++ .../components/modals/ContentUpdaterModal.vue | 546 +++++ .../components/modals/InlineBackupCreator.vue | 112 ++ .../modals/ModpackContentModal.vue | 120 +- .../composables/bulk-operations.ts | 70 + .../content-tab/composables/changing-items.ts | 21 + .../composables/content-filtering.ts | 98 + .../content-tab/composables/content-search.ts | 25 + .../composables/content-selection.ts | 34 + .../shared/content-tab/composables/index.ts | 6 + .../composables/use-inline-backup.ts | 235 +++ .../src/layouts/shared/content-tab/index.ts | 20 + .../src/layouts/shared/content-tab/layout.vue | 793 ++++++++ .../content-tab/providers/content-manager.ts | 111 ++ .../shared/content-tab/providers/index.ts | 1 + .../shared/content-tab}/types.ts | 7 +- .../components/ContentDiffModal.vue | 222 +++ .../composables/index.ts | 1 + .../composables/use-installation-form.ts | 278 +++ .../shared/installation-settings/index.ts | 5 + .../shared/installation-settings/layout.vue | 710 +++++++ .../installation-settings/providers/index.ts | 1 + .../providers/installation-settings.ts | 84 + .../shared/installation-settings/types.ts | 46 + .../hosting/manage/[id]/onboarding.vue | 260 +++ .../wrapped}/hosting/manage/backups.vue | 137 +- .../wrapped/hosting/manage/content.vue | 830 ++++++++ .../wrapped}/hosting/manage/files.vue | 87 +- .../wrapped}/hosting/manage/index.vue | 24 +- .../src/{pages => layouts/wrapped}/index.ts | 2 + packages/ui/src/locales/en-US/index.json | 505 ++++- packages/ui/src/providers/api-client.ts | 2 +- packages/ui/src/providers/app-backup.ts | 10 + packages/ui/src/providers/content-manager.ts | 7 + packages/ui/src/providers/create-context.ts | 79 + packages/ui/src/providers/file-picker.ts | 19 + packages/ui/src/providers/index.ts | 87 +- packages/ui/src/providers/instance-import.ts | 23 + packages/ui/src/providers/modal-behavior.ts | 14 + packages/ui/src/providers/server-context.ts | 13 + packages/ui/src/providers/tags.ts | 11 + .../ui/src/stories/base/Combobox.stories.ts | 121 +- .../ui/src/stories/base/EmptyState.stories.ts | 90 + .../instances/ContentCardTable.stories.ts | 1094 ++++++---- .../instances/ContentModpackCard.stories.ts | 8 +- .../instances/ContentUpdaterModal.stories.ts | 2 +- .../instances/ModpackContentModal.stories.ts | 4 +- .../servers/CreationFlowModal.stories.ts | 128 ++ packages/ui/src/utils/auto-icons.ts | 65 +- packages/ui/src/utils/common-messages.ts | 81 + packages/ui/src/utils/file-extensions.ts | 24 +- packages/ui/src/utils/index.ts | 1 + packages/ui/src/utils/loaders.ts | 13 + packages/ui/src/utils/search.ts | 2 + packages/ui/tsconfig.json | 7 +- packages/ui/vite.config.ts | 1 + packages/utils/servers/types/api.ts | 2 +- pnpm-lock.yaml | 17 +- turbo.jsonc | 2 +- 302 files changed, 20016 insertions(+), 12142 deletions(-) delete mode 100644 apps/app-frontend/src/components/ui/InstanceCreationModal.vue create mode 100644 apps/app-frontend/src/components/ui/modal/ConfirmDeleteInstanceModal.vue delete mode 100644 apps/app-frontend/src/helpers/pack.js create mode 100644 apps/app-frontend/src/helpers/pack.ts delete mode 100644 apps/app-frontend/src/helpers/profile.js create mode 100644 apps/app-frontend/src/helpers/profile.ts create mode 100644 apps/app-frontend/src/providers/content-install.ts create mode 100644 apps/app-frontend/src/providers/server-install.ts create mode 100644 apps/app-frontend/src/providers/setup.ts create mode 100644 apps/app-frontend/src/providers/setup/creation-modal.ts create mode 100644 apps/app-frontend/src/providers/setup/file-picker.ts create mode 100644 apps/app-frontend/src/providers/setup/instance-import.ts create mode 100644 apps/app-frontend/src/providers/setup/tags.ts create mode 100644 apps/frontend/.env.staging-archon delete mode 100644 apps/frontend/src/components/ui/servers/ContentVersionEditModal.vue delete mode 100644 apps/frontend/src/components/ui/servers/FileItem.vue delete mode 100644 apps/frontend/src/components/ui/servers/FileManagerError.vue delete mode 100644 apps/frontend/src/components/ui/servers/FileVirtualList.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesBrowseNavbar.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesContextMenu.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesCreateItemModal.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesDeleteItemModal.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesEditingNavbar.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesEditor.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesImageViewer.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesLabelBar.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesMoveItemModal.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesRenameItemModal.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesUploadConflictModal.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesUploadDragAndDrop.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesUploadDropdown.vue delete mode 100644 apps/frontend/src/components/ui/servers/FilesUploadZipUrlModal.vue delete mode 100644 apps/frontend/src/components/ui/servers/InstallingTicker.vue delete mode 100644 apps/frontend/src/components/ui/servers/PlatformMrpackModal.vue delete mode 100644 apps/frontend/src/components/ui/servers/ServerInstallation.vue delete mode 100644 apps/frontend/src/composables/servers/modrinth-servers.ts delete mode 100644 apps/frontend/src/composables/servers/modules/backups.ts delete mode 100644 apps/frontend/src/composables/servers/modules/base.ts delete mode 100644 apps/frontend/src/composables/servers/modules/content.ts delete mode 100644 apps/frontend/src/composables/servers/modules/general.ts delete mode 100644 apps/frontend/src/composables/servers/modules/index.ts delete mode 100644 apps/frontend/src/composables/servers/modules/network.ts delete mode 100644 apps/frontend/src/composables/servers/modules/startup.ts delete mode 100644 apps/frontend/src/composables/servers/modules/ws.ts create mode 100644 apps/frontend/src/composables/servers/use-server-image.ts create mode 100644 apps/frontend/src/composables/servers/use-server-project.ts delete mode 100644 apps/frontend/src/pages/hosting/manage/[id]/content/index.vue create mode 100644 apps/frontend/src/providers/setup.ts create mode 100644 apps/frontend/src/providers/setup/file-picker.ts create mode 100644 apps/frontend/src/providers/setup/modrinth-client.ts create mode 100644 apps/frontend/src/providers/setup/page-context.ts create mode 100644 apps/frontend/src/providers/setup/tags.ts delete mode 100644 packages/api-client/src/modules/archon/backups/v0.ts delete mode 100644 packages/api-client/src/modules/archon/content/v0.ts create mode 100644 packages/api-client/src/modules/archon/content/v1.ts create mode 100644 packages/api-client/src/modules/archon/options/v1.ts create mode 100644 packages/api-client/src/modules/archon/properties/v1.ts create mode 100644 packages/api-client/src/modules/kyros/content/v1.ts create mode 100644 packages/api-client/src/modules/labrinth/versions/v2.ts create mode 100644 packages/api-client/src/modules/launcher-meta/types.ts create mode 100644 packages/api-client/src/modules/launcher-meta/v0.ts create mode 100644 packages/api-client/src/modules/paper/types.ts create mode 100644 packages/api-client/src/modules/paper/v3.ts create mode 100644 packages/api-client/src/modules/purpur/types.ts create mode 100644 packages/api-client/src/modules/purpur/v2.ts create mode 100644 packages/app-lib/.sqlx/query-4d66e2bfedb7a31244d24858acf9b73a6289c1a90fb0988c4f5f5f64be01c4ec.json create mode 100644 packages/app-lib/src/state/instances/content.rs create mode 100644 packages/app-lib/src/state/instances/mod.rs create mode 100644 packages/assets/icons/arrow-up-down.svg create mode 100644 packages/assets/icons/circle-alert.svg create mode 100644 packages/assets/icons/pencil.svg create mode 100644 packages/assets/icons/text-cursor-input.svg create mode 100644 packages/assets/illustrations/done.svg create mode 100644 packages/assets/illustrations/empty-inbox.svg create mode 100644 packages/assets/illustrations/error.svg create mode 100644 packages/assets/illustrations/no-connection.svg create mode 100644 packages/assets/illustrations/no-credit-card.svg create mode 100644 packages/assets/illustrations/no-documents.svg create mode 100644 packages/assets/illustrations/no-gps.svg create mode 100644 packages/assets/illustrations/no-images.svg create mode 100644 packages/assets/illustrations/no-items-cart.svg create mode 100644 packages/assets/illustrations/no-messages.svg create mode 100644 packages/assets/illustrations/no-search-result.svg create mode 100644 packages/assets/illustrations/no-tasks.svg create mode 100644 packages/ui/src/components/base/BigOptionButton.vue create mode 100644 packages/ui/src/components/base/EmptyState.vue create mode 100644 packages/ui/src/components/flows/creation-flow-modal/components/CustomSetupStage.vue create mode 100644 packages/ui/src/components/flows/creation-flow-modal/components/FinalConfigStage.vue create mode 100644 packages/ui/src/components/flows/creation-flow-modal/components/ImportInstanceStage.vue create mode 100644 packages/ui/src/components/flows/creation-flow-modal/components/ModpackStage.vue create mode 100644 packages/ui/src/components/flows/creation-flow-modal/components/SetupTypeStage.vue create mode 100644 packages/ui/src/components/flows/creation-flow-modal/creation-flow-context.ts create mode 100644 packages/ui/src/components/flows/creation-flow-modal/index.vue create mode 100644 packages/ui/src/components/flows/creation-flow-modal/shared.ts create mode 100644 packages/ui/src/components/flows/creation-flow-modal/stages/custom-setup-stage.ts create mode 100644 packages/ui/src/components/flows/creation-flow-modal/stages/final-config-stage.ts create mode 100644 packages/ui/src/components/flows/creation-flow-modal/stages/import-instance-stage.ts create mode 100644 packages/ui/src/components/flows/creation-flow-modal/stages/index.ts create mode 100644 packages/ui/src/components/flows/creation-flow-modal/stages/modpack-stage.ts create mode 100644 packages/ui/src/components/flows/creation-flow-modal/stages/setup-type-stage.ts delete mode 100644 packages/ui/src/components/instances/ContentModpackCard.vue delete mode 100644 packages/ui/src/components/instances/index.ts delete mode 100644 packages/ui/src/components/instances/modals/ContentUpdaterModal.vue create mode 100644 packages/ui/src/components/modal/InstallToPlayModal.vue create mode 100644 packages/ui/src/components/servers/InstallingBanner.vue create mode 100644 packages/ui/src/components/servers/ServerSetupModal.vue rename {apps/frontend/src/components/ui/servers => packages/ui/src/components/servers/content}/ContentVersionFilter.vue (88%) create mode 100644 packages/ui/src/components/servers/flows/index.ts create mode 100644 packages/ui/src/composables/modal-stack.ts create mode 100644 packages/ui/src/layouts/index.ts rename packages/ui/src/{components/instances => layouts/shared/content-tab/components}/ContentCardItem.vue (77%) rename packages/ui/src/{components/instances => layouts/shared/content-tab/components}/ContentCardTable.vue (86%) create mode 100644 packages/ui/src/layouts/shared/content-tab/components/ContentModpackCard.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/ContentSelectionBar.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/modals/ConfirmBulkUpdateModal.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/modals/ConfirmDeletionModal.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/modals/ConfirmLeaveModal.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/modals/ConfirmModpackUpdateModal.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/modals/ConfirmReinstallModal.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/modals/ConfirmRepairModal.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/modals/ConfirmUnlinkModal.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/modals/ContentInstallModal.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/modals/ContentUpdaterModal.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/components/modals/InlineBackupCreator.vue rename packages/ui/src/{components/instances => layouts/shared/content-tab/components}/modals/ModpackContentModal.vue (83%) create mode 100644 packages/ui/src/layouts/shared/content-tab/composables/bulk-operations.ts create mode 100644 packages/ui/src/layouts/shared/content-tab/composables/changing-items.ts create mode 100644 packages/ui/src/layouts/shared/content-tab/composables/content-filtering.ts create mode 100644 packages/ui/src/layouts/shared/content-tab/composables/content-search.ts create mode 100644 packages/ui/src/layouts/shared/content-tab/composables/content-selection.ts create mode 100644 packages/ui/src/layouts/shared/content-tab/composables/index.ts create mode 100644 packages/ui/src/layouts/shared/content-tab/composables/use-inline-backup.ts create mode 100644 packages/ui/src/layouts/shared/content-tab/index.ts create mode 100644 packages/ui/src/layouts/shared/content-tab/layout.vue create mode 100644 packages/ui/src/layouts/shared/content-tab/providers/content-manager.ts create mode 100644 packages/ui/src/layouts/shared/content-tab/providers/index.ts rename packages/ui/src/{components/instances => layouts/shared/content-tab}/types.ts (89%) create mode 100644 packages/ui/src/layouts/shared/installation-settings/components/ContentDiffModal.vue create mode 100644 packages/ui/src/layouts/shared/installation-settings/composables/index.ts create mode 100644 packages/ui/src/layouts/shared/installation-settings/composables/use-installation-form.ts create mode 100644 packages/ui/src/layouts/shared/installation-settings/index.ts create mode 100644 packages/ui/src/layouts/shared/installation-settings/layout.vue create mode 100644 packages/ui/src/layouts/shared/installation-settings/providers/index.ts create mode 100644 packages/ui/src/layouts/shared/installation-settings/providers/installation-settings.ts create mode 100644 packages/ui/src/layouts/shared/installation-settings/types.ts create mode 100644 packages/ui/src/layouts/wrapped/hosting/manage/[id]/onboarding.vue rename packages/ui/src/{pages => layouts/wrapped}/hosting/manage/backups.vue (64%) create mode 100644 packages/ui/src/layouts/wrapped/hosting/manage/content.vue rename packages/ui/src/{pages => layouts/wrapped}/hosting/manage/files.vue (94%) rename packages/ui/src/{pages => layouts/wrapped}/hosting/manage/index.vue (92%) rename packages/ui/src/{pages => layouts/wrapped}/index.ts (57%) create mode 100644 packages/ui/src/providers/app-backup.ts create mode 100644 packages/ui/src/providers/content-manager.ts create mode 100644 packages/ui/src/providers/create-context.ts create mode 100644 packages/ui/src/providers/file-picker.ts create mode 100644 packages/ui/src/providers/instance-import.ts create mode 100644 packages/ui/src/providers/modal-behavior.ts create mode 100644 packages/ui/src/providers/tags.ts create mode 100644 packages/ui/src/stories/base/EmptyState.stories.ts create mode 100644 packages/ui/src/stories/servers/CreationFlowModal.stories.ts create mode 100644 packages/ui/src/utils/loaders.ts diff --git a/CLAUDE.md b/CLAUDE.md index 7cb1dad1b..7177ae0de 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -67,10 +67,22 @@ Each project may have its own `CLAUDE.md` with detailed instructions: - [`apps/labrinth/CLAUDE.md`](apps/labrinth/CLAUDE.md) — Backend API - [`apps/frontend/CLAUDE.md`](apps/frontend/CLAUDE.md) - Frontend Website +## Skills (`.claude/skills/`) + +Project-specific skill files with detailed patterns. Use them when the task matches: + +- **`api-module`** — Adding a new API endpoint module to `packages/api-client` (types, module class, registry registration) +- **`cross-platform-pages`** — Building a page that needs to work in both the website (`apps/frontend`) and the desktop app (`apps/app-frontend`) +- **`dependency-injection`** — Creating or wiring up a `provide`/`inject` context for platform abstraction or deep component state sharing +- **`figma-mcp`** — Translating a Figma design into Vue components using the Figma MCP tools +- **`i18n-convert`** — Converting hardcoded English strings in Vue SFCs into the `@modrinth/ui` i18n system (`defineMessages`, `formatMessage`, `IntlFormatted`) +- **`multistage-modals`** — Building a wizard-like modal with multiple stages, progress tracking, and per-stage buttons using `MultiStageModal` +- **`tanstack-query`** — Fetching, caching, or mutating server data with `@tanstack/vue-query` (queries, mutations, invalidation, optimistic updates) + ## Code Guidelines ### Comments -- DO NOT use "heading" comments like: // === Helper methods === . +- DO NOT use "heading" comments like: `=== Helper methods ===`. - Use doc comments, but avoid inline comments unless ABSOLUTELY necessary for clarity. Code should aim to be self documenting! ## Bash Guidelines @@ -78,12 +90,30 @@ Each project may have its own `CLAUDE.md` with detailed instructions: ### Output handling - DO NOT pipe output through `head`, `tail`, `less`, or `more` - NEVER use `| head -n X` or `| tail -n X` to truncate output -- Run commands directly without pipes when possible -- If you need to limit output, use command-specific flags (e.g. `git log -n 10` instead of `git log | head -10`) +- IMPORTANT: Run commands directly without pipes when possible +- IMPORTANT: If you need to limit output, use command-specific flags (e.g. `git log -n 10` instead of `git log | head -10`) - ALWAYS read the full output — never pipe through filters ### General - Do not create new non-source code files (e.g. Bash scripts, SQL scripts) unless explicitly prompted to +- For Frontend, when doing lint checks, only use the `prepr` commands, do not use `typecheck` or `tsc` etc. + +## Edit Tool - Whitespace Handling (CLAUDE ONLY) + +The Read tool uses `→` to mark where line numbers end and file content begins. + +**Rule:** Copy the EXACT whitespace that appears after the `→` marker. +- Whatever appears between `→` and the code text is what's actually in the file +- That whitespace must be used EXACTLY in Edit tool's old_string +- Don't count arrows, don't interpret - just copy what's after the `→` + +**Example:** +14→ private byte tag; +For Edit, use: ` private byte tag;` (copy everything after →, including the two tabs) + +**If Edit fails:** Stop and explain the problem. Do not attempt sed/awk/bash workarounds. + +**IMPORTANT**: Trust the Read tool output. Copy what's after `→` into Edit immediately. DO NOT verify with sed/od/grep first - that's wasting time and the instructions already tell you to stop if Edit fails, not to pre-verify. ## Skills diff --git a/apps/app-frontend/package.json b/apps/app-frontend/package.json index c7561a588..d892df69f 100644 --- a/apps/app-frontend/package.json +++ b/apps/app-frontend/package.json @@ -22,23 +22,24 @@ "@tanstack/vue-query": "^5.90.7", "@tauri-apps/api": "^2.5.0", "@tauri-apps/plugin-dialog": "^2.2.1", - "@tauri-apps/plugin-http": "^2.5.0", + "@tauri-apps/plugin-http": "~2.5.7", "@tauri-apps/plugin-opener": "^2.2.6", "@tauri-apps/plugin-os": "^2.2.1", "@tauri-apps/plugin-updater": "^2.7.1", "@tauri-apps/plugin-window-state": "^2.2.2", "@types/three": "^0.172.0", - "intl-messageformat": "^10.7.7", - "vue-i18n": "^10.0.0", "@vueuse/core": "^11.1.0", "dayjs": "^1.11.10", "floating-vue": "^5.2.2", + "fuse.js": "^6.6.2", + "intl-messageformat": "^10.7.7", "ofetch": "^1.3.4", "pinia": "^3.0.0", "posthog-js": "^1.158.2", "three": "^0.172.0", "vite-svg-loader": "^5.1.0", "vue": "^3.5.13", + "vue-i18n": "^10.0.0", "vue-multiselect": "3.0.0", "vue-router": "^4.6.0", "vue-virtual-scroller": "v2.0.0-beta.8" diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue index eed52f835..f7a029b5c 100644 --- a/apps/app-frontend/src/App.vue +++ b/apps/app-frontend/src/App.vue @@ -31,6 +31,8 @@ import { Button, ButtonStyled, commonMessages, + ContentInstallModal, + CreationFlowModal, defineMessages, I18nDebugPanel, NewsArticleCard, @@ -38,6 +40,7 @@ import { OverflowMenu, PopupNotificationPanel, ProgressSpinner, + provideModalBehavior, provideModrinthClient, provideNotificationManager, providePageContext, @@ -66,8 +69,6 @@ import FriendsList from '@/components/ui/friends/FriendsList.vue' import AddServerToInstanceModal from '@/components/ui/install_flow/AddServerToInstanceModal.vue' import IncompatibilityWarningModal from '@/components/ui/install_flow/IncompatibilityWarningModal.vue' import InstallConfirmModal from '@/components/ui/install_flow/InstallConfirmModal.vue' -import ModInstallModal from '@/components/ui/install_flow/ModInstallModal.vue' -import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue' import MinecraftAuthErrorModal from '@/components/ui/minecraft-auth-error-modal/MinecraftAuthErrorModal.vue' import AppSettingsModal from '@/components/ui/modal/AppSettingsModal.vue' import AuthGrantFlowWaitModal from '@/components/ui/modal/AuthGrantFlowWaitModal.vue' @@ -86,6 +87,7 @@ import { check_reachable } from '@/helpers/auth.js' import { get_user } from '@/helpers/cache.js' import { command_listener, warning_listener } from '@/helpers/events.js' import { cancelLogin, get as getCreds, login, logout } from '@/helpers/mr_auth.ts' +import { create_profile_and_install_from_file } from '@/helpers/pack' import { list } from '@/helpers/profile.js' import { get as getSettings, set as setSettings } from '@/helpers/settings.ts' import { get_opening_command, initialize_state } from '@/helpers/state' @@ -98,15 +100,16 @@ import { isNetworkMetered, } from '@/helpers/utils.js' import i18n from '@/i18n.config' +import { createContentInstall, provideContentInstall } from '@/providers/content-install' import { provideAppUpdateDownloadProgress, subscribeToDownloadProgress, } from '@/providers/download-progress.ts' +import { createServerInstall, provideServerInstall } from '@/providers/server-install' +import { setupProviders } from '@/providers/setup' import { useError } from '@/store/error.js' -import { playServerProject, useInstall } from '@/store/install.js' import { useLoading, useTheming } from '@/store/state' -import { create_profile_and_install_from_file } from './helpers/pack' import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer' import { get_available_capes, get_available_skins } from './helpers/skins' import { AppNotificationManager } from './providers/app-notifications' @@ -136,6 +139,20 @@ providePageContext({ hierarchicalSidebarAvailable: ref(true), showAds: ref(false), }) +provideModalBehavior({ + noblur: computed(() => !themeStore.advancedRendering), + onShow: () => hide_ads_window(), + onHide: () => show_ads_window(), +}) + +const { + installationModal, + handleCreate, + handleBrowseModpacks, + searchModpacks, + getProjectVersions, +} = setupProviders(notificationManager) + const news = ref([]) const availableSurvey = ref(false) @@ -392,7 +409,34 @@ const error = useError() const errorModal = ref() const minecraftAuthErrorModal = ref() -const install = useInstall() +const contentInstall = createContentInstall({ router, handleError }) +provideContentInstall(contentInstall) +const { + instances: contentInstallInstances, + compatibleLoaders: contentInstallLoaders, + gameVersions: contentInstallGameVersions, + loading: contentInstallLoading, + defaultTab: contentInstallDefaultTab, + preferredLoader: contentInstallPreferredLoader, + preferredGameVersion: contentInstallPreferredGameVersion, + releaseGameVersions: contentInstallReleaseGameVersions, + handleInstallToInstance, + handleCreateAndInstall, + handleNavigate: handleContentInstallNavigate, + handleCancel: handleContentInstallCancel, + setContentInstallModal, + setInstallConfirmModal: setContentInstallConfirmModal, + setIncompatibilityWarningModal: setContentIncompatibilityWarningModal, +} = contentInstall + +const serverInstall = createServerInstall({ router, handleError, popupNotificationManager }) +provideServerInstall(serverInstall) +const { + setInstallToPlayModal: setServerInstallToPlayModal, + setUpdateToPlayModal: setServerUpdateToPlayModal, + setAddServerToInstanceModal: setServerAddServerToInstanceModal, +} = serverInstall + const modInstallModal = ref() const addServerToInstanceModal = ref() const installConfirmModal = ref() @@ -474,13 +518,12 @@ onMounted(() => { error.setErrorModal(errorModal.value) error.setMinecraftAuthErrorModal(minecraftAuthErrorModal.value) - install.setIncompatibilityWarningModal(incompatibilityWarningModal) - install.setInstallConfirmModal(installConfirmModal) - install.setModInstallModal(modInstallModal) - install.setAddServerToInstanceModal(addServerToInstanceModal) - install.setInstallToPlayModal(installToPlayModal) - install.setUpdateToPlayModal(updateToPlayModal) - install.setPopupNotificationManager(popupNotificationManager) + setContentIncompatibilityWarningModal(incompatibilityWarningModal.value) + setContentInstallConfirmModal(installConfirmModal.value) + setContentInstallModal(modInstallModal.value) + setServerAddServerToInstanceModal(addServerToInstanceModal.value) + setServerInstallToPlayModal(installToPlayModal.value) + setServerUpdateToPlayModal(updateToPlayModal.value) }) const accounts = ref(null) @@ -898,9 +941,15 @@ provideAppUpdateDownloadProgress(appUpdateDownload) - - - +
@@ -946,7 +995,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload) @@ -1021,9 +1070,9 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
-
- -
+
+ +
-
+
- + diff --git a/apps/app-frontend/src/components/GridDisplay.vue b/apps/app-frontend/src/components/GridDisplay.vue index aa2b0bb8f..68bea3895 100644 --- a/apps/app-frontend/src/components/GridDisplay.vue +++ b/apps/app-frontend/src/components/GridDisplay.vue @@ -22,7 +22,7 @@ import { computed, ref } from 'vue' import ContextMenu from '@/components/ui/ContextMenu.vue' import Instance from '@/components/ui/Instance.vue' -import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue' +import ConfirmDeleteInstanceModal from '@/components/ui/modal/ConfirmDeleteInstanceModal.vue' import { duplicate, remove } from '@/helpers/profile.js' const { handleError } = injectNotificationManager() @@ -302,14 +302,7 @@ const filteredResults = computed(() => { />
- + diff --git a/apps/app-frontend/src/components/RowDisplay.vue b/apps/app-frontend/src/components/RowDisplay.vue index a8e8970ae..174d3e1ae 100644 --- a/apps/app-frontend/src/components/RowDisplay.vue +++ b/apps/app-frontend/src/components/RowDisplay.vue @@ -19,15 +19,16 @@ import { useRouter } from 'vue-router' import ContextMenu from '@/components/ui/ContextMenu.vue' import Instance from '@/components/ui/Instance.vue' import LegacyProjectCard from '@/components/ui/LegacyProjectCard.vue' -import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue' +import ConfirmDeleteInstanceModal from '@/components/ui/modal/ConfirmDeleteInstanceModal.vue' import { trackEvent } from '@/helpers/analytics' import { get_by_profile_path } from '@/helpers/process.js' import { duplicate, kill, remove, run } from '@/helpers/profile.js' import { showProfileInFolder } from '@/helpers/utils.js' +import { injectContentInstall } from '@/providers/content-install' import { handleSevereError } from '@/store/error.js' -import { install as installVersion } from '@/store/install.js' const { handleError } = injectNotificationManager() +const { install: installVersion } = injectContentInstall() const router = useRouter() @@ -238,14 +239,7 @@ onUnmounted(() => {