瀏覽代碼

chore: config cell displayable data

appflowy 2 年之前
父節點
當前提交
1e3640f8ac

+ 1 - 1
frontend/rust-lib/flowy-grid/src/event_handler.rs

@@ -376,7 +376,7 @@ pub(crate) async fn get_select_option_handler(
                 },
                 Some(cell_rev) => cell_rev.try_into()?,
             };
-            let option_context = type_option.selected_select_option(any_cell_data);
+            let option_context = type_option.selected_select_option(any_cell_data.into());
             data_result(option_context)
         }
     }

+ 17 - 12
frontend/rust-lib/flowy-grid/src/services/cell/any_cell_data.rs

@@ -100,36 +100,33 @@ impl AnyCellData {
 /// * Use String to parse the data when the FieldType is RichText, Number, or Checkbox.
 /// * Check out the implementation of CellDataOperation trait for more information.
 #[derive(Default)]
-pub struct DecodedCellData {
-    pub data: Vec<u8>,
-}
+pub struct CellBytes(pub Bytes);
 
-impl DecodedCellData {
+impl CellBytes {
     pub fn new<T: AsRef<[u8]>>(data: T) -> Self {
-        Self {
-            data: data.as_ref().to_vec(),
-        }
+        let bytes = Bytes::from(data.as_ref().to_vec());
+        Self(bytes)
     }
 
-    pub fn try_from_bytes<T: TryInto<Bytes>>(bytes: T) -> FlowyResult<Self>
+    pub fn from<T: TryInto<Bytes>>(bytes: T) -> FlowyResult<Self>
     where
         <T as TryInto<Bytes>>::Error: std::fmt::Debug,
     {
         let bytes = bytes.try_into().map_err(internal_error)?;
-        Ok(Self { data: bytes.to_vec() })
+        Ok(Self(bytes))
     }
 
     pub fn parse<'a, T: TryFrom<&'a [u8]>>(&'a self) -> FlowyResult<T>
     where
         <T as TryFrom<&'a [u8]>>::Error: std::fmt::Debug,
     {
-        T::try_from(self.data.as_ref()).map_err(internal_error)
+        T::try_from(self.0.as_ref()).map_err(internal_error)
     }
 }
 
-impl ToString for DecodedCellData {
+impl ToString for CellBytes {
     fn to_string(&self) -> String {
-        match String::from_utf8(self.data.clone()) {
+        match String::from_utf8(self.0.to_vec()) {
             Ok(s) => s,
             Err(e) => {
                 tracing::error!("DecodedCellData to string failed: {:?}", e);
@@ -138,3 +135,11 @@ impl ToString for DecodedCellData {
         }
     }
 }
+
+impl std::ops::Deref for CellBytes {
+    type Target = Bytes;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}

+ 33 - 22
frontend/rust-lib/flowy-grid/src/services/cell/cell_operation.rs

@@ -1,31 +1,45 @@
-use flowy_error::{ErrorCode, FlowyError, FlowyResult};
-use flowy_grid_data_model::revision::{CellRevision, FieldRevision, FieldTypeRevision};
-
 use crate::entities::FieldType;
-use crate::services::cell::{AnyCellData, DecodedCellData};
+use crate::services::cell::{AnyCellData, CellBytes};
 use crate::services::field::*;
 
+use flowy_error::{ErrorCode, FlowyError, FlowyResult};
+use flowy_grid_data_model::revision::{CellRevision, FieldRevision, FieldTypeRevision};
+
+/// This trait is used when doing filter/search on the grid.
 pub trait CellFilterOperation<T> {
     /// Return true if any_cell_data match the filter condition.
     fn apply_filter(&self, any_cell_data: AnyCellData, filter: &T) -> FlowyResult<bool>;
 }
 
-pub trait CellDataOperation<D, C> {
-    /// The cell_data is able to parse into the specific data that was impl the FromCellData trait.
+/// Return object that describes the cell.
+pub trait CellDisplayable<CD, DC> {
+    fn display_data(
+        &self,
+        cell_data: CellData<CD>,
+        decoded_field_type: &FieldType,
+        field_rev: &FieldRevision,
+    ) -> FlowyResult<DC>;
+}
+
+// CD: Short for CellData. This type is the type return by apply_changeset function.
+// CS: Short for Changeset. Parse the string into specific Changeset type.
+pub trait CellDataOperation<CD, CS> {
+    /// The cell_data is able to parse into the specific data if CD impl the FromCellData trait.
     /// For example:
     /// URLCellData, DateCellData. etc.
     fn decode_cell_data(
         &self,
-        cell_data: CellData<D>,
+        cell_data: CellData<CD>,
         decoded_field_type: &FieldType,
         field_rev: &FieldRevision,
-    ) -> FlowyResult<DecodedCellData>;
+    ) -> FlowyResult<CellBytes>;
 
-    /// The changeset is able to parse into the specific data that was impl the FromCellChangeset trait.
+    /// The changeset is able to parse into the specific data if CS impl the FromCellChangeset trait.
     /// For example:
     /// SelectOptionCellChangeset,DateCellChangeset. etc.  
-    fn apply_changeset(&self, changeset: CellDataChangeset<C>, cell_rev: Option<CellRevision>) -> FlowyResult<String>;
+    fn apply_changeset(&self, changeset: CellDataChangeset<CS>, cell_rev: Option<CellRevision>) -> FlowyResult<String>;
 }
+
 /// changeset: It will be deserialized into specific data base on the FieldType.
 ///     For example,
 ///         FieldType::RichText => String
@@ -53,23 +67,20 @@ pub fn apply_cell_data_changeset<C: ToString, T: AsRef<FieldRevision>>(
     Ok(AnyCellData::new(s, field_type).json())
 }
 
-pub fn decode_any_cell_data<T: TryInto<AnyCellData>>(data: T, field_rev: &FieldRevision) -> DecodedCellData {
+pub fn decode_any_cell_data<T: TryInto<AnyCellData>>(data: T, field_rev: &FieldRevision) -> CellBytes {
     if let Ok(any_cell_data) = data.try_into() {
-        let AnyCellData {
-            data: cell_data,
-            field_type,
-        } = any_cell_data;
+        let AnyCellData { data, field_type } = any_cell_data;
         let to_field_type = field_rev.field_type_rev.into();
-        match try_decode_cell_data(CellData(Some(cell_data)), field_rev, &field_type, &to_field_type) {
-            Ok(cell_data) => cell_data,
+        match try_decode_cell_data(data.into(), field_rev, &field_type, &to_field_type) {
+            Ok(cell_bytes) => cell_bytes,
             Err(e) => {
                 tracing::error!("Decode cell data failed, {:?}", e);
-                DecodedCellData::default()
+                CellBytes::default()
             }
         }
     } else {
         tracing::error!("Decode type option data failed");
-        DecodedCellData::default()
+        CellBytes::default()
     }
 }
 
@@ -78,7 +89,7 @@ pub fn try_decode_cell_data(
     field_rev: &FieldRevision,
     s_field_type: &FieldType,
     t_field_type: &FieldType,
-) -> FlowyResult<DecodedCellData> {
+) -> FlowyResult<CellBytes> {
     let cell_data = cell_data.try_into_inner()?;
     let get_cell_data = || {
         let field_type: FieldTypeRevision = t_field_type.into();
@@ -112,9 +123,9 @@ pub fn try_decode_cell_data(
         Some(Ok(data)) => Ok(data),
         Some(Err(err)) => {
             tracing::error!("{:?}", err);
-            Ok(DecodedCellData::default())
+            Ok(CellBytes::default())
         }
-        None => Ok(DecodedCellData::default()),
+        None => Ok(CellBytes::default()),
     }
 }
 

+ 25 - 6
frontend/rust-lib/flowy-grid/src/services/field/select_option.rs

@@ -1,5 +1,5 @@
 use crate::entities::{CellChangeset, CellIdentifier, CellIdentifierPayload, FieldType};
-use crate::services::cell::{AnyCellData, FromCellChangeset, FromCellString};
+use crate::services::cell::{AnyCellData, CellData, CellDisplayable, FromCellChangeset, FromCellString};
 use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOption};
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
@@ -60,12 +60,11 @@ impl std::default::Default for SelectOptionColor {
     }
 }
 
-pub fn make_selected_select_options<T: TryInto<AnyCellData>>(
-    any_cell_data: T,
+pub fn make_selected_select_options(
+    cell_data: CellData<SelectOptionIds>,
     options: &[SelectOption],
 ) -> Vec<SelectOption> {
-    if let Ok(type_option_cell_data) = any_cell_data.try_into() {
-        let ids = SelectOptionIds::from(type_option_cell_data.data);
+    if let Ok(ids) = cell_data.try_into_inner() {
         ids.iter()
             .flat_map(|option_id| options.iter().find(|option| &option.id == option_id).cloned())
             .collect()
@@ -100,13 +99,27 @@ pub trait SelectOptionOperation: TypeOptionDataEntry + Send + Sync {
         SelectOption::with_color(name, color)
     }
 
-    fn selected_select_option(&self, any_cell_data: AnyCellData) -> SelectOptionCellData;
+    fn selected_select_option(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellData;
 
     fn options(&self) -> &Vec<SelectOption>;
 
     fn mut_options(&mut self) -> &mut Vec<SelectOption>;
 }
 
+impl<T> CellDisplayable<SelectOptionIds, SelectOptionCellData> for T
+where
+    T: SelectOptionOperation,
+{
+    fn display_data(
+        &self,
+        cell_data: CellData<SelectOptionIds>,
+        _decoded_field_type: &FieldType,
+        _field_rev: &FieldRevision,
+    ) -> FlowyResult<SelectOptionCellData> {
+        Ok(self.selected_select_option(cell_data))
+    }
+}
+
 pub fn select_option_operation(field_rev: &FieldRevision) -> FlowyResult<Box<dyn SelectOptionOperation>> {
     let field_type: FieldType = field_rev.field_type_rev.into();
     match &field_type {
@@ -155,6 +168,12 @@ impl std::convert::TryFrom<AnyCellData> for SelectOptionIds {
     }
 }
 
+impl std::convert::From<AnyCellData> for CellData<SelectOptionIds> {
+    fn from(any_cell_data: AnyCellData) -> Self {
+        any_cell_data.data.into()
+    }
+}
+
 impl FromCellString for SelectOptionIds {
     fn from_cell_str(s: &str) -> FlowyResult<Self>
     where

+ 17 - 5
frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs

@@ -1,6 +1,6 @@
 use crate::entities::FieldType;
 use crate::impl_type_option;
-use crate::services::cell::{AnyCellData, CellData, CellDataChangeset, CellDataOperation, DecodedCellData};
+use crate::services::cell::{AnyCellData, CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
 use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
 use bytes::Bytes;
 use flowy_derive::ProtoBuf;
@@ -40,23 +40,35 @@ impl_type_option!(CheckboxTypeOption, FieldType::Checkbox);
 const YES: &str = "Yes";
 const NO: &str = "No";
 
+impl CellDisplayable<String, bool> for CheckboxTypeOption {
+    fn display_data(
+        &self,
+        cell_data: CellData<String>,
+        _decoded_field_type: &FieldType,
+        _field_rev: &FieldRevision,
+    ) -> FlowyResult<bool> {
+        let s: String = cell_data.try_into_inner()?;
+        Ok(s == YES)
+    }
+}
+
 impl CellDataOperation<String, String> for CheckboxTypeOption {
     fn decode_cell_data(
         &self,
         cell_data: CellData<String>,
         decoded_field_type: &FieldType,
         _field_rev: &FieldRevision,
-    ) -> FlowyResult<DecodedCellData> {
+    ) -> FlowyResult<CellBytes> {
         if !decoded_field_type.is_checkbox() {
-            return Ok(DecodedCellData::default());
+            return Ok(CellBytes::default());
         }
 
         let s: String = cell_data.try_into_inner()?;
         if s == YES || s == NO {
-            return Ok(DecodedCellData::new(s));
+            return Ok(CellBytes::new(s));
         }
 
-        Ok(DecodedCellData::default())
+        Ok(CellBytes::default())
     }
 
     fn apply_changeset(

+ 18 - 7
frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs

@@ -2,7 +2,8 @@ use crate::entities::{CellChangeset, FieldType};
 use crate::entities::{CellIdentifier, CellIdentifierPayload};
 use crate::impl_type_option;
 use crate::services::cell::{
-    AnyCellData, CellData, CellDataChangeset, CellDataOperation, DecodedCellData, FromCellChangeset, FromCellString,
+    AnyCellData, CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable, FromCellChangeset,
+    FromCellString,
 };
 use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
 use bytes::Bytes;
@@ -121,23 +122,33 @@ impl DateTypeOption {
     }
 }
 
+impl CellDisplayable<DateTimestamp, DateCellData> for DateTypeOption {
+    fn display_data(
+        &self,
+        cell_data: CellData<DateTimestamp>,
+        _decoded_field_type: &FieldType,
+        _field_rev: &FieldRevision,
+    ) -> FlowyResult<DateCellData> {
+        let timestamp = cell_data.try_into_inner()?;
+        Ok(self.today_desc_from_timestamp(timestamp.0))
+    }
+}
+
 impl CellDataOperation<DateTimestamp, DateCellChangeset> for DateTypeOption {
     fn decode_cell_data(
         &self,
         cell_data: CellData<DateTimestamp>,
         decoded_field_type: &FieldType,
-        _field_rev: &FieldRevision,
-    ) -> FlowyResult<DecodedCellData> {
+        field_rev: &FieldRevision,
+    ) -> FlowyResult<CellBytes> {
         // Return default data if the type_option_cell_data is not FieldType::DateTime.
         // It happens when switching from one field to another.
         // For example:
         // FieldType::RichText -> FieldType::DateTime, it will display empty content on the screen.
         if !decoded_field_type.is_date() {
-            return Ok(DecodedCellData::default());
+            return Ok(CellBytes::default());
         }
-        let timestamp = cell_data.try_into_inner()?;
-        let date = self.today_desc_from_timestamp(timestamp.0);
-        DecodedCellData::try_from_bytes(date)
+        CellBytes::from(self.display_data(cell_data, decoded_field_type, field_rev)?)
     }
 
     fn apply_changeset(

+ 8 - 18
frontend/rust-lib/flowy-grid/src/services/field/type_options/multi_select_type_option.rs

@@ -1,7 +1,7 @@
 use crate::entities::FieldType;
 
 use crate::impl_type_option;
-use crate::services::cell::{AnyCellData, CellData, CellDataChangeset, CellDataOperation, DecodedCellData};
+use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
 use crate::services::field::select_option::{
     make_selected_select_options, SelectOption, SelectOptionCellChangeset, SelectOptionCellData, SelectOptionIds,
     SelectOptionOperation, SELECTION_IDS_SEPARATOR,
@@ -28,8 +28,8 @@ pub struct MultiSelectTypeOption {
 impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect);
 
 impl SelectOptionOperation for MultiSelectTypeOption {
-    fn selected_select_option(&self, any_cell_data: AnyCellData) -> SelectOptionCellData {
-        let select_options = make_selected_select_options(any_cell_data, &self.options);
+    fn selected_select_option(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellData {
+        let select_options = make_selected_select_options(cell_data, &self.options);
         SelectOptionCellData {
             options: self.options.clone(),
             select_options,
@@ -50,24 +50,14 @@ impl CellDataOperation<SelectOptionIds, SelectOptionCellChangeset> for MultiSele
         &self,
         cell_data: CellData<SelectOptionIds>,
         decoded_field_type: &FieldType,
-        _field_rev: &FieldRevision,
-    ) -> FlowyResult<DecodedCellData> {
+        field_rev: &FieldRevision,
+    ) -> FlowyResult<CellBytes> {
         if !decoded_field_type.is_select_option() {
-            return Ok(DecodedCellData::default());
+            return Ok(CellBytes::default());
         }
 
-        let ids: SelectOptionIds = cell_data.try_into_inner()?;
-        let select_options = ids
-            .iter()
-            .flat_map(|option_id| self.options.iter().find(|option| &option.id == option_id).cloned())
-            .collect::<Vec<SelectOption>>();
-
-        let cell_data = SelectOptionCellData {
-            options: self.options.clone(),
-            select_options,
-        };
-
-        DecodedCellData::try_from_bytes(cell_data)
+        let cell_data = self.display_data(cell_data, decoded_field_type, field_rev)?;
+        CellBytes::from(cell_data)
     }
 
     fn apply_changeset(

+ 5 - 5
frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option.rs

@@ -1,7 +1,7 @@
 use crate::impl_type_option;
 
 use crate::entities::FieldType;
-use crate::services::cell::{CellData, CellDataChangeset, CellDataOperation, DecodedCellData};
+use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation};
 use crate::services::field::number_currency::Currency;
 use crate::services::field::type_options::number_type_option::format::*;
 use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
@@ -110,15 +110,15 @@ impl CellDataOperation<String, String> for NumberTypeOption {
         cell_data: CellData<String>,
         decoded_field_type: &FieldType,
         _field_rev: &FieldRevision,
-    ) -> FlowyResult<DecodedCellData> {
+    ) -> FlowyResult<CellBytes> {
         if decoded_field_type.is_date() {
-            return Ok(DecodedCellData::default());
+            return Ok(CellBytes::default());
         }
 
         let cell_data: String = cell_data.try_into_inner()?;
         match self.format_cell_data(&cell_data) {
-            Ok(num) => Ok(DecodedCellData::new(num.to_string())),
-            Err(_) => Ok(DecodedCellData::default()),
+            Ok(num) => Ok(CellBytes::new(num.to_string())),
+            Err(_) => Ok(CellBytes::default()),
         }
     }
 

+ 10 - 18
frontend/rust-lib/flowy-grid/src/services/field/type_options/single_select_type_option.rs

@@ -1,6 +1,6 @@
 use crate::entities::FieldType;
 use crate::impl_type_option;
-use crate::services::cell::{AnyCellData, CellData, CellDataChangeset, CellDataOperation, DecodedCellData};
+use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
 use crate::services::field::select_option::{
     make_selected_select_options, SelectOption, SelectOptionCellChangeset, SelectOptionCellData, SelectOptionIds,
     SelectOptionOperation,
@@ -24,8 +24,10 @@ pub struct SingleSelectTypeOption {
 impl_type_option!(SingleSelectTypeOption, FieldType::SingleSelect);
 
 impl SelectOptionOperation for SingleSelectTypeOption {
-    fn selected_select_option(&self, any_cell_data: AnyCellData) -> SelectOptionCellData {
-        let select_options = make_selected_select_options(any_cell_data, &self.options);
+    fn selected_select_option(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellData {
+        let mut select_options = make_selected_select_options(cell_data, &self.options);
+        // only keep option in single select
+        select_options.truncate(1);
         SelectOptionCellData {
             options: self.options.clone(),
             select_options,
@@ -46,24 +48,14 @@ impl CellDataOperation<SelectOptionIds, SelectOptionCellChangeset> for SingleSel
         &self,
         cell_data: CellData<SelectOptionIds>,
         decoded_field_type: &FieldType,
-        _field_rev: &FieldRevision,
-    ) -> FlowyResult<DecodedCellData> {
+        field_rev: &FieldRevision,
+    ) -> FlowyResult<CellBytes> {
         if !decoded_field_type.is_select_option() {
-            return Ok(DecodedCellData::default());
-        }
-
-        let ids: SelectOptionIds = cell_data.try_into_inner()?;
-        let mut cell_data = SelectOptionCellData {
-            options: self.options.clone(),
-            select_options: vec![],
-        };
-        if let Some(option_id) = ids.first() {
-            if let Some(option) = self.options.iter().find(|option| &option.id == option_id) {
-                cell_data.select_options.push(option.clone());
-            }
+            return Ok(CellBytes::default());
         }
 
-        DecodedCellData::try_from_bytes(cell_data)
+        let cell_data = self.display_data(cell_data, decoded_field_type, field_rev)?;
+        CellBytes::from(cell_data)
     }
 
     fn apply_changeset(

+ 16 - 4
frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs

@@ -1,7 +1,7 @@
 use crate::entities::FieldType;
 use crate::impl_type_option;
 use crate::services::cell::{
-    try_decode_cell_data, AnyCellData, CellData, CellDataChangeset, CellDataOperation, DecodedCellData,
+    try_decode_cell_data, AnyCellData, CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable,
 };
 use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
 use bytes::Bytes;
@@ -32,13 +32,25 @@ pub struct RichTextTypeOption {
 }
 impl_type_option!(RichTextTypeOption, FieldType::RichText);
 
+impl CellDisplayable<String, String> for RichTextTypeOption {
+    fn display_data(
+        &self,
+        cell_data: CellData<String>,
+        _decoded_field_type: &FieldType,
+        _field_rev: &FieldRevision,
+    ) -> FlowyResult<String> {
+        let cell_str: String = cell_data.try_into_inner()?;
+        Ok(cell_str)
+    }
+}
+
 impl CellDataOperation<String, String> for RichTextTypeOption {
     fn decode_cell_data(
         &self,
         cell_data: CellData<String>,
         decoded_field_type: &FieldType,
         field_rev: &FieldRevision,
-    ) -> FlowyResult<DecodedCellData> {
+    ) -> FlowyResult<CellBytes> {
         if decoded_field_type.is_date()
             || decoded_field_type.is_single_select()
             || decoded_field_type.is_multi_select()
@@ -46,8 +58,8 @@ impl CellDataOperation<String, String> for RichTextTypeOption {
         {
             try_decode_cell_data(cell_data, field_rev, decoded_field_type, decoded_field_type)
         } else {
-            let cell_data: String = cell_data.try_into_inner()?;
-            Ok(DecodedCellData::new(cell_data))
+            let content = self.display_data(cell_data, decoded_field_type, field_rev)?;
+            Ok(CellBytes::new(content))
         }
     }
 

+ 18 - 6
frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option.rs

@@ -1,7 +1,7 @@
 use crate::entities::FieldType;
 use crate::impl_type_option;
 use crate::services::cell::{
-    AnyCellData, CellData, CellDataChangeset, CellDataOperation, DecodedCellData, FromCellString,
+    AnyCellData, CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable, FromCellString,
 };
 use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
 use bytes::Bytes;
@@ -34,18 +34,30 @@ pub struct URLTypeOption {
 }
 impl_type_option!(URLTypeOption, FieldType::URL);
 
+impl CellDisplayable<URLCellData, URLCellData> for URLTypeOption {
+    fn display_data(
+        &self,
+        cell_data: CellData<URLCellData>,
+        _decoded_field_type: &FieldType,
+        _field_rev: &FieldRevision,
+    ) -> FlowyResult<URLCellData> {
+        let cell_data: URLCellData = cell_data.try_into_inner()?;
+        Ok(cell_data)
+    }
+}
+
 impl CellDataOperation<URLCellData, String> for URLTypeOption {
     fn decode_cell_data(
         &self,
         cell_data: CellData<URLCellData>,
         decoded_field_type: &FieldType,
-        _field_rev: &FieldRevision,
-    ) -> FlowyResult<DecodedCellData> {
+        field_rev: &FieldRevision,
+    ) -> FlowyResult<CellBytes> {
         if !decoded_field_type.is_url() {
-            return Ok(DecodedCellData::default());
+            return Ok(CellBytes::default());
         }
-        let cell_data: URLCellData = cell_data.try_into_inner()?;
-        DecodedCellData::try_from_bytes(cell_data)
+        let cell_data = self.display_data(cell_data, decoded_field_type, field_rev)?;
+        CellBytes::from(cell_data)
     }
 
     fn apply_changeset(

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/filter/impls/select_option_filter.rs

@@ -45,7 +45,7 @@ impl CellFilterOperation<GridSelectOptionFilter> for MultiSelectTypeOption {
             return Ok(true);
         }
 
-        let selected_options = SelectedSelectOptions::from(self.selected_select_option(any_cell_data));
+        let selected_options = SelectedSelectOptions::from(self.selected_select_option(any_cell_data.into()));
         Ok(filter.is_visible(&selected_options))
     }
 }
@@ -55,7 +55,7 @@ impl CellFilterOperation<GridSelectOptionFilter> for SingleSelectTypeOption {
         if !any_cell_data.is_single_select() {
             return Ok(true);
         }
-        let selected_options = SelectedSelectOptions::from(self.selected_select_option(any_cell_data));
+        let selected_options = SelectedSelectOptions::from(self.selected_select_option(any_cell_data.into()));
         Ok(filter.is_visible(&selected_options))
     }
 }

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -344,7 +344,7 @@ impl GridRevisionEditor {
         let row_rev = self.block_manager.get_row_rev(&params.row_id).await.ok()??;
 
         let cell_rev = row_rev.cells.get(&params.field_id)?.clone();
-        let data = decode_any_cell_data(cell_rev.data, &field_rev).data;
+        let data = decode_any_cell_data(cell_rev.data, &field_rev).to_vec();
         Some(Cell::new(&params.field_id, data))
     }