Skip to content

Commit 8d6179f

Browse files
committed
feat: reshuffle layout for worlds
1 parent ce99c35 commit 8d6179f

33 files changed

Lines changed: 550 additions & 179 deletions

File tree

apps/app-frontend/src/App.vue

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,11 @@ const sidebarOverlayScrollbarsOptions = Object.freeze({
439439
},
440440
})
441441
442+
router.beforeEach(async (to) => {
443+
const redirect = await resolveLegacyServerWorldTabRedirect(to)
444+
if (redirect) return redirect
445+
})
446+
442447
router.beforeEach(() => {
443448
suspensePending = false
444449
if (routerToken) loading.end(routerToken)
@@ -470,6 +475,50 @@ function onSuspensePending() {
470475
suspenseToken = loading.begin()
471476
}
472477
478+
async function resolveLegacyServerWorldTabRedirect(to) {
479+
if (!['ServerManageContent', 'ServerManageFiles', 'ServerManageBackups'].includes(to.name)) {
480+
return null
481+
}
482+
483+
const serverId = getRouteParam(to.params.id)
484+
if (!serverId) return null
485+
486+
const tabPath =
487+
to.name === 'ServerManageFiles' ? '/files' : to.name === 'ServerManageBackups' ? '/backups' : ''
488+
const worldsPath = `/hosting/manage/${encodeURIComponent(serverId)}/worlds`
489+
490+
try {
491+
const serverFull = await tauriApiClient.archon.servers_v1.get(serverId)
492+
const world = serverFull.worlds.find((item) => item.is_active) ?? serverFull.worlds[0]
493+
if (world) {
494+
return {
495+
path: `${worldsPath}/${encodeURIComponent(world.id)}${tabPath}`,
496+
query: to.query,
497+
hash: to.hash,
498+
replace: true,
499+
}
500+
}
501+
} catch {
502+
return {
503+
path: worldsPath,
504+
query: to.query,
505+
hash: to.hash,
506+
replace: true,
507+
}
508+
}
509+
510+
return {
511+
path: worldsPath,
512+
query: to.query,
513+
hash: to.hash,
514+
replace: true,
515+
}
516+
}
517+
518+
function getRouteParam(param) {
519+
return Array.isArray(param) ? param[0] : param
520+
}
521+
473522
function onSuspenseResolve() {
474523
if (suspenseToken) {
475524
loading.end(suspenseToken)

apps/app-frontend/src/pages/hosting/manage/Backups.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const queryClient = useQueryClient()
1313
if (worldId.value) {
1414
try {
1515
await queryClient.ensureQueryData({
16-
queryKey: ['backups', 'list', serverId],
16+
queryKey: ['backups', 'list', serverId, worldId.value],
1717
queryFn: () => client.archon.backups_v1.list(serverId, worldId.value!),
1818
staleTime: 30_000,
1919
})

apps/app-frontend/src/pages/hosting/manage/Content.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const queryClient = useQueryClient()
1313
if (worldId.value) {
1414
try {
1515
await queryClient.ensureQueryData({
16-
queryKey: ['content', 'list', 'v1', serverId],
16+
queryKey: ['content', 'list', 'v1', serverId, worldId.value],
1717
queryFn: () =>
1818
client.archon.content_v1.getAddons(serverId, worldId.value!, { from_modpack: false }),
1919
staleTime: 30_000,

apps/app-frontend/src/pages/hosting/manage/Index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ watch(
9393
breadcrumbs.setName('Server', server.name)
9494
breadcrumbs.setContext({
9595
name: server.name,
96-
link: `/hosting/manage/${serverId.value}/content`,
96+
link: `/hosting/manage/${serverId.value}/worlds`,
9797
})
9898
}
9999
},
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<template>
2+
<ServersManageWorldRootLayout>
3+
<RouterView v-slot="{ Component }">
4+
<template v-if="Component">
5+
<Suspense>
6+
<component :is="Component" />
7+
</Suspense>
8+
</template>
9+
</RouterView>
10+
</ServersManageWorldRootLayout>
11+
</template>
12+
13+
<script setup lang="ts">
14+
import { ServersManageWorldRootLayout } from '@modrinth/ui'
15+
import { RouterView } from 'vue-router'
16+
</script>

apps/app-frontend/src/pages/hosting/manage/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Content from './Content.vue'
33
import Files from './Files.vue'
44
import Index from './Index.vue'
55
import Overview from './Overview.vue'
6+
import World from './World.vue'
67
import Worlds from './Worlds.vue'
78

8-
export { Backups, Content, Files, Index, Overview, Worlds }
9+
export { Backups, Content, Files, Index, Overview, World, Worlds }

apps/app-frontend/src/providers/setup/server-install-content.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export function createServerInstallContent(opts: {
101101
if (serverFlowFrom.value === 'reset-server') {
102102
return `/hosting/manage/${sid}?openSettings=installation`
103103
}
104-
return `/hosting/manage/${sid}/content`
104+
return getServerWorldContentPath(sid, effectiveServerWorldId.value)
105105
})
106106
const serverBackLabel = computed(() => {
107107
if (serverFlowFrom.value === 'onboarding') return 'Back to setup'
@@ -351,7 +351,7 @@ export function createServerInstallContent(opts: {
351351

352352
if (serverFlowFrom.value === 'onboarding') {
353353
await client.archon.servers_v1.endIntro(sid)
354-
await router.push(`/hosting/manage/${sid}/content`)
354+
await router.push(getServerWorldContentPath(sid, wid))
355355
return
356356
}
357357

@@ -366,6 +366,11 @@ export function createServerInstallContent(opts: {
366366
serverContentProjectIds.value = new Set([...serverContentProjectIds.value, id])
367367
}
368368

369+
function getServerWorldContentPath(serverId: string, worldId: string | null) {
370+
const base = `/hosting/manage/${encodeURIComponent(serverId)}/worlds`
371+
return worldId ? `${base}/${encodeURIComponent(worldId)}` : base
372+
}
373+
369374
return {
370375
serverIdQuery,
371376
worldIdQuery,

apps/app-frontend/src/routes.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,40 @@ export default new createRouter({
6565
breadcrumb: [{ name: '?Server' }],
6666
},
6767
},
68+
{
69+
path: 'worlds/:world_id',
70+
name: 'ServerManageWorld',
71+
component: Hosting.World,
72+
meta: {
73+
breadcrumb: [{ name: '?Server' }],
74+
},
75+
children: [
76+
{
77+
path: '',
78+
name: 'ServerManageWorldContent',
79+
component: Hosting.Content,
80+
meta: {
81+
breadcrumb: [{ name: '?Server' }],
82+
},
83+
},
84+
{
85+
path: 'files',
86+
name: 'ServerManageWorldFiles',
87+
component: Hosting.Files,
88+
meta: {
89+
breadcrumb: [{ name: '?Server' }],
90+
},
91+
},
92+
{
93+
path: 'backups',
94+
name: 'ServerManageWorldBackups',
95+
component: Hosting.Backups,
96+
meta: {
97+
breadcrumb: [{ name: '?Server' }],
98+
},
99+
},
100+
],
101+
},
68102
{
69103
path: 'files',
70104
name: 'ServerManageFiles',
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { createModrinthClient } from '~/helpers/api.ts'
2+
3+
export default defineNuxtRouteMiddleware(async (to) => {
4+
const match = to.path.match(/^\/hosting\/manage\/([^/]+)\/(content|files|backups)\/?$/)
5+
if (!match) return
6+
7+
const serverId = decodeURIComponent(match[1])
8+
const tab = match[2]
9+
const worldsPath = `/hosting/manage/${encodeURIComponent(serverId)}/worlds`
10+
const tabPath = tab === 'content' ? '' : `/${tab}`
11+
const auth = await useAuth()
12+
13+
if (auth.value.token) {
14+
try {
15+
const config = useRuntimeConfig()
16+
const client = createModrinthClient(auth, {
17+
apiBaseUrl: config.public.apiBaseUrl.replace('/v2/', '/'),
18+
archonBaseUrl: config.public.pyroBaseUrl.replace('/v2/', '/'),
19+
rateLimitKey: config.rateLimitKey,
20+
})
21+
const serverFull = await client.archon.servers_v1.get(serverId)
22+
const world = serverFull.worlds.find((item) => item.is_active) ?? serverFull.worlds[0]
23+
24+
if (world) {
25+
return navigateTo(
26+
{
27+
path: `${worldsPath}/${encodeURIComponent(world.id)}${tabPath}`,
28+
query: to.query,
29+
hash: to.hash,
30+
},
31+
{ replace: true },
32+
)
33+
}
34+
} catch {
35+
return navigateTo({ path: worldsPath, query: to.query, hash: to.hash }, { replace: true })
36+
}
37+
}
38+
39+
return navigateTo({ path: worldsPath, query: to.query, hash: to.hash }, { replace: true })
40+
})

apps/frontend/src/pages/discover/[type]/index.vue

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,10 @@ function syncHiddenInstalledProjectIds() {
211211
hiddenInstalledProjectIdsInitialized.value = true
212212
}
213213
214-
const contentQueryKey = computed(() => ['content', 'list', currentServerId.value ?? ''] as const)
214+
const contentQueryKey = computed(
215+
() =>
216+
['content', 'list', 'v1', currentServerId.value ?? '', currentWorldId.value ?? null] as const,
217+
)
215218
const { data: serverContentData, error: serverContentError } = useQuery({
216219
queryKey: contentQueryKey,
217220
queryFn: () => client.archon.content_v1.getAddons(currentServerId.value!, currentWorldId.value!),
@@ -252,7 +255,7 @@ const installContentMutation = useMutation({
252255
}),
253256
onSuccess: () => {
254257
if (currentServerId.value) {
255-
queryClient.refetchQueries({ queryKey: ['content', 'list', currentServerId.value] })
258+
queryClient.refetchQueries({ queryKey: contentQueryKey.value })
256259
}
257260
},
258261
})
@@ -551,7 +554,7 @@ async function onModpackFlowCreate(config: CreationFlowContextValue) {
551554
if (fromContext.value === 'onboarding') {
552555
await client.archon.servers_v1.endIntro(currentServerId.value)
553556
queryClient.invalidateQueries({ queryKey: ['servers', 'detail', currentServerId.value] })
554-
navigateTo(`/hosting/manage/${currentServerId.value}/content`)
557+
navigateTo(getServerWorldContentPath(currentServerId.value, currentWorldId.value ?? null))
555558
} else {
556559
navigateTo(`/hosting/manage/${currentServerId.value}?openSettings=installation`)
557560
}
@@ -566,9 +569,14 @@ const serverBackUrl = computed(() => {
566569
const id = serverData.value.server_id
567570
if (fromContext.value === 'onboarding') return `/hosting/manage/${id}?resumeModal=setup-type`
568571
if (fromContext.value === 'reset-server') return `/hosting/manage/${id}?openSettings=installation`
569-
return `/hosting/manage/${id}/content`
572+
return getServerWorldContentPath(id, currentWorldId.value ?? null)
570573
})
571574
575+
function getServerWorldContentPath(serverId: string, worldId: string | null) {
576+
const base = `/hosting/manage/${encodeURIComponent(serverId)}/worlds`
577+
return worldId ? `${base}/${encodeURIComponent(worldId)}` : base
578+
}
579+
572580
const serverBackLabel = computed(() => {
573581
if (fromContext.value === 'onboarding') return 'Back to setup'
574582
if (fromContext.value === 'reset-server') return 'Cancel reset'

0 commit comments

Comments
 (0)