fix(xo6,lite): translate VM and host state tooltips in tree view

This commit is contained in:
Elise-F
2026-10-22 10:06:58 +02:00
parent c8c11ae63c
commit bf6f8ce3a7
10 changed files with 62 additions and 34 deletions

View File

@@ -54,8 +54,8 @@
</template>
<script lang="ts" setup>
import { VM_POWER_STATE } from '@/libs/xen-api/xen-api.enums.ts'
import type { XenApiVm } from '@/libs/xen-api/xen-api.types.ts'
import { useVmUtils } from '@/modules/vm/composables/vm-utils.composable.ts'
import { getHostIcon } from '@/modules/host/utils/host.util.ts'
import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store.ts'
import { usePoolStore } from '@/stores/xen-api/pool.store.ts'
@@ -70,7 +70,6 @@ import VtsTag from '@core/components/tag/VtsTag.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'
import { useTimeAgo } from '@core/composables/locale-time-ago.composable.ts'
import { useMapper } from '@core/packages/mapper'
import { formatSizeRaw } from '@core/utils/size.util.ts'
import { formatDate, parseDateTime } from '@core/utils/time.util.ts'
import { computed } from 'vue'
@@ -98,16 +97,7 @@ const isPoolMaster = computed(() => pool.value?.master === host.value?.$ref)
const hostIcon = computed(() => getHostIcon(host.value, getHostPowerState(host.value)))
const powerState = useMapper(
() => vm.power_state,
{
[VM_POWER_STATE.RUNNING]: { icon: 'status:running-circle', text: t('vm:status:running') },
[VM_POWER_STATE.HALTED]: { icon: 'status:halted-circle', text: t('vm:status:halted') },
[VM_POWER_STATE.PAUSED]: { icon: 'status:paused-circle', text: t('vm:status:paused') },
[VM_POWER_STATE.SUSPENDED]: { icon: 'status:suspended-circle', text: t('vm:status:suspended') },
},
VM_POWER_STATE.RUNNING
)
const { powerState } = useVmUtils(() => vm)
function getValidDateTime(dateTime: string | undefined): string | undefined {
return dateTime === '19700101T00:00:00Z' ? undefined : dateTime

View File

@@ -5,7 +5,7 @@ import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store.ts'
import { usePoolStore } from '@/stores/xen-api/pool.store.ts'
import type { IconName } from '@core/icons'
import { useTimeAgo } from '@core/composables/locale-time-ago.composable.ts'
import { useMapper } from '@core/packages/mapper'
import { createMapper, useMapper } from '@core/packages/mapper'
import { parseDateTime } from '@core/utils/time.util.ts'
import { toComputed } from '@core/utils/to-computed.util.ts'
import { HOST_POWER_STATE } from '@vates/types'
@@ -70,20 +70,31 @@ export function useHostUtils(rawHost: MaybeRefOrGetter<XenApiHost | undefined>)
const currentOperation = useMapper<string, string>(
() => pendingStateOperation.value,
{
() => ({
[HOST_OPERATION.ENABLE]: t('operation:enable'),
[HOST_OPERATION.EVACUATE]: t('operation:evacuate'),
[HOST_OPERATION.POWER_ON]: t('operation:start'),
[HOST_OPERATION.REBOOT]: t('operation:clean-reboot'),
[HOST_OPERATION.SHUTDOWN]: t('operation:shutdown'),
unknown: '',
},
}),
'unknown'
)
const getHostStatus = createMapper<HostState, { text: string; icon: IconName | undefined }>(
() => ({
running: { text: t('host:status:running'), icon: 'status:running-circle' },
halted: { text: t('host:status:halted'), icon: 'status:halted-circle' },
disabled: { text: t('host:status:disabled'), icon: 'status:host-disabled-circle' },
unknown: { text: t('host:status:unknown'), icon: undefined },
}),
'unknown'
)
return {
isMaster,
isRunning,
getHostStatus,
hostState,
powerState,
isChangingState,

View File

@@ -7,7 +7,7 @@
>
{{ branch.data.name_label || '(Host)' }}
<template #icon>
<VtsObjectIcon v-tooltip="hostState" type="host" size="medium" :state="hostState" />
<VtsObjectIcon v-tooltip="powerState.text" type="host" size="medium" :state="hostState" />
</template>
<template #addons>
<UiLoader v-if="isChangingState" v-tooltip="currentOperation" />
@@ -63,7 +63,8 @@ const { t } = useI18n()
const { isMasterHost } = usePoolStore().subscribe()
const { runningVmsCountByHostRef } = useVmStore().subscribe()
const { hostState, isChangingState, currentOperation } = useHostUtils(() => branch.data)
const { getHostStatus, hostState, isChangingState, currentOperation } = useHostUtils(() => branch.data)
const powerState = computed(() => getHostStatus(hostState.value))
const isMaster = computed(() => isMasterHost(branch.data.$ref))

View File

@@ -1,9 +1,9 @@
<template>
<VtsTreeItem expanded :node-id="leaf.dataId">
<VtsTreeItem :node-id="leaf.dataId" expanded>
<UiTreeItemLabel :route="{ name: '/vm/[uuid]', params: { uuid: leaf.data.uuid } }" no-indent>
{{ leaf.data.name_label || '(VM)' }}
<template #icon>
<VtsObjectIcon size="medium" :state="powerState" type="vm" />
<VtsObjectIcon v-tooltip="powerState.text" :state="vmState" size="medium" type="vm" />
</template>
<template #addons>
<UiLoader v-if="isChangingState" v-tooltip="{ placement: 'top', content: currentOperation }" />
@@ -11,10 +11,10 @@
<template #trigger="{ open, isOpen }">
<UiButtonIcon
v-tooltip="{ placement: 'top', content: t('quick-actions') }"
icon="action:more-actions"
accent="brand"
size="small"
:selected="isOpen"
accent="brand"
icon="action:more-actions"
size="small"
@click="open($event)"
/>
</template>
@@ -26,10 +26,10 @@
</template>
<script lang="ts" setup>
import type { VM_POWER_STATE } from '@/libs/xen-api/xen-api.enums.ts'
import type { VmLeaf } from '@/modules/treeview/types/tree.type.ts'
import VmTreeActions from '@/modules/vm/components/actions/VmTreeActions.vue'
import { useVmOperation } from '@/modules/vm/composables/vm-operation.composable.ts'
import { useVmUtils } from '@/modules/vm/composables/vm-utils.composable.ts'
import MenuList from '@core/components/menu/MenuList.vue'
import VtsObjectIcon from '@core/components/object-icon/VtsObjectIcon.vue'
import VtsTreeItem from '@core/components/tree/VtsTreeItem.vue'
@@ -37,6 +37,7 @@ import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
import UiLoader from '@core/components/ui/loader/UiLoader.vue'
import UiTreeItemLabel from '@core/components/ui/tree-item-label/UiTreeItemLabel.vue'
import { vTooltip } from '@core/directives/tooltip.directive.ts'
import { toLower } from 'lodash-es'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
@@ -47,6 +48,7 @@ const { leaf } = defineProps<{
const { t } = useI18n()
const { isChangingState, currentOperation } = useVmOperation(() => leaf.data)
const { powerState } = useVmUtils(() => leaf.data)
const powerState = computed(() => leaf.data.power_state.toLowerCase() as Lowercase<VM_POWER_STATE>)
const vmState = computed(() => toLower(leaf.data.power_state))
</script>

View File

@@ -17,7 +17,7 @@ export function useVmOperation(rawVm: MaybeRefOrGetter<XenApiVm | undefined>) {
const currentOperation = useMapper<string, string>(
() => Object.values(vm.value?.current_operations ?? {})[0],
{
() => ({
start: t('operation:start'),
start_on: t('operation:start-on-host'),
pause: t('operation:pause'),
@@ -36,7 +36,7 @@ export function useVmOperation(rawVm: MaybeRefOrGetter<XenApiVm | undefined>) {
export: t('operation:export'),
import: t('operation:import'),
unknown: '',
},
}),
'unknown'
)

View File

@@ -0,0 +1,28 @@
import { VM_POWER_STATE } from '@/libs/xen-api/xen-api.enums.ts'
import type { XenApiVm } from '@/libs/xen-api/xen-api.types.ts'
import type { IconName } from '@core/icons'
import { useMapper } from '@core/packages/mapper'
import { toComputed } from '@core/utils/to-computed.util.ts'
import type { MaybeRefOrGetter } from 'vue'
import { useI18n } from 'vue-i18n'
export function useVmUtils(rawVm: MaybeRefOrGetter<XenApiVm>) {
const { t } = useI18n()
const vm = toComputed(rawVm)
const powerState = useMapper<VM_POWER_STATE, { icon: IconName; text: string }>(
() => vm.value.power_state,
() => ({
[VM_POWER_STATE.RUNNING]: { icon: 'status:running-circle', text: t('vm:status:running') },
[VM_POWER_STATE.HALTED]: { icon: 'status:halted-circle', text: t('vm:status:halted') },
[VM_POWER_STATE.PAUSED]: { icon: 'status:paused-circle', text: t('vm:status:paused') },
[VM_POWER_STATE.SUSPENDED]: { icon: 'status:suspended-circle', text: t('vm:status:suspended') },
}),
VM_POWER_STATE.RUNNING
)
return {
powerState,
}
}

View File

@@ -1,3 +0,0 @@
export type VmState = 'running' | 'halted' | 'paused' | 'suspended'
export type HostState = 'running' | 'halted' | 'warning' | 'disabled' | 'unknown'

View File

@@ -1 +0,0 @@
export type POWER_STATE = 'running' | 'paused' | 'halted' | 'suspended'

View File

@@ -19,12 +19,12 @@ export function useXoHostUtils(rawHost: MaybeRefOrGetter<FrontXoHost>) {
const { vmsByHost } = useXoVmCollection()
const getHostStateDisplay = createMapper<XoHostState, { text: string; icon: IconName | undefined }>(
{
() => ({
running: { text: t('host:status:running'), icon: 'status:running-circle' },
halted: { text: t('host:status:halted'), icon: 'status:halted-circle' },
disabled: { text: t('host:status:disabled'), icon: 'status:host-disabled-circle' },
unknown: { text: t('host:status:unknown'), icon: undefined },
},
}),
'unknown'
)

View File

@@ -29,12 +29,12 @@ export function useXoVmUtils(rawVm: MaybeRefOrGetter<FrontXoVm>) {
const powerState = useMapper<VM_POWER_STATE, { icon: IconName; text: string }>(
() => vm.value.power_state,
{
() => ({
[VM_POWER_STATE.RUNNING]: { icon: 'status:running-circle', text: t('vm:status:running') },
[VM_POWER_STATE.HALTED]: { icon: 'status:halted-circle', text: t('vm:status:halted') },
[VM_POWER_STATE.PAUSED]: { icon: 'status:paused-circle', text: t('vm:status:paused') },
[VM_POWER_STATE.SUSPENDED]: { icon: 'status:suspended-circle', text: t('vm:status:suspended') },
},
}),
VM_POWER_STATE.RUNNING
)