mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-10-24 12:26:07 +08:00
Show indicators of state on session sidebar (#657)
* Added range input (Slider)
* Added range input (Slider)
* Custom css to range input
* Formatting correction
* Defined min and max values of input range
* Revert "Defined min and max values of input range"
This reverts commit 815167ab0f.
* Added input select
* working with a options like list
* Formatting correction
* swapped li for inputs in input settings
* Removed unused attribute
* Final adjustments
* Improve users connected display
* Update lib/livebook_web/live/session_live.ex
Co-authored-by: Jonatan Kłosko <jonatanklosko@gmail.com>
* Update lib/livebook_web/live/session_live.ex
Co-authored-by: Jonatan Kłosko <jonatanklosko@gmail.com>
* Adjust elements
* Change favicon based on notebook status
* Format correction
* "operation" is unused
* Improvements for better functioning of icons
* Renamed icons files
* Update favicons
* Update changelog
* Show indicators of state on session sidebar
* Changes to status colors
* Improve spacing
* Scroll to cell on status click
* global_evaluation_status -> global_status
Co-authored-by: Jonatan Kłosko <jonatanklosko@gmail.com>
This commit is contained in:
parent
e16c8a5dab
commit
421b1c69a1
3 changed files with 78 additions and 38 deletions
|
|
@ -72,7 +72,7 @@ const Session = {
|
|||
|
||||
// Set initial favicon based on the current status
|
||||
|
||||
setFavicon(faviconForEvaluationStatus(this.props.globalEvaluationStatus));
|
||||
setFavicon(faviconForEvaluationStatus(this.props.globalStatus));
|
||||
|
||||
// Load initial data
|
||||
|
||||
|
|
@ -104,6 +104,7 @@ const Session = {
|
|||
|
||||
getSectionsList().addEventListener("click", (event) => {
|
||||
handleSectionsListClick(this, event);
|
||||
handleCellIndicatorsClick(this, event);
|
||||
});
|
||||
|
||||
getClientsList().addEventListener("click", (event) => {
|
||||
|
|
@ -212,10 +213,8 @@ const Session = {
|
|||
const prevProps = this.props;
|
||||
this.props = getProps(this);
|
||||
|
||||
if (
|
||||
this.props.globalEvaluationStatus !== prevProps.globalEvaluationStatus
|
||||
) {
|
||||
setFavicon(faviconForEvaluationStatus(this.props.globalEvaluationStatus));
|
||||
if (this.props.globalStatus !== prevProps.globalStatus) {
|
||||
setFavicon(faviconForEvaluationStatus(this.props.globalStatus));
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -237,11 +236,7 @@ function getProps(hook) {
|
|||
"data-autofocus-cell-id",
|
||||
null
|
||||
),
|
||||
globalEvaluationStatus: getAttributeOrDefault(
|
||||
hook.el,
|
||||
"data-global-evaluation-status",
|
||||
null
|
||||
),
|
||||
globalStatus: getAttributeOrDefault(hook.el, "data-global-status", null),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
id="session"
|
||||
data-element="session"
|
||||
phx-hook="Session"
|
||||
data-global-evaluation-status={elem(@data_view.global_evaluation_status, 0)}
|
||||
data-global-status={elem(@data_view.global_status, 0)}
|
||||
data-autofocus-cell-id={@autofocus_cell_id}>
|
||||
<SidebarHelpers.sidebar>
|
||||
<SidebarHelpers.logo_item socket={@socket} />
|
||||
|
|
@ -120,18 +120,23 @@ defmodule LivebookWeb.SessionLive do
|
|||
</h3>
|
||||
<div class="flex flex-col mt-4 space-y-4">
|
||||
<%= for section_item <- @data_view.sections_items do %>
|
||||
<button class="flex items-center space-x-1 text-left text-gray-500 hover:text-gray-900"
|
||||
data-element="sections-list-item"
|
||||
data-section-id={section_item.id}>
|
||||
<span><%= section_item.name %></span>
|
||||
<%= if section_item.parent do %>
|
||||
<%# Note: the container has overflow-y auto, so we cannot set overflow-x visible,
|
||||
consequently we show the tooltip wrapped to a fixed number of characters %>
|
||||
<span {branching_tooltip_attrs(section_item.name, section_item.parent.name)}>
|
||||
<.remix_icon icon="git-branch-line" class="text-lg font-normal leading-none flip-horizontally" />
|
||||
<div class="flex items-center">
|
||||
<button class="flex-grow flex items-center text-gray-500 hover:text-gray-900"
|
||||
data-element="sections-list-item"
|
||||
data-section-id={section_item.id}>
|
||||
<span class="flex items-center space-x-1">
|
||||
<span><%= section_item.name %></span>
|
||||
<%= if section_item.parent do %>
|
||||
<%# Note: the container has overflow-y auto, so we cannot set overflow-x visible,
|
||||
consequently we show the tooltip wrapped to a fixed number of characters %>
|
||||
<span {branching_tooltip_attrs(section_item.name, section_item.parent.name)}>
|
||||
<.remix_icon icon="git-branch-line" class="text-lg font-normal leading-none flip-horizontally" />
|
||||
</span>
|
||||
<% end %>
|
||||
</span>
|
||||
<% end %>
|
||||
</button>
|
||||
</button>
|
||||
<.session_status status={elem(section_item.status, 0)} cell_id={elem(section_item.status, 1)} />
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<button class="inline-flex items-center justify-center p-8 py-1 mt-8 space-x-2 text-sm font-medium text-gray-500 border border-gray-400 border-dashed rounded-xl hover:bg-gray-100"
|
||||
|
|
@ -259,7 +264,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
dirty: @data_view.dirty,
|
||||
autosave_interval_s: @data_view.autosave_interval_s,
|
||||
runtime: @data_view.runtime,
|
||||
global_evaluation_status: @data_view.global_evaluation_status %>
|
||||
global_status: @data_view.global_status %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -350,6 +355,41 @@ defmodule LivebookWeb.SessionLive do
|
|||
"""
|
||||
end
|
||||
|
||||
defp session_status(%{status: :evaluating} = assigns) do
|
||||
~H"""
|
||||
<button data-element="focus-cell-button" data-target={@cell_id}>
|
||||
<.status_indicator circle_class="bg-blue-500" animated_circle_class="bg-blue-400">
|
||||
</.status_indicator>
|
||||
</button>
|
||||
"""
|
||||
end
|
||||
|
||||
defp session_status(%{status: :stale} = assigns) do
|
||||
~H"""
|
||||
<button data-element="focus-cell-button" data-target={@cell_id}>
|
||||
<.status_indicator circle_class="bg-yellow-200">
|
||||
</.status_indicator>
|
||||
</button>
|
||||
"""
|
||||
end
|
||||
|
||||
defp session_status(assigns), do: ~H""
|
||||
|
||||
defp status_indicator(assigns) do
|
||||
assigns = assign_new(assigns, :animated_circle_class, fn -> nil end)
|
||||
|
||||
~H"""
|
||||
<div class="flex items-center space-x-1">
|
||||
<span class="flex relative h-3 w-3">
|
||||
<%= if @animated_circle_class do %>
|
||||
<span class={"#{@animated_circle_class} animate-ping absolute inline-flex h-3 w-3 rounded-full opacity-75"}></span>
|
||||
<% end %>
|
||||
<span class={"#{@circle_class} relative inline-flex rounded-full h-3 w-3"}></span>
|
||||
</span>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp settings_component_for(%Cell.Elixir{}),
|
||||
do: LivebookWeb.SessionLive.ElixirCellSettingsComponent
|
||||
|
||||
|
|
@ -1134,14 +1174,15 @@ defmodule LivebookWeb.SessionLive do
|
|||
autosave_interval_s: data.notebook.autosave_interval_s,
|
||||
dirty: data.dirty,
|
||||
runtime: data.runtime,
|
||||
global_evaluation_status: global_evaluation_status(data),
|
||||
global_status: global_status(data),
|
||||
notebook_name: data.notebook.name,
|
||||
sections_items:
|
||||
for section <- data.notebook.sections do
|
||||
%{
|
||||
id: section.id,
|
||||
name: section.name,
|
||||
parent: parent_section_view(section.parent_id, data)
|
||||
parent: parent_section_view(section.parent_id, data),
|
||||
status: cells_status(section.cells, data)
|
||||
}
|
||||
end,
|
||||
clients:
|
||||
|
|
@ -1154,12 +1195,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
}
|
||||
end
|
||||
|
||||
defp global_evaluation_status(data) do
|
||||
cells =
|
||||
data.notebook
|
||||
|> Notebook.elixir_cells_with_section()
|
||||
|> Enum.map(fn {cell, _} -> cell end)
|
||||
|
||||
defp cells_status(cells, data) do
|
||||
cond do
|
||||
evaluating = Enum.find(cells, &evaluating?(&1, data)) ->
|
||||
{:evaluating, evaluating.id}
|
||||
|
|
@ -1175,6 +1211,15 @@ defmodule LivebookWeb.SessionLive do
|
|||
end
|
||||
end
|
||||
|
||||
defp global_status(data) do
|
||||
cells =
|
||||
data.notebook
|
||||
|> Notebook.elixir_cells_with_section()
|
||||
|> Enum.map(fn {cell, _} -> cell end)
|
||||
|
||||
cells_status(cells, data)
|
||||
end
|
||||
|
||||
defp evaluating?(cell, data), do: data.cell_infos[cell.id].evaluation_status == :evaluating
|
||||
|
||||
defp stale?(cell, data), do: data.cell_infos[cell.id].validity_status == :stale
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
<% end %>
|
||||
|
||||
<%= if @runtime do %>
|
||||
<.global_evaluation_status
|
||||
status={elem(@global_evaluation_status, 0)}
|
||||
cell_id={elem(@global_evaluation_status, 1)} />
|
||||
<.global_status
|
||||
status={elem(@global_status, 0)}
|
||||
cell_id={elem(@global_status, 1)} />
|
||||
<% else %>
|
||||
<span class="tooltip left" aria-label="Choose a runtime to run the notebook in">
|
||||
<%= live_patch to: Routes.session_path(@socket, :runtime_settings, @session_id),
|
||||
|
|
@ -62,7 +62,7 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
"""
|
||||
end
|
||||
|
||||
defp global_evaluation_status(%{status: :evaluating} = assigns) do
|
||||
defp global_status(%{status: :evaluating} = assigns) do
|
||||
~H"""
|
||||
<span class="tooltip left" aria-label="Go to evaluating cell">
|
||||
<button class="border-blue-400 icon-button icon-outlined-button hover:bg-blue-50 focus:bg-blue-50"
|
||||
|
|
@ -74,7 +74,7 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
"""
|
||||
end
|
||||
|
||||
defp global_evaluation_status(%{status: :evaluated} = assigns) do
|
||||
defp global_status(%{status: :evaluated} = assigns) do
|
||||
~H"""
|
||||
<span class="tooltip left" aria-label="Go to last evaluated cell">
|
||||
<button class="border-green-300 icon-button icon-outlined-button hover:bg-green-50 focus:bg-green-50"
|
||||
|
|
@ -86,7 +86,7 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
"""
|
||||
end
|
||||
|
||||
defp global_evaluation_status(%{status: :stale} = assigns) do
|
||||
defp global_status(%{status: :stale} = assigns) do
|
||||
~H"""
|
||||
<span class="tooltip left" aria-label="Go to first stale cell">
|
||||
<button class="border-yellow-200 icon-button icon-outlined-button hover:bg-yellow-50 focus:bg-yellow-50"
|
||||
|
|
@ -98,7 +98,7 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
"""
|
||||
end
|
||||
|
||||
defp global_evaluation_status(%{status: :fresh} = assigns) do
|
||||
defp global_status(%{status: :fresh} = assigns) do
|
||||
~H"""
|
||||
<span class="tooltip left" aria-label="Ready to evaluate">
|
||||
<button class="border-gray-200 cursor-default icon-button icon-outlined-button hover:bg-gray-100 focus:bg-gray-100">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue