This commit is contained in:
Calum H. (IMB11)
2026-06-26 17:09:22 +01:00
parent 45d02bd5e6
commit c0d839c7f6
5 changed files with 49 additions and 12 deletions
@@ -103,7 +103,7 @@ export class ArchonServersV0Module extends AbstractModule {
*/ */
public async power( public async power(
serverId: string, serverId: string,
action: 'Start' | 'Stop' | 'Restart' | 'Kill', action: Archon.Servers.v0.PowerAction,
): Promise<void> { ): Promise<void> {
await this.client.request(`/servers/${serverId}/power`, { await this.client.request(`/servers/${serverId}/power`, {
api: 'archon', api: 'archon',
@@ -681,6 +681,8 @@ export namespace Archon {
token: string // JWT token for filesystem access token: string // JWT token for filesystem access
} }
export type PowerAction = 'Start' | 'Stop' | 'Restart' | 'Kill'
export type ReinstallLoaderRequest = { export type ReinstallLoaderRequest = {
loader: string loader: string
loader_version?: string loader_version?: string
@@ -320,6 +320,22 @@ const startSplitActions = computed<JoinedButtonAction[]>(() => [
})), })),
]) ])
const restartSplitActions = computed<JoinedButtonAction[]>(() => [
{
id: 'restart',
label: primaryActionText.value,
icon: UpdatedIcon,
action: () => initiateAction('Restart'),
},
// TODO: Implement world scoping when Archon/Kyros support target worlds in power requests.
...startableWorlds.value.map((world) => ({
id: `restart-${world.id}`,
label: `Restart with ${world.name}`,
icon: GlobeIcon,
action: () => initiateAction('Restart'),
})),
])
const stopSplitActions = computed<JoinedButtonAction[]>(() => [ const stopSplitActions = computed<JoinedButtonAction[]>(() => [
{ {
id: 'stop', id: 'stop',
@@ -353,11 +369,10 @@ const powerActions = computed<HeaderAction[]>(() => {
{ {
id: 'restart', id: 'restart',
label: primaryActionText.value, label: primaryActionText.value,
icon: UpdatedIcon,
color: 'orange', color: 'orange',
tooltip: busyTooltip.value, joinedActions: restartSplitActions.value,
disabled: !canTakeAction.value, primaryDisabled: !canTakeAction.value,
onClick: handlePrimaryAction, dropdownDisabled: !canTakeAction.value,
}, },
{ {
id: 'stop', id: 'stop',
@@ -1,3 +1,4 @@
import type { Archon } from '@modrinth/api-client'
import { computed, type Ref } from 'vue' import { computed, type Ref } from 'vue'
import { useVIntl } from '#ui/composables/i18n' import { useVIntl } from '#ui/composables/i18n'
@@ -8,7 +9,7 @@ import {
injectNotificationManager, injectNotificationManager,
} from '#ui/providers' } from '#ui/providers'
export type PowerAction = 'Start' | 'Stop' | 'Restart' | 'Kill' export type PowerAction = Archon.Servers.v0.PowerAction
export function useServerPowerAction(options?: { disabled?: Ref<boolean> }) { export function useServerPowerAction(options?: { disabled?: Ref<boolean> }) {
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()
@@ -24,9 +24,10 @@ import {
BoxesIcon, BoxesIcon,
DatabaseBackupIcon, DatabaseBackupIcon,
FolderOpenIcon, FolderOpenIcon,
GlobeIcon,
LoaderCircleIcon, LoaderCircleIcon,
PlayIcon, PlayIcon,
SettingsIcon, Settings2Icon,
SlashIcon, SlashIcon,
StopCircleIcon, StopCircleIcon,
UpdatedIcon, UpdatedIcon,
@@ -35,6 +36,7 @@ import { useQuery } from '@tanstack/vue-query'
import { computed, watch } from 'vue' import { computed, watch } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import type { JoinedButtonAction } from '#ui/components/base/JoinedButtons.vue'
import NavTabs from '#ui/components/base/NavTabs.vue' import NavTabs from '#ui/components/base/NavTabs.vue'
import { WorldManageHeader } from '#ui/components/servers/server-header' import { WorldManageHeader } from '#ui/components/servers/server-header'
import { useServerPowerAction } from '#ui/components/servers/server-header/use-server-power-action' import { useServerPowerAction } from '#ui/components/servers/server-header/use-server-power-action'
@@ -167,6 +169,24 @@ const stopSplitActions = computed(() => [
action: () => initiateAction('Kill'), action: () => initiateAction('Kill'),
}, },
]) ])
const restartableWorlds = computed(() =>
(serverFull.value?.worlds ?? []).filter((world) => world.id !== worldId.value),
)
const restartSplitActions = computed<JoinedButtonAction[]>(() => [
{
id: 'restart',
label: primaryActionText.value,
icon: UpdatedIcon,
action: () => initiateAction('Restart'),
},
// TODO: Implement world scoping when Archon/Kyros support target worlds in power requests.
...restartableWorlds.value.map((world) => ({
id: `restart-${world.id}`,
label: `Restart with ${world.name}`,
icon: GlobeIcon,
action: () => initiateAction('Restart'),
})),
])
const powerActions = computed(() => { const powerActions = computed(() => {
if (isInstalling.value) { if (isInstalling.value) {
return [ return [
@@ -185,11 +205,10 @@ const powerActions = computed(() => {
{ {
id: 'restart', id: 'restart',
label: primaryActionText.value, label: primaryActionText.value,
icon: UpdatedIcon,
color: 'orange' as const, color: 'orange' as const,
tooltip: busyTooltip.value, joinedActions: restartSplitActions.value,
disabled: !canTakeAction.value, primaryDisabled: !canTakeAction.value,
onClick: handlePrimaryAction, dropdownDisabled: !canTakeAction.value,
}, },
{ {
id: 'stop', id: 'stop',
@@ -231,7 +250,7 @@ const headerActions = computed(() => [
{ {
id: 'settings', id: 'settings',
label: formatMessage(messages.instanceSettings), label: formatMessage(messages.instanceSettings),
icon: SettingsIcon, icon: Settings2Icon,
labelHidden: true, labelHidden: true,
tooltip: formatMessage(messages.instanceSettings), tooltip: formatMessage(messages.instanceSettings),
onClick: () => openServerSettings({ tabId: 'installation' }), onClick: () => openServerSettings({ tabId: 'installation' }),