Commit cd7b716c authored by Hannu Hartikainen's avatar Hannu Hartikainen

Implement deactivating machines (instead of deleting)

Resolves #3.
parent 34c0e520
defmodule CodeStats.Repo.Migrations.AddMachineActiveFlag do
use Ecto.Migration
def change do
alter table(:machines) do
add :active, :boolean, default: true, null: false
end
end
end
......@@ -96,6 +96,28 @@ defmodule CodeStats.MachineController do
end
end
def deactivate(conn, %{"id" => id}) do
activate_or_deactivate(conn, id, false)
end
def activate(conn, %{"id" => id}) do
activate_or_deactivate(conn, id, true)
end
defp activate_or_deactivate(conn, id, active) do
user = SetSessionUser.get_user_data(conn)
verb = if active, do: "activated", else: "deactivated"
with %Machine{} = machine <- get_machine_or_404(conn, user, id),
changeset = Machine.activation_changeset(machine, %{active: active}),
%Machine{} = machine <- edit_machine_or_flash(conn, changeset)
do
conn
|> put_flash(:success, "Machine #{machine.name} #{verb}.")
|> redirect(to: machine_path(conn, :list))
end
end
defp common_assigns(conn) do
user = SetSessionUser.get_user_data(conn)
conn = conn
......
......@@ -4,6 +4,7 @@ defmodule CodeStats.Machine do
schema "machines" do
field :name, :string
field :api_salt, :string
field :active, :boolean
belongs_to :user, CodeStats.User
has_many :pulses, CodeStats.Pulse
......@@ -22,6 +23,7 @@ defmodule CodeStats.Machine do
|> cast(params, [:name])
|> name_validations()
|> put_change(:api_salt, generate_api_salt())
|> put_change(:active, true)
end
def update_changeset(data, params \\ %{}) do
......@@ -30,6 +32,11 @@ defmodule CodeStats.Machine do
|> name_validations()
end
def activation_changeset(data, params \\ %{}) do
data
|> cast(params, [:active])
end
@doc """
Creates a changeset to regenerate the API salt of the Machine.
......
......@@ -74,6 +74,8 @@ defmodule CodeStats.Router do
get "/machines/:id", MachineController, :view_single
put "/machines/:id", MachineController, :edit
delete "/machines/:id", MachineController, :delete
post "/machines/:id/activate", MachineController, :activate
post "/machines/:id/deactivate", MachineController, :deactivate
post "/machines/:id/key", MachineController, :regen_machine_key
end
end
......
......@@ -8,21 +8,16 @@
'copy'
'regen'
'edit'
'deact'
'delete'
/ 1fr;
grid-gap: 20px;
@media #{$sm} {
grid-template: 'name name name name '
'key key key key '
'copy regen edit delete'
/ auto auto auto auto;
}
@media #{$lg} {
grid-template: 'name name name name name '
'key copy regen edit delete'
/ 1fr auto auto auto auto;
grid-template: 'name name name name '
'key key key copy '
'regen edit deact delete'
/ 1fr 1fr 1fr 1fr;
}
>h2 {
......@@ -54,6 +49,10 @@
grid-area: regen;
}
>.deactivate-form {
grid-area: deact;
}
>.delete-form {
grid-area: delete;
}
......@@ -64,3 +63,12 @@
}
}
}
.inactive-machine-list {
>.machine {
display: grid;
grid-template-columns: 1fr auto;
margin-bottom: 1rem;
align-items: center;
}
}
......@@ -4,14 +4,20 @@
function machine_page() {
document.addEventListener('DOMContentLoaded', () => {
const buttons = document.getElementsByClassName('machine-delete-button');
const delete_buttons = document.getElementsByClassName('machine-delete-button');
for (const button of buttons) {
for (const button of delete_buttons) {
button.onclick = () => {
return confirm('Are you sure you wish to delete this machine? You will lose all XP associated with it.');
};
}
const deactivate_buttons = document.getElementsByClassName('machine-deactivate-button');
for (const button of deactivate_buttons) {
button.onclick = () => confirm('Are you sure you wish to deactivate this machine? It will be hidden, but can be re-activated.');
}
const copy_buttons = document.getElementsByClassName('copy-button');
for (const button of copy_buttons) {
......
......@@ -2,7 +2,7 @@
<h1>Configured machines</h1>
<div class="machine-list">
<%= for machine <- @machines do %>
<%= for %{active: true} = machine <- @machines do %>
<div class="machine">
<h2><%= machine.name %></h2>
<div class="api-key-text">
......@@ -20,6 +20,10 @@
<button type="submit" class="button-warning">Regenerate API key</button>
</form>
<%= form_tag(machine_path(@conn, :deactivate, machine.id), class: "deactivate-form") %>
<button type="submit" class="button-danger machine-deactivate-button">Deactivate</button>
</form>
<%= form_tag(machine_path(@conn, :delete, machine.id), method: :delete, class: "delete-form") %>
<button type="submit" class="button-danger machine-delete-button">Delete</button>
</form>
......@@ -51,4 +55,16 @@
<div class="submit"><%= submit("Add machine") %></div>
<% end) %>
<%= if Enum.any?(@machines, &match?(%{active: false}, &1)) do %>
<div class="inactive-machine-list">
<h2>Inactive machines</h2>
<%= for %{active: false} = machine <- @machines do %>
<%= form_tag(machine_path(@conn, :activate, machine.id), class: "machine") %>
<div class="machine-name"><%= machine.name %></div>
<button type="submit">Activate</button>
</form>
<% end %>
</div>
<% end %>
</div>
......@@ -252,7 +252,8 @@ defmodule CodeStats.AuthUtils do
defp get_machine(machine_id, user) do
query = from m in Machine,
where: m.id == ^machine_id and
m.user_id == ^user.id
m.user_id == ^user.id and
m.active == true
Repo.one(query)
end
......
......@@ -66,7 +66,9 @@ defmodule CodeStats.ProfileUtils do
new_xps_q = from m in Machine,
join: p in Pulse, on: m.id == p.machine_id,
join: x in XP, on: p.id == x.pulse_id,
where: m.user_id == ^user.id and p.sent_at >= ^then,
where: m.user_id == ^user.id and
p.sent_at >= ^then and
m.active == true,
group_by: m.id,
order_by: [desc: sum(x.amount)],
select: {m, sum(x.amount)}
......@@ -100,7 +102,8 @@ defmodule CodeStats.ProfileUtils do
machine_xps = Map.to_list(machine_xps)
machine_q = from m in Machine,
where: m.user_id == ^user.id,
where: m.user_id == ^user.id and
m.active == true,
select: {m.id, m}
machines = Repo.all(machine_q) |> Map.new()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment