Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Column Settings Panel UI Tweaks #2421

Merged
merged 1 commit into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions rust/perspective-viewer/src/rust/components/column_selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,15 @@ impl Component for ColumnSelector {
let ondragenter = ondragenter.reform(move |_| Some(idx));
let size_hint = if named_count > 0 { 50.0 } else { 28.0 };
named_count = named_count.saturating_sub(1);
let key = name.get_name().map(|x| x.to_owned()).unwrap_or_else(|| format!("__auto_{}__", idx));
let key = name
.get_name()
.map(|x| x.to_owned())
.unwrap_or_else(|| format!("__auto_{}__", idx));
let column_dropdown = self.column_dropdown.clone();
let is_editing = matches!(&ctx.props().selected_column, Some(ColumnLocator::Plain(x)) if x == &key);
let is_editing = matches!(
&ctx.props().selected_column,
Some(ColumnLocator::Plain(x)) | Some(ColumnLocator::Expr(Some(x))) if x == &key
);
html_nested! {
<ScrollPanelItem key={ key } { size_hint }>
<ActiveColumn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,15 @@ impl Component for ActiveColumn {
class.push("required");
};

// TODO: This doesn't scale well. Need a better attrs API.
// Thankfully this will be removed when we unify expression and table columns.
let show_edit_btn = match &*ctx.props().renderer.get_active_plugin().unwrap().name()
{
"Datagrid" => col_type != Type::Bool,
"X/Y Scatter" => col_type == Type::String && label.as_deref() == Some("Symbol"),
_ => false,
} || is_expression;

html! {
<div
class={ outer_classes }
Expand Down Expand Up @@ -368,12 +377,14 @@ impl Component for ActiveColumn {
<span class="column-selector--spacer"></span>
}

<ExprEditButton
name={ name.clone() }
on_open_expr_panel={ &ctx.props().on_open_expr_panel }
{ is_expression }
is_editing={ ctx.props().is_editing }
></ExprEditButton>
if show_edit_btn {
<ExprEditButton
name={ name.clone() }
on_open_expr_panel={ &ctx.props().on_open_expr_panel }
{ is_expression }
is_editing={ ctx.props().is_editing }
></ExprEditButton>
}
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ pub struct ExprEditButtonProps {
pub is_editing: bool,
}

// TODO: Move this logic to ColumnSettingsSidebar
// Button should just pass the name to the on_open callback, and the sidebar
// should render it. generally, rendering logic should live on the closest
// component
/// A button that goes into a column-list for a custom expression
/// when pressed, it opens up the expression editor side-panel.
#[function_component]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

use std::fmt::Display;

use yew::{function_component, html, Callback, Html, Properties};
use yew::{function_component, html, use_callback, use_state, Callback, Html, Properties};

use crate::components::column_settings_sidebar::attributes_tab::AttributesTab;
use crate::components::column_settings_sidebar::style_tab::StyleTab;
Expand All @@ -21,6 +21,7 @@ use crate::components::containers::tablist::{Tab, TabList};
use crate::components::expression_editor::get_new_column_name;
use crate::components::style::LocalStyle;
use crate::components::viewer::ColumnLocator;
use crate::config::Type;
use crate::custom_events::CustomEvents;
use crate::model::*;
use crate::renderer::Renderer;
Expand Down Expand Up @@ -49,6 +50,7 @@ pub struct ColumnSettingsProps {
pub session: Session,
pub renderer: Renderer,
pub custom_events: CustomEvents,
pub width_override: Option<i32>,
}

derive_model!(CustomEvents, Session, Renderer for ColumnSettingsProps);
Expand All @@ -69,7 +71,7 @@ pub fn ColumnSettingsSidebar(p: &ColumnSettingsProps) -> Html {
let column_type = p.session.metadata().get_column_view_type(&column_name);
let is_active = column_type.is_some();

let (config, attrs) = p.get_plugin_config();
let (config, attrs) = (p.get_plugin_config(), p.get_plugin_attrs());
if config.is_none() || attrs.is_none() {
tracing::warn!(
"Could not get full plugin config!\nconfig (plugin.save()): {:?}\nplugin_attrs: {:?}",
Expand All @@ -79,14 +81,22 @@ pub fn ColumnSettingsSidebar(p: &ColumnSettingsProps) -> Html {
}
let maybe_ty = p.session.metadata().get_column_view_type(&column_name);

let title = format!("Editing ‘{column_name}’...");

let mut tabs = vec![];

// TODO: This is a hack and needs to be replaced.
let plugin = p.renderer.get_active_plugin().unwrap();
let show_styles = maybe_ty
.map(|ty| match &*plugin.name() {
"Datagrid" => ty != Type::Bool,
"X/Y Scatter" => ty == Type::String,
_ => false,
})
.unwrap_or_default();

if !matches!(p.selected_column, ColumnLocator::Expr(None))
&& show_styles
&& is_active
&& config.is_some()
&& attrs.is_some()
&& maybe_ty.is_some()
{
tabs.push(ColumnSettingsTab::Style);
Expand All @@ -95,58 +105,76 @@ pub fn ColumnSettingsSidebar(p: &ColumnSettingsProps) -> Html {
tabs.push(ColumnSettingsTab::Attributes);
}

clone!(
p.selected_column,
p.on_close,
p.session,
p.renderer,
p.custom_events,
column_name
);
let match_fn = Callback::from(move |tab| {
let match_fn = {
clone!(
selected_column,
on_close,
session,
renderer,
custom_events,
p.selected_column,
p.on_close,
p.session,
p.renderer,
p.custom_events,
column_name
);
match tab {
ColumnSettingsTab::Attributes => {
html! {
<AttributesTab
Callback::from(move |tab| {
clone!(
selected_column,
on_close,
session,
renderer,
custom_events,
column_name
);
match tab {
ColumnSettingsTab::Attributes => {
html! {
<AttributesTab
{ session }
{ renderer }
{ custom_events }

{ selected_column }
{ on_close }
/>
}
}
ColumnSettingsTab::Style => html! {
<StyleTab
{ session }
{ renderer }
{ custom_events }

{ selected_column }
{ on_close }
{ column_name }
ty={ maybe_ty.unwrap() }
/>
}
},
}
ColumnSettingsTab::Style => html! {
<StyleTab
{ session }
{ renderer }
{ custom_events }

{ column_name }
ty={ maybe_ty.unwrap() }
/>
},
}
});
})
};

let selected_tab = use_state(|| None);

let on_tab_change = {
clone!(selected_tab);
use_callback((), move |idx, _| {
selected_tab.set(Some(idx));
})
};

html_template! {
<LocalStyle href={css!("column-settings-panel")} />
<Sidebar
{title}
title={column_name}
on_close={p.on_close.clone()}
id_prefix="column_settings"
icon={"column_settings_icon"}
width_override={p.width_override}
selected_tab={*selected_tab}
>
<TabList<ColumnSettingsTab> {tabs} {match_fn} />
<TabList<ColumnSettingsTab>
{tabs}
{match_fn}
{on_tab_change}
selected_tab={*selected_tab}
/>
</Sidebar>

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ derive_model!(CustomEvents, Session, Renderer for ColumnStyleProps);
#[function_component]
pub fn ColumnStyle(p: &ColumnStyleProps) -> Html {
let props = p.clone();
let (config, attrs) = props.get_plugin_config();
let (config, attrs) = (props.get_plugin_config(), props.get_plugin_attrs());
let (config, attrs) = (config.unwrap(), attrs.unwrap());
let title = format!("{} Styling", props.ty.to_capitalized());
let opt_html = match props.ty {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::config::plugin::{PluginConfig, Symbol};
use crate::config::Type;
use crate::custom_elements::FilterDropDownElement;
use crate::custom_events::CustomEvents;
use crate::model::UpdatePluginConfig;
use crate::model::{GetPluginConfig, UpdatePluginConfig};
use crate::renderer::Renderer;
use crate::session::Session;
use crate::{css, derive_model, html_template};
Expand All @@ -49,7 +49,7 @@ pub struct SymbolAttrProps {
derive_model!(CustomEvents, Session, Renderer for SymbolAttrProps);
impl SymbolAttrProps {
pub fn get_config(&self) -> (PluginConfig, Vec<Symbol>) {
let (config, attrs) = self.get_plugin_config();
let (config, attrs) = (self.get_plugin_config(), self.get_plugin_attrs());
(
config.unwrap(),
attrs.and_then(|a| a.symbol.map(|s| s.symbols)).unwrap(),
Expand Down
35 changes: 33 additions & 2 deletions rust/perspective-viewer/src/rust/components/containers/sidebar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

use yew::{function_component, html, AttrValue, Callback, Children, Html, Properties};
use web_sys::Element;
use yew::{
function_component, html, use_effect_with, use_node_ref, use_state_eq, AttrValue, Callback,
Children, Html, Properties,
};

use crate::clone;

#[derive(PartialEq, Clone, Properties)]
pub struct SidebarProps {
Expand All @@ -21,14 +27,38 @@ pub struct SidebarProps {
pub title: String,
pub id_prefix: String,
pub icon: Option<String>,
pub width_override: Option<i32>,
pub selected_tab: Option<usize>,
}

/// Sidebars are designed to live in a [SplitPanel]
#[function_component]
pub fn Sidebar(p: &SidebarProps) -> Html {
let id = &p.id_prefix;
let noderef = use_node_ref();
let auto_width = use_state_eq(|| 0f64);

// this gets the last calculated width and ensures that
// the auto-width element is at least that big.
// this ensures the panel grows but does not shrink.
use_effect_with((p.children.clone(), p.selected_tab), {
clone!(noderef, auto_width, p.width_override);
move |_| {
if width_override.is_none() {
let updated_width = noderef
.cast::<Element>()
.map(|el| el.get_bounding_client_rect().width())
.unwrap_or_default();
auto_width.set((*auto_width).max(updated_width));
} else {
auto_width.set(0f64);
}
}
});
let width_style = format!("min-width: 200px; width: {}px", *auto_width);

html! {
<div class="sidebar_column" id={format!("{id}_sidebar")}>
<div class="sidebar_column" id={format!("{id}_sidebar")} ref={noderef}>
<SidebarCloseButton
id={ format!("{id}_close_button") }
on_close_sidebar={ &p.on_close }
Expand All @@ -45,6 +75,7 @@ pub fn Sidebar(p: &SidebarProps) -> Html {
<div class="sidebar_content" id={format!("{id}_content")}>
{p.children.iter().collect::<Html>()}
</div>
<div class="sidebar-auto-width" style={width_style}></div>
</div>
}
}
Expand Down
15 changes: 11 additions & 4 deletions rust/perspective-viewer/src/rust/components/containers/tablist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use yew::{classes, html, Callback, Component, Html, Properties};

use crate::components::style::LocalStyle;
use crate::{css, html_template};
use crate::{clone, css, html_template};

pub trait Tab: PartialEq + std::fmt::Display + Clone + Default + 'static {}
impl Tab for String {}
Expand All @@ -23,6 +23,8 @@ impl Tab for &'static str {}
pub struct TabListProps<T: Tab> {
pub tabs: Vec<T>,
pub match_fn: Callback<T, Html>,
pub on_tab_change: Callback<usize>,
pub selected_tab: Option<usize>,
}

pub enum TabListMsg {
Expand Down Expand Up @@ -54,8 +56,8 @@ impl<T: Tab> Component for TabList<T> {
}
}

fn changed(&mut self, _ctx: &yew::Context<Self>, _old_props: &Self::Properties) -> bool {
self.selected_idx = 0;
fn changed(&mut self, ctx: &yew::Context<Self>, _old_props: &Self::Properties) -> bool {
self.selected_idx = ctx.props().selected_tab.unwrap_or_default();
true
}

Expand All @@ -70,7 +72,12 @@ impl<T: Tab> Component for TabList<T> {
Some("tab"),
(idx == self.selected_idx).then_some("selected")
]);
let onclick = ctx.link().callback(move |_| TabListMsg::SetSelected(idx));

clone!(ctx.props().on_tab_change);
let onclick = ctx.link().callback(move |_| {
on_tab_change.emit(idx);
TabListMsg::SetSelected(idx)
});
html! {
<span {class} {onclick}>
<div class="tab-title">{tab.to_string()}</div>
Expand Down
1 change: 1 addition & 0 deletions rust/perspective-viewer/src/rust/components/viewer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ impl Component for PerspectiveViewer {
custom_events={ &ctx.props().custom_events }
{ selected_column }
on_close={ctx.link().callback(|_| PerspectiveViewerMsg::ToggleColumnSettings(None, None))}
width_override={self.column_settings_panel_width_override}
/>
<></>
</SplitPanel>
Expand Down
Loading
Loading