Quellcode durchsuchen

fix: date field created when reference a calendar (#2910)

* fix: date field created when reference a calendar

* fix: make everything one transaction

* chore: apply suggestions from Lucas

* chore: do the same for board

---------

Co-authored-by: Lucas.Xu <[email protected]>
Richard Shiue vor 1 Jahr
Ursprung
Commit
ea37f46f88

+ 7 - 6
frontend/rust-lib/flowy-database2/src/manager.rs

@@ -249,12 +249,13 @@ impl DatabaseManager {
     let wdb = self.get_workspace_database().await?;
     let mut params = CreateViewParams::new(database_id.clone(), database_view_id, name, layout);
     if let Some(database) = wdb.get_database(&database_id).await {
-      if let Some((field, layout_setting)) = DatabaseLayoutDepsResolver::new(database, layout)
-        .resolve_deps_when_create_database_linked_view()
-      {
-        params = params
-          .with_deps_fields(vec![field])
-          .with_layout_setting(layout_setting);
+      let (field, layout_setting) = DatabaseLayoutDepsResolver::new(database, layout)
+        .resolve_deps_when_create_database_linked_view();
+      if let Some(field) = field {
+        params = params.with_deps_fields(vec![field]);
+      }
+      if let Some(layout_setting) = layout_setting {
+        params = params.with_layout_setting(layout_setting);
       }
     };
     wdb.create_database_linked_view(params).await?;

+ 54 - 9
frontend/rust-lib/flowy-database2/src/services/database_view/layout_deps.rs

@@ -4,11 +4,13 @@ use collab_database::views::{DatabaseLayout, LayoutSetting};
 use std::sync::Arc;
 
 use crate::entities::FieldType;
-use crate::services::field::DateTypeOption;
+use crate::services::field::{DateTypeOption, SingleSelectTypeOption};
 use crate::services::setting::CalendarLayoutSetting;
 
-/// When creating a database, we need to resolve the dependencies of the views. Different database
-/// view has different dependencies. For example, a calendar view depends on a date field.
+/// When creating a database, we need to resolve the dependencies of the views.
+/// Different database views have different dependencies. For example, a board
+/// view depends on a field that can be used to group rows while a calendar view
+/// depends on a date field.
 pub struct DatabaseLayoutDepsResolver {
   pub database: Arc<MutexDatabase>,
   /// The new database layout.
@@ -23,14 +25,44 @@ impl DatabaseLayoutDepsResolver {
     }
   }
 
-  pub fn resolve_deps_when_create_database_linked_view(&self) -> Option<(Field, LayoutSetting)> {
+  pub fn resolve_deps_when_create_database_linked_view(
+    &self,
+  ) -> (Option<Field>, Option<LayoutSetting>) {
     match self.database_layout {
-      DatabaseLayout::Grid => None,
-      DatabaseLayout::Board => None,
+      DatabaseLayout::Grid => (None, None),
+      DatabaseLayout::Board => {
+        if self
+          .database
+          .lock()
+          .get_fields(None)
+          .into_iter()
+          .find(|field| FieldType::from(field.field_type).can_be_group())
+          .is_none()
+        {
+          let select_field = self.create_select_field();
+          (Some(select_field), None)
+        } else {
+          (None, None)
+        }
+      },
       DatabaseLayout::Calendar => {
-        let field = self.create_date_field();
-        let layout_setting: LayoutSetting = CalendarLayoutSetting::new(field.id.clone()).into();
-        Some((field, layout_setting))
+        match self
+          .database
+          .lock()
+          .get_fields(None)
+          .into_iter()
+          .find(|field| FieldType::from(field.field_type).is_date())
+        {
+          Some(field) => {
+            let layout_setting = CalendarLayoutSetting::new(field.id).into();
+            (None, Some(layout_setting))
+          },
+          None => {
+            let date_field = self.create_date_field();
+            let layout_setting = CalendarLayoutSetting::new(date_field.clone().id).into();
+            (Some(date_field), Some(layout_setting))
+          },
+        }
       },
     }
   }
@@ -89,6 +121,19 @@ impl DatabaseLayoutDepsResolver {
     )
     .with_type_option_data(field_type, default_date_type_option.into())
   }
+
+  fn create_select_field(&self) -> Field {
+    let field_type = FieldType::SingleSelect;
+    let default_select_type_option = SingleSelectTypeOption::default();
+    let field_id = gen_field_id();
+    Field::new(
+      field_id,
+      "Status".to_string(),
+      field_type.clone().into(),
+      false,
+    )
+    .with_type_option_data(field_type, default_select_type_option.into())
+  }
 }
 
 // pub async fn v_get_layout_settings(&self, layout_ty: &DatabaseLayout) -> LayoutSettingParams {