Skip to content

Commit 4a397c8

Browse files
committed
feat(lite): add forget action on host
1 parent 3187b33 commit 4a397c8

6 files changed

Lines changed: 116 additions & 3 deletions

File tree

@xen-orchestra/lite/src/components/host/HostHeader.vue

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,37 @@
2020
</template>
2121
<HostPowerStateActions :host />
2222
</MenuList>
23+
24+
<MenuList placement="bottom-end">
25+
<template #trigger="{ open }">
26+
<UiButtonIcon
27+
v-tooltip="{
28+
placement: 'left',
29+
content: t('more-actions'),
30+
}"
31+
icon="action:more-actions"
32+
accent="brand"
33+
size="medium"
34+
@click="open($event)"
35+
/>
36+
</template>
37+
<HostMoreActions :host />
38+
</MenuList>
2339
</template>
2440
</UiHeadBar>
2541
</template>
2642

2743
<script lang="ts" setup>
2844
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
2945
import HostPowerStateActions from '@/modules/host/components/actions/HostPowerStateActions.vue'
46+
import HostMoreActions from '@/modules/host/components/HostMoreActions.vue'
3047
import { useHostUtils } from '@/modules/host/composables/host-utils.composable.ts'
3148
import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store.ts'
3249
import { usePoolStore } from '@/stores/xen-api/pool.store.ts'
3350
import VtsIcon from '@core/components/icon/VtsIcon.vue'
3451
import MenuList from '@core/components/menu/MenuList.vue'
3552
import VtsObjectIcon from '@core/components/object-icon/VtsObjectIcon.vue'
53+
import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
3654
import UiDropdownButton from '@core/components/ui/dropdown-button/UiDropdownButton.vue'
3755
import UiHeadBar from '@core/components/ui/head-bar/UiHeadBar.vue'
3856
import { vTooltip } from '@core/directives/tooltip.directive.ts'

@xen-orchestra/lite/src/components/infra/InfraHostItem.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
@click="open($event)"
3434
/>
3535
</template>
36-
<HostTreeActions :host />
36+
<HostMoreActions :host show-change-state-button />
3737
</MenuList>
3838
</template>
3939
</UiTreeItemLabel>
@@ -48,7 +48,7 @@
4848
<script lang="ts" setup>
4949
import InfraVmItems from '@/components/infra/InfraVmItems.vue'
5050
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
51-
import HostTreeActions from '@/modules/host/components/actions/HostTreeActions.vue'
51+
import HostMoreActions from '@/modules/host/components/HostMoreActions.vue'
5252
import { useHostUtils } from '@/modules/host/composables/host-utils.composable.ts'
5353
import { useHostStore } from '@/stores/xen-api/host.store.ts'
5454
import { usePoolStore } from '@/stores/xen-api/pool.store.ts'

