Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const computeHeaders = ref<DataTableHeader[]>([
{ title: "CPU cores", align: "start", sortable: true, key: "core_count" },
{ title: "Memory [GB]", align: "start", sortable: true, key: "ram" },
{ title: "GPU", align: "start", sortable: true, key: "gpu" },
{ title: "GPU count", align: "start", sortable: true, key: "gpu_count" },
{ title: "Subscription", align: "start", sortable: true, key: "subscription" },
{ title: "Price / month", align: "start", sortable: true, key: "monthlyPrice" },
{ title: "Price / year", align: "start", sortable: true, key: "yearlyPrice" },
Expand Down
36 changes: 33 additions & 3 deletions docs/.vitepress/theme/components/price-estimator/MachineModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const formData = ref<MachineFormData>({
name: undefined,
machine_type: undefined,
gpu: undefined,
gpu_count: 1,
subscription: undefined,
})

Expand Down Expand Up @@ -62,11 +63,15 @@ const getComputePriceMonth = computed((): string | number => {
})

const getGpuPriceYear = computed((): string | number => {
if (!formData.value.gpu) {
const gpu = formData.value.gpu
const gpuCount = formData.value.gpu_count

if (!gpu || !gpuCount) {
return 0
}
const price = priceEstimatorStore.catalogue.gpuPrices.find((item: PriceListItem) => item["service.unit"] === formData.value.gpu && item["service.level"] === "ONDEMAND")
return price ? Number(price["price.nok.ex.vat"]).toFixed(2) : 0
const price = priceEstimatorStore.catalogue.gpuPrices.find((item: PriceListItem) => item["service.unit"] === gpu && item["service.level"] === "ONDEMAND")

return price ? (Number(price["price.nok.ex.vat"]) * gpuCount).toFixed(2) : 0
})

const getGpuPriceMonth = computed((): string | number => {
Expand All @@ -90,6 +95,21 @@ const getGpus = computed(() => {
})
})

const gpuCount = computed({
get: () => (formData.value.gpu ? formData.value.gpu_count : undefined),
set: (val) => {
if (formData.value.gpu) formData.value.gpu_count = val
},
})

const getMaxGpuCount = computed((): number => {
if (!formData.value.gpu) return 1

const selectedGpu = priceEstimatorStore.catalogue.availableGpus.find((item: GpuModel) => item["type"] === formData.value.gpu)

return selectedGpu?.max ?? 1
})

const close = () => {
emit("close")
}
Expand All @@ -110,6 +130,10 @@ const save = () => {
const machineWithGpu = formData.value.machine_type
const subscription = formData.value.subscription
const gpu = formData.value.gpu
var gpuCount
if (gpu) {
gpuCount = formData.value.gpu_count
}

if (props.editData) {
priceEstimatorStore.editComputeInLab(props.labId, props.editData.id, {
Expand All @@ -119,6 +143,7 @@ const save = () => {
ram: ram,
subscription: subscription!,
gpu: gpu,
gpuCount: gpuCount,
})
} else {
// Add new compute
Expand All @@ -129,6 +154,7 @@ const save = () => {
ram: ram,
subscription: subscription!,
gpu: gpu,
gpu_count: gpuCount,
})
}

Expand All @@ -148,6 +174,7 @@ onMounted(() => {
} else {
formData.value.machine_type = props.editData.machine_type
formData.value.gpu = props.editData.gpu
formData.value.gpu_count = props.editData.gpu_count
}
} else {
formData.value.id = props.computeId
Expand Down Expand Up @@ -197,6 +224,9 @@ onMounted(() => {
<v-col cols="12">
<v-select v-model="formData.gpu" :items="getGpus" label="GPU type (optional)" variant="outlined" clearable :disabled="!formData.subscription"></v-select>
</v-col>
<v-col cols="12">
<v-number-input v-model="gpuCount" variant="outlined" label="GPU count" :min="1" :max="getMaxGpuCount" :disabled="!formData.gpu"></v-number-input>
</v-col>
<v-col v-show="formData.gpu" cols="12" sm="6">
<v-text-field v-model="getGpuPriceMonth" label="GPU Price / Month" suffix="NOK ex. VAT" readonly variant="outlined"></v-text-field>
</v-col>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export default {
async getPriceList() {
try {
const res = await axios.get(price_list_url)
// console.log("Fetched price list:", res.data)
return res.data
} catch (error) {
console.error("Error fetching price list:", error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export const priceEstimatorStore = reactive({
ram: comp.ram,
subscription: comp.subscription,
gpu: comp.gpu,
gpu_count: comp.gpu_count,
})
}
}
Expand Down Expand Up @@ -109,11 +110,18 @@ export const priceEstimatorStore = reactive({
const priceListPromise = pricesApi.getPriceList().then((json: PriceListItem[]) => {
this.catalogue.computePrices = json.filter((item) => item["service.group"] === "cpu").map(this.convertPricesToYearly)
this.catalogue.storagePrices = json.filter((item) => item["service.family"] === "store")
this.catalogue.gpuPrices = json.filter((item) => item["service.group"] === "gpu").map(this.convertPricesToYearly)
this.catalogue.gpuPrices = json
.filter((item) => item["service.group"] === "gpu")
.map((item) => ({ ...item, "service.unit": item["service.unit"]?.replace("nvidia.", "") }))
.map(this.convertPricesToYearly)
this.catalogue.labPrices = json.filter((item) => item["service.group"] === "lab")
})

const gpusPromise = pricesApi.getAvailableGPUS().then((gpus: GpuModel[]) => {
gpus = gpus.map((item) => ({
...item,
type: item.type.replace("nvidia.", ""),
}))
this.catalogue.availableGpus = gpus
})

Expand Down Expand Up @@ -412,7 +420,7 @@ export const priceEstimatorStore = reactive({

/* Compute helpers */

getComputePriceFromCatalogue(machineType: string, type: string, machineWithGpu?: string) {
getComputePriceFromCatalogue(machineType: string, type: string, machineWithGpu?: string, gpuCount: number = 1) {
let totalYearlyPrice = 0
let totalMonthlyPrice = 0
let mainMachineTypePrice: number | undefined
Expand Down Expand Up @@ -443,7 +451,7 @@ export const priceEstimatorStore = reactive({
if (machineWithGpu) {
const gpuPrice = this.catalogue.gpuPrices.find((p) => p["service.unit"] === machineWithGpu && p["service.level"] === "ONDEMAND")
if (gpuPrice) {
gpuYearly = gpuPrice["price.nok.ex.vat"]
gpuYearly = gpuPrice["price.nok.ex.vat"] * gpuCount
totalYearlyPrice += gpuYearly
totalMonthlyPrice = totalMonthlyPrice + Number(gpuYearly / 12)
}
Expand All @@ -454,18 +462,19 @@ export const priceEstimatorStore = reactive({
}
},

addComputeToLab(labId: number, payload: { name: string; machine_type: string; core_count: number; ram: number; subscription: string; gpu?: string }) {
addComputeToLab(labId: number, payload: { name: string; machine_type: string; core_count: number; ram: number; subscription: string; gpu?: string; gpu_count?: number }) {
const lab = this.labs.find((l) => l.id === labId)
if (!lab) return

const compId = lab.selectedCompute?.length || 0
const prices = this.getComputePriceFromCatalogue(payload.machine_type, payload.subscription, payload.gpu)
const prices = this.getComputePriceFromCatalogue(payload.machine_type, payload.subscription, payload.gpu, payload.gpu_count)
const newCompute: ComputeUnit = {
id: compId,
name: payload.name,
machine_type: payload.machine_type,
core_count: payload.core_count,
gpu: payload.gpu,
gpu_count: payload.gpu_count,
ram: payload.ram,
subscription: payload.subscription as SubscriptionType,
monthlyPrice: prices.monthlyPrice,
Expand All @@ -477,7 +486,11 @@ export const priceEstimatorStore = reactive({
this.saveStateToLocal()
},

editComputeInLab(labId: number, computeId: number, payload: { name: string; machine_type: string; core_count: number; ram: number; subscription: string; gpu?: string }) {
editComputeInLab(
labId: number,
computeId: number,
payload: { name: string; machine_type: string; core_count: number; ram: number; subscription: string; gpu?: string; gpuCount?: number },
) {
const lab = this.labs.find((l) => l.id === labId)
if (!lab || !lab.selectedCompute) return

Expand All @@ -491,6 +504,7 @@ export const priceEstimatorStore = reactive({
machine_type: payload.machine_type,
core_count: payload.core_count,
gpu: payload.gpu,
gpu_count: payload.gpuCount,
ram: payload.ram,
subscription: payload.subscription as SubscriptionType,
monthlyPrice: prices.monthlyPrice,
Expand Down Expand Up @@ -652,6 +666,7 @@ export const priceEstimatorStore = reactive({
ram: comp.ram,
subscription: comp.subscription,
gpu: comp.gpu,
gpu_count: comp.gpu_count,
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface ComputeUnit {
core_count: number
ram: number
gpu?: string
gpu_count?: number
subscription: SubscriptionType
monthlyPrice: number
yearlyPrice: number
Expand All @@ -46,6 +47,7 @@ export interface StorageUnit {
export interface GpuModel {
type: string
vram: number
max: number
}

export interface MachineType {
Expand Down Expand Up @@ -87,6 +89,7 @@ export interface MachineFormData {
name?: string
machine_type?: string
gpu?: string
gpu_count?: number
subscription?: SubscriptionType
}

Expand Down