Skip to content

Commit

Permalink
Merge pull request #531 from eyra/feldspar-loading
Browse files Browse the repository at this point in the history
Feldspar loading
  • Loading branch information
mellelieuwes authored Dec 21, 2023
2 parents e986074 + 64db9a5 commit f7a5cb6
Show file tree
Hide file tree
Showing 15 changed files with 145 additions and 35 deletions.
Binary file added core/assets/static/images/icons/loading.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added core/assets/static/images/icons/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions core/frameworks/fabric.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ defmodule Fabric do

require Logger

def reset_fabric(%Phoenix.LiveView.Socket{} = socket) do
reset_children(socket)
end

def compose_element(%Phoenix.LiveView.Socket{assigns: assigns} = socket, element_id)
when is_atom(element_id) do
%Phoenix.LiveView.Socket{socket | assigns: compose_element(assigns, element_id)}
Expand Down Expand Up @@ -75,6 +79,7 @@ defmodule Fabric do

def child_id(%{id: id}, child_name), do: child_id(id, child_name)
def child_id(context, child_name), do: "#{child_name}->#{context}"

# Prepare

def prepare_child(context, child_name, %{module: module, params: params}) do
Expand Down Expand Up @@ -119,6 +124,15 @@ defmodule Fabric do
%Fabric.Model{fabric | children: children}
end

# Reset
def reset_children(%Phoenix.LiveView.Socket{assigns: %{fabric: fabric}} = socket) do
Phoenix.Component.assign(socket, fabric: reset_children(fabric))
end

def reset_children(%Fabric.Model{} = fabric) do
%Fabric.Model{fabric | children: []}
end

# CRUD

def get_child(%Phoenix.LiveView.Socket{assigns: %{fabric: fabric}}, child_name) do
Expand Down
14 changes: 12 additions & 2 deletions core/frameworks/pixel/components/button_face.ex
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,21 @@ defmodule Frameworks.Pixel.Button.Face do
attr(:label, :string, required: true)
attr(:bg_color, :string, default: "bg-primary")
attr(:text_color, :string, default: "text-white")
attr(:loading, :boolean, default: false)

def primary(assigns) do
~H"""
<div class={"pt-15px pb-15px active:shadow-top4px active:pt-4 active:pb-14px leading-none font-button text-button rounded pr-4 pl-4 #{@bg_color} #{@text_color}"}>
<%= @label %>
<div class="relative">
<div class={"flex flex-col items-center leading-none font-button text-button rounded cursor-pointer active:shadow-top4px #{@bg_color} #{@text_color}"}>
<div class={"pt-15px pb-15px pr-4 pl-4 active:pt-4 active:pb-14px #{if @loading do "opacity-0" else "" end}"}>
<%= @label %>
</div>
</div>
<div class={"absolute z-100 top-0 h-full w-full flex flex-col justify-center items-center #{if @loading do "block" else "hidden" end}"}>
<div class="w-6 h-6 animate-spin">
<img src={~p"/images/icons/[email protected]"} alt={"Loading"}>
</div>
</div>
</div>
"""
end
Expand Down
2 changes: 1 addition & 1 deletion core/priv/gettext/nl/LC_MESSAGES/eyra-assignment.po
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ msgstr "Taken"

#, elixir-autogen, elixir-format
msgid "intro.page.title"
msgstr "Introductie"
msgstr "Informatie"

#, elixir-autogen, elixir-format, fuzzy
msgid "intro_form.off.label"
Expand Down
82 changes: 71 additions & 11 deletions core/systems/assignment/crew_work_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ defmodule Systems.Assignment.CrewWorkView do
},
socket
) do
tool_started = Map.get(socket.assigns, :tool_started, false)
tool_initialized = Map.get(socket.assigns, :tool_initialized, false)

{
:ok,
socket
Expand All @@ -39,18 +42,30 @@ defmodule Systems.Assignment.CrewWorkView do
support_page_ref: support_page_ref,
crew: crew,
user: user,
panel_info: panel_info
panel_info: panel_info,
tool_started: tool_started,
tool_initialized: tool_initialized
)
|> update_selected_item_id()
|> update_selected_item()
|> compose_child(:work_list_view)
|> compose_child(:start_view)
|> compose_child(:context_menu)
|> update_child(:tool_ref_view)
|> update_tool_ref_view()
|> update_child(:finished_view)
}
end

defp update_tool_ref_view(%{assigns: %{selected_item_id: selected_item_id}} = socket) do
case Fabric.get_child(socket, :tool_ref_view) do
%{params: %{work_item: {%{id: id}, _}}} when id == selected_item_id ->
socket

_ ->
compose_child(socket, :tool_ref_view)
end
end

