Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[X06] VM Creation #8324

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
37 changes: 31 additions & 6 deletions @xen-orchestra/web-core/lib/components/ui/input/UiInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,26 @@
<VtsIcon :icon accent="current" class="before" />
<input
:id
v-model.trim="modelValue"
v-model.trim="inputValue"
class="typo-body-regular input text-ellipsis"
:type
:disabled
v-bind="attrs"
/>
<VtsIcon
v-if="!attrs.disabled && modelValue && clearable"
v-if="!attrs.disabled && inputValue && clearable"
:icon="faXmark"
class="after"
accent="brand"
@click="modelValue = ''"
@click="inputValue = ''"
/>
</div>
<UiInfo v-if="slots.info || info" :accent="accent === 'brand' ? 'info' : accent">
<slot name="info">{{ info }}</slot>
</UiInfo>
<UiInfo v-if="errorMessage" accent="danger">
{{ errorMessage }}
</UiInfo>
</div>
</template>

Expand All @@ -35,6 +38,7 @@ import UiLabel from '@core/components/ui/label/UiLabel.vue'
import { toVariants } from '@core/utils/to-variants.util'
import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
import { faXmark } from '@fortawesome/free-solid-svg-icons'
import { useField } from 'vee-validate'
import { computed, useAttrs, useId } from 'vue'

type InputAccent = 'brand' | 'warning' | 'danger'
Expand All @@ -43,8 +47,14 @@ type InputType = 'text' | 'number' | 'password' | 'search'
defineOptions({
inheritAttrs: false,
})

