Skip to content

Commit

Permalink
feat: add bulk select support for tables
Browse files Browse the repository at this point in the history
  • Loading branch information
HoKim98 committed Jul 30, 2024
1 parent 045327b commit 63e5338
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ base64 = { version = "0.22" }
browser-panic-hook = { version = "0.2" }
built = { version = "0.7", features = ["chrono", "dependency-tree", "git2"] }
byte-unit = { version = "5.1" }
chrono = { version = "0.4", default-features = false }
clap = { version = "4.5", features = ["derive", "env", "string"] }
csv = { version = "1.3" }
futures = { version = "0.3" }
Expand Down
8 changes: 8 additions & 0 deletions crates/cassette-core/src/cassette.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,13 @@ impl<T> CassetteTaskHandle<Vec<T>> {
self.item.get(index)
}

pub fn is_all(&self, value: T) -> bool
where
T: PartialEq,
{
self.item.iter().all(|v| *v == value)
}

pub fn set_all(&self, value: T)
where
T: 'static + Copy,
Expand All @@ -477,6 +484,7 @@ impl<T> CassetteTaskHandle<Vec<T>> {
}
}
}

#[cfg(feature = "ui")]
#[derive(Debug)]
pub struct CassetteLazyHandle<T>(CassetteTaskHandle<T>);
Expand Down
1 change: 1 addition & 0 deletions crates/cassette/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ cassette-plugin-openai-chat = { path = "../cassette-plugin-openai-chat", optiona

browser-panic-hook = { workspace = true }
byte-unit = { workspace = true }
chrono = { workspace = true }
futures = { workspace = true }
gloo-storage = { workspace = true }
gloo-utils = { workspace = true }
Expand Down
44 changes: 42 additions & 2 deletions crates/cassette/src/components/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use cassette_core::{
data::table::DataTable,
task::{TaskResult, TaskState},
};
use chrono::Utc;
use patternfly_yew::prelude::*;
use serde::{Deserialize, Serialize};
use serde_json::Value;
Expand All @@ -19,9 +20,17 @@ use yew::virtual_dom::VChild;
#[derive(Clone, Debug, PartialEq, Deserialize, Properties)]
#[serde(rename_all = "camelCase")]
pub struct Spec {
#[serde(default = "Spec::default_label_bulk_select")]
label_bulk_select: String,
table: DataTable,
}

impl Spec {
fn default_label_bulk_select() -> String {
"All".into()
}
}

#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct State {
Expand All @@ -32,6 +41,7 @@ pub struct State {
impl ComponentRenderer<Spec> for State {
fn render(self, ctx: &mut CassetteContext, spec: Spec) -> TaskResult<Option<Self>> {
let Spec {
label_bulk_select,
table: DataTable { name, data, log },
} = spec;

Expand Down Expand Up @@ -76,6 +86,7 @@ impl ComponentRenderer<Spec> for State {
let body = html! {
<Inner
columns={ columns.clone() }
{ label_bulk_select }
{ log }
name={ name.clone() }
{ records }
Expand Down Expand Up @@ -106,6 +117,7 @@ impl ComponentRenderer<Spec> for State {
#[derive(Clone, Debug, PartialEq, Properties)]
struct Props {
columns: Vec<String>,
label_bulk_select: String,
log: DataTableLog,
name: String,
records: Rc<Vec<Vec<Value>>>,
Expand All @@ -116,12 +128,18 @@ struct Props {
fn inner(props: &Props) -> Html {
let Props {
columns,
label_bulk_select,
log: _,
name,
records,
selections,
} = props;

let updated_at = use_memo((), |()| Utc::now());

let chip_name = format!("Name: {name}");
let chip_updated_at = format!("Updated At: {}", updated_at.to_rfc3339());

let header = Column::build_headers(columns, selections);

let offset = use_state_eq(|| 0);
Expand Down Expand Up @@ -161,9 +179,31 @@ fn inner(props: &Props) -> Html {
<>
<Toolbar>
<ToolbarContent>
// FIXME: add bulk-select support: https://www.patternfly.org/components/table/react-demos/bulk-select/
<ToolbarItem r#type={ ToolbarItemType::BulkSelect }>
{ name }
<Checkbox
checked={
if selections.is_all(true) {
CheckboxState::Checked
} else {
CheckboxState::Unchecked
}
}
label={ label_bulk_select.clone() }
onchange={
let selections = selections.clone();
Callback::from(move |state: CheckboxState| selections.set_all(state.into()))
}
/>
</ToolbarItem>
<ToolbarItem r#type={ ToolbarItemType::ChipGroup }>
<ChipGroup>
<Chip
text={ chip_name }
/>
<Chip
text={ chip_updated_at }
/>
</ChipGroup>
</ToolbarItem>
</ToolbarContent>
</Toolbar>
Expand Down

0 comments on commit 63e5338

Please # to comment.