defp update_selected_item_id(
%{assigns: %{work_items: work_items, selected_item_id: selected_item_id}} = socket
)
Expand Down Expand Up @@ -92,8 +107,19 @@ defmodule Systems.Assignment.CrewWorkView do
# Compose

@impl true
def compose(:start_view, %{selected_item: selected_item}) when not is_nil(selected_item) do
%{module: Assignment.StartView, params: %{work_item: selected_item}}
def compose(:start_view, %{
selected_item: selected_item,
tool_started: tool_started,
tool_initialized: tool_initialized
})
when not is_nil(selected_item) do
%{
module: Assignment.StartView,
params: %{
work_item: selected_item,
loading: tool_started and not tool_initialized
}
}
end

@impl true
Expand Down Expand Up @@ -178,6 +204,18 @@ defmodule Systems.Assignment.CrewWorkView do

# Events

def handle_event("tool_initialized", _, %{assign: %{tool_started: true}} = socket) do
{
:noreply,
socket
|> assign(tool_initialized: true)
}
end

def handle_event("tool_initialized", _, socket) do
{:noreply, socket}
end

@impl true
def handle_event(
"complete_task",
Expand All @@ -192,7 +230,11 @@ defmodule Systems.Assignment.CrewWorkView do
{
:noreply,
socket
|> hide_child(:tool_ref_view)
|> assign(
tool_started: false,
tool_initialized: false
)
|> compose_child(:tool_ref_view)
|> handle_finished_state()
}
end
Expand All @@ -208,10 +250,15 @@ defmodule Systems.Assignment.CrewWorkView do
{
:noreply,
socket
|> assign(selected_item_id: item_id)
|> assign(
tool_initialized: false,
tool_started: false,
selected_item_id: item_id
)
|> update_selected_item()
|> update_child(:start_view)
|> compose_child(:start_view)
|> update_child(:work_list_view)
|> compose_child(:tool_ref_view)
}
end

Expand All @@ -220,7 +267,7 @@ defmodule Systems.Assignment.CrewWorkView do
{
:noreply,
socket
|> compose_child(:tool_ref_view)
|> assign(tool_started: true)
|> lock_task(task)
}
end
Expand Down Expand Up @@ -299,7 +346,9 @@ defmodule Systems.Assignment.CrewWorkView do

socket =
if Enum.count(work_items) > 1 do
hide_child(socket, :tool_ref_view)
socket
|> assign(tool_started: false, tool_initialized: false)
|> hide_child(:tool_ref_view)
else
socket
end
Expand All @@ -324,6 +373,14 @@ defmodule Systems.Assignment.CrewWorkView do
|> Frameworks.Pixel.Flash.put_info("Donated")
end

defp handle_feldspar_event(socket, %{
"__type__" => "CommandSystemEvent",
"name" => "initialized"
}) do
socket
|> assign(tool_initialized: true)
end

defp handle_feldspar_event(socket, %{"__type__" => type}) do
socket |> Frameworks.Pixel.Flash.put_error("Unsupported event " <> type)
end
Expand All @@ -349,8 +406,11 @@ defmodule Systems.Assignment.CrewWorkView do
~H"""
<div class="w-full h-full flex flex-row">
<%= if exists?(@fabric, :tool_ref_view) do %>
<.child name={:tool_ref_view} fabric={@fabric} />
<% else %>
<div class={"w-full h-full #{ if @tool_initialized and @tool_started do "block" else "hidden" end }"}>
<.child name={:tool_ref_view} fabric={@fabric} />
</div>
<% end %>
<%= if not (@tool_initialized and @tool_started) do %>
<%= if exists?(@fabric, :work_list_view) do %>
<div class="w-left-column flex flex-col py-6 gap-6">
<div class="px-6">
Expand Down
17 changes: 12 additions & 5 deletions core/systems/assignment/start_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ defmodule Systems.Assignment.StartView do

alias Systems.Project

def update(%{id: id, work_item: work_item}, socket) do
def update(%{id: id, work_item: work_item, loading: loading}, socket) do
{
:ok,
socket
|> assign(
id: id,
work_item: work_item
work_item: work_item,
loading: loading
)
|> compose_element(:title)
|> compose_element(:description)
Expand All @@ -25,10 +26,10 @@ defmodule Systems.Assignment.StartView do
end

@impl true
def compose(:button, %{work_item: work_item}) do
def compose(:button, %{work_item: work_item, loading: loading}) do
%{
action: start_action(work_item),
face: %{type: :primary, label: "Start"}
face: %{type: :primary, label: "Start", loading: loading}
}
end

Expand Down Expand Up @@ -60,7 +61,13 @@ defmodule Systems.Assignment.StartView do

@impl true
def handle_event("start", _, socket) do
{:noreply, socket |> send_event(:parent, "start")}
{
:noreply,
socket
|> assign(loading: true)
|> compose_element(:button)
|> send_event(:parent, "start")
}
end

@impl true
Expand Down
1 change: 1 addition & 0 deletions core/systems/document/pdf_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule Systems.Document.PDFView do
socket
|> assign(title: title, url: url)
|> compose_element(:close_button)
|> send_event(:parent, "tool_initialized")
}
end

Expand Down
4 changes: 3 additions & 1 deletion core/systems/feldspar/app_page.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ defmodule Systems.Feldspar.AppPage do
socket
|> update_menus()
|> assign(
app_id: app_id,
app_url: app_url,
error: nil
)
Expand All @@ -25,10 +26,11 @@ defmodule Systems.Feldspar.AppPage do
end

@impl true
def compose(:app_view, %{app_url: app_url}) do
def compose(:app_view, %{app_id: app_id, app_url: app_url}) do
%{
module: Feldspar.AppView,
params: %{
key: "app_#{app_id}",
url: app_url,
locale: Gettext.get_locale()
}
Expand Down
6 changes: 3 additions & 3 deletions core/systems/feldspar/app_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ defmodule Systems.Feldspar.AppView do
use Fabric.LiveComponent

@impl true
def update(%{url: url, locale: locale}, socket) do
{:ok, socket |> assign(url: url, locale: locale)}
def update(%{key: key, url: url, locale: locale}, socket) do
{:ok, socket |> assign(key: key, url: url, locale: locale)}
end

@impl true
Expand All @@ -15,7 +15,7 @@ defmodule Systems.Feldspar.AppView do
Changing the preceding siblings of the iframe would result in a reload of the iframe
due to Morphdom (https://github.com/patrick-steele-idem/morphdom/issues/200).
--%>
<div phx-update="ignore" id="web-app-frame" phx-hook="FeldsparApp" data-locale={@locale} data-src={@url}>
<div phx-update="ignore" id={@key} phx-hook="FeldsparApp" data-locale={@locale} data-src={@url}>
<iframe class="w-full"></iframe>
</div>
</div>
Expand Down
3 changes: 2 additions & 1 deletion core/systems/feldspar/tool_model.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ defmodule Systems.Feldspar.ToolModel do
def ready?(tool), do: Feldspar.ToolModel.ready?(tool)
def form(_), do: Feldspar.ToolForm

def launcher(%{archive_ref: archive_ref}) when is_binary(archive_ref) do
def launcher(%{id: id, archive_ref: archive_ref}) when is_binary(archive_ref) do
%{
module: Feldspar.AppView,
params: %{
key: "feldspar_tool_#{id}",
url: archive_ref <> "/index.html",
locale: Gettext.get_locale(CoreWeb.Gettext)
}
Expand Down
23 changes: 15 additions & 8 deletions core/systems/project/tool_ref_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,35 @@ defmodule Systems.Project.ToolRefView do
tool_ref: tool_ref,
task: task
)
|> compose_child(:launcher)
|> reset_fabric()
|> update_launcher()
}
end

@impl true
def compose(:launcher, %{tool_ref: tool_ref}) do
Project.ToolRefModel.tool(tool_ref)
|> Concept.ToolModel.launcher()
def update_launcher(%{assigns: %{tool_ref: %{id: id} = tool_ref}} = socket) do
%{module: module, params: params} =
Project.ToolRefModel.tool(tool_ref)
|> Concept.ToolModel.launcher()

child = Fabric.prepare_child(socket, "tool_ref_#{id}", module, params)
socket |> show_child(child)
end

@impl true
def handle_event("complete_task", _payload, socket) do
{:noreply, socket |> send_event(:parent, "complete_task")}
end

@impl true
def handle_event("tool_initialized", _payload, socket) do
{:noreply, socket |> send_event(:parent, "tool_initialized")}
end

@impl true
def render(assigns) do
~H"""
<div class="w-full h-full">
<%= if Fabric.get_child(@fabric, :launcher) do %>
<.child name={:launcher} fabric={@fabric} />
<% end %>
<.stack fabric={@fabric} />
</div>
"""
end
Expand Down
2 changes: 1 addition & 1 deletion core/systems/workflow/item_views.ex
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ defmodule Systems.Workflow.ItemViews do
<div class="flex-grow"></div>
<%= if @icon do %>
<div class="w-8 h-8">
<img src={"/images/icons/#{@icon}.svg"} onerror="this.src='/images/icons/placeholder.svg';" alt={@icon}>
<img src={"/images/icons/#{String.downcase(@icon)}.svg"} onerror="this.src='/images/icons/placeholder.svg';" alt={@icon}>
</div>
<% end %>
</div>
Expand Down
Loading

0 comments on commit f7a5cb6

Please sign in to comment.