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

View File

@ -5,6 +5,34 @@ require "../funko.cr"
module Funko
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|
funkos = Funko.from_docker
funkos.sort! { |a, b| a.name <=> b.name }

View File

@ -173,6 +173,18 @@ module Funko
}
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
def unpause
docker_api = Docr::API.new(Docr::Client.new)
@ -192,17 +204,54 @@ module Funko
}
end
# Restart exited container with the newer image
# Start exited container with the newer image
# or unpause paused container
def start
# FIXME refactor DRY with unpause
if self.exited?
docker_api = Docr::API.new(Docr::Client.new)
images = self.image_history
exited = self.containers.select { |container|
container.@state == "exited"
}.sort! { |i, j|
(images.index(j.@image_id) || 9999) <=> (images.index(i.@image_id) || 9999)
}
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
exited = self.containers.select { |container|
container.@state == "exited"
}.sort! { |i, j|
containers = self.containers.sort! { |i, j|
(images.index(j.@image_id) || 9999) <=> (images.index(i.@image_id) || 9999)
}
docker_api.containers.restart(exited[0].@id) unless exited.empty?
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
# Create a container for this funko

View File

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