const { accent, id = useId() } = defineProps<{
const {
accent,
id = useId(),
name,
modelValue,
} = defineProps<{
name?: string
modelValue: string | number
accent: InputAccent
label?: string
info?: string
Expand All @@ -58,16 +68,31 @@ const { accent, id = useId() } = defineProps<{
type?: InputType
}>()

const modelValue = defineModel<string | number>({ required: true })
const emit = defineEmits<{
'update:modelValue': [value: string | number]
}>()

const slots = defineSlots<{
default?(): any
info?(): any
}>()

const { value, errorMessage } = useField(() => name ?? '', undefined, {
initialValue: modelValue,
syncVModel: true,
})

const attrs = useAttrs()

const labelAccent = computed(() => (accent === 'brand' ? 'neutral' : accent))

const inputValue = computed({
get: () => modelValue,
set: val => {
value.value = val
emit('update:modelValue', val)
},
})
</script>

<style lang="postcss" scoped>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const { accent, value, disabled } = defineProps<{
disabled?: boolean
}>()

const model = defineModel<boolean>()
const model = defineModel<string>()

defineSlots<{
default(): any
Expand Down
47 changes: 47 additions & 0 deletions @xen-orchestra/web-core/lib/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,53 @@
"networks": "Networks",
"new": "New",
"new-features-are-coming": "New features are coming soon!",
"new-vm": "New VM",
"new-vm.add": "Add new VM",
"new-vm.affinity-host": "Affinity host",
"new-vm.auto-generated": "Auto-generated",
"new-vm.auto-power": "Auto power-on",
"new-vm.boot-firmware": "Boot firmware",
"new-vm.boot-vm": "Boot VM after creation",
"new-vm.copy-host": "Copy host BIOS strings to VM",
"new-vm.create": "Create VM",
"new-vm.created-by-xo": "Created by XO",
"new-vm.custom-config": "Custom config",
"new-vm.description": "Description",
"new-vm.disk-name": "Disk name",
"new-vm.fast-clone": "Fast clone",
"new-vm.install-settings": "Install settings",
"new-vm.interfaces": "Interfaces",
"new-vm.iso-dvd": "ISO/DVD",
"new-vm.mac-addresses": "Mac addresses",
"new-vm.memory": "Memory",
"new-vm.multi-creation": "Multi-creation",
"new-vm.network": "Network",
"new-vm.network-config": "Network configuration",
"new-vm.networks": "Networks",
"new-vm.new": "New",
"new-vm.no-config": "No config",
"new-vm.other-installation-media": "Other installation media",
"new-vm.paste-public-key": "Paste public key",
"new-vm.pick-template": "Pick a template from your list",
"new-vm.pxe": "PXE",
"new-vm.ram": "Ram",
"new-vm.settings": "Settings",
"new-vm.size": "Size",
"new-vm.socketsWithCoresPerSocket": "{nSockets} sockets × {nCores} cores/socket",
"new-vm.ssh-key": "SSH key",
"new-vm.storage": "Storage",
"new-vm.storage-repositories": "Storage repositories (SR)",
"new-vm.summary": "Summary",
"new-vm.system": "System",
"new-vm.tags": "Tags",
"new-vm.template": "Template",
"new-vm.topology": "Topology",
"new-vm.user-config": "User configuration",
"new-vm.vcpu": "Vcpu",
"new-vm.vifs": "VIFs",
"new-vm.vm-description": "VM description",
"new-vm.vm-name": "VM name",
"new-vm.write-configurations": "Write configurations",
"news": "News",
"news-name": "{name} news",
"no-alarm-triggered": "No alarm triggered",
Expand Down
47 changes: 47 additions & 0 deletions @xen-orchestra/web-core/lib/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,53 @@
"networks": "Réseaux",
"new": "Nouveau",
"new-features-are-coming": "De nouvelles fonctionnalités arrivent bientôt !",
"new-vm": "Nouvelle VM",
"new-vm.socketsWithCoresPerSocket": "{nSockets} sockets × {nCores} cœurs/socket",
"new-vm.add": "Ajouter une nouvelle VM",
"new-vm.affinity-host": "Hôte d'affinité",
"new-vm.auto-generated": "Généré automatiquement",
"new-vm.auto-power": "Mise sous tension automatique",
"new-vm.boot-firmware": "Micrologiciel de démarrage",
"new-vm.boot-vm": "Démarrer la VM après la création",
"new-vm.copy-host": "Copier les chaînes du BIOS de l'hôte sur la VM",
"new-vm.create": "Créer une VM",
"new-vm.created-by-xo": "Créé par XO",
"new-vm.custom-config": "Configuration personnalisée",
"new-vm.description": "Description",
"new-vm.disk-name": "Nom du disque",
"new-vm.fast-clone": "Clonage rapide",
"new-vm.install-settings": "Paramètres d'installation",
"new-vm.interfaces": "Interfaces",
"new-vm.iso-dvd": "ISO/DVD",
"new-vm.mac-addresses": "Adresses Mac",
"new-vm.memory": "Mémoire",
"new-vm.multi-creation": "Multi-création",
"new-vm.network": "Réseau",
"new-vm.network-config": "Configuration du réseau",
"new-vm.networks": "Réseaux",
"new-vm.new": "Nouveau",
"new-vm.no-config": "Aucune configuration",
"new-vm.other-installation-media": "Autres supports d'installation",
"new-vm.paste-public-key": "Coller la clé publique",
"new-vm.pick-template": "Choisissez un modèle dans votre liste",
"new-vm.pxe": "PXE",
"new-vm.ram": "Ram",
"new-vm.settings": "Paramètres",
"new-vm.size": "Taille",
"new-vm.ssh-key": "Clé SSH",
"new-vm.storage": "Stockage",
"new-vm.storage-repositories": "Dépôts de stockage (SR)",
"new-vm.summary": "Résumé",
"new-vm.system": "Système",
"new-vm.tags": "Tags",
"new-vm.template": "Modèle",
"new-vm.topology": "Topologie",
"new-vm.user-config": "Configuration utilisateur",
"new-vm.vcpu": "Vcpu",
"new-vm.vifs": "VIFs",
"new-vm.vm-description": "Description de la VM",
"new-vm.vm-name": "Nom de la VM",
"new-vm.write-configurations": "Écrire les configurations",
"news": "Actualités",
"news-name": "Actualités {name}",
"no-alarm-triggered": "Aucune alarme déclenchée",
Expand Down
12 changes: 12 additions & 0 deletions @xen-orchestra/web-core/lib/types/new-vm.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export interface Disk {
name_label: string
name_description: string
size: number
sr: string
type?: string
}

export interface NetworkInterface {
interface: string
macAddress: string
}
5 changes: 4 additions & 1 deletion @xen-orchestra/web-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@
"@vueuse/core": "^10.7.1",
"@vueuse/math": "^10.7.1",
"@vueuse/shared": "^10.7.1",
"@vee-validate/yup": "^4.15.0",
"d3-time-format": "^4.1.0",
"echarts": "^5.4.3",
"human-format": "^1.2.1",
"iterable-backoff": "^0.1.0",
"lodash-es": "^4.17.21",
"placement.js": "^1.0.0-beta.5",
"vue-echarts": "^6.6.8"
"vue-echarts": "^6.6.8",
"vee-validate": "^4.15.0",
"yup": "^1.6.1"
},
"peerDependencies": {
"pinia": "^2.2.6",
Expand Down
5 changes: 4 additions & 1 deletion @xen-orchestra/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@vueuse/shared": "^10.7.1",
"@vueuse/integrations": "^10.7.1",
"@xen-orchestra/web-core": "^0.16.0",
"@vee-validate/yup": "^4.15.0",
"lodash-es": "^4.17.21",
"npm-run-all2": "^6.1.1",
"pinia": "^2.2.6",
Expand All @@ -42,7 +43,9 @@
"vue": "~3.5.12",
"vue-i18n": "^9.9.0",
"vue-router": "^4.4.5",
"vue-tsc": "~2.1.10"
"vue-tsc": "~2.1.10",
"vee-validate": "^4.15.0",
"yup": "^1.6.1"
},
"overrides": {
"vite": {
Expand Down
13 changes: 12 additions & 1 deletion @xen-orchestra/web/src/components/pool/PoolHeader.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<template>
<UiHeadBar :icon="faCity">
{{ pool.name_label }}
<template #actions>
<UiButton :left-icon="faPlus" variant="primary" accent="brand" size="medium" @click="goToNewVm">
{{ $t('new-vm') }}
</UiButton>
</template>
</UiHeadBar>
<TabList>
<TabItem disabled>{{ $t('dashboard') }}</TabItem>
Expand Down Expand Up @@ -31,10 +36,16 @@
import type { XoPool } from '@/types/xo/pool.type'
import TabItem from '@core/components/tab/TabItem.vue'
import TabList from '@core/components/tab/TabList.vue'
import UiButton from '@core/components/ui/button/UiButton.vue'
import UiHeadBar from '@core/components/ui/head-bar/UiHeadBar.vue'
import { faCity } from '@fortawesome/free-solid-svg-icons'
import { faCity, faPlus } from '@fortawesome/free-solid-svg-icons'
import { useRouter } from 'vue-router'

defineProps<{
pool: XoPool
}>()

const router = useRouter()

const goToNewVm = () => router.push({ name: '/vm/NewVm' })
</script>
14 changes: 14 additions & 0 deletions @xen-orchestra/web/src/jobs/vm-create.jobs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useFetch } from '@vueuse/core'

export async function createVM(payload: Record<string, any>, poolId: string) {
const { data, error } = await useFetch(`/rest/v0/pools/${poolId}/actions/create_vm?sync`, {
method: 'POST',
body: JSON.stringify(payload),
headers: { 'Content-Type': 'application/json' },
}).text()

if (error.value) {
throw new Error(error.value.message)
}
return data.value
}
Loading
Loading