mirror of
https://github.com/vatesfr/xen-orchestra.git
synced 2026-09-10 22:14:48 -05:00
feat(xo6/pool): add connect/disconnect actions on page site (#10075)
This commit is contained in:
@@ -498,6 +498,9 @@
|
||||
"job:pbd-plug:pbd-connected": "One or several PBDs are already connected",
|
||||
"job:pbd-unplug:missing-pbd": "No PBDs to disconnect",
|
||||
"job:pbd-unplug:pbd-disconnected": "One or several PBDs are already disconnected",
|
||||
"job:server-connect:missing-server": "No servers to connect",
|
||||
"job:server-disconnect:missing-server": "No servers to disconnect",
|
||||
"job:server-disconnect:server-disconnected": "One or several servers are already disconnected",
|
||||
"job:snapshot-delete:missing-snapshot": "No snapshots to delete",
|
||||
"job:sr-connect:missing-sr": "No SRs to connect",
|
||||
"job:sr-delete:missing-sr": "No SRs to delete",
|
||||
@@ -643,6 +646,7 @@
|
||||
"modal:confirm-vm-shutdown": "Confirm VM shutdown",
|
||||
"modal:host-disable-message": "The host will be marked unavailable for starting or receiving new VMs. Already-running VMs are not affected.",
|
||||
"modal:host-enable-message": "The host becomes available again for starting or receiving VMs.",
|
||||
"modal:pool-disconnect-message": "The pool will no longer be manageable from XO. You can reconnect it later.",
|
||||
"modal:vm-force-reboot-message": "This will immediately reboot the virtual machine without a clean shutdown. Data loss may occur and ongoing processes will be interrupted.",
|
||||
"modal:vm-force-shutdown-message": "This will immediately power off the virtual machine without a clean shutdown. Data loss may occur and ongoing processes will be interrupted.",
|
||||
"modal:vm-reboot-message": "Restarts the virtual machine gracefully by shutting it down and starting it again. Running processes will be closed properly.",
|
||||
@@ -832,7 +836,6 @@
|
||||
"pool-connection-ip-info": "Provide the primary host’s address of the pool you want to connect to.",
|
||||
"pool-connection-success": "You have successfully connected to the pool. You can now find it in your treeview and start managing your hosts and VMs.",
|
||||
"pool-cpu-usage": "Pool CPU Usage",
|
||||
"pool-disconnect-info": "You will no longer be able to manage this pool from XO. You can reconnect it later.",
|
||||
"pool-management": "Pool management",
|
||||
"pool-ram-usage": "Pool RAM Usage",
|
||||
"pool:status:connected": "@:status:connected",
|
||||
|
||||
@@ -498,6 +498,9 @@
|
||||
"job:pbd-plug:pbd-connected": "Un ou plusieurs PBDs sont déjà connectés",
|
||||
"job:pbd-unplug:missing-pbd": "Aucun PBD à déconnecter",
|
||||
"job:pbd-unplug:pbd-disconnected": "Un ou plusieurs PBDs sont déjà déconnectés",
|
||||
"job:server-connect:missing-server": "Aucun serveur à connecter",
|
||||
"job:server-disconnect:missing-server": "Aucun serveur à déconnecter",
|
||||
"job:server-disconnect:server-disconnected": "Un ou plusieurs serveurs sont déjà déconnectés",
|
||||
"job:snapshot-delete:missing-snapshot": "Aucun instantané à supprimer",
|
||||
"job:sr-connect:missing-sr": "Aucun SR à connecter",
|
||||
"job:sr-delete:missing-sr": "Aucun SR à supprimer",
|
||||
@@ -643,6 +646,7 @@
|
||||
"modal:confirm-vm-shutdown": "Confirmer l'arrêt de la VM",
|
||||
"modal:host-disable-message": "L’hôte sera marqué comme indisponible pour le démarrage ou la réception de nouvelles VMs. Les VMs déjà en cours d’exécution ne sont pas affectées.",
|
||||
"modal:host-enable-message": "L’hôte redevient disponible pour démarrer ou recevoir des VMs.",
|
||||
"modal:pool-disconnect-message": "Le pool ne pourra plus être géré depuis XO. Vous pourrez le reconnecter ultérieurement.",
|
||||
"modal:vm-force-reboot-message": "Cela redémarrera immédiatement la VM sans arrêt propre. Des pertes de données peuvent survenir et les processus en cours seront interrompus.",
|
||||
"modal:vm-force-shutdown-message": "Cela éteindra immédiatement la VM sans arrêt propre. Des pertes de données peuvent survenir et les processus en cours seront interrompus.",
|
||||
"modal:vm-reboot-message": "Redémarre la VM de manière propre en l'éteignant puis en la redémarrant. Les processus en cours seront fermés correctement.",
|
||||
@@ -832,7 +836,6 @@
|
||||
"pool-connection-ip-info": "Entrez l’adresse de l’hôte primaire du pool auquel vous souhaitez vous connecter.",
|
||||
"pool-connection-success": "Vous êtes connecté au pool. Vous pouvez désormais le retrouver dans votre arborescence et commencer à gérer vos hôtes et vos machines virtuelles.",
|
||||
"pool-cpu-usage": "Utilisation CPU du Pool",
|
||||
"pool-disconnect-info": "Vous ne pourrez plus gérer ce pool depuis XO. Vous pourrez le reconnecter ultérieurement.",
|
||||
"pool-management": "Gestion du Pool",
|
||||
"pool-ram-usage": "Utilisation RAM du Pool",
|
||||
"pool:status:connected": "@:status:connected",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { defineColumns } from '@core/packages/table/define-columns.ts'
|
||||
import { useActionColumn } from '@core/tables/column-definitions/action-column.ts'
|
||||
import { useAddressColumn } from '@core/tables/column-definitions/address-column.ts'
|
||||
import { useLinkColumn } from '@core/tables/column-definitions/link-column'
|
||||
import { useSelectItemColumn } from '@core/tables/column-definitions/select-item-column'
|
||||
import { useStatusColumn } from '@core/tables/column-definitions/status-column.ts'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
@@ -13,6 +13,6 @@ export const useServerColumns = defineColumns(() => {
|
||||
hostIp: useAddressColumn({ headerLabel: () => t('ip-address') }),
|
||||
status: useStatusColumn({ headerLabel: () => t('status') }),
|
||||
primaryHost: useLinkColumn({ headerLabel: () => t('master') }),
|
||||
selectItem: useSelectItemColumn(),
|
||||
actions: useActionColumn({}),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<PoolNewVmButton :pool-id="pool.id" />
|
||||
<PoolDisconnectButton :pool-id="pool.id" :pool-name="pool.name_label" />
|
||||
<PoolDisconnectButton :pool-id="pool.id" />
|
||||
<VtsDivider type="stretch" />
|
||||
<PoolDownloadButton :pool-id="pool.id" />
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<template v-if="server">
|
||||
<UiButton
|
||||
v-if="server.status === 'connected'"
|
||||
v-tooltip="!canDisconnect ? disconnectErrorMessage : undefined"
|
||||
left-icon="action:disconnect"
|
||||
variant="tertiary"
|
||||
accent="danger"
|
||||
size="medium"
|
||||
:disabled="!canDisconnect"
|
||||
:busy="isDisconnecting"
|
||||
@click="openDisconnectModal()"
|
||||
>
|
||||
{{ t('action:disconnect-pool') }}
|
||||
</UiButton>
|
||||
<UiButton
|
||||
v-else
|
||||
v-tooltip="!canConnect ? connectErrorMessage : undefined"
|
||||
left-icon="action:connect"
|
||||
variant="tertiary"
|
||||
accent="brand"
|
||||
size="medium"
|
||||
:disabled="!canConnect"
|
||||
:busy="isConnecting"
|
||||
@click="handleConnect()"
|
||||
>
|
||||
{{ t('action:connect-pool') }}
|
||||
</UiButton>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useServerDisconnectModal } from '@/modules/server/composables/use-server-disconnect-modal.composable.ts'
|
||||
import { useXoServerConnectJob } from '@/modules/server/jobs/xo-server-connect.job.ts'
|
||||
import {
|
||||
type FrontXoServer,
|
||||
useXoServerCollection,
|
||||
} from '@/modules/server/remote-resources/use-xo-server-collection.ts'
|
||||
import UiButton from '@core/components/ui/button/UiButton.vue'
|
||||
import { vTooltip } from '@core/directives/tooltip.directive.ts'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { serverId } = defineProps<{ serverId: FrontXoServer['id'] }>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const { getServerById } = useXoServerCollection()
|
||||
|
||||
const server = computed(() => getServerById(serverId))
|
||||
|
||||
const serverIdArg = computed(() => serverId)
|
||||
|
||||
const {
|
||||
isRunning: isConnecting,
|
||||
canRun: canConnect,
|
||||
errorMessage: connectErrorMessage,
|
||||
run: connect,
|
||||
} = useXoServerConnectJob([serverIdArg])
|
||||
|
||||
const {
|
||||
openModal: openDisconnectModal,
|
||||
canRun: canDisconnect,
|
||||
isRunning: isDisconnecting,
|
||||
errorMessage: disconnectErrorMessage,
|
||||
} = useServerDisconnectModal(() => serverId)
|
||||
|
||||
async function handleConnect() {
|
||||
try {
|
||||
await connect()
|
||||
} catch (error) {
|
||||
console.error('Error when connecting server:', error)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -12,36 +12,22 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
|
||||
import { useXoServerDisconnectJob } from '@/modules/server/jobs/xo-server-disconnect.job.ts'
|
||||
import { useServerDisconnectModal } from '@/modules/server/composables/use-server-disconnect-modal.composable.ts'
|
||||
import { useXoServerCollection } from '@/modules/server/remote-resources/use-xo-server-collection.ts'
|
||||
import MenuItem from '@core/components/menu/MenuItem.vue'
|
||||
import { useModal } from '@core/packages/modal/use-modal.ts'
|
||||
import type { XoServer } from '@vates/types'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { poolId, poolName } = defineProps<{ poolId: FrontXoPool['id']; poolName: string }>()
|
||||
const { poolId } = defineProps<{ poolId: FrontXoPool['id'] }>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const { serverByPool } = useXoServerCollection()
|
||||
|
||||
const server = computed(() => serverByPool.value.get(poolId)?.[0])
|
||||
const serverId = computed(() => server.value?.id ?? ('' as XoServer['id']))
|
||||
const serverId = computed(() => serverByPool.value.get(poolId)?.[0]?.id ?? ('' as XoServer['id']))
|
||||
|
||||
const { canRun, isRunning, run } = useXoServerDisconnectJob([serverId])
|
||||
|
||||
const openModal = useModal(() => ({
|
||||
component: import('@core/components/modal/VtsDisconnectModal.vue'),
|
||||
props: { title: poolName },
|
||||
onConfirm: async () => {
|
||||
try {
|
||||
await run()
|
||||
} catch (error) {
|
||||
console.error('Error when disconnecting server:', error)
|
||||
}
|
||||
},
|
||||
}))
|
||||
const { openModal, canRun, isRunning } = useServerDisconnectModal(serverId)
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
|
||||
@@ -1,36 +1,18 @@
|
||||
<template>
|
||||
<MenuItem
|
||||
icon="action:download"
|
||||
class="typo-body-bold-small"
|
||||
:busy="areHostsFetching"
|
||||
:disabled="(areHostsReady && primaryHost === undefined) || hasHostFetchError"
|
||||
@click="download()"
|
||||
>
|
||||
<MenuItem icon="action:download" class="typo-body-bold-small" :busy="isBusy" :disabled="isDisabled" @click="download">
|
||||
{{ t('action:download-bugtools-archive') }}
|
||||
</MenuItem>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useXoHostCollection } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
|
||||
import { usePoolBugToolsDownload } from '@/modules/pool/composables/use-pool-bugtools-download.composable.ts'
|
||||
import type { FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
|
||||
import MenuItem from '@core/components/menu/MenuItem.vue'
|
||||
import { downloadBugTools } from '@core/utils/download-bugtools.utils.ts'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { poolId } = defineProps<{ poolId: FrontXoPool['id'] }>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const { getMasterHostByPoolId, areHostsFetching, areHostsReady, hasHostFetchError } = useXoHostCollection()
|
||||
|
||||
const primaryHost = computed(() => getMasterHostByPoolId(poolId))
|
||||
|
||||
const download = () => {
|
||||
if (primaryHost.value?.address === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
downloadBugTools(primaryHost.value.address)
|
||||
}
|
||||
const { download, isBusy, isDisabled } = usePoolBugToolsDownload(() => poolId)
|
||||
</script>
|
||||
|
||||
@@ -22,14 +22,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { usePoolBugToolsDownload } from '@/modules/pool/composables/use-pool-bugtools-download.composable.ts'
|
||||
import {
|
||||
usePoolEnhancedData,
|
||||
type PoolDisplayData,
|
||||
type PoolFilterableData,
|
||||
usePoolEnhancedData,
|
||||
} from '@/modules/pool/composables/use-pool-enhanced-data.composable.ts'
|
||||
import { useServerDisconnectModal } from '@/modules/server/composables/use-server-disconnect-modal.composable.ts'
|
||||
import { useXoServerConnectJob } from '@/modules/server/jobs/xo-server-connect.job.ts'
|
||||
import {
|
||||
useXoServerCollection,
|
||||
type FrontXoServer,
|
||||
useXoServerCollection,
|
||||
} from '@/modules/server/remote-resources/use-xo-server-collection.ts'
|
||||
import VtsQueryBuilder from '@core/components/query-builder/VtsQueryBuilder.vue'
|
||||
import VtsRow from '@core/components/table/VtsRow.vue'
|
||||
@@ -104,6 +107,30 @@ const { HeadCells, BodyCells } = useServerColumns({
|
||||
icon: server.poolIcon,
|
||||
}))
|
||||
|
||||
const serverIdArg = computed(() => server.id)
|
||||
|
||||
const { canRun: canConnect, isRunning: isConnecting, run: connect } = useXoServerConnectJob([serverIdArg])
|
||||
|
||||
const {
|
||||
openModal: openDisconnectModal,
|
||||
canRun: canDisconnect,
|
||||
isRunning: isDisconnecting,
|
||||
} = useServerDisconnectModal(() => server.id)
|
||||
|
||||
const {
|
||||
download: downloadBugTools,
|
||||
isBusy: isDownloadBusy,
|
||||
isDisabled: isDownloadDisabled,
|
||||
} = usePoolBugToolsDownload(() => server.poolId)
|
||||
|
||||
async function handleConnect() {
|
||||
try {
|
||||
await connect()
|
||||
} catch (error) {
|
||||
console.error('Error when connecting server:', error)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
pool: r => r(poolInfo.value),
|
||||
hostIp: r => r(server.masterHostIp),
|
||||
@@ -120,7 +147,34 @@ const { HeadCells, BodyCells } = useServerColumns({
|
||||
}
|
||||
: undefined,
|
||||
}),
|
||||
selectItem: r => r(() => (selectedServerId.value = server.id)),
|
||||
actions: r =>
|
||||
r({
|
||||
onClick: () => (selectedServerId.value = server.id),
|
||||
actions: [
|
||||
server.status === 'connected'
|
||||
? {
|
||||
label: t('action:disconnect-pool'),
|
||||
icon: 'action:disconnect',
|
||||
busy: isDisconnecting.value,
|
||||
disabled: !canDisconnect.value,
|
||||
onClick: () => openDisconnectModal(),
|
||||
}
|
||||
: {
|
||||
label: t('action:connect-pool'),
|
||||
icon: 'action:connect',
|
||||
busy: isConnecting.value,
|
||||
disabled: !canConnect.value,
|
||||
onClick: () => handleConnect(),
|
||||
},
|
||||
{
|
||||
label: t('action:download-bugtools-archive'),
|
||||
icon: 'action:download',
|
||||
busy: isDownloadBusy.value,
|
||||
disabled: isDownloadDisabled.value,
|
||||
onClick: () => downloadBugTools(),
|
||||
},
|
||||
],
|
||||
}),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
<template>
|
||||
<VtsSidePanel :has-selection="!!server" @close="emit('close')">
|
||||
<template v-if="server" #actions>
|
||||
<PoolConnectionToggleButton :server-id="server.id" />
|
||||
<MenuList v-if="server.poolId !== undefined" placement="bottom-end">
|
||||
<template #trigger="{ open }">
|
||||
<UiButtonIcon
|
||||
v-tooltip="{ placement: 'left', content: t('more-actions') }"
|
||||
accent="brand"
|
||||
icon="action:more-actions"
|
||||
size="medium"
|
||||
@click="open($event)"
|
||||
/>
|
||||
</template>
|
||||
<PoolDownloadButton :pool-id="server.poolId" />
|
||||
</MenuList>
|
||||
</template>
|
||||
<template v-if="server">
|
||||
<VtsStateHero v-if="!arePoolsReady" format="panel" type="busy" size="medium" />
|
||||
<template v-else>
|
||||
@@ -160,17 +175,21 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useXoHostCollection } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
|
||||
import PoolConnectionToggleButton from '@/modules/pool/components/actions/connection/PoolConnectionToggleButton.vue'
|
||||
import PoolDownloadButton from '@/modules/pool/components/actions/download/PoolDownloadButton.vue'
|
||||
import { useXoPoolCollection } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
|
||||
import type { FrontXoServer } from '@/modules/server/remote-resources/use-xo-server-collection.ts'
|
||||
import VtsCardRowKeyValue from '@core/components/card/VtsCardRowKeyValue.vue'
|
||||
import VtsCardObjectTitle from '@core/components/card-object-title/VtsCardObjectTitle.vue'
|
||||
import VtsCopyButton from '@core/components/copy-button/VtsCopyButton.vue'
|
||||
import VtsIcon from '@core/components/icon/VtsIcon.vue'
|
||||
import MenuList from '@core/components/menu/MenuList.vue'
|
||||
import VtsSidePanel from '@core/components/panel/VtsSidePanel.vue'
|
||||
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
|
||||
import VtsStatus from '@core/components/status/VtsStatus.vue'
|
||||
import VtsTag from '@core/components/tag/VtsTag.vue'
|
||||
import UiAlert from '@core/components/ui/alert/UiAlert.vue'
|
||||
import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
|
||||
import UiCard from '@core/components/ui/card/UiCard.vue'
|
||||
import UiCardTitle from '@core/components/ui/card-title/UiCardTitle.vue'
|
||||
import UiCounter from '@core/components/ui/counter/UiCounter.vue'
|
||||
@@ -178,6 +197,7 @@ import UiInfo from '@core/components/ui/info/UiInfo.vue'
|
||||
import UiLink from '@core/components/ui/link/UiLink.vue'
|
||||
import UiLogEntryViewer from '@core/components/ui/log-entry-viewer/UiLogEntryViewer.vue'
|
||||
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'
|
||||
import { vTooltip } from '@core/directives/tooltip.directive.ts'
|
||||
import { useMapper } from '@core/packages/mapper'
|
||||
import { toLower } from 'lodash-es'
|
||||
import { computed } from 'vue'
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useXoHostCollection } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
|
||||
import type { FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
|
||||
import { downloadBugTools } from '@core/utils/download-bugtools.utils.ts'
|
||||
import { computed, type MaybeRefOrGetter, toValue } from 'vue'
|
||||
|
||||
export function usePoolBugToolsDownload(rawPoolId: MaybeRefOrGetter<FrontXoPool['id'] | undefined>) {
|
||||
const { getMasterHostByPoolId, areHostsFetching, areHostsReady, hasHostFetchError } = useXoHostCollection()
|
||||
|
||||
const masterHost = computed(() => {
|
||||
const poolId = toValue(rawPoolId)
|
||||
|
||||
return poolId === undefined ? undefined : getMasterHostByPoolId(poolId)
|
||||
})
|
||||
|
||||
const isDisabled = computed(
|
||||
() => hasHostFetchError.value || (areHostsReady.value && masterHost.value?.address === undefined)
|
||||
)
|
||||
|
||||
function download() {
|
||||
const address = masterHost.value?.address
|
||||
|
||||
if (address === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
downloadBugTools(address)
|
||||
}
|
||||
|
||||
return { download, isBusy: areHostsFetching, isDisabled }
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<VtsModal accent="info" icon="status:info-picto">
|
||||
<VtsModal accent="warning" icon="status:warning-picto" dismissible>
|
||||
<template #title>
|
||||
<I18nT keypath="confirm-disconnect" scope="global" tag="div">
|
||||
<span class="n-disconnect">{{ title }}</span>
|
||||
@@ -7,7 +7,7 @@
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
{{ t('pool-disconnect-info') }}
|
||||
{{ t('modal:pool-disconnect-message') }}
|
||||
</template>
|
||||
|
||||
<template #buttons>
|
||||
@@ -23,7 +23,7 @@
|
||||
import VtsModal from '@core/components/modal/VtsModal.vue'
|
||||
import VtsModalCancelButton from '@core/components/modal/VtsModalCancelButton.vue'
|
||||
import VtsModalConfirmButton from '@core/components/modal/VtsModalConfirmButton.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { I18nT, useI18n } from 'vue-i18n'
|
||||
|
||||
defineProps<{
|
||||
title: string
|
||||
@@ -34,6 +34,6 @@ const { t } = useI18n()
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.n-disconnect {
|
||||
color: var(--color-info-item-base);
|
||||
color: var(--color-warning-item-base);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,34 @@
|
||||
import { useXoServerDisconnectJob } from '@/modules/server/jobs/xo-server-disconnect.job.ts'
|
||||
import {
|
||||
useXoServerCollection,
|
||||
type FrontXoServer,
|
||||
} from '@/modules/server/remote-resources/use-xo-server-collection.ts'
|
||||
import { useModal } from '@core/packages/modal/use-modal.ts'
|
||||
import { toComputed } from '@core/utils/to-computed.util.ts'
|
||||
import { computed, type MaybeRefOrGetter } from 'vue'
|
||||
|
||||
export function useServerDisconnectModal(rawServerId: MaybeRefOrGetter<FrontXoServer['id']>) {
|
||||
const serverId = toComputed(rawServerId)
|
||||
|
||||
const { getServerById } = useXoServerCollection()
|
||||
|
||||
const server = computed(() => getServerById(serverId.value))
|
||||
|
||||
const serverLabel = computed(() => server.value?.poolNameLabel ?? server.value?.label ?? '')
|
||||
|
||||
const { run, canRun, isRunning, errorMessage } = useXoServerDisconnectJob([serverId])
|
||||
|
||||
const openModal = useModal(() => ({
|
||||
component: import('@/modules/server/components/modal/ServerDisconnectModal.vue'),
|
||||
props: { title: serverLabel.value },
|
||||
onConfirm: async () => {
|
||||
try {
|
||||
await run()
|
||||
} catch (error) {
|
||||
console.error('Error when disconnecting server:', error)
|
||||
}
|
||||
},
|
||||
}))
|
||||
|
||||
return { openModal, canRun, isRunning, errorMessage }
|
||||
}
|
||||
@@ -3,24 +3,35 @@ import { useXoTaskUtils } from '@/shared/composables/xo-task-utils.composable.ts
|
||||
import { fetchPost } from '@/shared/utils/fetch.util.ts'
|
||||
import { defineJob, JobError, JobRunningError } from '@core/packages/job'
|
||||
import type { XoTask } from '@vates/types'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
export const useXoServerConnectJob = defineJob('server.connect', [xoServerIdsArg], () => {
|
||||
const { t } = useI18n()
|
||||
const { monitorTask } = useXoTaskUtils()
|
||||
|
||||
return {
|
||||
run(serverIds) {
|
||||
return Promise.allSettled(
|
||||
async run(serverIds) {
|
||||
const results = await Promise.allSettled(
|
||||
serverIds.map(async serverId => {
|
||||
const { taskId } = await fetchPost<{ taskId: XoTask['id'] }>(`servers/${serverId.value}/actions/connect`)
|
||||
await monitorTask(taskId)
|
||||
})
|
||||
)
|
||||
|
||||
results.forEach((result, index) => {
|
||||
if (result.status === 'rejected') {
|
||||
console.error(`Failed to connect server ${serverIds[index].value}:`, result.reason)
|
||||
}
|
||||
})
|
||||
|
||||
return results
|
||||
},
|
||||
validate(isRunning, serverIds) {
|
||||
if (isRunning) {
|
||||
throw new JobRunningError('connect server already running')
|
||||
throw new JobRunningError(t('job:connect:in-progress'))
|
||||
}
|
||||
if (serverIds.length === 0 || serverIds.some(id => id.value === '')) {
|
||||
throw new JobError('server ids are required')
|
||||
throw new JobError(t('job:server-connect:missing-server'))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ import { useXoTaskUtils } from '@/shared/composables/xo-task-utils.composable.ts
|
||||
import { fetchPost } from '@/shared/utils/fetch.util.ts'
|
||||
import { defineJob, JobError, JobRunningError } from '@core/packages/job'
|
||||
import type { XoTask } from '@vates/types'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
export const useXoServerDisconnectJob = defineJob('server.disconnect', [xoServerIdsArg], () => {
|
||||
const { t } = useI18n()
|
||||
const { monitorTask } = useXoTaskUtils()
|
||||
const { getServersByIds } = useXoServerCollection()
|
||||
|
||||
@@ -17,23 +19,25 @@ export const useXoServerDisconnectJob = defineJob('server.disconnect', [xoServer
|
||||
await monitorTask(taskId)
|
||||
})
|
||||
)
|
||||
|
||||
results.forEach((result, index) => {
|
||||
if (result.status === 'rejected') {
|
||||
console.error(`Failed to disconnect server ${serverIds[index].value}:`, result.reason)
|
||||
}
|
||||
})
|
||||
|
||||
return results
|
||||
},
|
||||
validate(isRunning, serverIds) {
|
||||
if (isRunning) {
|
||||
throw new JobRunningError('server disconnection already in progress')
|
||||
throw new JobRunningError(t('job:disconnect:in-progress'))
|
||||
}
|
||||
if (serverIds.length === 0 || serverIds.some(id => id.value === '')) {
|
||||
throw new JobError('server ids are required')
|
||||
throw new JobError(t('job:server-disconnect:missing-server'))
|
||||
}
|
||||
const servers = getServersByIds(serverIds.map(id => id.value))
|
||||
if (servers.some(server => server.status !== 'connected')) {
|
||||
throw new JobError('server must be connected')
|
||||
throw new JobError(t('job:server-disconnect:server-disconnected'))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
- [XO6] Input fields now support prefix/suffix sections, and display validation messages ordered by severity (PR [#10009](https://github.com/vatesfr/xen-orchestra/pull/10009))
|
||||
- [XO6/New VM] Add the possibility to set the HA restart priority when creating a VM (PR [#10072](https://github.com/vatesfr/xen-orchestra/pull/10072))
|
||||
- [REST API] Add `POST /srs` REST route to create a storage repository (PR [#9990](https://github.com/vatesfr/xen-orchestra/pull/9990))
|
||||
- [XO6/Pool] Add connect/disconnect action on page Site (PR [#10075])(https://github.com/vatesfr/xen-orchestra/pull/10075)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user