url_controller.rs 6.4 KB

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