Skip to content

Commit

Permalink
Added dataclips model using generator
Browse files Browse the repository at this point in the history
Finishes #8
  • Loading branch information
stuartc committed Feb 3, 2022
1 parent 55e2395 commit 2673b24
Show file tree
Hide file tree
Showing 16 changed files with 598 additions and 2 deletions.
125 changes: 125 additions & 0 deletions lib/lightning/invocation.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
defmodule Lightning.Invocation do
@moduledoc """
The Invocation context.
"""

import Ecto.Query, warn: false
alias Lightning.Repo

alias Lightning.Invocation.Dataclip

@doc """
Returns the list of dataclips.
## Examples
iex> list_dataclips()
[%Dataclip{}, ...]
"""
def list_dataclips do
Repo.all(Dataclip)
end

@doc """
Gets a single dataclip.
Raises `Ecto.NoResultsError` if the Dataclip does not exist.
## Examples
iex> get_dataclip!(123)
%Dataclip{}
iex> get_dataclip!(456)
** (Ecto.NoResultsError)
"""
def get_dataclip!(id), do: Repo.get!(Dataclip, id)

@doc """
Creates a dataclip.
## Examples
iex> create_dataclip(%{field: value})
{:ok, %Dataclip{}}
iex> create_dataclip(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_dataclip(attrs \\ %{}) do
%Dataclip{}
|> Dataclip.changeset(attrs |> coerce_json_body())
|> Repo.insert()
end

@doc """
Updates a dataclip.
## Examples
iex> update_dataclip(dataclip, %{field: new_value})
{:ok, %Dataclip{}}
iex> update_dataclip(dataclip, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_dataclip(%Dataclip{} = dataclip, attrs) do
dataclip
|> Dataclip.changeset(attrs |> coerce_json_body())
|> Repo.update()
end

@doc """
Deletes a dataclip.
## Examples
iex> delete_dataclip(dataclip)
{:ok, %Dataclip{}}
iex> delete_dataclip(dataclip)
{:error, %Ecto.Changeset{}}
"""
def delete_dataclip(%Dataclip{} = dataclip) do
Repo.delete(dataclip)
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking dataclip changes.
## Examples
iex> change_dataclip(dataclip)
%Ecto.Changeset{data: %Dataclip{}}
"""
def change_dataclip(%Dataclip{} = dataclip, attrs \\ %{}) do
Dataclip.changeset(dataclip, attrs |> coerce_json_body())
end

defp coerce_json_body(attrs) do
{_, attrs} =
Map.get_and_update(attrs, "body", fn body ->
case body do
nil ->
:pop

body when is_binary(body) ->
case Jason.decode(body) do
{:error, _} -> {body, body}
{:ok, body_map} -> {body, body_map}
end

any ->
{body, any}
end
end)

attrs
end
end
20 changes: 20 additions & 0 deletions lib/lightning/invocation/dataclip.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
defmodule Lightning.Invocation.Dataclip do
use Ecto.Schema
import Ecto.Changeset

@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "dataclips" do
field :body, :map
field :type, Ecto.Enum, values: [:http_request, :global]

timestamps()
end

@doc false
def changeset(dataclip, attrs) do
dataclip
|> cast(attrs, [:body, :type])
|> validate_required([:body, :type])
end
end
1 change: 1 addition & 0 deletions lib/lightning_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ defmodule LightningWeb do
import Phoenix.View

import LightningWeb.ErrorHelpers
import LightningWeb.FormHelpers
import LightningWeb.Gettext
alias LightningWeb.Router.Helpers, as: Routes

Expand Down
55 changes: 55 additions & 0 deletions lib/lightning_web/live/dataclip_live/form_component.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
defmodule LightningWeb.DataclipLive.FormComponent do
use LightningWeb, :live_component

alias Lightning.Invocation

@impl true
def update(%{dataclip: dataclip} = assigns, socket) do
changeset = Invocation.change_dataclip(dataclip)

{:ok,
socket
|> assign(assigns)
|> assign(:changeset, changeset)}
end

@impl true
def handle_event("validate", %{"dataclip" => dataclip_params}, socket) do
changeset =
socket.assigns.dataclip
|> Invocation.change_dataclip(dataclip_params)
|> Map.put(:action, :validate)

{:noreply, assign(socket, :changeset, changeset)}
end

def handle_event("save", %{"dataclip" => dataclip_params}, socket) do
save_dataclip(socket, socket.assigns.action, dataclip_params)
end

defp save_dataclip(socket, :edit, dataclip_params) do
case Invocation.update_dataclip(socket.assigns.dataclip, dataclip_params) do
{:ok, _dataclip} ->
{:noreply,
socket
|> put_flash(:info, "Dataclip updated successfully")
|> push_redirect(to: socket.assigns.return_to)}

{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, :changeset, changeset)}
end
end

defp save_dataclip(socket, :new, dataclip_params) do
case Invocation.create_dataclip(dataclip_params) do
{:ok, _dataclip} ->
{:noreply,
socket
|> put_flash(:info, "Dataclip created successfully")
|> push_redirect(to: socket.assigns.return_to)}

{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, changeset: changeset)}
end
end
end
24 changes: 24 additions & 0 deletions lib/lightning_web/live/dataclip_live/form_component.html.heex
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<div>
<h2><%= @title %></h2>

<.form
let={f}
for={@changeset}
id="dataclip-form"
phx-target={@myself}
phx-change="validate"
phx-submit="save">

<%= label f, :body %>
<%= textarea f, :body %>
<%= error_tag f, :body %>

<%= label f, :type %>
<%= select f, :type, Ecto.Enum.values(Lightning.Invocation.Dataclip, :type), prompt: "Choose a value" %>
<%= error_tag f, :type %>

<div>
<%= submit "Save", phx_disable_with: "Saving..." %>
</div>
</.form>
</div>
46 changes: 46 additions & 0 deletions lib/lightning_web/live/dataclip_live/index.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
defmodule LightningWeb.DataclipLive.Index do
use LightningWeb, :live_view

alias Lightning.Invocation
alias Lightning.Invocation.Dataclip

@impl true
def mount(_params, _session, socket) do
{:ok, assign(socket, :dataclips, list_dataclips()) |> assign(:active_menu_item, :dataclips)}
end

@impl true
def handle_params(params, _url, socket) do
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
end

defp apply_action(socket, :edit, %{"id" => id}) do
socket
|> assign(:page_title, "Edit Dataclip")
|> assign(:dataclip, Invocation.get_dataclip!(id))
end

defp apply_action(socket, :new, _params) do
socket
|> assign(:page_title, "New Dataclip")
|> assign(:dataclip, %Dataclip{})
end

defp apply_action(socket, :index, _params) do
socket
|> assign(:page_title, "Listing Dataclips")
|> assign(:dataclip, nil)
end

@impl true
def handle_event("delete", %{"id" => id}, socket) do
dataclip = Invocation.get_dataclip!(id)
{:ok, _} = Invocation.delete_dataclip(dataclip)

{:noreply, assign(socket, :dataclips, list_dataclips())}
end

defp list_dataclips do
Invocation.list_dataclips()
end
end
45 changes: 45 additions & 0 deletions lib/lightning_web/live/dataclip_live/index.html.heex
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<MainSection.header title="Dataclips" />

<MainSection.main>


<%= if @live_action in [:new, :edit] do %>
<.modal return_to={Routes.dataclip_index_path(@socket, :index)}>
<.live_component
module={LightningWeb.DataclipLive.FormComponent}
id={@dataclip.id || :new}
title={@page_title}
action={@live_action}
dataclip={@dataclip}
return_to={Routes.dataclip_index_path(@socket, :index)}
/>
</.modal>
<% end %>

<table>
<thead>
<tr>
<th>Body</th>
<th>Type</th>

<th></th>
</tr>
</thead>
<tbody id="dataclips">
<%= for dataclip <- @dataclips do %>
<tr id={"dataclip-#{dataclip.id}"}>
<td><%= dataclip.body %></td>
<td><%= dataclip.type %></td>

<td>
<span><%= live_redirect "Show", to: Routes.dataclip_show_path(@socket, :show, dataclip) %></span>
<span><%= live_patch "Edit", to: Routes.dataclip_index_path(@socket, :edit, dataclip) %></span>
<span><%= link "Delete", to: "#", phx_click: "delete", phx_value_id: dataclip.id, data: [confirm: "Are you sure?"] %></span>
</td>
</tr>
<% end %>
</tbody>
</table>

<span><%= live_patch "New Dataclip", to: Routes.dataclip_index_path(@socket, :new) %></span>
</MainSection.main>
21 changes: 21 additions & 0 deletions lib/lightning_web/live/dataclip_live/show.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule LightningWeb.DataclipLive.Show do
use LightningWeb, :live_view

alias Lightning.Invocation

@impl true
def mount(_params, _session, socket) do
{:ok, socket}
end

@impl true
def handle_params(%{"id" => id}, _, socket) do
{:noreply,
socket
|> assign(:page_title, page_title(socket.assigns.live_action))
|> assign(:dataclip, Invocation.get_dataclip!(id))}
end

defp page_title(:show), do: "Show Dataclip"
defp page_title(:edit), do: "Edit Dataclip"
end
31 changes: 31 additions & 0 deletions lib/lightning_web/live/dataclip_live/show.html.heex
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<h1>Show Dataclip</h1>

<%= if @live_action in [:edit] do %>
<.modal return_to={Routes.dataclip_show_path(@socket, :show, @dataclip)}>
<.live_component
module={LightningWeb.DataclipLive.FormComponent}
id={@dataclip.id}
title={@page_title}
action={@live_action}
dataclip={@dataclip}
return_to={Routes.dataclip_show_path(@socket, :show, @dataclip)}
/>
</.modal>
<% end %>

<ul>

<li>
<strong>Body:</strong>
<%= @dataclip.body %>
</li>

<li>
<strong>Type:</strong>
<%= @dataclip.type %>
</li>

</ul>

<span><%= live_patch "Edit", to: Routes.dataclip_show_path(@socket, :edit, @dataclip), class: "button" %></span> |
<span><%= live_redirect "Back", to: Routes.dataclip_index_path(@socket, :index) %></span>
7 changes: 7 additions & 0 deletions lib/lightning_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ defmodule LightningWeb.Router do
live "/jobs/:id", JobLive.Show, :show
live "/jobs/:id/edit", JobLive.Edit, :edit
# live "/jobs/:id/show/edit", JobLive.Show, :edit

live "/dataclips", DataclipLive.Index, :index
live "/dataclips/new", DataclipLive.Index, :new
live "/dataclips/:id/edit", DataclipLive.Index, :edit

live "/dataclips/:id", DataclipLive.Show, :show
live "/dataclips/:id/show/edit", DataclipLive.Show, :edit
end

# Other scopes may use custom stacks.
Expand Down

0 comments on commit 2673b24

Please sign in to comment.