Skip to content

Commit

Permalink
feat: implement default values for radio groups
Browse files Browse the repository at this point in the history
  • Loading branch information
ctron committed Sep 13, 2023
1 parent d42aa21 commit e9fd0c0
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 6 deletions.
7 changes: 7 additions & 0 deletions spog/model/schema/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,13 @@
"type"
],
"properties": {
"default": {
"description": "The ID of the option which should be selected by default",
"type": [
"string",
"null"
]
},
"group": {
"description": "Internal ID (groups radio options)",
"type": "string"
Expand Down
3 changes: 3 additions & 0 deletions spog/model/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ pub struct FilterCheckOption {
pub struct FilterSelectOption {
/// Internal ID (groups radio options)
pub group: String,
/// The ID of the option which should be selected by default
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default: Option<String>,
/// Search terms which will be added using an OR group
pub options: Vec<FilterSelectItem>,
}
Expand Down
12 changes: 11 additions & 1 deletion spog/ui/src/components/advisory/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,17 @@ pub struct AdvisorySearchControlsProperties {
pub fn advisory_search_controls(props: &AdvisorySearchControlsProperties) -> Html {
let config = use_config();
let filters = use_memo(|()| config.vexination.filters.clone(), ());
let search_config = use_memo(|()| convert_search(&filters), ());

let search_config = {
use_memo(
move |()| {
let search = convert_search(&filters);
search.apply_defaults(&props.search_params);
search
},
(),
)
};

html!(
<SimpleSearch<DynamicSearchParameters> search={search_config} search_params={props.search_params.clone()} />
Expand Down
9 changes: 8 additions & 1 deletion spog/ui/src/components/sbom/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ pub struct SbomSearchControlsProperties {
pub fn sbom_search_controls(props: &SbomSearchControlsProperties) -> Html {
let config = use_config();
let filters = use_memo(|()| config.bombastic.filters.clone(), ());
let search_config = use_memo(|()| convert_search(&filters), ());
let search_config = use_memo(
|()| {
let search = convert_search(&filters);
search.apply_defaults(&props.search_params);
search
},
(),
);

html!(
<SimpleSearch<DynamicSearchParameters> search={search_config} search_params={props.search_params.clone()} />
Expand Down
27 changes: 23 additions & 4 deletions spog/ui/src/components/search/dynamic.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::components::search::{
Search, SearchCategory, SearchOption, SearchOptionCheck, SearchOptionSelect, SearchOptionSelectItem,
DefaultEntry, Search, SearchCategory, SearchOption, SearchOptionCheck, SearchOptionSelect, SearchOptionSelectItem,
};
use crate::utils::search::{escape_terms, or_group, SimpleProperties, ToFilterExpression};
use gloo_utils::format::JsValueSerdeExt;
Expand Down Expand Up @@ -109,19 +109,29 @@ impl ToFilterExpression for DynamicSearchParameters {
}

pub fn convert_search(filters: &Filters) -> Search<DynamicSearchParameters> {
let mut defaults = vec![];

let categories = filters
.categories
.iter()
.map(|cat| SearchCategory {
title: cat.label.clone(),
options: cat.options.iter().map(|opt| convert_option(&cat.label, opt)).collect(),
options: cat
.options
.iter()
.map(|opt| convert_option(&cat.label, opt, &mut defaults))
.collect(),
})
.collect();

Search { categories }
Search { categories, defaults }
}

fn convert_option(cat_id: &str, opt: &FilterOption) -> SearchOption<DynamicSearchParameters> {
fn convert_option(
cat_id: &str,
opt: &FilterOption,
defaults: &mut Vec<DefaultEntry>,
) -> SearchOption<DynamicSearchParameters> {
let cat_id = Rc::new(cat_id.to_string());

match opt {
Expand All @@ -145,6 +155,15 @@ fn convert_option(cat_id: &str, opt: &FilterOption) -> SearchOption<DynamicSearc
}
FilterOption::Select(select) => {
let group = Rc::new(select.group.clone());

if let Some(default) = &select.default {
defaults.push(DefaultEntry {
category: cat_id.clone(),
id: group.clone(),
value: Rc::new(default.clone()),
});
}

SearchOption::Select(SearchOptionSelect::<DynamicSearchParameters> {
options: select
.options
Expand Down
31 changes: 31 additions & 0 deletions spog/ui/src/components/search/simple.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
use crate::components::search::DynamicSearchParameters;
use crate::utils::search::*;
use patternfly_yew::prelude::*;
use std::collections::HashSet;
use std::rc::Rc;
use yew::prelude::*;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct DefaultEntry {
pub category: Rc<String>,
pub id: Rc<String>,
pub value: Rc<String>,
}

#[derive(Clone)]
pub struct Search<T> {
pub categories: Vec<SearchCategory<T>>,
pub defaults: Vec<DefaultEntry>,
}

impl<T> Search<T> {
Expand All @@ -15,6 +24,28 @@ impl<T> Search<T> {
}
}

impl<T> Search<T> {
/// Apply the current set of defaults to a search state
///
/// NOTE: We might consider pulling out a trait for handling any `T`. Right now, we don't need it.
pub fn apply_defaults(&self, handle: &UseStateHandle<SearchMode<DynamicSearchParameters>>) {
if self.defaults.is_empty() {
// early return
return;
}

let mut state = (**handle).clone();

if let SearchMode::Simple(state) = &mut state {
for DefaultEntry { category, id, value } in self.defaults.clone() {
state.set(category, id, Some(value));
}
}

handle.set(state);
}
}

#[derive(Clone)]
pub struct SearchCategory<T> {
pub title: String,
Expand Down

0 comments on commit e9fd0c0

Please sign in to comment.