group_util.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. use crate::entities::FieldType;
  2. use crate::services::group::configuration::GroupSettingReader;
  3. use crate::services::group::controller::GroupController;
  4. use crate::services::group::{
  5. CheckboxGroupContext, CheckboxGroupController, DefaultGroupController, Group, GroupSetting,
  6. GroupSettingWriter, MultiSelectGroupController, MultiSelectOptionGroupContext,
  7. SingleSelectGroupController, SingleSelectOptionGroupContext, URLGroupContext, URLGroupController,
  8. };
  9. use collab_database::fields::Field;
  10. use collab_database::rows::Row;
  11. use collab_database::views::DatabaseLayout;
  12. use flowy_error::FlowyResult;
  13. use std::sync::Arc;
  14. /// Returns a group controller.
  15. ///
  16. /// Each view can be grouped by one field, each field has its own group controller.
  17. /// # Arguments
  18. ///
  19. /// * `view_id`: the id of the view
  20. /// * `grouping_field_rev`: the grouping field
  21. /// * `row_revs`: the rows will be separated into different groups
  22. /// * `configuration_reader`: a reader used to read the group configuration from disk
  23. /// * `configuration_writer`: as writer used to write the group configuration to disk
  24. ///
  25. #[tracing::instrument(
  26. level = "trace",
  27. skip_all,
  28. fields(grouping_field_id=%grouping_field.id, grouping_field_type)
  29. err
  30. )]
  31. pub async fn make_group_controller<R, W>(
  32. view_id: String,
  33. grouping_field: Arc<Field>,
  34. rows: Vec<Arc<Row>>,
  35. setting_reader: R,
  36. setting_writer: W,
  37. ) -> FlowyResult<Box<dyn GroupController>>
  38. where
  39. R: GroupSettingReader,
  40. W: GroupSettingWriter,
  41. {
  42. let grouping_field_type = FieldType::from(grouping_field.field_type);
  43. tracing::Span::current().record("grouping_field_type", &grouping_field_type.default_name());
  44. let mut group_controller: Box<dyn GroupController>;
  45. let configuration_reader = Arc::new(setting_reader);
  46. let configuration_writer = Arc::new(setting_writer);
  47. match grouping_field_type {
  48. FieldType::SingleSelect => {
  49. let configuration = SingleSelectOptionGroupContext::new(
  50. view_id,
  51. grouping_field.clone(),
  52. configuration_reader,
  53. configuration_writer,
  54. )
  55. .await?;
  56. let controller = SingleSelectGroupController::new(&grouping_field, configuration).await?;
  57. group_controller = Box::new(controller);
  58. },
  59. FieldType::MultiSelect => {
  60. let configuration = MultiSelectOptionGroupContext::new(
  61. view_id,
  62. grouping_field.clone(),
  63. configuration_reader,
  64. configuration_writer,
  65. )
  66. .await?;
  67. let controller = MultiSelectGroupController::new(&grouping_field, configuration).await?;
  68. group_controller = Box::new(controller);
  69. },
  70. FieldType::Checkbox => {
  71. let configuration = CheckboxGroupContext::new(
  72. view_id,
  73. grouping_field.clone(),
  74. configuration_reader,
  75. configuration_writer,
  76. )
  77. .await?;
  78. let controller = CheckboxGroupController::new(&grouping_field, configuration).await?;
  79. group_controller = Box::new(controller);
  80. },
  81. FieldType::URL => {
  82. let configuration = URLGroupContext::new(
  83. view_id,
  84. grouping_field.clone(),
  85. configuration_reader,
  86. configuration_writer,
  87. )
  88. .await?;
  89. let controller = URLGroupController::new(&grouping_field, configuration).await?;
  90. group_controller = Box::new(controller);
  91. },
  92. _ => {
  93. group_controller = Box::new(DefaultGroupController::new(&grouping_field));
  94. },
  95. }
  96. // Separates the rows into different groups
  97. let rows = rows.iter().map(|row| row.as_ref()).collect::<Vec<&Row>>();
  98. group_controller.fill_groups(rows.as_slice(), &grouping_field)?;
  99. Ok(group_controller)
  100. }
  101. #[tracing::instrument(level = "debug", skip_all)]
  102. pub fn find_new_grouping_field(
  103. fields: &[Arc<Field>],
  104. _layout: &DatabaseLayout,
  105. ) -> Option<Arc<Field>> {
  106. let mut groupable_field_revs = fields
  107. .iter()
  108. .flat_map(|field_rev| {
  109. let field_type = FieldType::from(field_rev.field_type);
  110. match field_type.can_be_group() {
  111. true => Some(field_rev.clone()),
  112. false => None,
  113. }
  114. })
  115. .collect::<Vec<Arc<Field>>>();
  116. if groupable_field_revs.is_empty() {
  117. // If there is not groupable fields then we use the primary field.
  118. fields
  119. .iter()
  120. .find(|field_rev| field_rev.is_primary)
  121. .cloned()
  122. } else {
  123. Some(groupable_field_revs.remove(0))
  124. }
  125. }
  126. /// Returns a `default` group configuration for the [Field]
  127. ///
  128. /// # Arguments
  129. ///
  130. /// * `field`: making the group configuration for the field
  131. ///
  132. pub fn default_group_setting(field: &Field) -> GroupSetting {
  133. let field_id = field.id.clone();
  134. GroupSetting::new(field_id, field.field_type, "".to_owned())
  135. }
  136. pub fn make_no_status_group(field: &Field) -> Group {
  137. Group {
  138. id: field.id.clone(),
  139. name: format!("No {}", field.name),
  140. visible: true,
  141. }
  142. }