use std::rc::Rc;
use perspective_client::config::{ViewConfig, ViewConfigUpdate};
use perspective_js::utils::ApiFuture;
use yew::prelude::*;
use super::column_selector::ColumnSelector;
use super::plugin_selector::PluginSelector;
use crate::components::containers::sidebar_close_button::SidebarCloseButton;
use crate::config::PluginUpdate;
use crate::dragdrop::*;
use crate::presentation::{ColumnLocator, OpenColumnSettings, Presentation};
use crate::renderer::*;
use crate::session::column_defaults_update::*;
use crate::session::*;
use crate::tasks::can_render_column_styles;
use crate::utils::*;
#[derive(Clone, Properties)]
pub struct SettingsPanelProps {
pub on_close: Callback<()>,
pub on_resize: Rc<PubSub<()>>,
pub on_select_column: Callback<ColumnLocator>,
pub on_debug: Callback<()>,
pub is_debug: bool,
pub plugin_name: Option<String>,
pub available_plugins: PtrEqRc<Vec<String>>,
pub has_table: Option<TableLoadState>,
pub named_column_count: usize,
pub view_config: PtrEqRc<ViewConfig>,
pub drag_column: Option<String>,
pub metadata: SessionMetadataRc,
pub open_column_settings: OpenColumnSettings,
pub selected_theme: Option<String>,
pub dragdrop: DragDrop,
pub session: Session,
pub renderer: Renderer,
pub presentation: Presentation,
}
impl PartialEq for SettingsPanelProps {
fn eq(&self, rhs: &Self) -> bool {
self.is_debug == rhs.is_debug
&& self.plugin_name == rhs.plugin_name
&& self.available_plugins == rhs.available_plugins
&& self.has_table == rhs.has_table
&& self.named_column_count == rhs.named_column_count
&& self.view_config == rhs.view_config
&& self.drag_column == rhs.drag_column
&& self.metadata == rhs.metadata
&& self.open_column_settings == rhs.open_column_settings
&& self.selected_theme == rhs.selected_theme
}
}
#[function_component]
pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
let SettingsPanelProps {
dragdrop,
presentation,
renderer,
session,
..
} = &props;
let selected_column = {
let locator = props.open_column_settings.locator.clone();
let config = &props.view_config;
locator.filter(|locator| match locator {
ColumnLocator::Table(name) => {
locator
.name()
.map(|n| {
config.columns.iter().any(|maybe_col| {
maybe_col.as_ref().map(|col| col == n).unwrap_or_default()
}) || config.group_by.iter().any(|col| col == n)
|| config.split_by.iter().any(|col| col == n)
|| config.filter.iter().any(|col| col.column() == n)
|| config.sort.iter().any(|col| &col.0 == n)
})
.unwrap_or_default()
&& can_render_column_styles(&props.renderer, config, &props.metadata, name)
.unwrap_or_default()
},
_ => true,
})
};
let plugin_name = props.plugin_name.clone();
let available_plugins = props.available_plugins.clone();
let on_select_plugin = {
clone!(renderer, session, presentation);
let session_metadata = props.metadata.clone();
Callback::from(move |plugin_name: String| {
if !session.is_errored() {
let metadata =
renderer.get_next_plugin_metadata(&PluginUpdate::Update(plugin_name));
let prev_metadata = renderer.metadata();
let requirements = metadata.as_ref().unwrap_or(&*prev_metadata);
let rollup_features = session_metadata
.get_features()
.map(|x| x.get_group_rollup_modes())
.unwrap();
let group_rollups = requirements.get_group_rollups(&rollup_features);
let mut update = ViewConfigUpdate {
group_rollup_mode: group_rollups.first().cloned(),
..ViewConfigUpdate::default()
};
update.set_update_column_defaults(
&session_metadata,
&session.get_view_config().columns,
requirements,
);
if session.update_view_config(update).is_ok() {
clone!(renderer, session);
ApiFuture::spawn(async move {
renderer.apply_pending_plugin()?;
renderer.draw(session.validate().await?.create_view()).await
});
}
presentation.set_open_column_settings(None);
}
})
};
html! {
<div id="settings_panel" class="sidebar_column noselect split-panel orient-vertical">
if selected_column.is_none() {
<SidebarCloseButton
id="settings_close_button"
on_close_sidebar={&props.on_close.clone()}
/>
}
<SidebarCloseButton
id={if props.is_debug {"debug_close_button"} else {"debug_open_button"}}
on_close_sidebar={&props.on_debug}
/>
<PluginSelector {plugin_name} {available_plugins} {on_select_plugin} />
<ColumnSelector
on_resize={&props.on_resize}
on_open_expr_panel={&props.on_select_column}
{selected_column}
has_table={props.has_table.clone()}
named_column_count={props.named_column_count}
view_config={props.view_config.clone()}
drag_column={props.drag_column.clone()}
metadata={props.metadata.clone()}
selected_theme={props.selected_theme.clone()}
{dragdrop}
renderer={renderer.clone()}
session={session.clone()}
/>
</div>
}
}