@xen-orchestra/lite/src/libs/xen-api/operations/host-operations.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export function createHostOperations(xenApi: XenApi) {
1616

1717
const shutdown = (hostRef: HostRef) => xenApi.call('host.shutdown', [hostRef])
1818

19+
const destroy = (hostRef: HostRef) => xenApi.call('host.destroy', [hostRef])
20+
1921
const clearHost = async (hostRef: HostRef, force: boolean) => {
2022
await disable(hostRef)
2123

@@ -33,6 +35,8 @@ export function createHostOperations(xenApi: XenApi) {
3335

3436
return {
3537
powerOn,
38+
shutdown,
39+
destroy,
3640
cleanReboot: async (hostRef: HostRef, forceReboot: boolean) => {
3741
await clearHost(hostRef, forceReboot)
3842

@xen-orchestra/lite/src/modules/host/components/actions/HostTreeActions.vue renamed to @xen-orchestra/lite/src/modules/host/components/HostMoreActions.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
<template>
2-
<MenuItem icon="action:change-state" class="change-state">
2+
<MenuItem v-if="showChangeStateButton" icon="action:change-state" class="change-state">
33
{{ t('action:change-state') }}
44
<template #submenu>
55
<HostPowerStateActions :host />
66
</template>
77
</MenuItem>
8+
<HostForgetButton :host />
89
<VtsDivider type="stretch" />
910
<HostDownloadButton :host-opaque-ref="host.$ref" />
1011
</template>
1112

1213
<script setup lang="ts">
1314
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
1415
import HostDownloadButton from '@/modules/host/components/actions/download/HostDownloadButton.vue'
16+
import HostForgetButton from '@/modules/host/components/actions/forget/HostForgetButton.vue'
1517
import HostPowerStateActions from '@/modules/host/components/actions/HostPowerStateActions.vue'
1618
import VtsDivider from '@core/components/divider/VtsDivider.vue'
1719
import MenuItem from '@core/components/menu/MenuItem.vue'
1820
import { useI18n } from 'vue-i18n'
1921
2022
defineProps<{
2123
host: XenApiHost
24+
showChangeStateButton?: boolean
2225
}>()
2326
2427
const { t } = useI18n()
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<template>
2+
<MenuItem
3+
v-tooltip="!canForgetHost && forgetHostErrorMessage"
4+
:busy="isForgettingHost"
5+
class="host-forget-button"
6+
:disabled="!canForgetHost"
7+
icon="action:forget"
8+
@click="forgetHost()"
9+
>
10+
{{ t('action:forget') }}
11+
</MenuItem>
12+
</template>
13+
14+
<script lang="ts" setup>
15+
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
16+
import { useHostForgetJob } from '@/modules/host/jobs/host-forget.job.ts'
17+
import MenuItem from '@core/components/menu/MenuItem.vue'
18+
import { useActionModal } from '@core/composables/modals/use-action-modal.ts'
19+
import { vTooltip } from '@core/directives/tooltip.directive.ts'
20+
import { useI18n } from 'vue-i18n'
21+
22+
const { host } = defineProps<{
23+
host: XenApiHost
24+
}>()
25+
26+
const { t } = useI18n()
27+
28+
const { open: openActionModal } = useActionModal()
29+
30+
const {
31+
run,
32+
canRun: canForgetHost,
33+
isRunning: isForgettingHost,
34+
errorMessage: forgetHostErrorMessage,
35+
} = useHostForgetJob(() => host)
36+
37+
function forgetHost() {
38+
return openActionModal({
39+
props: {
40+
accent: 'danger',
41+
action: 'forget',
42+
object: 'host',
43+
hostName: host.name_label,
44+
icon: 'status:danger-circle',
45+
},
46+
events: {
47+
onConfirm: async () => {
48+
void run()
49+
},
50+
},
51+
})
52+
}
53+
</script>
54+
55+
<style lang="postcss" scoped>
56+
.host-forget-button {
57+
color: var(--color-danger-item-base);
58+
}
59+
</style>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { hostArg } from '@/modules/host/jobs/host-args.ts'
2+
import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store.ts'
3+
import { useXenApiStore } from '@/stores/xen-api.store.ts'
4+
import { defineJob, JobError, JobRunningError } from '@core/packages/job'
5+
import { useI18n } from 'vue-i18n'
6+
7+
export const useHostForgetJob = defineJob('host.forget', [hostArg], () => {
8+
const xapi = useXenApiStore().getXapi()
9+
const { t } = useI18n()
10+
const { isHostHalted } = useHostMetricsStore().subscribe()
11+
12+
return {
13+
run: host => xapi.host.destroy(host.$ref),
14+
15+
validate: (isRunning, host) => {
16+
if (host === undefined) {
17+
throw new JobError(t('job:host-forget:missing-host'))
18+
}
19+
20+
if (!isHostHalted(host)) {
21+
throw new JobError(t('job:host-forget:bad-power-state'))
22+
}
23+
24+
if (isRunning) {
25+
throw new JobRunningError(t('job:host-forget:in-progress'))
26+
}
27+
},
28+
}
29+
})

0 commit comments

Comments
 (0)