diff --git a/Cargo.toml b/Cargo.toml index 98e4023..a233278 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" } diff --git a/crates/cassette-core/src/cassette.rs b/crates/cassette-core/src/cassette.rs index 9d5ca0c..75a60ad 100644 --- a/crates/cassette-core/src/cassette.rs +++ b/crates/cassette-core/src/cassette.rs @@ -457,6 +457,13 @@ impl CassetteTaskHandle> { 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, @@ -477,6 +484,7 @@ impl CassetteTaskHandle> { } } } + #[cfg(feature = "ui")] #[derive(Debug)] pub struct CassetteLazyHandle(CassetteTaskHandle); diff --git a/crates/cassette/Cargo.toml b/crates/cassette/Cargo.toml index 125c2f0..d57ee8e 100644 --- a/crates/cassette/Cargo.toml +++ b/crates/cassette/Cargo.toml @@ -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 } diff --git a/crates/cassette/src/components/table.rs b/crates/cassette/src/components/table.rs index 4e37f2d..5b5e011 100644 --- a/crates/cassette/src/components/table.rs +++ b/crates/cassette/src/components/table.rs @@ -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; @@ -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 { @@ -32,6 +41,7 @@ pub struct State { impl ComponentRenderer for State { fn render(self, ctx: &mut CassetteContext, spec: Spec) -> TaskResult> { let Spec { + label_bulk_select, table: DataTable { name, data, log }, } = spec; @@ -76,6 +86,7 @@ impl ComponentRenderer for State { let body = html! { for State { #[derive(Clone, Debug, PartialEq, Properties)] struct Props { columns: Vec, + label_bulk_select: String, log: DataTableLog, name: String, records: Rc>>, @@ -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); @@ -161,9 +179,31 @@ fn inner(props: &Props) -> Html { <> - // FIXME: add bulk-select support: https://www.patternfly.org/components/table/react-demos/bulk-select/ - { name } + + + + + + +