Created
January 28, 2025 14:51
-
-
Save wktdev/405003a4940ff8bd65c9bb7257a2f0dc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
``` | |
defmodule AppWeb.PageLive do | |
@moduledoc """ | |
This is the web interface for the testbed application. | |
This is where the HTML is rendered and CSS is applied. | |
The core of this apps code resides here. | |
1. Code that listens and respond to interactive user events is written here. | |
2. Code here moves data to and from the database. | |
The following code are imported functions used to communicate | |
with the database. | |
alias App.TestBeds | |
alias App.StatusActions | |
The above functions are available in: | |
app/test_beds.ex and app/status_actions.ex | |
To render an image of the app schema, run these three commands | |
mix ecto.gen.erd # generates ecto_erd.dot | |
mix ecto.gen.erd --output-path=ecto_erd.dot | |
mix ecto.gen.erd && dot -Tpng ecto_erd.dot -o erd.png && xdg-open erd.png | |
""" | |
use AppWeb, :live_view | |
alias App.TestBeds | |
alias App.Alerts | |
alias App.StatusActions | |
@doc """ | |
mount runs immediatley when the page loads. | |
Dynamic variables in HTML are placed in assign() after | |
the socket parameter. The following code is used to get TestBed | |
data out of the database and used in the HTML | |
#Example | |
testbeds: TestBeds.list_testbeds() | |
testbeds variable above is used in the HTML to render testbed data. | |
The Testbeds.subscribe() is part of the pub/sub websockets API. | |
The call site for TestBeds.subscribe is in the App/test_beds.ex folder | |
""" | |
def mount(_params, _session, socket) do | |
TestBeds.subscribe() | |
Alerts.subscribe() | |
{:ok, | |
assign(socket, | |
testbeds: TestBeds.list_testbeds(), | |
sort_direction: false, # Here | |
sort_field: :name, # Here | |
alerts: Alerts.list_alerts(), | |
developer: "None", | |
name_warning: "" | |
)} | |
end | |
# Set initial state, including sorting direction (ascending or descending) | |
@doc """ | |
handle_info in this app is used as part of the pub/sub process. | |
Handle_info listens to certain non-user events and runs code. | |
This is one area that I am still learning about so my understanding is limited. | |
""" | |
def handle_info({TestBeds, [:testbed | _], _}, socket) do | |
testbeds = Enum.sort_by(socket.assigns.testbeds, fn item -> Map.get(item, socket.assigns.sort_field) end, socket.assigns.sort_direction) | |
{:noreply, assign(socket, testbeds: testbeds)} | |
end | |
def handle_info({Alerts, [:alert | _], _}, socket) do | |
{:noreply, assign(socket, alerts: Alerts.list_alerts())} | |
end | |
def convert_time(time_stamp) do | |
time_stamp | |
|> DateTime.from_naive!("Europe/London") | |
|> DateTime.shift_zone!("America/Montreal") | |
|> Calendar.strftime("%m-%d-%y %I:%M %p") | |
end | |
def create_timestamp() do | |
DateTime.utc_now | |
end | |
# def convert_time(time_stamp) do | |
# time_stamp | |
# |> DateTime.from_naive!("Europe/London") | |
# |> DateTime.shift_zone!("America/Chicago") | |
# |> Calendar.strftime("%m-%d-%y %I:%M %p") | |
# end | |
@doc """ | |
handle_event is similar to a conventional JavaScript event handler. | |
The event it listens for is the second argument. The event is then assigned | |
to html elements using code such as phx-click ="reset". | |
The first handle_event is responsible for responding to reset events. | |
The second handle event handles input to the modal. | |
Both handle_event functions submit data to the database | |
""" | |
def handle_event("reset", %{"id" => id}, socket) do | |
testbed = TestBeds.get_test_bed!(id) | |
StatusActions.create_status_action(%{ | |
testbed_name: testbed.name, | |
testbed_value: id, | |
status: "Available", | |
developer: testbed.developer | |
}) | |
TestBeds.get_test_bed!(id) | |
|> TestBeds.update_test_bed(%{status: "Available", developer: "None"}) | |
# {:noreply, socket} | |
{:noreply, assign(socket, testbeds: TestBeds.list_testbeds())} | |
end | |
def handle_event("get_localstorage", %{"developer" => developer}, socket) do | |
{:noreply, assign(socket, developer: developer)} | |
end | |
def handle_event("create-status", params, socket) do | |
# Create Record | |
%{"status" => status, "testbed_id" => testbed_id, "developer" => developer} = params | |
stripped_developer = String.trim(developer) | |
if stripped_developer === "" || String.trim(developer) === "" || String.trim(developer) === "None" do | |
{:noreply, assign(socket, developer: developer, name_warning: " (can't be empty or set to None)")} | |
else | |
TestBeds.get_test_bed!(testbed_id) | |
|> TestBeds.update_test_bed(%{status: status, developer: developer}) | |
current_testbed = TestBeds.get_test_bed!(testbed_id) | |
StatusActions.create_status_action(%{ | |
testbed_name: current_testbed.name, | |
testbed_value: testbed_id, | |
status: status, | |
developer: developer | |
}) | |
{:noreply, assign(socket, developer: developer)} | |
end | |
end | |
def handle_event("send", params, socket) do | |
IO.inspect"____________________________________________XYZ" | |
IO.inspect AppWeb.PageLive.create_timestamp | |
IO.inspect"______________________________________________" | |
IO.inspect params | |
eleID = params["id_data"] | |
is_note_important = params["is_note_important"] | |
note_data = params["data"] | |
# IO.inspect(eleID) | |
if String.length(String.trim(note_data)) == 0 do | |
TestBeds.get_test_bed!(eleID) | |
|> TestBeds.update_test_bed(%{note: ""}) | |
else | |
TestBeds.get_test_bed!(eleID) | |
|> TestBeds.update_test_bed(%{note: note_data, note_date_creation: AppWeb.PageLive.create_timestamp }) | |
end | |
if is_note_important == nil do | |
TestBeds.get_test_bed!(eleID) | |
|> TestBeds.update_test_bed(%{is_note_important: false}) | |
else | |
TestBeds.get_test_bed!(eleID) | |
|> TestBeds.update_test_bed(%{is_note_important: true}) | |
end | |
%JS{} | |
|> JS.remove_class("active", to: "#preview_button_#{eleID}") | |
|> JS.add_class("hidden", to: "#preview_button_#{eleID}") | |
|> JS.remove_class("hidden", to: "#editing_button_#{eleID}") | |
|> JS.add_class("active", to: "#editing_button_#{eleID}") | |
|> JS.remove_class("active", to: "#editing_#{eleID}") | |
|> JS.add_class("hidden", to: "#editing_#{eleID}") | |
|> JS.remove_class("hidden", to: "#preview_#{eleID}") | |
|> JS.add_class("active", to: "#preview_#{eleID}") | |
{:noreply, redirect(socket, to: "/")} | |
end | |
def handle_event("manual-reset", _params, socket) do | |
# TestBeds.reset_testbeds(status: "Available") | |
TestBeds.reset_testbeds() | |
# File.write("timestamp.txt", DateTime.to_string(DateTime.utc_now())) | |
{:noreply, socket} | |
end | |
def handle_event("transmit-text", _params, socket) do | |
# Create Record | |
# IO.inspect(params) | |
{:noreply, socket} | |
end | |
@doc """ | |
a_timed_event schedules events at given interval. This is a test version. Ideally | |
at 12am each night testbeds reset | |
""" | |
def a_timed_event() do | |
TestBeds.reset_testbeds() | |
# TestBeds.reset_testbeds() | |
File.write("timestamp.txt", DateTime.to_string(DateTime.utc_now())) | |
# IO.inspect(data) | |
end | |
def button_event("invoke_editing", eleID) do | |
# IO.inspect(eleID) | |
%JS{} | |
|> JS.remove_class("active", to: "#editing_button_#{eleID}") | |
|> JS.add_class("hidden", to: "#editing_button_#{eleID}") | |
|> JS.remove_class("hidden", to: "#preview_button_#{eleID}") | |
|> JS.add_class("active", to: "#preview_button_#{eleID}") | |
|> JS.remove_class("active", to: "#preview_#{eleID}") | |
|> JS.add_class("hidden", to: "#preview_#{eleID}") | |
|> JS.remove_class("hidden", to: "#editing_#{eleID}") | |
|> JS.add_class("active", to: "#editing_#{eleID}") | |
end | |
def button_event("invoke_preview", eleID) do | |
# IO.inspect(eleID) | |
%JS{} | |
|> JS.remove_class("active", to: "#preview_button_#{eleID}") | |
|> JS.add_class("hidden", to: "#preview_button_#{eleID}") | |
|> JS.remove_class("hidden", to: "#editing_button_#{eleID}") | |
|> JS.add_class("active", to: "#editing_button_#{eleID}") | |
|> JS.remove_class("active", to: "#editing_#{eleID}") | |
|> JS.add_class("hidden", to: "#editing_#{eleID}") | |
|> JS.remove_class("hidden", to: "#preview_#{eleID}") | |
|> JS.add_class("active", to: "#preview_#{eleID}") | |
end | |
def sort_by(socket, field) do | |
atomParam = String.to_existing_atom(field) | |
if socket.assigns[:sort_direction] == false do | |
sorted_testbeds = Enum.sort_by(socket.assigns.testbeds, fn item -> Map.get(item, atomParam) end) | |
{:noreply, assign(socket, testbeds: sorted_testbeds, sort_direction: true, sort_field: atomParam)} | |
else | |
sorted_testbeds = Enum.sort_by(socket.assigns.testbeds, fn item -> Map.get(item, atomParam) end) | |
|> Enum.reverse() | |
{:noreply, assign(socket, testbeds: sorted_testbeds, sort_direction: false, sort_field: atomParam)} | |
end | |
end | |
def handle_event("sort_by_string", %{"field" => field}, socket) do | |
sort_by(socket, field) | |
end | |
def render(assigns) do | |
~H""" | |
<body class="bg-blue_body"> | |
<div class="flex flex-col bg-dark_blue_background mt-0"> | |
<div class=" sm:-mx-6 lg:-mx-12 "> | |
<div class="inline-block min-w-full sm:px-6 lg:px-8 bg-dark_blue_background pb-40 "> | |
<div class=""> | |
<table class="min-w-full text-left text-sm font-light "> | |
<div class="testbed-status-title text-3xl font-bold text-white py-3 "> | |
Testbed Status | |
<a href ="/status_actions"> | |
<.button class=" bg-[#800080] float-right mx-5 relative bottom-[10px]">[User Logs]</.button> | |
</a> | |
<!-- BEGIN Alerts --> | |
<%= for alert <- @alerts do %> | |
<%= if alert.enabled do %> | |
<div | |
class="bg-[#fff8c1fc] border-t-4 border-teal-500 rounded-b text-teal-900 px-4 py-3 shadow-md" | |
role="alert" | |
> | |
<div class="flex"> | |
<div class="py-1 px-2"> | |
<span class="relative flex h-3 w-3"> | |
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-sky-400 opacity-75"> | |
</span> | |
<span class="relative inline-flex rounded-full h-3 w-3 bg-yellow-300"> | |
</span> | |
</span> | |
</div> | |
<div> | |
<p class="font-bold text-base"> | |
<span class="font-bold text-base text-[#d3288c]">ALERT:</span> <%= alert.title %> | |
<span class="font-bold text-sm text-[#d3288c] block">Time of Alert: <span class="text-sm text-[#000]"><%= convert_time(alert.updated_at) %></span></span> | |
</p> | |
<p class="text-sm font-medium"> | |
<%= alert.content %> | |
</p> | |
</div> | |
</div> | |
</div> | |
<% end %> | |
<% end %> | |
<!-- END Alerts--> | |
</div> | |
<thead class=" font-medium "> | |
<tr class="bg-table_blue text-white "> | |
<th scope="col" class="px-6 rounded-l-full ">Group</th> | |
<th scope="col" class="px-6 text-center">Info</th> | |
<th scope="col" class="px-6 text-center">Testbed</th> | |
<th> | |
<div class="relative left-[20px] z-10 "> | |
<div class="info-button"> Core </div> | |
<span class="info-box-container"> | |
<span class="rounded-full bg-[#fff8c1fc]"> | |
<ul class="bg-[#fff8c1fc] text-black absolute w-[200px] left-[-80px] p-5 outline outline-[#e11d48] outline-1 font-medium"> | |
<div> Testbed Version Number</div> | |
<hr> | |
</ul> | |
</span> | |
</span> | |
</div> | |
</th> | |
<th> | |
<div class="relative left-[20px] z-10 "> | |
<div class="info-button"> F/W </div> | |
<span class="info-box-container"> | |
<span class="rounded-full bg-[#fff8c1fc]"> | |
<ul class="bg-[#fff8c1fc] text-black absolute w-[200px] left-[-80px] p-5 outline outline-[#e11d48] outline-1 font-medium"> | |
<div> Firmware Version</div> | |
<hr> | |
</ul> | |
</span> | |
</span> | |
</div> | |
</th> | |
<th> | |
<div class="relative left-[20px] z-10 "> | |
<div class="info-button"> DC </div> | |
<span class="info-box-container"> | |
<span class="rounded-full bg-[#fff8c1fc]"> | |
<ul class="bg-[#fff8c1fc] text-black absolute w-[200px] left-[-80px] p-5 outline outline-[#e11d48] outline-1 font-medium"> | |
<div> If Testbed is Data Center column shows "DC". Otherwise, left blank</div> | |
<hr> | |
</ul> | |
</span> | |
</span> | |
</div> | |
</th> | |
<th> | |
<div class="relative left-[20px] z-10 "> | |
<div class="info-button"> MS </div> | |
<span class="info-box-container"> | |
<span class="rounded-full bg-[#fff8c1fc]"> | |
<ul class="bg-[#fff8c1fc] text-black absolute w-[200px] left-[-80px] p-5 outline outline-[#e11d48] outline-1 font-medium"> | |
<div> If Testbed is Multisite this column shows MS. Otherwise, left blank.</div> | |
<hr> | |
</ul> | |
</span> | |
</span> | |
</div> | |
</th> | |
<th> | |
<div class="relative left-[15px] z-10 "> | |
<div class="info-button"> Mon </div> | |
<span class="info-box-container"> | |
<span class="rounded-full bg-[#fff8c1fc]"> | |
<ul class="bg-[#fff8c1fc] text-black absolute w-[200px] left-[-80px] p-5 outline outline-[#e11d48] outline-1 font-medium"> | |
<div> Associated Monitoring Dashboard Address. If applicable the column displays "Mon". Otherwise, left blank. To view the address value look under the "info" column</div> | |
<hr> | |
</ul> | |
</span> | |
</span> | |
</div> | |
</th> | |
<th> | |
<div class="relative left-[0px] z-10 "> | |
<div class="info-button" phx-click="sort_by_string" phx-value-field="hardware" > Hardware</div> | |
<span class="info-box-container"> | |
<span class="rounded-full bg-[#fff8c1fc]"> | |
<ul class="bg-[#fff8c1fc] text-black absolute w-[200px] left-[-80px] p-5 outline outline-[#e11d48] outline-1 font-medium"> | |
<div> Device Hardware type (gns3, sim, real, etc)</div> | |
<hr> | |
</ul> | |
</span> | |
</span> | |
</div> | |
</th> | |
<th scope="col" class="px-6 text-center">Note</th> | |
<%!-- <th scope="col" class="px-6 text-center ">Status</th> --%> | |
<th scope="col" class="px-6 text-center">Developer</th> | |
<th scope="col" class="px-6 text-center">Date</th> | |
<th scope="col" class="px-6 px-6 rounded-r-full text-center">Set Status</th> | |
<!-- <th scope="col" class="px-6 py-2 rounded-r-full">Clear</th> --> | |
</tr> | |
</thead> | |
<%!-- <%= for testbed <- Enum.sort_by(@testbeds , &("#{&1.group.name}#{&1.version}"), :asc) do %> --%> | |
<!-----------Loop through testbeds and perform conditional actions based on the state of data____Apply user event listeners to items--> | |
<%!-- <%= for testbed <- Enum.sort_by(@testbeds , &("#{&1.group.name},#{&1.name}"), :asc) do %> --%> | |
<%= for testbed <- @testbeds do %> | |
<tbody> | |
<tr class="transition duration-300 ease-in-out hover:bg-table_blue text-white"> | |
<td id={"testbed_group_color#{testbed.id}"}> | |
<div class={"outline-[#D1D1D1] outline outline-1 relative left-7 top-1 w-3 h-3 "} style={"background-color: #{testbed.group.color}"}></div> | |
</td> | |
<td> | |
<div class="relative left-[20px] z-10 "> | |
<a class="info-button" href= {"/testbeds/#{testbed.id}/edit"}><button>Info</button> </a> | |
<span class="info-box-container"> | |
<span class="rounded-full bg-[#fff8c1fc]"> | |
<ul class="bg-[#fff8c1fc] text-black absolute w-[260px] left-[50px] p-5 outline outline-[#e11d48] outline-1 font-medium"> | |
<li><b>Name:</b> <%= testbed.name %> </li> | |
<hr> | |
<li><b>Owner:</b> <%= testbed.owner %></li> | |
<hr> | |
<li><b>Group:</b> <%= testbed.group.name %></li> | |
<hr> | |
<li><b>Manager:</b> <%= testbed.manager%></li> | |
<hr> | |
<li> <b>vNetC Auto Upgrade:</b> <%= testbed.vnetc_auto_upgrade %></li> | |
<hr> | |
<li><b>Firmware Auto Upgrade: </b><%= testbed.firmware_auto_upgrade %></li> | |
<hr> | |
<li><b>Firmware Version: </b><%= testbed.firmware_version %></li> | |
<hr> | |
<li><b>Managed Out of Service: </b><%= testbed.managed_out_of_service %></li> | |
<hr> | |
<li><b>DB Backup: </b><%= testbed.db_backup %></li> | |
<hr> | |
<hr> | |
<li><b>Host: </b><%= testbed.host %></li> | |
<hr> | |
<hr> | |
<li><b>Monitoring: </b><%= testbed.monitoring%></li> | |
<hr> | |
</ul> | |
</span> | |
</span> | |
</div> | |
</td> | |
<td class="whitespace-nowrap px-6 font-medium text-center"> | |
<a | |
href={testbed.url} | |
target="_blank" | |
class="hover:bg-[#D48E22] focus-within:bg-blue-50/50 ease-in-out" | |
> | |
<%!-- <%= testbed.name %> --%> | |
<%= if testbed.managed_out_of_service do %> | |
<div class="bg-[#73808D] "><%= testbed.name %></div> | |
<% end %> | |
<%= if !testbed.managed_out_of_service do %> | |
<div ><%= testbed.name %></div> | |
<% end %> | |
</a> | |
</td> | |
<td id={"testbed_version_#{testbed.id}"} phx-hook="TestbedVersionHover" class="whitespace-nowrap px-6 testbed-version"> <%= testbed.version %></td> | |
<td id={"testbed_firmware_version#{testbed.id}"} phx-hook="TestbedOwnerHover" | |
class="whitespace-nowrap px-6 testbed-firmware_version"> <%= testbed.firmware_version %></td> | |
<td id={"testbed_datacenter#{testbed.id}"} | |
class="whitespace-nowrap px-6 testbed-datacenter"> | |
<%!-- <%= testbed.datacenter %> --%> | |
<%= if testbed.datacenter do %> | |
<p>DC</p> | |
<% else %> | |
<p></p> | |
<% end %> | |
</td> | |
<td id={"testbed_multisite#{testbed.id}"} | |
class="whitespace-nowrap px-6 testbed-multisite"> | |
<%!-- <%= testbed.multisite %> --%> | |
<%= if testbed.multisite do %> | |
<p>MS</p> | |
<% else %> | |
<p></p> | |
<% end %> | |
</td> | |
<td id={"testbed_monitoring#{testbed.id}"} | |
class="whitespace-nowrap px-6 testbed-monitoring"> | |
<%= if testbed.monitoring do %> | |
<div class="relative left-[-5px] z-10 "> | |
<div class="info-button"> Mon </div> | |
<span class="info-box-container"> | |
<span class="rounded-full bg-[#fff8c1fc]"> | |
<ul class="bg-[#fff8c1fc] text-black absolute w-[200px] left-[-80px] p-5 outline outline-[#e11d48] outline-1 font-medium"> | |
<div> <%= testbed.monitoring %> </div> | |
<hr> | |
</ul> | |
</span> | |
</span> | |
</div> | |
<% else %> | |
<p></p> | |
<% end %> | |
</td> | |
<td id={"testbed_hardware#{testbed.id}"} | |
class="whitespace-nowrap px-6 testbed-hardware"> | |
<%= if testbed.remote_desktop_connection_ip do %> | |
<div class="relative left-[-5px] z-10 "> | |
<div class="info-button"> <%= testbed.hardware%> </div> | |
<span class="info-box-container"> | |
<span class="rounded-full bg-[#fff8c1fc]"> | |
<ul class="bg-[#fff8c1fc] text-black absolute w-[200px] left-[-80px] p-5 outline outline-[#e11d48] outline-1 font-medium"> | |
<div> <%= testbed.remote_desktop_connection_ip %> </div> | |
<hr> | |
</ul> | |
</span> | |
</span> | |
</div> | |
<% else %> | |
<%= testbed.hardware%> | |
<% end %> | |
</td> | |
<%!-- <td id={"testbed_host#{testbed.id}"} | |
class="whitespace-nowrap px-6 testbed-host"> <%= testbed.host%></td>--%> | |
<.modal id={"modal-note#{testbed.id}"}> | |
<div class="text-black bg-amber-300 px-20 py-10 "> | |
<!-- <.button | |
phx-click={button_event("invoke_editing", testbed.id)} | |
id={"editing_button_#{testbed.id}"} | |
class="hidden bg-green-500" | |
> | |
Preview / Save | |
</.button> | |
--> <%!-- <div class="mark-as-important-container relative left-[450px] top-10 w-40" > | |
<form> | |
<div class="checkboxes"> | |
<label><input type="checkbox"> <span>Mark as Important!</span></label> | |
</div> | |
</form> | |
</div> --%> | |
<%!-- | |
position:relative | |
left: 400 px | |
top: 25px | |
--%> | |
<.button | |
phx-click={button_event("invoke_preview", testbed.id)} | |
id={"preview_button_#{testbed.id}"} | |
class="bg-green-500" | |
> | |
Quick Edit | |
</.button> | |
<h1 class="text-rose-800 text-4xl ">Add Note</h1> | |
<h1 class="text-rose-800 font-medium"> | |
<%= testbed.name %> | <%= testbed.version %> | |
</h1> | |
<h3 class="text-rose-800 font-medium"> | |
<%= AppWeb.PageLive.convert_time(testbed.updated_at) %> | |
</h3> | |
<p><%= testbed.note %></p> | |
<hr /> | |
<div id={"preview_#{testbed.id}"} class="hidden"> | |
<form phx-submit="send"> | |
<input value={testbed.id} name="id_data" hidden /> | |
<textarea value={testbed.note} name="data" class="w-full"><%=testbed.note%> </textarea> | |
<div class="mark-as-important-container relative left-[450px] top-10 w-40" > | |
<label><input type="checkbox" checked={testbed.is_note_important} name="is_note_important"> <span>Mark as Important!</span></label> | |
</div> | |
<.button type="submit" class="left-0 bg-red-600">SAVE WORK</.button> | |
</form> | |
</div> | |
</div> | |
</.modal> | |
<!-- END Workspace | |
--> | |
<div> | |
<%= if testbed.note do %> | |
<td phx-click={show_modal("modal-note#{testbed.id}")}> | |
<%= if testbed.is_note_important do %> | |
<div class="bg-[#fef7a6] text-center outline-8 outline-rose-600 w-48"> | |
<b class="text-[#6E0000] font-medium text-xs">Read Me! </b> | |
<p class="text-xs text-[#000] "><%=String.slice(testbed.note, 0, 35) %>...</p> | |
</div> | |
<% end %> | |
<%= if testbed.is_note_important == false do %> | |
<div class="bg-[#888da1] text-center outline-8 outline-rose-600"> | |
<b class="text-[#000] font-medium">Note</b> | |
<p class="text-xs text-[#000] "><%=String.slice(testbed.note, 0, 35) %>...</p> | |
</div> | |
<% end %> | |
</td> | |
<% end %> | |
<%= if !testbed.note do %> | |
<td | |
class="opacity-20 hover:bg-orange-400 z-40 hover:opacity-100 text-center " | |
phx-click={show_modal("modal-note#{testbed.id}")} | |
> | |
Add Note | |
</td> | |
<% end %> | |
</div> | |
<%!-- <%= if testbed.status == "Available" do %> | |
<td class="whitespace-nowrap px-6 relative"> | |
<span class=" font-bold text-teal-900 rounded-full bg-green-400 h-1 relative px-5"> | |
<%= testbed.status %> | |
</span> | |
</td> | |
<% end %> | |
<%= if testbed.status == "Frozen" do %> | |
<td class="whitespace-nowrap px-6 relative "> | |
<span class=" text-teal-900 font-bold rounded-full bg-teal-400 h-1 relative px-5"> | |
<%= testbed.status %> | |
</span> | |
</td> | |
<% end %> | |
<%= if testbed.status == "Taken" do %> | |
<td class="whitespace-nowrap px-6 relative "> | |
<span class=" font-bold text-red-900 rounded-full bg-rose-300 h-1 relative px-5"> | |
<%= testbed.status %> | |
</span> | |
</td> | |
<% end %> | |
<%= if testbed.status !=="Frozen" && testbed.status !=="Taken" && testbed.status !=="Available"do %> | |
<td class="whitespace-nowrap px-6 relative "> | |
<span class=" font-bold rounded-full bg-green-500 h-1 relative px-5"> | |
<%= testbed.status %> | |
</span> | |
</td> | |
<% end %> --%> | |
<td id={"testbed_developer_#{testbed.id}"} phx-hook="TestbedDeveloperHover" class="text-center whitespace-nowrap px-6 testbed-developer"> <%= testbed.developer %></td> | |
<%= if testbed.status == "Taken" || testbed.status == "Frozen" do %> | |
<td class="whitespace-nowrap px-6 text-center"> | |
<%= AppWeb.PageLive.convert_time(testbed.updated_at) %> | |
</td> | |
<% end %> | |
<%= if testbed.status == "Available" do %> | |
<td class="whitespace-nowrap px-6 text-center">NA</td> | |
<% end %> | |
<%= if testbed.status == "Available" do %> | |
<td class="whitespace-nowrap px-6 "> | |
<button | |
phx-click={show_modal("delete-modal-#{testbed.id}")} | |
value={testbed.id} | |
class="bg-[#5ddc8c] hover:bg-green-400 font-bold text-teal-900 px-4 border border-gray-400 rounded shadow " | |
> | |
Available | |
</button> | |
</td> | |
<% end %> | |
<%= if testbed.status != "Available" do %> | |
<%= if testbed.status == "Frozen" do %> | |
<td | |
phx-click={'reset'} | |
phx-value-id={testbed.id} | |
class="whitespace-nowrap px-6 py-4" | |
> | |
<button class="bg-teal-400 hover:bg-teal-200 text-teal-900 font-bold px-6 px-4 border border-black-400 rounded shadow "> | |
Frozen | |
</button> | |
</td> | |
<% end %> | |
<%= if testbed.status == "Taken" do %> | |
<td | |
phx-click={'reset'} | |
phx-value-id={testbed.id} | |
class="whitespace-nowrap px-6 py-4" | |
> | |
<button class="bg-rose-300 hover:bg-pink-400 text-red-900 font-bold px-7 border border-gray-400 rounded shadow "> | |
Taken | |
</button> | |
</td> | |
<% end %> | |
<%!-- <td | |
phx-click={'reset'} | |
phx-value-id={testbed.id} | |
class="whitespace-nowrap px-6 py-4" | |
> | |
<button class="bg-pink-500 hover:bg-blue-700 text-white font-bold px-6 rounded "> | |
Clear | |
</button> | |
</td> --%> | |
<% end %> | |
</tr> | |
<div class="modal-container"> | |
<.modal id={"delete-modal-#{testbed.id}"}> | |
<!-- Container --> | |
<!-- Login form --> | |
<div class="flex flex-wrap content-center justify-center bg-dark_blue_background text-white"> | |
<div class="w-72 mt-10"> | |
<!-- Heading --> | |
<small class="text-black-400 text-xl "> | |
You Are Reserving <%= testbed.name %> | |
</small> | |
<!-- Form --> | |
<form | |
class="mt-4" | |
phx-submit="create-status" | |
phx-hook="FormLocalStorageHook" | |
id={"local_storage_hoook-#{testbed.id}"} | |
> | |
<div class="mb-3"> | |
<div class="flex justify-center"></div> | |
</div> | |
<div class="mb-3 h-2"> | |
<input type="hidden" class="" value={testbed.id} name="testbed_id" /> | |
</div> | |
<div class="mb-6 "> | |
<p>Status</p> | |
<select | |
name="status" | |
id={"status-id-#{testbed.id}"} | |
class="rounded mt-2 text-cyan-800" | |
> | |
<option value="Taken">Taken</option> | |
<option value="Frozen">Frozen</option> | |
</select> | |
</div> | |
<div class="mb-3"> | |
<label class="mb-2 block font-semibold"> Your Name <span class="text-[#ffce57]"><%= @name_warning %></span></label> | |
<input | |
value={@developer} | |
name="developer" | |
type="text" | |
class="block w-full rounded-md border border-gray-300 focus:border-purple-700 focus:outline-none focus:ring-1 focus:ring-purple-700 py-1 px-1.5 text-gray-500" | |
/> | |
</div> | |
<div class="mb-3"> | |
<button phx-click={hide_modal("delete-modal-#{testbed.id}")} class="bg-sky-500/75 mb-1.5 block w-full text-center text-white bg-cyan-700 hover:bg-cyan-900 px-2 py-1.5 rounded-md"> | |
Reserve | |
</button> | |
</div> | |
</form> | |
</div> | |
</div> | |
</.modal> | |
</div> | |
</tbody> | |
<% end %> | |
</table> | |
</div> | |
</div> | |
</div> | |
</div> | |
</body> | |
""" | |
end | |
end | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment