chore: rename worlds -> instances

This commit is contained in:
Calum H. (IMB11)
2026-06-26 17:09:22 +01:00
parent f799e6f67e
commit f097409b92
33 changed files with 227 additions and 172 deletions
@@ -191,8 +191,8 @@ const metrics = computed(() => {
chartOptions: null as ReturnType<typeof buildChartOptions> | null,
series: null as { name: string; data: number[] }[] | null,
link: worldId.value
? `/hosting/manage/${encodeURIComponent(serverId)}/worlds/${encodeURIComponent(worldId.value)}/files`
: `/hosting/manage/${encodeURIComponent(serverId)}/worlds`,
? `/hosting/manage/${encodeURIComponent(serverId)}/instances/${encodeURIComponent(worldId.value)}/files`
: `/hosting/manage/${encodeURIComponent(serverId)}/instances`,
}
if (props.loading) {
@@ -59,7 +59,7 @@ const isOnFilesTab = computed(() => route.path.includes('/files'))
const isOnContentTab = computed(
() =>
route.path.includes('/content') ||
(!!route.params.world_id && !isOnFilesTab.value && !route.path.includes('/backups')),
(!!route.params.instance_id && !isOnFilesTab.value && !route.path.includes('/backups')),
)
const bannerCoversInstalling = computed(
@@ -76,7 +76,7 @@
<div class="mt-6 flex flex-col gap-1">
<h2 class="m-0 text-2xl font-semibold leading-8 text-contrast">{{ world.name }}</h2>
<p class="m-0 text-base leading-6 text-secondary">
{{ formatMessage(messages.newWorldInstance) }}
{{ formatMessage(messages.newInstance) }}
</p>
</div>
</div>
@@ -85,7 +85,7 @@
<ButtonStyled color="brand">
<button class="w-full !h-10" @click="emit('create', world.id)">
<PlusIcon aria-hidden="true" />
{{ formatMessage(messages.createWorld) }}
{{ formatMessage(messages.createInstance) }}
</button>
</ButtonStyled>
</div>
@@ -172,12 +172,12 @@
<ButtonStyled>
<button class="!shadow-none" @click="emit('edit', world.id)">
<PencilIcon aria-hidden="true" />
{{ formatMessage(messages.editWorld) }}
{{ formatMessage(messages.editInstance) }}
</button>
</ButtonStyled>
<ButtonStyled circular>
<button
v-tooltip="formatMessage(messages.worldSettings)"
v-tooltip="formatMessage(messages.instanceSettings)"
class="!shadow-none"
@click="emit('settings', world.id)"
>
@@ -203,44 +203,44 @@ import { truncatedTooltip } from '#ui/utils'
import { commonMessages } from '#ui/utils/common-messages'
const messages = defineMessages({
newWorldInstance: {
id: 'servers.manage.worlds.card.empty-description',
defaultMessage: 'New world instance',
newInstance: {
id: 'servers.manage.instances.card.empty-description',
defaultMessage: 'New instance',
},
createWorld: {
id: 'servers.manage.worlds.card.create',
defaultMessage: 'Create world',
createInstance: {
id: 'servers.manage.instances.card.create',
defaultMessage: 'Create instance',
},
active: {
id: 'servers.manage.worlds.card.active',
id: 'servers.manage.instances.card.active',
defaultMessage: 'Active',
},
none: {
id: 'servers.manage.worlds.card.none',
id: 'servers.manage.instances.card.none',
defaultMessage: 'None',
},
installedContent: {
id: 'servers.manage.worlds.card.installed-content',
id: 'servers.manage.instances.card.installed-content',
defaultMessage: 'Installed content',
},
lastActive: {
id: 'servers.manage.worlds.card.last-active',
id: 'servers.manage.instances.card.last-active',
defaultMessage: 'Last active',
},
created: {
id: 'servers.manage.worlds.card.created',
id: 'servers.manage.instances.card.created',
defaultMessage: 'Created',
},
editWorld: {
id: 'servers.manage.worlds.card.edit',
defaultMessage: 'Edit world',
editInstance: {
id: 'servers.manage.instances.card.edit',
defaultMessage: 'Edit instance',
},
worldSettings: {
id: 'servers.manage.worlds.card.settings',
defaultMessage: 'World settings',
instanceSettings: {
id: 'servers.manage.instances.card.settings',
defaultMessage: 'Instance settings',
},
notTrackedYet: {
id: 'servers.manage.worlds.card.not-tracked-yet',
id: 'servers.manage.instances.card.not-tracked-yet',
defaultMessage: 'Not tracked yet',
},
})
@@ -319,8 +319,8 @@ const advancedActionTooltip = computed(() =>
)
const filesTabLink = computed(() =>
worldId.value
? `/hosting/manage/${encodeURIComponent(serverId)}/worlds/${encodeURIComponent(worldId.value)}/files?path=/&editing=server.properties`
: `/hosting/manage/${encodeURIComponent(serverId)}/worlds`,
? `/hosting/manage/${encodeURIComponent(serverId)}/instances/${encodeURIComponent(worldId.value)}/files?path=/&editing=server.properties`
: `/hosting/manage/${encodeURIComponent(serverId)}/instances`,
)
const serverSettings = injectServerSettings(null)
@@ -93,8 +93,8 @@
</ErrorInformationCard>
</div>
<div
v-else-if="serverData && isWorldDetailRoute"
data-pyro-world-manager-root
v-else-if="serverData && isInstanceDetailRoute"
data-pyro-instance-manager-root
class="experimental-styles-within relative mx-auto box-border flex w-full min-w-0 flex-col px-6 transition-all duration-300"
:class="[
'server-panel-' + revealState,
@@ -316,7 +316,7 @@
</template>
</div>
<div
v-if="showAdvancedDebugInfo && !isWorldDetailRoute"
v-if="showAdvancedDebugInfo && !isInstanceDetailRoute"
class="experimental-styles-within relative mx-auto mt-6 box-border w-full min-w-0 max-w-[1280px] px-6"
>
<h2 class="m-0 text-lg font-extrabold text-contrast">
@@ -632,9 +632,9 @@ const messages = defineMessages({
id: 'servers.manage.nav.overview',
defaultMessage: 'Overview',
},
worldsNav: {
id: 'servers.manage.nav.worlds',
defaultMessage: 'Worlds',
instancesNav: {
id: 'servers.manage.nav.instances',
defaultMessage: 'Instances',
},
errorDismissingNotice: {
id: 'servers.manage.notice.dismiss-error',
@@ -769,14 +769,14 @@ const { data: serverFull } = useQuery({
})
const worldId = computed(() => {
const routeWorldId = getRouteParam(route.params.world_id)
if (routeWorldId) return routeWorldId
const routeInstanceId = getRouteParam(route.params.instance_id)
if (routeInstanceId) return routeInstanceId
if (!serverFull.value) return null
const activeWorld = serverFull.value.worlds.find((w) => w.is_active)
return activeWorld?.id ?? serverFull.value.worlds[0]?.id ?? null
})
const isWorldDetailRoute = computed(() => !!getRouteParam(route.params.world_id))
const isInstanceDetailRoute = computed(() => !!getRouteParam(route.params.instance_id))
const activeWorldName = computed(() => {
if (!serverFull.value) return null
const activeWorld = serverFull.value.worlds.find((world) => world.is_active)
@@ -789,7 +789,7 @@ function getRouteParam(param: string | string[] | undefined): string | null {
}
function getWorldPath(targetWorldId: string) {
return `/hosting/manage/${encodeURIComponent(props.serverId)}/worlds/${encodeURIComponent(targetWorldId)}`
return `/hosting/manage/${encodeURIComponent(props.serverId)}/instances/${encodeURIComponent(targetWorldId)}`
}
const { handleWsBackupProgress, busyReasons: backupsBusy } = useServerBackupsQueue(
@@ -1051,8 +1051,8 @@ const navLinks = computed<Tab[]>(() => [
subpages: [],
},
{
label: formatMessage(messages.worldsNav),
href: `/hosting/manage/${encodeURIComponent(props.serverId)}/worlds`,
label: formatMessage(messages.instancesNav),
href: `/hosting/manage/${encodeURIComponent(props.serverId)}/instances`,
icon: WorldIcon,
subpages: [],
},
@@ -1476,7 +1476,7 @@ const copyServerDebugInfo = () => {
const openInstallLog = () => {
const filesPath = worldId.value
? `${getWorldPath(worldId.value)}/files`
: `/hosting/manage/${encodeURIComponent(props.serverId)}/worlds`
: `/hosting/manage/${encodeURIComponent(props.serverId)}/instances`
const url = `${filesPath}?editing=${encodeURIComponent(errorLogFile.value)}`
window.history.pushState({}, '', url)
window.dispatchEvent(new PopStateEvent('popstate'))
@@ -386,7 +386,7 @@ const error = computed(() => {
})
const refetch = () => query.refetch()
/** Until world exists we cannot fetch; `isLoading` is false while the query is disabled, which would flash empty state. */
/** Until the instance exists we cannot fetch; `isLoading` is false while the query is disabled, which would flash empty state. */
const backupsReadyPending = computed(
() => !worldId.value || (query.data.value === undefined && !query.error.value),
)
@@ -2,11 +2,11 @@
<div class="flex min-h-[36rem] flex-col gap-6 text-primary">
<div class="flex flex-col gap-2">
<RouterLink
:to="worldsPath"
:to="instancesPath"
class="flex w-fit items-center gap-1 text-base font-medium text-blue hover:underline"
>
<ChevronLeftIcon class="size-4" aria-hidden="true" />
{{ formatMessage(messages.allWorlds) }}
{{ formatMessage(messages.allInstances) }}
</RouterLink>
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
@@ -23,10 +23,10 @@
</div>
<div class="flex shrink-0 items-center gap-2">
<PanelServerActionButton size="large" start-label="Start world" />
<PanelServerActionButton size="large" start-label="Start instance" />
<ButtonStyled size="large" circular>
<button
v-tooltip="formatMessage(messages.worldSettings)"
v-tooltip="formatMessage(messages.instanceSettings)"
@click="openServerSettings({ tabId: 'installation' })"
>
<SettingsIcon aria-hidden="true" />
@@ -78,9 +78,9 @@ interface Tab {
}
const messages = defineMessages({
allWorlds: {
id: 'servers.manage.world.all-worlds',
defaultMessage: 'All worlds',
allInstances: {
id: 'servers.manage.instance.all-instances',
defaultMessage: 'All instances',
},
contentNav: {
id: 'servers.manage.nav.content',
@@ -95,16 +95,16 @@ const messages = defineMessages({
defaultMessage: 'Backups',
},
worldFallbackName: {
id: 'servers.manage.world.fallback-name',
defaultMessage: 'World',
id: 'servers.manage.instance.fallback-name',
defaultMessage: 'Instance',
},
lastActive: {
id: 'servers.manage.world.last-active',
id: 'servers.manage.instance.last-active',
defaultMessage: 'Last active {time}',
},
worldSettings: {
id: 'servers.manage.world.settings',
defaultMessage: 'World settings',
instanceSettings: {
id: 'servers.manage.instance.settings',
defaultMessage: 'Instance settings',
},
})
@@ -121,9 +121,11 @@ const { data: serverFull } = useQuery({
staleTime: 30_000,
})
const worldsPath = computed(() => `/hosting/manage/${encodeURIComponent(serverId)}/worlds`)
const instancesPath = computed(() => `/hosting/manage/${encodeURIComponent(serverId)}/instances`)
const worldPath = computed(() =>
worldId.value ? `${worldsPath.value}/${encodeURIComponent(worldId.value)}` : worldsPath.value,
worldId.value
? `${instancesPath.value}/${encodeURIComponent(worldId.value)}`
: instancesPath.value,
)
const currentWorld = computed(() => {
@@ -193,7 +195,7 @@ watch(
() => [serverFull.value, currentWorld.value, worldId.value] as const,
([full, world, id]) => {
if (full && id && !world) {
router.replace(worldsPath.value)
router.replace(instancesPath.value)
}
},
{ immediate: true },
@@ -6,12 +6,12 @@
>
<div
v-for="slot in WORLD_SLOT_COUNT"
:key="`world-card-skeleton-${slot}`"
:key="`instance-card-skeleton-${slot}`"
class="min-h-[19.75rem] animate-pulse rounded-2xl border border-solid border-surface-5 bg-bg-raised shadow-xl"
/>
</div>
<div v-else class="grid grid-cols-[repeat(auto-fit,minmax(min(100%,20.25rem),1fr))] gap-6">
<WorldCard
<InstanceCard
v-for="world in worldSlots"
:key="world.id"
:world="world"
@@ -29,7 +29,7 @@ import { useQuery } from '@tanstack/vue-query'
import { computed } from 'vue'
import { useRouter } from 'vue-router'
import WorldCard from '#ui/components/servers/worlds/WorldCard.vue'
import InstanceCard from '#ui/components/servers/instances/InstanceCard.vue'
import { defineMessages, useVIntl } from '#ui/composables/i18n'
import {
injectModrinthClient,
@@ -39,9 +39,9 @@ import {
import { formatLoaderLabel } from '#ui/utils/loaders'
const messages = defineMessages({
worldSlotName: {
id: 'servers.manage.worlds.slot-name',
defaultMessage: 'World #{index}',
instanceSlotName: {
id: 'servers.manage.instances.slot-name',
defaultMessage: 'Instance #{index}',
},
})
@@ -154,7 +154,7 @@ function padWorldSlots(slots: WorldSlot[]): WorldSlot[] {
padded.push({
type: 'empty',
id: `empty-world-slot-${i + 1}`,
name: formatMessage(messages.worldSlotName, { index: i + 1 }),
name: formatMessage(messages.instanceSlotName, { index: i + 1 }),
})
}
return padded
@@ -268,14 +268,14 @@ function createDummyWorldSlots(): WorldSlot[] {
{
type: 'empty',
id: 'empty-world-slot-3',
name: formatMessage(messages.worldSlotName, { index: 3 }),
name: formatMessage(messages.instanceSlotName, { index: 3 }),
},
]
}
function handleEditWorld(worldId: string) {
router.push(
`/hosting/manage/${encodeURIComponent(serverId)}/worlds/${encodeURIComponent(worldId)}`,
`/hosting/manage/${encodeURIComponent(serverId)}/instances/${encodeURIComponent(worldId)}`,
)
}
@@ -146,14 +146,14 @@ const messages = defineMessages({
defaultMessage:
'Pick your favorite modpack from Modrinth, or choose a loader and add the mods you want.',
},
configureWorldTitle: {
id: 'servers.setup.onboarding.step.configure-world.title',
defaultMessage: 'Configure your world',
configureInstanceTitle: {
id: 'servers.setup.onboarding.step.configure-instance.title',
defaultMessage: 'Configure your instance',
},
configureWorldDescription: {
id: 'servers.setup.onboarding.step.configure-world.description',
configureInstanceDescription: {
id: 'servers.setup.onboarding.step.configure-instance.description',
defaultMessage:
'Set up your world just like singleplayer. Choose your gamemode and world seed.',
'Set up your instance just like singleplayer. Choose your gamemode and world seed.',
},
inviteFriendsTitle: {
id: 'servers.setup.onboarding.step.invite-friends.title',
@@ -274,8 +274,8 @@ async function finalizeSetup() {
})
await router.push(
worldId.value
? `/hosting/manage/${encodeURIComponent(serverId)}/worlds/${encodeURIComponent(worldId.value)}`
: `/hosting/manage/${encodeURIComponent(serverId)}/worlds`,
? `/hosting/manage/${encodeURIComponent(serverId)}/instances/${encodeURIComponent(worldId.value)}`
: `/hosting/manage/${encodeURIComponent(serverId)}/instances`,
)
}
@@ -375,8 +375,8 @@ const steps = computed(() => [
},
{
icon: GlobeIcon,
title: formatMessage(messages.configureWorldTitle),
description: formatMessage(messages.configureWorldDescription),
title: formatMessage(messages.configureInstanceTitle),
description: formatMessage(messages.configureInstanceDescription),
},
{
icon: UsersIcon,
+5 -5
View File
@@ -2,9 +2,9 @@ export { default as ServersManageAccessPage } from './hosting/manage/[id]/access
export { default as ServersManageRootLayout } from './hosting/manage/[id]/index.vue'
export { default as ServerOnboardingPanelPage } from './hosting/manage/[id]/onboarding.vue'
export { default as ServersManageOverviewPage } from './hosting/manage/[id]/overview.vue'
export { default as ServersManageBackupsPage } from './hosting/manage/[id]/worlds/[world-id]/backups.vue'
export { default as ServersManageContentPage } from './hosting/manage/[id]/worlds/[world-id]/content.vue'
export { default as ServersManageFilesPage } from './hosting/manage/[id]/worlds/[world-id]/files.vue'
export { default as ServersManageWorldRootLayout } from './hosting/manage/[id]/worlds/[world-id]/index.vue'
export { default as ServersManageWorldsPage } from './hosting/manage/[id]/worlds/index.vue'
export { default as ServersManageBackupsPage } from './hosting/manage/[id]/instances/[instance-id]/backups.vue'
export { default as ServersManageContentPage } from './hosting/manage/[id]/instances/[instance-id]/content.vue'
export { default as ServersManageFilesPage } from './hosting/manage/[id]/instances/[instance-id]/files.vue'
export { default as ServersManageInstanceRootLayout } from './hosting/manage/[id]/instances/[instance-id]/index.vue'
export { default as ServersManageInstancesPage } from './hosting/manage/[id]/instances/index.vue'
export { default as ServersManagePageIndex } from './hosting/manage/index.vue'
+29 -29
View File
@@ -4670,8 +4670,8 @@
"servers.manage.nav.overview": {
"defaultMessage": "Overview"
},
"servers.manage.nav.worlds": {
"defaultMessage": "Worlds"
"servers.manage.nav.instances": {
"defaultMessage": "Instances"
},
"servers.manage.new-server-button": {
"defaultMessage": "New server"
@@ -4766,50 +4766,50 @@
"servers.manage.websocket.reconnecting": {
"defaultMessage": "Hang on, we're reconnecting to your server."
},
"servers.manage.world.all-worlds": {
"defaultMessage": "All worlds"
"servers.manage.instance.all-instances": {
"defaultMessage": "All instances"
},
"servers.manage.world.fallback-name": {
"defaultMessage": "World"
"servers.manage.instance.fallback-name": {
"defaultMessage": "Instance"
},
"servers.manage.world.last-active": {
"servers.manage.instance.last-active": {
"defaultMessage": "Last active {time}"
},
"servers.manage.world.settings": {
"defaultMessage": "World settings"
"servers.manage.instance.settings": {
"defaultMessage": "Instance settings"
},
"servers.manage.worlds.card.active": {
"servers.manage.instances.card.active": {
"defaultMessage": "Active"
},
"servers.manage.worlds.card.create": {
"defaultMessage": "Create world"
"servers.manage.instances.card.create": {
"defaultMessage": "Create instance"
},
"servers.manage.worlds.card.created": {
"servers.manage.instances.card.created": {
"defaultMessage": "Created"
},
"servers.manage.worlds.card.edit": {
"defaultMessage": "Edit world"
"servers.manage.instances.card.edit": {
"defaultMessage": "Edit instance"
},
"servers.manage.worlds.card.empty-description": {
"defaultMessage": "New world instance"
"servers.manage.instances.card.empty-description": {
"defaultMessage": "New instance"
},
"servers.manage.worlds.card.installed-content": {
"servers.manage.instances.card.installed-content": {
"defaultMessage": "Installed content"
},
"servers.manage.worlds.card.last-active": {
"servers.manage.instances.card.last-active": {
"defaultMessage": "Last active"
},
"servers.manage.worlds.card.none": {
"servers.manage.instances.card.none": {
"defaultMessage": "None"
},
"servers.manage.worlds.card.not-tracked-yet": {
"servers.manage.instances.card.not-tracked-yet": {
"defaultMessage": "Not tracked yet"
},
"servers.manage.worlds.card.settings": {
"defaultMessage": "World settings"
"servers.manage.instances.card.settings": {
"defaultMessage": "Instance settings"
},
"servers.manage.worlds.slot-name": {
"defaultMessage": "World #{index}"
"servers.manage.instances.slot-name": {
"defaultMessage": "Instance #{index}"
},
"servers.manage.your-servers-title": {
"defaultMessage": "Your servers"
@@ -5042,11 +5042,11 @@
"servers.setup.onboarding.step.choose.title": {
"defaultMessage": "Choose what to play"
},
"servers.setup.onboarding.step.configure-world.description": {
"defaultMessage": "Set up your world just like singleplayer. Choose your gamemode and world seed."
"servers.setup.onboarding.step.configure-instance.description": {
"defaultMessage": "Set up your instance just like singleplayer. Choose your gamemode and world seed."
},
"servers.setup.onboarding.step.configure-world.title": {
"defaultMessage": "Configure your world"
"servers.setup.onboarding.step.configure-instance.title": {
"defaultMessage": "Configure your instance"
},
"servers.setup.onboarding.step.invite-friends.description": {
"defaultMessage": "Share your server with friends by copying the address and letting them know which mods they'll need to join."
@@ -0,0 +1,53 @@
import type { Meta, StoryObj } from '@storybook/vue3-vite'
import InstanceCard from '../../components/servers/instances/InstanceCard.vue'
const meta = {
title: 'Servers/InstanceCard',
component: InstanceCard,
parameters: {
layout: 'padded',
},
render: (args) => ({
components: { InstanceCard },
setup() {
return { args }
},
template: '<div style="max-width: 360px"><InstanceCard v-bind="args" /></div>',
}),
} satisfies Meta<typeof InstanceCard>
export default meta
type Story = StoryObj<typeof meta>
export const Active: Story = {
args: {
world: {
type: 'world',
id: 'demo-world',
name: 'Cobbletown',
active: true,
gameVersion: '1.20.4',
loaderLabel: 'Fabric 0.16.6',
linkedModpack: {
name: 'Cobblemon Official',
iconUrl: null,
link: null,
},
installedContentCount: 47,
lastActiveAt: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(),
createdAt: new Date(Date.now() - 197 * 24 * 60 * 60 * 1000).toISOString(),
},
},
}
export const Empty: Story = {
args: {
world: {
type: 'empty',
id: 'empty-instance-slot',
name: 'Instance #2',
},
},
}
@@ -25,7 +25,7 @@ const meta = {
setup() {
const router = useRouter()
onMounted(() => {
router.replace('/hosting/manage/demo-server/worlds/demo-world')
router.replace('/hosting/manage/demo-server/instances/demo-world')
})
const server = ref({