url_controller.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. use std::sync::Arc;
  2. use collab_database::fields::Field;
  3. use collab_database::rows::{new_cell_builder, Cell, Cells, Row, RowDetail};
  4. use serde::{Deserialize, Serialize};
  5. use flowy_error::FlowyResult;
  6. use crate::entities::{
  7. FieldType, GroupPB, GroupRowsNotificationPB, InsertedGroupPB, InsertedRowPB, RowMetaPB,
  8. URLCellDataPB,
  9. };
  10. use crate::services::cell::insert_url_cell;
  11. use crate::services::field::{URLCellData, URLCellDataParser, URLTypeOption};
  12. use crate::services::group::action::GroupCustomize;
  13. use crate::services::group::configuration::GroupContext;
  14. use crate::services::group::controller::{
  15. BaseGroupController, GroupController, GroupsBuilder, MoveGroupRowContext,
  16. };
  17. use crate::services::group::{
  18. make_no_status_group, move_group_row, GeneratedGroupConfig, GeneratedGroups, Group,
  19. };
  20. #[derive(Default, Serialize, Deserialize)]
  21. pub struct URLGroupConfiguration {
  22. pub hide_empty: bool,
  23. }
  24. pub type URLGroupController =
  25. BaseGroupController<URLGroupConfiguration, URLTypeOption, URLGroupGenerator, URLCellDataParser>;
  26. pub type URLGroupContext = GroupContext<URLGroupConfiguration>;
  27. impl GroupCustomize for URLGroupController {
  28. type CellData = URLCellDataPB;
  29. fn placeholder_cell(&self) -> Option<Cell> {
  30. Some(
  31. new_cell_builder(FieldType::URL)
  32. .insert_str_value("data", "")
  33. .build(),
  34. )
  35. }
  36. fn can_group(&self, content: &str, cell_data: &Self::CellData) -> bool {
  37. cell_data.content == content
  38. }
  39. fn create_or_delete_group_when_cell_changed(
  40. &mut self,
  41. row_detail: &RowDetail,
  42. _old_cell_data: Option<&Self::CellData>,
  43. _cell_data: &Self::CellData,
  44. ) -> FlowyResult<(Option<InsertedGroupPB>, Option<GroupPB>)> {
  45. // Just return if the group with this url already exists
  46. let mut inserted_group = None;
  47. if self.context.get_group(&_cell_data.url).is_none() {
  48. let cell_data: URLCellData = _cell_data.clone().into();
  49. let group = make_group_from_url_cell(&cell_data);
  50. let mut new_group = self.context.add_new_group(group)?;
  51. new_group.group.rows.push(RowMetaPB::from(&row_detail.meta));
  52. inserted_group = Some(new_group);
  53. }
  54. // Delete the old url group if there are no rows in that group
  55. let deleted_group = match _old_cell_data
  56. .and_then(|old_cell_data| self.context.get_group(&old_cell_data.content))
  57. {
  58. None => None,
  59. Some((_, group)) => {
  60. if group.rows.len() == 1 {
  61. Some(group.clone())
  62. } else {
  63. None
  64. }
  65. },
  66. };
  67. let deleted_group = match deleted_group {
  68. None => None,
  69. Some(group) => {
  70. self.context.delete_group(&group.id)?;
  71. Some(GroupPB::from(group.clone()))
  72. },
  73. };
  74. Ok((inserted_group, deleted_group))
  75. }
  76. fn add_or_remove_row_when_cell_changed(
  77. &mut self,
  78. row_detail: &RowDetail,
  79. cell_data: &Self::CellData,
  80. ) -> Vec<GroupRowsNotificationPB> {
  81. let mut changesets = vec![];
  82. self.context.iter_mut_status_groups(|group| {
  83. let mut changeset = GroupRowsNotificationPB::new(group.id.clone());
  84. if group.id == cell_data.content {
  85. if !group.contains_row(&row_detail.row.id) {
  86. changeset
  87. .inserted_rows
  88. .push(InsertedRowPB::new(RowMetaPB::from(&row_detail.meta)));
  89. group.add_row(row_detail.clone());
  90. }
  91. } else if group.contains_row(&row_detail.row.id) {
  92. group.remove_row(&row_detail.row.id);
  93. changeset
  94. .deleted_rows
  95. .push(row_detail.row.id.clone().into_inner());
  96. }
  97. if !changeset.is_empty() {
  98. changesets.push(changeset);
  99. }
  100. });
  101. changesets
  102. }
  103. fn delete_row(&mut self, row: &Row, _cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
  104. let mut changesets = vec![];
  105. self.context.iter_mut_groups(|group| {
  106. let mut changeset = GroupRowsNotificationPB::new(group.id.clone());
  107. if group.contains_row(&row.id) {
  108. group.remove_row(&row.id);
  109. changeset.deleted_rows.push(row.id.clone().into_inner());
  110. }
  111. if !changeset.is_empty() {
  112. changesets.push(changeset);
  113. }
  114. });
  115. changesets
  116. }
  117. fn move_row(
  118. &mut self,
  119. _cell_data: &Self::CellData,
  120. mut context: MoveGroupRowContext,
  121. ) -> Vec<GroupRowsNotificationPB> {
  122. let mut group_changeset = vec![];
  123. self.context.iter_mut_groups(|group| {
  124. if let Some(changeset) = move_group_row(group, &mut context) {
  125. group_changeset.push(changeset);
  126. }
  127. });
  128. group_changeset
  129. }
  130. fn delete_group_when_move_row(
  131. &mut self,
  132. _row: &Row,
  133. _cell_data: &Self::CellData,
  134. ) -> Option<GroupPB> {
  135. let mut deleted_group = None;
  136. if let Some((_, group)) = self.context.get_group(&_cell_data.content) {
  137. if group.rows.len() == 1 {
  138. deleted_group = Some(GroupPB::from(group.clone()));
  139. }
  140. }
  141. if deleted_group.is_some() {
  142. let _ = self
  143. .context
  144. .delete_group(&deleted_group.as_ref().unwrap().group_id);
  145. }
  146. deleted_group
  147. }
  148. }
  149. impl GroupController for URLGroupController {
  150. fn did_update_field_type_option(&mut self, _field: &Arc<Field>) {}
  151. fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str) {
  152. match self.context.get_group(group_id) {
  153. None => tracing::warn!("Can not find the group: {}", group_id),
  154. Some((_, group)) => {
  155. let cell = insert_url_cell(group.id.clone(), field);
  156. cells.insert(field.id.clone(), cell);
  157. },
  158. }
  159. }
  160. fn did_create_row(&mut self, row_detail: &RowDetail, group_id: &str) {
  161. if let Some(group) = self.context.get_mut_group(group_id) {
  162. group.add_row(row_detail.clone())
  163. }
  164. }
  165. }
  166. pub struct URLGroupGenerator();
  167. impl GroupsBuilder for URLGroupGenerator {
  168. type Context = URLGroupContext;
  169. type TypeOptionType = URLTypeOption;
  170. fn build(
  171. field: &Field,
  172. context: &Self::Context,
  173. _type_option: &Option<Self::TypeOptionType>,
  174. ) -> GeneratedGroups {
  175. // Read all the cells for the grouping field
  176. let cells = futures::executor::block_on(context.get_all_cells());
  177. // Generate the groups
  178. let group_configs = cells
  179. .into_iter()
  180. .flat_map(|value| value.into_url_field_cell_data())
  181. .filter(|cell| !cell.data.is_empty())
  182. .map(|cell| GeneratedGroupConfig {
  183. group: make_group_from_url_cell(&cell),
  184. filter_content: cell.data,
  185. })
  186. .collect();
  187. let no_status_group = Some(make_no_status_group(field));
  188. GeneratedGroups {
  189. no_status_group,
  190. group_configs,
  191. }
  192. }
  193. }
  194. fn make_group_from_url_cell(cell: &URLCellData) -> Group {
  195. let group_id = cell.data.clone();
  196. let group_name = cell.data.clone();
  197. Group::new(group_id, group_name)
  198. }