Files
ubicloud/views/vm/create.erb
Burak Yucesoy 48a8796f7b Fix IP price display
We find the element that we put the pricing info by concatenating the name of
the input field and "monthly-price" string. We changed the name of the input
field but forgot to change the class of the element that we put the pricing
info. This commit fixes that.
2024-08-26 14:00:04 +02:00

241 lines
12 KiB
Plaintext

<% @page_title = "Create Virtual Machine" %>
<%== render("components/billing_warning") %>
<div class="space-y-1">
<%== render(
"components/breadcrumb",
locals: {
back: "#{@project_data[:path]}/vm",
parts: [
%w[Projects /project],
[@project_data[:name], @project_data[:path]],
["Virtual Machines", "#{@project_data[:path]}/vm"],
%w[Create #]
]
}
) %>
<%== render("components/page_header", locals: { title: "Create Virtual Machine" }) %>
</div>
<div class="grid gap-6">
<form action="<%= "#{@project_data[:path]}/vm" %>" method="POST">
<%== csrf_tag("#{@project_data[:path]}/vm") %>
<!-- Create Card -->
<div class="overflow-hidden rounded-lg shadow ring-1 ring-black ring-opacity-5 bg-white divide-y divide-gray-200">
<div class="px-4 py-5 sm:p-6">
<div class="space-y-12">
<div>
<h2 class="text-base font-semibold leading-7 text-gray-900">Details</h2>
<p class="mt-1 text-sm leading-6 text-gray-600">Enter details for your virtual machine.</p>
<div class="mt-6 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<div class="sm:col-span-3">
<%== render(
"components/form/text",
locals: {
name: "name",
label: "Name",
attributes: {
required: true,
placeholder: "Enter name"
}
}
) %>
</div>
<div class="col-span-full">
<% locations = Option
.locations
.map { |l| [l.display_name, l.ui_name, @prices[l.name].to_json] }
default_location = Option.locations.detect { |l| l.name == @default_location }&.display_name
%>
<%== render(
"components/form/radio_small_cards",
locals: {
name: "location",
label: "Location",
options: locations,
selected: default_location,
attributes: {
required: true
}
}
) %>
</div>
<div class="sm:col-span-3">
<%== render(
"components/form/select",
locals: {
name: "private_subnet_id",
label: "Private Subnet",
placeholder: "Create new subnet",
options: @subnets.map { |s| [s[:id], s[:name], "location-based-option #{s[:location]}"] }
}
) %>
</div>
<div class="col-span-full">
<%== render(
"components/form/checkbox",
locals: {
name: "enable_ip4",
label: "Public IPv4 Support (+<span class='enable_ip4-1-monthly-price'>-</span><span class='text-xs text-gray-500'>/mo</span>)",
options: [
["1", "Enable Public IPv4", "location-based-price", {"data-amount" => "1", "data-resource-type" => "IPAddress", "data-resource-family" => "IPv4", "data-default" => "true"}]
],
selected: "1",
description:
"Needed for inbound and outbound public IPv4 connections. Websites that do not support IPv6 will be inaccessible without an IPv4 address."
}
) %>
</div>
<div class="col-span-full">
<div class="space-y-2">
<label for="size" class="text-sm font-medium leading-6 text-gray-900">Server size (Dedicated CPU)</label>
<fieldset class="radio-small-cards" id="size-radios">
<legend class="sr-only">Server size</legend>
<div class="grid gap-3 grid-cols-1 md:grid-cols-2 xl:grid-cols-3">
<% Option::VmSizes.select { _1.visible }.each_with_index do |size, idx| %>
<% disabled = !@enabled_vm_sizes.include?(size.name) %>
<label class="size-<%= size.name %>" title="<%= disabled ? "Insufficient quota. You can reach us at support@ubicloud.com to increase your quota." : "" %>">
<input
type="radio"
name="size"
value="<%= size.name %>"
class="peer sr-only location-based-price"
data-resource-type="VmCores"
data-resource-family="<%= size.family %>"
data-amount="<%= size.vcpu / 2 %>"
data-storage-resource-type="VmStorage"
data-storage-size-options="<%= size.storage_size_options %>"
required
<%= (flash.dig("old", "size") == size.name || flash.dig("old", "size").nil? && idx == 0) ? "checked" : "" %>
<%= disabled ? "disabled" : "" %>
>
<span
class="flex items-center justify-between rounded-md py-4 px-4 sm:flex-1 cursor-pointer focus:outline-none
ring-1 ring-gray-300 bg-white text-gray-900 hover:bg-gray-50
peer-focus-visible:ring-2 peer-focus-visible:ring-orange-600 peer-focus-visible:ring-offset-2 peer-checked:bg-orange-600 peer-checked:text-white peer-checked:hover:bg-orange-700
<%= disabled ? "opacity-50" : "" %>"
>
<span class="flex flex-col">
<span class="text-md font-semibold"><%= size.display_name %></span>
<span class="text-sm opacity-80">
<span class="block sm:inline">
<%= size.vcpu %>
vCPUs /
<%= size.memory %>
GB RAM
</span>
</span>
</span>
<span class="mt-2 flex text-sm sm:ml-4 sm:mt-0 sm:flex-col sm:text-right">
<span class="font-medium"><span class="size-<%= size.name %>-monthly-price">-</span>/mo</span>
<span class="ml-1 opacity-50 sm:ml-0"><span class="size-<%= size.name %>-hourly-price">-</span>/hour</span>
</span>
</span>
</label>
<% end %>
</div>
</fieldset>
</div>
</div>
<div class="col-span-full instance-size-based-storage-sizes">
<div class="space-y-2">
<label for="storage_size" class="text-sm font-medium leading-6 text-gray-900">Storage size</label>
<fieldset class="radio-small-cards" id="storage-size-radios">
<legend class="sr-only">Storage size</legend>
<div class="grid gap-3 grid-cols-1 md:grid-cols-2 xl:grid-cols-3">
<% size = flash.dig("old", "size") ? Option::VmSizes.find { _1.name == flash.dig("old", "size") } : Option::VmSizes[0] %>
<% size.storage_size_options.each_with_index do |storage_size, idx| %>
<label class="storage-size storage-size-<%= storage_size %>">
<input
type="radio"
name="storage_size"
value="<%= storage_size %>"
class="peer sr-only"
required
<%= (flash.dig("old", "storage_size") == storage_size || flash.dig("old", "storage_size").nil? && idx == 0) ? "checked" : "" %>
>
<span
class="flex items-center justify-between rounded-md py-4 px-4 sm:flex-1 cursor-pointer focus:outline-none
ring-1 ring-gray-300 bg-white text-gray-900 hover:bg-gray-50
peer-focus-visible:ring-2 peer-focus-visible:ring-orange-600 peer-focus-visible:ring-offset-2 peer-checked:bg-orange-600 peer-checked:text-white peer-checked:hover:bg-orange-700"
>
<span class="text-md font-semibold storage-size-label"><%= storage_size %>GB</span>
<span class="mt-2 flex text-sm sm:ml-4 sm:mt-0 sm:flex-col sm:text-right">
<span class="font-medium"><span class="storage-size-monthly-price">-</span>/mo</span>
<span class="ml-1 opacity-50 sm:ml-0"><span class="storage-size-hourly-price">-</span>/hour</span>
</span>
</span>
</label>
<% end %>
</div>
</fieldset>
</div>
</div>
<div class="col-span-full">
<%== render(
"components/form/radio_small_cards",
locals: {
name: "boot_image",
label: "Boot Image",
options: Option::BootImages.to_h { |bi| [bi.name, bi.display_name] },
attributes: {
required: true
}
}
) %>
</div>
</div>
</div>
<div>
<h2 class="text-base font-semibold leading-7 text-gray-900">Login Information</h2>
<p class="mt-1 text-sm leading-6 text-gray-600">This information will be used to login virtual machine.</p>
<div class="mt-6 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<div class="sm:col-span-2">
<%== render(
"components/form/text",
locals: {
name: "unix_user",
label: "User",
value: "ubi",
attributes: {
required: true,
placeholder: "Unix username"
}
}
) %>
</div>
<div class="col-span-full">
<%== render(
"components/form/textarea",
locals: {
name: "public_key",
label: "SSH Public Key",
description: "SSH keys are a more secure method of logging into a server.",
attributes: {
required: true,
placeholder: "ssh-ed25519 AAAA...",
rows: 3
}
}
) %>
</div>
</div>
</div>
</div>
</div>
<div class="px-4 py-5 sm:p-6">
<div class="flex items-center justify-end gap-x-6">
<a href="<%= @project_data[:path] %>/vm" class="text-sm font-semibold leading-6 text-gray-900">Cancel</a>
<%== render("components/form/submit_button", locals: { text: "Create" }) %>
</div>
</div>
</div>
</form>
</div>