|
@@ -1,39 +1,77 @@
|
|
|
#![allow(clippy::needless_collect)]
|
|
|
|
|
|
-use crate::entities::{ChecklistFilterPB, SelectOptionCondition, SelectOptionFilterPB};
|
|
|
+use crate::entities::{ChecklistFilterPB, FieldType, SelectOptionCondition, SelectOptionFilterPB};
|
|
|
use crate::services::cell::{CellFilterOperation, TypeCellData};
|
|
|
use crate::services::field::{ChecklistTypeOptionPB, MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
|
|
|
use crate::services::field::{SelectTypeOptionSharedAction, SelectedSelectOptions};
|
|
|
use flowy_error::FlowyResult;
|
|
|
|
|
|
impl SelectOptionFilterPB {
|
|
|
- pub fn is_visible(&self, selected_options: &SelectedSelectOptions) -> bool {
|
|
|
+ pub fn is_visible(&self, selected_options: &SelectedSelectOptions, field_type: FieldType) -> bool {
|
|
|
let selected_option_ids: Vec<&String> = selected_options.options.iter().map(|option| &option.id).collect();
|
|
|
match self.condition {
|
|
|
- SelectOptionCondition::OptionIs => {
|
|
|
- if self.option_ids.len() != selected_option_ids.len() {
|
|
|
- return false;
|
|
|
+ SelectOptionCondition::OptionIs => match field_type {
|
|
|
+ FieldType::SingleSelect => {
|
|
|
+ if self.option_ids.is_empty() {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if selected_options.options.is_empty() {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ let required_options = self
|
|
|
+ .option_ids
|
|
|
+ .iter()
|
|
|
+ .filter(|id| selected_option_ids.contains(id))
|
|
|
+ .collect::<Vec<_>>();
|
|
|
+
|
|
|
+ !required_options.is_empty()
|
|
|
+ }
|
|
|
+ FieldType::MultiSelect => {
|
|
|
+ if self.option_ids.is_empty() {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ let required_options = self
|
|
|
+ .option_ids
|
|
|
+ .iter()
|
|
|
+ .filter(|id| selected_option_ids.contains(id))
|
|
|
+ .collect::<Vec<_>>();
|
|
|
+
|
|
|
+ !required_options.is_empty()
|
|
|
}
|
|
|
- // if selected options equal to filter's options, then the required_options will be empty.
|
|
|
- let required_options = self
|
|
|
- .option_ids
|
|
|
- .iter()
|
|
|
- .filter(|id| selected_option_ids.contains(id))
|
|
|
- .collect::<Vec<_>>();
|
|
|
- required_options.len() == selected_option_ids.len()
|
|
|
- }
|
|
|
- SelectOptionCondition::OptionIsNot => {
|
|
|
- if self.option_ids.len() != selected_option_ids.len() {
|
|
|
- return true;
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ SelectOptionCondition::OptionIsNot => match field_type {
|
|
|
+ FieldType::SingleSelect => {
|
|
|
+ if self.option_ids.is_empty() {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if selected_options.options.is_empty() {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ let required_options = self
|
|
|
+ .option_ids
|
|
|
+ .iter()
|
|
|
+ .filter(|id| selected_option_ids.contains(id))
|
|
|
+ .collect::<Vec<_>>();
|
|
|
+
|
|
|
+ required_options.is_empty()
|
|
|
+ }
|
|
|
+ FieldType::MultiSelect => {
|
|
|
+ let required_options = self
|
|
|
+ .option_ids
|
|
|
+ .iter()
|
|
|
+ .filter(|id| selected_option_ids.contains(id))
|
|
|
+ .collect::<Vec<_>>();
|
|
|
+
|
|
|
+ required_options.is_empty()
|
|
|
}
|
|
|
- let required_options = self
|
|
|
- .option_ids
|
|
|
- .iter()
|
|
|
- .filter(|id| selected_option_ids.contains(id))
|
|
|
- .collect::<Vec<_>>();
|
|
|
-
|
|
|
- required_options.len() != selected_option_ids.len()
|
|
|
- }
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
SelectOptionCondition::OptionIsEmpty => selected_option_ids.is_empty(),
|
|
|
SelectOptionCondition::OptionIsNotEmpty => !selected_option_ids.is_empty(),
|
|
|
}
|
|
@@ -47,7 +85,7 @@ impl CellFilterOperation<SelectOptionFilterPB> for MultiSelectTypeOptionPB {
|
|
|
}
|
|
|
|
|
|
let selected_options = SelectedSelectOptions::from(self.get_selected_options(any_cell_data.into()));
|
|
|
- Ok(filter.is_visible(&selected_options))
|
|
|
+ Ok(filter.is_visible(&selected_options, FieldType::MultiSelect))
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -57,7 +95,7 @@ impl CellFilterOperation<SelectOptionFilterPB> for SingleSelectTypeOptionPB {
|
|
|
return Ok(true);
|
|
|
}
|
|
|
let selected_options = SelectedSelectOptions::from(self.get_selected_options(any_cell_data.into()));
|
|
|
- Ok(filter.is_visible(&selected_options))
|
|
|
+ Ok(filter.is_visible(&selected_options, FieldType::SingleSelect))
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -74,7 +112,7 @@ impl CellFilterOperation<ChecklistFilterPB> for ChecklistTypeOptionPB {
|
|
|
#[cfg(test)]
|
|
|
mod tests {
|
|
|
#![allow(clippy::all)]
|
|
|
- use crate::entities::{SelectOptionCondition, SelectOptionFilterPB};
|
|
|
+ use crate::entities::{FieldType, SelectOptionCondition, SelectOptionFilterPB};
|
|
|
use crate::services::field::selection_type_option::{SelectOptionPB, SelectedSelectOptions};
|
|
|
|
|
|
#[test]
|
|
@@ -85,10 +123,26 @@ mod tests {
|
|
|
option_ids: vec![],
|
|
|
};
|
|
|
|
|
|
- assert_eq!(filter.is_visible(&SelectedSelectOptions { options: vec![] }), true);
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options: vec![] }, FieldType::SingleSelect),
|
|
|
+ true
|
|
|
+ );
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(
|
|
|
+ &SelectedSelectOptions {
|
|
|
+ options: vec![option.clone()]
|
|
|
+ },
|
|
|
+ FieldType::SingleSelect
|
|
|
+ ),
|
|
|
+ false,
|
|
|
+ );
|
|
|
|
|
|
assert_eq!(
|
|
|
- filter.is_visible(&SelectedSelectOptions { options: vec![option] }),
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options: vec![] }, FieldType::MultiSelect),
|
|
|
+ true
|
|
|
+ );
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options: vec![option] }, FieldType::MultiSelect),
|
|
|
false,
|
|
|
);
|
|
|
}
|
|
@@ -103,82 +157,162 @@ mod tests {
|
|
|
};
|
|
|
|
|
|
assert_eq!(
|
|
|
- filter.is_visible(&SelectedSelectOptions {
|
|
|
- options: vec![option_1]
|
|
|
- }),
|
|
|
+ filter.is_visible(
|
|
|
+ &SelectedSelectOptions {
|
|
|
+ options: vec![option_1.clone()]
|
|
|
+ },
|
|
|
+ FieldType::SingleSelect
|
|
|
+ ),
|
|
|
true
|
|
|
);
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options: vec![] }, FieldType::SingleSelect),
|
|
|
+ false,
|
|
|
+ );
|
|
|
|
|
|
- assert_eq!(filter.is_visible(&SelectedSelectOptions { options: vec![] }), false,);
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(
|
|
|
+ &SelectedSelectOptions {
|
|
|
+ options: vec![option_1.clone()]
|
|
|
+ },
|
|
|
+ FieldType::MultiSelect
|
|
|
+ ),
|
|
|
+ true
|
|
|
+ );
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options: vec![] }, FieldType::MultiSelect),
|
|
|
+ false,
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
|
- fn select_option_filter_is_not_test() {
|
|
|
+ fn single_select_option_filter_is_not_test() {
|
|
|
let option_1 = SelectOptionPB::new("A");
|
|
|
let option_2 = SelectOptionPB::new("B");
|
|
|
let option_3 = SelectOptionPB::new("C");
|
|
|
-
|
|
|
let filter = SelectOptionFilterPB {
|
|
|
condition: SelectOptionCondition::OptionIsNot,
|
|
|
option_ids: vec![option_1.id.clone(), option_2.id.clone()],
|
|
|
};
|
|
|
|
|
|
- assert_eq!(
|
|
|
- filter.is_visible(&SelectedSelectOptions {
|
|
|
- options: vec![option_1.clone(), option_2.clone()],
|
|
|
- }),
|
|
|
- false
|
|
|
- );
|
|
|
-
|
|
|
- assert_eq!(
|
|
|
- filter.is_visible(&SelectedSelectOptions {
|
|
|
- options: vec![option_1.clone(), option_2.clone(), option_3.clone()],
|
|
|
- }),
|
|
|
- true
|
|
|
- );
|
|
|
+ for (options, is_visible) in vec![
|
|
|
+ (vec![option_2.clone()], false),
|
|
|
+ (vec![option_1.clone()], false),
|
|
|
+ (vec![option_3.clone()], true),
|
|
|
+ (vec![option_1.clone(), option_2.clone()], false),
|
|
|
+ ] {
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options }, FieldType::SingleSelect),
|
|
|
+ is_visible
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- assert_eq!(
|
|
|
- filter.is_visible(&SelectedSelectOptions {
|
|
|
- options: vec![option_1.clone(), option_3.clone()],
|
|
|
- }),
|
|
|
- true
|
|
|
- );
|
|
|
+ #[test]
|
|
|
+ fn single_select_option_filter_is_test() {
|
|
|
+ let option_1 = SelectOptionPB::new("A");
|
|
|
+ let option_2 = SelectOptionPB::new("B");
|
|
|
+ let option_3 = SelectOptionPB::new("c");
|
|
|
|
|
|
- assert_eq!(filter.is_visible(&SelectedSelectOptions { options: vec![] }), true);
|
|
|
+ let filter = SelectOptionFilterPB {
|
|
|
+ condition: SelectOptionCondition::OptionIs,
|
|
|
+ option_ids: vec![option_1.id.clone()],
|
|
|
+ };
|
|
|
+ for (options, is_visible) in vec![
|
|
|
+ (vec![option_1.clone()], true),
|
|
|
+ (vec![option_2.clone()], false),
|
|
|
+ (vec![option_3.clone()], false),
|
|
|
+ (vec![option_1.clone(), option_2.clone()], true),
|
|
|
+ ] {
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options }, FieldType::SingleSelect),
|
|
|
+ is_visible
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
|
- fn select_option_filter_is_test() {
|
|
|
+ fn single_select_option_filter_is_test2() {
|
|
|
let option_1 = SelectOptionPB::new("A");
|
|
|
let option_2 = SelectOptionPB::new("B");
|
|
|
- let option_3 = SelectOptionPB::new("C");
|
|
|
|
|
|
let filter = SelectOptionFilterPB {
|
|
|
condition: SelectOptionCondition::OptionIs,
|
|
|
+ option_ids: vec![],
|
|
|
+ };
|
|
|
+ for (options, is_visible) in vec![
|
|
|
+ (vec![option_1.clone()], true),
|
|
|
+ (vec![option_2.clone()], true),
|
|
|
+ (vec![option_1.clone(), option_2.clone()], true),
|
|
|
+ ] {
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options }, FieldType::SingleSelect),
|
|
|
+ is_visible
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn multi_select_option_filter_not_contains_test() {
|
|
|
+ let option_1 = SelectOptionPB::new("A");
|
|
|
+ let option_2 = SelectOptionPB::new("B");
|
|
|
+ let option_3 = SelectOptionPB::new("C");
|
|
|
+ let filter = SelectOptionFilterPB {
|
|
|
+ condition: SelectOptionCondition::OptionIsNot,
|
|
|
option_ids: vec![option_1.id.clone(), option_2.id.clone()],
|
|
|
};
|
|
|
|
|
|
- assert_eq!(
|
|
|
- filter.is_visible(&SelectedSelectOptions {
|
|
|
- options: vec![option_1.clone(), option_2.clone()],
|
|
|
- }),
|
|
|
- true
|
|
|
- );
|
|
|
+ for (options, is_visible) in vec![
|
|
|
+ (vec![option_1.clone(), option_2.clone()], false),
|
|
|
+ (vec![option_1.clone()], false),
|
|
|
+ (vec![option_2.clone()], false),
|
|
|
+ (vec![option_3.clone()], true),
|
|
|
+ (vec![option_1.clone(), option_2.clone(), option_3.clone()], false),
|
|
|
+ (vec![], true),
|
|
|
+ ] {
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options }, FieldType::MultiSelect),
|
|
|
+ is_visible
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #[test]
|
|
|
+ fn multi_select_option_filter_contains_test() {
|
|
|
+ let option_1 = SelectOptionPB::new("A");
|
|
|
+ let option_2 = SelectOptionPB::new("B");
|
|
|
+ let option_3 = SelectOptionPB::new("C");
|
|
|
|
|
|
- assert_eq!(
|
|
|
- filter.is_visible(&SelectedSelectOptions {
|
|
|
- options: vec![option_1.clone(), option_2.clone(), option_3.clone()],
|
|
|
- }),
|
|
|
- false
|
|
|
- );
|
|
|
+ let filter = SelectOptionFilterPB {
|
|
|
+ condition: SelectOptionCondition::OptionIs,
|
|
|
+ option_ids: vec![option_1.id.clone(), option_2.id.clone()],
|
|
|
+ };
|
|
|
+ for (options, is_visible) in vec![
|
|
|
+ (vec![option_1.clone(), option_2.clone(), option_3.clone()], true),
|
|
|
+ (vec![option_2.clone(), option_1.clone()], true),
|
|
|
+ (vec![option_2.clone()], true),
|
|
|
+ (vec![option_1.clone(), option_3.clone()], true),
|
|
|
+ (vec![option_3.clone()], false),
|
|
|
+ ] {
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options }, FieldType::MultiSelect),
|
|
|
+ is_visible
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- assert_eq!(
|
|
|
- filter.is_visible(&SelectedSelectOptions {
|
|
|
- options: vec![option_1.clone(), option_3.clone()],
|
|
|
- }),
|
|
|
- false
|
|
|
- );
|
|
|
+ #[test]
|
|
|
+ fn multi_select_option_filter_contains_test2() {
|
|
|
+ let option_1 = SelectOptionPB::new("A");
|
|
|
|
|
|
- assert_eq!(filter.is_visible(&SelectedSelectOptions { options: vec![] }), false);
|
|
|
+ let filter = SelectOptionFilterPB {
|
|
|
+ condition: SelectOptionCondition::OptionIs,
|
|
|
+ option_ids: vec![],
|
|
|
+ };
|
|
|
+ for (options, is_visible) in vec![(vec![option_1.clone()], true), (vec![], true)] {
|
|
|
+ assert_eq!(
|
|
|
+ filter.is_visible(&SelectedSelectOptions { options }, FieldType::MultiSelect),
|
|
|
+ is_visible
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
}
|