mirror of
https://github.com/modrinth/code.git
synced 2026-08-31 03:55:59 +00:00
feat: reshuffle layout for worlds
This commit is contained in:
@@ -495,6 +495,11 @@ const sidebarOverlayScrollbarsOptions = Object.freeze({
|
||||
},
|
||||
})
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
const redirect = await resolveLegacyServerWorldTabRedirect(to)
|
||||
if (redirect) return redirect
|
||||
})
|
||||
|
||||
router.beforeEach(() => {
|
||||
suspensePending = false
|
||||
if (routerToken) loading.end(routerToken)
|
||||
@@ -526,6 +531,50 @@ function onSuspensePending() {
|
||||
suspenseToken = loading.begin()
|
||||
}
|
||||
|
||||
async function resolveLegacyServerWorldTabRedirect(to) {
|
||||
if (!['ServerManageContent', 'ServerManageFiles', 'ServerManageBackups'].includes(to.name)) {
|
||||
return null
|
||||
}
|
||||
|
||||
const serverId = getRouteParam(to.params.id)
|
||||
if (!serverId) return null
|
||||
|
||||
const tabPath =
|
||||
to.name === 'ServerManageFiles' ? '/files' : to.name === 'ServerManageBackups' ? '/backups' : ''
|
||||
const worldsPath = `/hosting/manage/${encodeURIComponent(serverId)}/worlds`
|
||||
|
||||
try {
|
||||
const serverFull = await tauriApiClient.archon.servers_v1.get(serverId)
|
||||
const world = serverFull.worlds.find((item) => item.is_active) ?? serverFull.worlds[0]
|
||||
if (world) {
|
||||
return {
|
||||
path: `${worldsPath}/${encodeURIComponent(world.id)}${tabPath}`,
|
||||
query: to.query,
|
||||
hash: to.hash,
|
||||
replace: true,
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
return {
|
||||
path: worldsPath,
|
||||
query: to.query,
|
||||
hash: to.hash,
|
||||
replace: true,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
path: worldsPath,
|
||||
query: to.query,
|
||||
hash: to.hash,
|
||||
replace: true,
|
||||
}
|
||||
}
|
||||
|
||||
function getRouteParam(param) {
|
||||
return Array.isArray(param) ? param[0] : param
|
||||
}
|
||||
|
||||
function onSuspenseResolve() {
|
||||
if (suspenseToken) {
|
||||
loading.end(suspenseToken)
|
||||
|
||||
@@ -13,7 +13,7 @@ const queryClient = useQueryClient()
|
||||
if (worldId.value) {
|
||||
try {
|
||||
await queryClient.ensureQueryData({
|
||||
queryKey: ['backups', 'list', serverId],
|
||||
queryKey: ['backups', 'list', serverId, worldId.value],
|
||||
queryFn: () => client.archon.backups_v1.list(serverId, worldId.value!),
|
||||
staleTime: 30_000,
|
||||
})
|
||||
|
||||
@@ -13,7 +13,7 @@ const queryClient = useQueryClient()
|
||||
if (worldId.value) {
|
||||
try {
|
||||
await queryClient.ensureQueryData({
|
||||
queryKey: ['content', 'list', 'v1', serverId],
|
||||
queryKey: ['content', 'list', 'v1', serverId, worldId.value],
|
||||
queryFn: () =>
|
||||
client.archon.content_v1.getAddons(serverId, worldId.value!, { from_modpack: false }),
|
||||
staleTime: 30_000,
|
||||
|
||||
@@ -93,7 +93,7 @@ watch(
|
||||
breadcrumbs.setName('Server', server.name)
|
||||
breadcrumbs.setContext({
|
||||
name: server.name,
|
||||
link: `/hosting/manage/${serverId.value}/content`,
|
||||
link: `/hosting/manage/${serverId.value}/worlds`,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<ServersManageWorldRootLayout>
|
||||
<RouterView v-slot="{ Component }">
|
||||
<template v-if="Component">
|
||||
<Suspense>
|
||||
<component :is="Component" />
|
||||
</Suspense>
|
||||
</template>
|
||||
</RouterView>
|
||||
</ServersManageWorldRootLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ServersManageWorldRootLayout } from '@modrinth/ui'
|
||||
import { RouterView } from 'vue-router'
|
||||
</script>
|
||||
@@ -4,6 +4,7 @@ import Content from './Content.vue'
|
||||
import Files from './Files.vue'
|
||||
import Index from './Index.vue'
|
||||
import Overview from './Overview.vue'
|
||||
import World from './World.vue'
|
||||
import Worlds from './Worlds.vue'
|
||||
|
||||
export { Access, Backups, Content, Files, Index, Overview, Worlds }
|
||||
export { Access, Backups, Content, Files, Index, Overview, World, Worlds }
|
||||
|
||||
@@ -252,7 +252,7 @@ export function createServerInstallContent(opts: {
|
||||
if (serverFlowFrom.value === 'reset-server') {
|
||||
return `/hosting/manage/${sid}?openSettings=installation`
|
||||
}
|
||||
return `/hosting/manage/${sid}/content`
|
||||
return getServerWorldContentPath(sid, effectiveServerWorldId.value)
|
||||
})
|
||||
const serverBackLabel = computed(() => {
|
||||
if (serverFlowFrom.value === 'onboarding') return 'Back to setup'
|
||||
@@ -556,7 +556,7 @@ export function createServerInstallContent(opts: {
|
||||
|
||||
if (serverFlowFrom.value === 'onboarding') {
|
||||
await client.archon.servers_v1.endIntro(sid)
|
||||
await router.push(`/hosting/manage/${sid}/content`)
|
||||
await router.push(getServerWorldContentPath(sid, wid))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -571,6 +571,11 @@ export function createServerInstallContent(opts: {
|
||||
serverContentProjectIds.value = new Set([...serverContentProjectIds.value, id])
|
||||
}
|
||||
|
||||
function getServerWorldContentPath(serverId: string, worldId: string | null) {
|
||||
const base = `/hosting/manage/${encodeURIComponent(serverId)}/worlds`
|
||||
return worldId ? `${base}/${encodeURIComponent(worldId)}` : base
|
||||
}
|
||||
|
||||
return {
|
||||
serverIdQuery,
|
||||
worldIdQuery,
|
||||
|
||||
@@ -65,6 +65,40 @@ export default new createRouter({
|
||||
breadcrumb: [{ name: '?Server' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'worlds/:world_id',
|
||||
name: 'ServerManageWorld',
|
||||
component: Hosting.World,
|
||||
meta: {
|
||||
breadcrumb: [{ name: '?Server' }],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'ServerManageWorldContent',
|
||||
component: Hosting.Content,
|
||||
meta: {
|
||||
breadcrumb: [{ name: '?Server' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'files',
|
||||
name: 'ServerManageWorldFiles',
|
||||
component: Hosting.Files,
|
||||
meta: {
|
||||
breadcrumb: [{ name: '?Server' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'backups',
|
||||
name: 'ServerManageWorldBackups',
|
||||
component: Hosting.Backups,
|
||||
meta: {
|
||||
breadcrumb: [{ name: '?Server' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'files',
|
||||
name: 'ServerManageFiles',
|
||||
|
||||
@@ -187,7 +187,10 @@ export function useServerInstallContent({
|
||||
},
|
||||
}
|
||||
|
||||
const contentQueryKey = computed(() => ['content', 'list', currentServerId.value ?? ''] as const)
|
||||
const contentQueryKey = computed(
|
||||
() =>
|
||||
['content', 'list', 'v1', currentServerId.value ?? '', currentWorldId.value ?? null] as const,
|
||||
)
|
||||
const { data: serverContentData, error: serverContentError } = useQuery({
|
||||
queryKey: contentQueryKey,
|
||||
queryFn: () =>
|
||||
@@ -659,7 +662,7 @@ export function useServerInstallContent({
|
||||
if (fromContext.value === 'onboarding') {
|
||||
await client.archon.servers_v1.endIntro(currentServerId.value)
|
||||
queryClient.invalidateQueries({ queryKey: ['servers', 'detail', currentServerId.value] })
|
||||
navigateTo(`/hosting/manage/${currentServerId.value}/content`)
|
||||
navigateTo(getServerWorldContentPath(currentServerId.value, currentWorldId.value ?? null))
|
||||
} else {
|
||||
navigateTo(`/hosting/manage/${currentServerId.value}?openSettings=installation`)
|
||||
}
|
||||
@@ -675,9 +678,14 @@ export function useServerInstallContent({
|
||||
if (fromContext.value === 'onboarding') return `/hosting/manage/${id}?resumeModal=setup-type`
|
||||
if (fromContext.value === 'reset-server')
|
||||
return `/hosting/manage/${id}?openSettings=installation`
|
||||
return `/hosting/manage/${id}/content`
|
||||
return getServerWorldContentPath(id, currentWorldId.value)
|
||||
})
|
||||
|
||||
function getServerWorldContentPath(serverId: string, worldId: string | null) {
|
||||
const base = `/hosting/manage/${encodeURIComponent(serverId)}/worlds`
|
||||
return worldId ? `${base}/${encodeURIComponent(worldId)}` : base
|
||||
}
|
||||
|
||||
const serverBackLabel = computed(() => {
|
||||
if (fromContext.value === 'onboarding') return formatMessage(messages.backToSetup)
|
||||
if (fromContext.value === 'reset-server') return formatMessage(messages.cancelReset)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { createModrinthClient } from '~/helpers/api.ts'
|
||||
|
||||
export default defineNuxtRouteMiddleware(async (to) => {
|
||||
const match = to.path.match(/^\/hosting\/manage\/([^/]+)\/(content|files|backups)\/?$/)
|
||||
if (!match) return
|
||||
|
||||
const serverId = decodeURIComponent(match[1])
|
||||
const tab = match[2]
|
||||
const worldsPath = `/hosting/manage/${encodeURIComponent(serverId)}/worlds`
|
||||
const tabPath = tab === 'content' ? '' : `/${tab}`
|
||||
const auth = await useAuth()
|
||||
|
||||
if (auth.value.token) {
|
||||
try {
|
||||
const config = useRuntimeConfig()
|
||||
const client = createModrinthClient(auth, {
|
||||
apiBaseUrl: config.public.apiBaseUrl.replace('/v2/', '/'),
|
||||
archonBaseUrl: config.public.pyroBaseUrl.replace('/v2/', '/'),
|
||||
rateLimitKey: config.rateLimitKey,
|
||||
})
|
||||
const serverFull = await client.archon.servers_v1.get(serverId)
|
||||
const world = serverFull.worlds.find((item) => item.is_active) ?? serverFull.worlds[0]
|
||||
|
||||
if (world) {
|
||||
return navigateTo(
|
||||
{
|
||||
path: `${worldsPath}/${encodeURIComponent(world.id)}${tabPath}`,
|
||||
query: to.query,
|
||||
hash: to.hash,
|
||||
},
|
||||
{ replace: true },
|
||||
)
|
||||
}
|
||||
} catch {
|
||||
return navigateTo({ path: worldsPath, query: to.query, hash: to.hash }, { replace: true })
|
||||
}
|
||||
}
|
||||
|
||||
return navigateTo({ path: worldsPath, query: to.query, hash: to.hash }, { replace: true })
|
||||
})
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { ServersManageWorldRootLayout } from '@modrinth/ui'
|
||||
|
||||
const route = useNativeRoute()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ServersManageWorldRootLayout>
|
||||
<NuxtPage :route="route" />
|
||||
</ServersManageWorldRootLayout>
|
||||
</template>
|
||||
+1
-1
@@ -14,7 +14,7 @@ const flags = useFeatureFlags()
|
||||
if (worldId.value) {
|
||||
try {
|
||||
await queryClient.ensureQueryData({
|
||||
queryKey: ['backups', 'list', serverId],
|
||||
queryKey: ['backups', 'list', serverId, worldId.value],
|
||||
queryFn: () => client.archon.backups_v1.list(serverId, worldId.value!),
|
||||
staleTime: 30_000,
|
||||
})
|
||||
+1
-1
@@ -38,7 +38,7 @@ const contentWorldId = await getContentWorldId()
|
||||
if (contentWorldId) {
|
||||
try {
|
||||
const content = await queryClient.ensureQueryData({
|
||||
queryKey: ['content', 'list', 'v1', serverId],
|
||||
queryKey: ['content', 'list', 'v1', serverId, contentWorldId],
|
||||
queryFn: () =>
|
||||
client.archon.content_v1.getAddons(serverId, contentWorldId, { from_modpack: false }),
|
||||
staleTime: 30_000,
|
||||
Reference in New Issue
Block a user