|
@@ -2,7 +2,7 @@ use crate::entities::{CellChangesetPB, FieldType, GridCellIdPB, GridCellIdParams
|
|
use crate::services::cell::{
|
|
use crate::services::cell::{
|
|
CellBytes, CellBytesParser, CellData, CellDataIsEmpty, CellDisplayable, FromCellChangeset, FromCellString,
|
|
CellBytes, CellBytesParser, CellData, CellDataIsEmpty, CellDisplayable, FromCellChangeset, FromCellString,
|
|
};
|
|
};
|
|
-use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
|
|
|
|
|
|
+use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB, CHECK, UNCHECK};
|
|
use bytes::Bytes;
|
|
use bytes::Bytes;
|
|
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
|
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
|
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
|
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
|
@@ -64,10 +64,7 @@ impl std::default::Default for SelectOptionColorPB {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-pub fn make_selected_select_options(
|
|
|
|
- cell_data: CellData<SelectOptionIds>,
|
|
|
|
- options: &[SelectOptionPB],
|
|
|
|
-) -> Vec<SelectOptionPB> {
|
|
|
|
|
|
+pub fn make_selected_options(cell_data: CellData<SelectOptionIds>, options: &[SelectOptionPB]) -> Vec<SelectOptionPB> {
|
|
if let Ok(ids) = cell_data.try_into_inner() {
|
|
if let Ok(ids) = cell_data.try_into_inner() {
|
|
ids.iter()
|
|
ids.iter()
|
|
.flat_map(|option_id| options.iter().find(|option| &option.id == option_id).cloned())
|
|
.flat_map(|option_id| options.iter().find(|option| &option.id == option_id).cloned())
|
|
@@ -76,8 +73,11 @@ pub fn make_selected_select_options(
|
|
vec![]
|
|
vec![]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+/// Defines the shared actions used by SingleSelect or Multi-Select.
|
|
|
|
+pub trait SelectTypeOptionSharedAction: TypeOptionDataSerializer + Send + Sync {
|
|
|
|
+ /// Returns `None` means there is no limited
|
|
|
|
+ fn number_of_max_options(&self) -> Option<usize>;
|
|
|
|
|
|
-pub trait SelectOptionOperation: TypeOptionDataSerializer + Send + Sync {
|
|
|
|
/// Insert the `SelectOptionPB` into corresponding type option.
|
|
/// Insert the `SelectOptionPB` into corresponding type option.
|
|
fn insert_option(&mut self, new_option: SelectOptionPB) {
|
|
fn insert_option(&mut self, new_option: SelectOptionPB) {
|
|
let options = self.mut_options();
|
|
let options = self.mut_options();
|
|
@@ -104,7 +104,60 @@ pub trait SelectOptionOperation: TypeOptionDataSerializer + Send + Sync {
|
|
SelectOptionPB::with_color(name, color)
|
|
SelectOptionPB::with_color(name, color)
|
|
}
|
|
}
|
|
|
|
|
|
- fn selected_select_option(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellDataPB;
|
|
|
|
|
|
+ /// Return a list of options that are selected by user
|
|
|
|
+ fn get_selected_options(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellDataPB {
|
|
|
|
+ let mut select_options = make_selected_options(cell_data, self.options());
|
|
|
|
+ match self.number_of_max_options() {
|
|
|
|
+ None => {}
|
|
|
|
+ Some(number_of_max_options) => {
|
|
|
|
+ select_options.truncate(number_of_max_options);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ SelectOptionCellDataPB {
|
|
|
|
+ options: self.options().clone(),
|
|
|
|
+ select_options,
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn transform_type_option(&mut self, field_type: &FieldType, _type_option_data: String) {
|
|
|
|
+ match field_type {
|
|
|
|
+ FieldType::Checkbox => {
|
|
|
|
+ //add Yes and No options if it's not exist.
|
|
|
|
+ if !self.options().iter().any(|option| option.name == CHECK) {
|
|
|
|
+ let check_option = SelectOptionPB::with_color(CHECK, SelectOptionColorPB::Green);
|
|
|
|
+ self.mut_options().push(check_option);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if !self.options().iter().any(|option| option.name == UNCHECK) {
|
|
|
|
+ let uncheck_option = SelectOptionPB::with_color(UNCHECK, SelectOptionColorPB::Yellow);
|
|
|
|
+ self.mut_options().push(uncheck_option);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ FieldType::MultiSelect => {}
|
|
|
|
+ _ => {}
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn transform_cell_data(
|
|
|
|
+ &self,
|
|
|
|
+ cell_data: CellData<SelectOptionIds>,
|
|
|
|
+ decoded_field_type: &FieldType,
|
|
|
|
+ _field_rev: &FieldRevision,
|
|
|
|
+ ) -> FlowyResult<CellBytes> {
|
|
|
|
+ match decoded_field_type {
|
|
|
|
+ FieldType::SingleSelect | FieldType::MultiSelect => {
|
|
|
|
+ // Do nothing
|
|
|
|
+ }
|
|
|
|
+ FieldType::Checkbox => {
|
|
|
|
+ // transform the cell data to the option id
|
|
|
|
+ }
|
|
|
|
+ _ => {
|
|
|
|
+ return Ok(CellBytes::default());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ CellBytes::from(self.get_selected_options(cell_data))
|
|
|
|
+ }
|
|
|
|
|
|
fn options(&self) -> &Vec<SelectOptionPB>;
|
|
fn options(&self) -> &Vec<SelectOptionPB>;
|
|
|
|
|
|
@@ -113,19 +166,15 @@ pub trait SelectOptionOperation: TypeOptionDataSerializer + Send + Sync {
|
|
|
|
|
|
impl<T> CellDisplayable<SelectOptionIds> for T
|
|
impl<T> CellDisplayable<SelectOptionIds> for T
|
|
where
|
|
where
|
|
- T: SelectOptionOperation,
|
|
|
|
|
|
+ T: SelectTypeOptionSharedAction,
|
|
{
|
|
{
|
|
fn displayed_cell_bytes(
|
|
fn displayed_cell_bytes(
|
|
&self,
|
|
&self,
|
|
cell_data: CellData<SelectOptionIds>,
|
|
cell_data: CellData<SelectOptionIds>,
|
|
decoded_field_type: &FieldType,
|
|
decoded_field_type: &FieldType,
|
|
- _field_rev: &FieldRevision,
|
|
|
|
|
|
+ field_rev: &FieldRevision,
|
|
) -> FlowyResult<CellBytes> {
|
|
) -> FlowyResult<CellBytes> {
|
|
- if !decoded_field_type.is_select_option() {
|
|
|
|
- return Ok(CellBytes::default());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- CellBytes::from(self.selected_select_option(cell_data))
|
|
|
|
|
|
+ self.transform_cell_data(cell_data, decoded_field_type, field_rev)
|
|
}
|
|
}
|
|
|
|
|
|
fn displayed_cell_string(
|
|
fn displayed_cell_string(
|
|
@@ -135,7 +184,7 @@ where
|
|
_field_rev: &FieldRevision,
|
|
_field_rev: &FieldRevision,
|
|
) -> FlowyResult<String> {
|
|
) -> FlowyResult<String> {
|
|
Ok(self
|
|
Ok(self
|
|
- .selected_select_option(cell_data)
|
|
|
|
|
|
+ .get_selected_options(cell_data)
|
|
.select_options
|
|
.select_options
|
|
.into_iter()
|
|
.into_iter()
|
|
.map(|option| option.name)
|
|
.map(|option| option.name)
|
|
@@ -144,7 +193,9 @@ where
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-pub fn select_option_operation(field_rev: &FieldRevision) -> FlowyResult<Box<dyn SelectOptionOperation>> {
|
|
|
|
|
|
+pub fn select_type_option_from_field_rev(
|
|
|
|
+ field_rev: &FieldRevision,
|
|
|
|
+) -> FlowyResult<Box<dyn SelectTypeOptionSharedAction>> {
|
|
let field_type: FieldType = field_rev.ty.into();
|
|
let field_type: FieldType = field_rev.ty.into();
|
|
match &field_type {
|
|
match &field_type {
|
|
FieldType::SingleSelect => {
|
|
FieldType::SingleSelect => {
|