Frontend buttons to operate on funkos work, they show feedback, they refresh after they finish their request

This commit is contained in:
Roberto Alsina 2024-07-02 22:20:12 -03:00
parent 91466db97e
commit fcd597c143
4 changed files with 120 additions and 34 deletions

View File

@ -4,22 +4,30 @@
<link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css" /> <link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css" />
<script src="https://unpkg.com/htmx.org@2.0.0"></script> <script src="https://unpkg.com/htmx.org@2.0.0"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<body> </head>
<body>
<header class="container"> <header class="container">
<h1>Your Funko Collection</h1> <h1>Your Funko Collection</h1>
</header> </header>
<main class=container> <main class=container>
<button hx-get="funkos/?format=html" hx-target="#funko-list">Update</button> <span id="message"></span>
<table> <table hx-target="#message">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Status</th> <th>Status</th>
<th>Action</th> <th>Action</th>
</tr> </tr>
</thead>
<tbody id="funko-list"> <tbody id="funko-list">
</tbody> </tbody>
</thead> </table>
<button id="update-funkos" style="float:right;" hx-trigger="load, click" hx-get="funkos/?format=html"
hx-target="#funko-list">Update</button>
</main> </main>
</body> <script>
</head> update_funkos =function() {
document.getElementById("update-funkos").click()
}
</script>
</body>

View File

@ -5,6 +5,34 @@ require "../funko.cr"
module Funko module Funko
extend self extend self
get "/funkos/:name/pause/" do |env|
funko = Funko.from_names([env.params.url["name"]])[0]
funko.pause
funko.wait_for("paused", 5)
end
get "/funkos/:name/unpause/" do |env|
funko = Funko.from_names([env.params.url["name"]])[0]
funko.unpause
funko.wait_for("running", 5)
end
get "/funkos/:name/start/" do |env|
funko = Funko.from_names([env.params.url["name"]])[0]
funko.start
funko.wait_for("running", 5)
end
get "/funkos/:name/stop/" do |env|
funko = Funko.from_names([env.params.url["name"]])[0]
begin
funko.stop
funko.wait_for("exited", 5)
rescue ex : Docr::Errors::DockerAPIError
halt env, status_code: 500, response: "Failed to stop container"
end
end
get "/funkos/" do |env| get "/funkos/" do |env|
funkos = Funko.from_docker funkos = Funko.from_docker
funkos.sort! { |a, b| a.name <=> b.name } funkos.sort! { |a, b| a.name <=> b.name }

View File

@ -173,6 +173,18 @@ module Funko
} }
end end
# Pause running container
def pause
docker_api = Docr::API.new(Docr::Client.new)
images = self.image_history
running = self.containers.select { |container|
container.@state == "running"
}.sort! { |i, j|
(images.index(j.@image_id) || 9999) <=> (images.index(i.@image_id) || 9999)
}
docker_api.containers.pause(running[0].@id) unless running.empty?
end
# Unpause paused container with the newer image # Unpause paused container with the newer image
def unpause def unpause
docker_api = Docr::API.new(Docr::Client.new) docker_api = Docr::API.new(Docr::Client.new)
@ -192,9 +204,10 @@ module Funko
} }
end end
# Restart exited container with the newer image # Start exited container with the newer image
# or unpause paused container
def start def start
# FIXME refactor DRY with unpause if self.exited?
docker_api = Docr::API.new(Docr::Client.new) docker_api = Docr::API.new(Docr::Client.new)
images = self.image_history images = self.image_history
exited = self.containers.select { |container| exited = self.containers.select { |container|
@ -203,6 +216,42 @@ module Funko
(images.index(j.@image_id) || 9999) <=> (images.index(i.@image_id) || 9999) (images.index(j.@image_id) || 9999) <=> (images.index(i.@image_id) || 9999)
} }
docker_api.containers.restart(exited[0].@id) unless exited.empty? docker_api.containers.restart(exited[0].@id) unless exited.empty?
elsif self.paused?
self.unpause
end
end
# Stop container with the newer image
def stop
docker_api = Docr::API.new(Docr::Client.new)
images = self.image_history
containers = self.containers.sort! { |i, j|
(images.index(j.@image_id) || 9999) <=> (images.index(i.@image_id) || 9999)
}
return docker_api.containers.stop(containers[0].@id) unless containers.empty?
nil
end
# Wait up to `t` seconds for the funko to reach the requested `state`
def wait_for(state : String, t)
channel = Channel(Nil).new
spawn do
sleep 0.1.seconds
case state
when "exited"
if self.exited?
channel.send(nil)
end
when "running"
if self.running?
channel.send(nil)
end
when "paused"
if self.paused?
channel.send(nil)
end
end
end
end end
# Create a container for this funko # Create a container for this funko

View File

@ -1,5 +1,5 @@
<%- result.each do |f| -%> <%- result.each do |f| -%>
<tr> <tr hx-indicator="#spinner-<%= f["name"] %>">
<td><%= f["name"] %></td> <td><%= f["name"] %></td>
<%- if f["name"] == "proxy" -%> <%- if f["name"] == "proxy" -%>
<td>Running</td> <td>Running</td>
@ -10,24 +10,25 @@
<%- if f["name"] == "proxy" -%> <%- if f["name"] == "proxy" -%>
<%- else -%> <%- else -%>
<%- if f["state"] == "running" -%> <%- if f["state"] == "running" -%>
<button disabled>Start</button> <button disabled hx-get="funkos/<%= f["name"] %>/start">Start</button>
<button>Pause</button> <button hx-get="funkos/<%= f["name"] %>/pause" hx-on:htmx:after-request="update_funkos()">Pause</button>
<button>Stop</button> <button hx-get="funkos/<%= f["name"] %>/stop" hx-on:htmx:after-request="update_funkos()">Stop</button>
<button>Restart</button> <button hx-get="funkos/<%= f["name"] %>/restart" hx-on:htmx:after-request="update_funkos()">Restart</button>
<%- end -%> <%- end -%>
<%- if f["state"] == "paused" -%> <%- if f["state"] == "paused" -%>
<button>Start</button> <button hx-get="funkos/<%= f["name"] %>/start" hx-on:htmx:after-request="update_funkos()">Start</button>
<button disabled>Pause</button> <button disabled hx-get="funkos/<%= f["name"] %>/pause">Pause</button>
<button>Stop</button> <button hx-get="funkos/<%= f["name"] %>/stop" hx-on:htmx:after-request="update_funkos()">Stop</button>
<button>Restart</button> <button hx-get="funkos/<%= f["name"] %>/restart" hx-on:htmx:after-request="update_funkos()">Restart</button>
<%- end -%> <%- end -%>
<%- if f["state"] == "stopped" -%> <%- if f["state"] == "stopped" -%>
<button>Start</button> <button hx-get="funkos/<%= f["name"] %>/start" hx-on:htmx:after-request="update_funkos()">Start</button>
<button disabled>Pause</button> <button disabled hx-get="funkos/<%= f["name"] %>/pause">Pause</button>
<button disabled>Stop</button> <button disabled hx-get="funkos/<%= f["name"] %>/stop">Stop</button>
<button disabled>Restart</button> <button disabled hx-get="funkos/<%= f["name"] %>/restart">Restart</button>
<%- end -%> <%- end -%>
<%- end -%> <%- end -%>
<img id="spinner-<%= f["name"] %>" src="https://htmx.org/img/bars.svg" class="htmx-indicator">
</td> </td>
</tr> </tr>
<%- end -%> <%- end -%>