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:
Jean Carlos 2021-11-01 09:15:21 -03:00 committed by GitHub
parent e16c8a5dab
commit 421b1c69a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 78 additions and 38 deletions

View file

@ -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),
};
}

View file

@ -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

View file

@ -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">