configuration.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. use crate::entities::{GroupPB, GroupViewChangesetPB};
  2. use crate::services::group::{default_group_configuration, make_default_group, GeneratedGroup, Group};
  3. use flowy_error::{FlowyError, FlowyResult};
  4. use flowy_grid_data_model::revision::{
  5. FieldRevision, FieldTypeRevision, GroupConfigurationContentSerde, GroupConfigurationRevision, GroupRevision,
  6. };
  7. use indexmap::IndexMap;
  8. use lib_infra::future::AFFuture;
  9. use std::collections::HashMap;
  10. use std::fmt::Formatter;
  11. use std::marker::PhantomData;
  12. use std::sync::Arc;
  13. pub trait GroupConfigurationReader: Send + Sync + 'static {
  14. fn get_configuration(&self) -> AFFuture<Option<Arc<GroupConfigurationRevision>>>;
  15. }
  16. pub trait GroupConfigurationWriter: Send + Sync + 'static {
  17. fn save_configuration(
  18. &self,
  19. field_id: &str,
  20. field_type: FieldTypeRevision,
  21. group_configuration: GroupConfigurationRevision,
  22. ) -> AFFuture<FlowyResult<()>>;
  23. }
  24. impl<T> std::fmt::Display for GroupContext<T> {
  25. fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
  26. self.groups_map.iter().for_each(|(_, group)| {
  27. let _ = f.write_fmt(format_args!("Group:{} has {} rows \n", group.id, group.rows.len()));
  28. });
  29. Ok(())
  30. }
  31. }
  32. pub struct GroupContext<C> {
  33. pub view_id: String,
  34. configuration: Arc<GroupConfigurationRevision>,
  35. configuration_content: PhantomData<C>,
  36. field_rev: Arc<FieldRevision>,
  37. groups_map: IndexMap<String, Group>,
  38. /// default_group is used to store the rows that don't belong to any groups.
  39. // default_group: Group,
  40. writer: Arc<dyn GroupConfigurationWriter>,
  41. }
  42. impl<C> GroupContext<C>
  43. where
  44. C: GroupConfigurationContentSerde,
  45. {
  46. #[tracing::instrument(level = "trace", skip_all, err)]
  47. pub async fn new(
  48. view_id: String,
  49. field_rev: Arc<FieldRevision>,
  50. reader: Arc<dyn GroupConfigurationReader>,
  51. writer: Arc<dyn GroupConfigurationWriter>,
  52. ) -> FlowyResult<Self> {
  53. let configuration = match reader.get_configuration().await {
  54. None => {
  55. let default_configuration = default_group_configuration(&field_rev);
  56. writer
  57. .save_configuration(&field_rev.id, field_rev.ty, default_configuration.clone())
  58. .await?;
  59. Arc::new(default_configuration)
  60. }
  61. Some(configuration) => configuration,
  62. };
  63. Ok(Self {
  64. view_id,
  65. field_rev,
  66. groups_map: IndexMap::new(),
  67. writer,
  68. configuration,
  69. configuration_content: PhantomData,
  70. })
  71. }
  72. pub(crate) fn get_default_group(&self) -> Option<&Group> {
  73. self.groups_map.get(&self.field_rev.id)
  74. }
  75. pub(crate) fn get_mut_default_group(&mut self) -> Option<&mut Group> {
  76. self.groups_map.get_mut(&self.field_rev.id)
  77. }
  78. /// Returns the groups without the default group
  79. pub(crate) fn groups(&self) -> Vec<&Group> {
  80. self.groups_map.values().collect()
  81. }
  82. pub(crate) fn get_mut_group(&mut self, group_id: &str) -> Option<&mut Group> {
  83. self.groups_map.get_mut(group_id)
  84. }
  85. // Returns the index and group specified by the group_id
  86. pub(crate) fn get_group(&self, group_id: &str) -> Option<(usize, &Group)> {
  87. match (self.groups_map.get_index_of(group_id), self.groups_map.get(group_id)) {
  88. (Some(index), Some(group)) => Some((index, group)),
  89. _ => None,
  90. }
  91. }
  92. /// Iterate mut the groups. The default group will be the last one that get mutated.
  93. pub(crate) fn iter_mut_all_groups(&mut self, mut each: impl FnMut(&mut Group)) {
  94. self.groups_map.iter_mut().for_each(|(_, group)| {
  95. each(group);
  96. });
  97. }
  98. pub(crate) fn move_group(&mut self, from_id: &str, to_id: &str) -> FlowyResult<()> {
  99. let from_index = self.groups_map.get_index_of(from_id);
  100. let to_index = self.groups_map.get_index_of(to_id);
  101. match (from_index, to_index) {
  102. (Some(from_index), Some(to_index)) => {
  103. self.groups_map.move_index(from_index, to_index);
  104. self.mut_configuration(|configuration| {
  105. let from_index = configuration.groups.iter().position(|group| group.id == from_id);
  106. let to_index = configuration.groups.iter().position(|group| group.id == to_id);
  107. tracing::info!("Configuration groups: {:?} ", configuration.groups);
  108. if let (Some(from), Some(to)) = &(from_index, to_index) {
  109. tracing::trace!("Move group from index:{:?} to index:{:?}", from_index, to_index);
  110. let group = configuration.groups.remove(*from);
  111. configuration.groups.insert(*to, group);
  112. }
  113. from_index.is_some() && to_index.is_some()
  114. })?;
  115. Ok(())
  116. }
  117. _ => Err(FlowyError::record_not_found().context("Moving group failed. Groups are not exist")),
  118. }
  119. }
  120. #[tracing::instrument(level = "debug", skip(self, generated_groups), err)]
  121. pub(crate) fn init_groups(
  122. &mut self,
  123. generated_groups: Vec<GeneratedGroup>,
  124. ) -> FlowyResult<Option<GroupViewChangesetPB>> {
  125. let mut new_groups = vec![];
  126. let mut filter_content_map = HashMap::new();
  127. generated_groups.into_iter().for_each(|generate_group| {
  128. filter_content_map.insert(generate_group.group_rev.id.clone(), generate_group.filter_content);
  129. new_groups.push(generate_group.group_rev);
  130. });
  131. let mut old_groups = self.configuration.groups.clone();
  132. if !old_groups.iter().any(|group| group.id == self.field_rev.id) {
  133. old_groups.push(make_default_group(&self.field_rev));
  134. }
  135. let MergeGroupResult {
  136. mut all_group_revs,
  137. new_group_revs,
  138. updated_group_revs: _,
  139. deleted_group_revs,
  140. } = merge_groups(old_groups, new_groups);
  141. let deleted_group_ids = deleted_group_revs
  142. .into_iter()
  143. .map(|group_rev| group_rev.id)
  144. .collect::<Vec<String>>();
  145. self.mut_configuration(|configuration| {
  146. let mut is_changed = false;
  147. if !deleted_group_ids.is_empty() {
  148. configuration
  149. .groups
  150. .retain(|group| !deleted_group_ids.contains(&group.id));
  151. is_changed = true;
  152. }
  153. for group_rev in &mut all_group_revs {
  154. match configuration
  155. .groups
  156. .iter()
  157. .position(|old_group_rev| old_group_rev.id == group_rev.id)
  158. {
  159. None => {
  160. configuration.groups.push(group_rev.clone());
  161. is_changed = true;
  162. }
  163. Some(pos) => {
  164. let mut old_group = configuration.groups.remove(pos);
  165. group_rev.update_with_other(&old_group);
  166. is_changed = is_group_changed(group_rev, &old_group);
  167. old_group.name = group_rev.name.clone();
  168. configuration.groups.insert(pos, old_group);
  169. }
  170. }
  171. }
  172. is_changed
  173. })?;
  174. all_group_revs.into_iter().for_each(|group_rev| {
  175. let filter_content = filter_content_map
  176. .get(&group_rev.id)
  177. .cloned()
  178. .unwrap_or_else(|| "".to_owned());
  179. let group = Group::new(group_rev.id, self.field_rev.id.clone(), group_rev.name, filter_content);
  180. self.groups_map.insert(group.id.clone(), group);
  181. });
  182. let new_groups = new_group_revs
  183. .into_iter()
  184. .flat_map(|group_rev| {
  185. let filter_content = filter_content_map.get(&group_rev.id)?;
  186. let group = Group::new(
  187. group_rev.id,
  188. self.field_rev.id.clone(),
  189. group_rev.name,
  190. filter_content.clone(),
  191. );
  192. Some(GroupPB::from(group))
  193. })
  194. .collect();
  195. let changeset = GroupViewChangesetPB {
  196. view_id: self.view_id.clone(),
  197. new_groups,
  198. deleted_groups: deleted_group_ids,
  199. update_groups: vec![],
  200. inserted_groups: vec![],
  201. };
  202. tracing::trace!("Group changeset: {:?}", changeset);
  203. if changeset.is_empty() {
  204. Ok(None)
  205. } else {
  206. Ok(Some(changeset))
  207. }
  208. }
  209. #[allow(dead_code)]
  210. pub(crate) async fn hide_group(&mut self, group_id: &str) -> FlowyResult<()> {
  211. self.mut_group_rev(group_id, |group_rev| {
  212. group_rev.visible = false;
  213. })?;
  214. Ok(())
  215. }
  216. #[allow(dead_code)]
  217. pub(crate) async fn show_group(&mut self, group_id: &str) -> FlowyResult<()> {
  218. self.mut_group_rev(group_id, |group_rev| {
  219. group_rev.visible = true;
  220. })?;
  221. Ok(())
  222. }
  223. #[tracing::instrument(level = "trace", skip_all, err)]
  224. pub fn save_configuration(&self) -> FlowyResult<()> {
  225. let configuration = (&*self.configuration).clone();
  226. let writer = self.writer.clone();
  227. let field_id = self.field_rev.id.clone();
  228. let field_type = self.field_rev.ty;
  229. tokio::spawn(async move {
  230. match writer.save_configuration(&field_id, field_type, configuration).await {
  231. Ok(_) => {}
  232. Err(e) => {
  233. tracing::error!("Save group configuration failed: {}", e);
  234. }
  235. }
  236. });
  237. Ok(())
  238. }
  239. fn mut_configuration(
  240. &mut self,
  241. mut_configuration_fn: impl FnOnce(&mut GroupConfigurationRevision) -> bool,
  242. ) -> FlowyResult<()> {
  243. let configuration = Arc::make_mut(&mut self.configuration);
  244. let is_changed = mut_configuration_fn(configuration);
  245. if is_changed {
  246. let _ = self.save_configuration()?;
  247. }
  248. Ok(())
  249. }
  250. fn mut_group_rev(&mut self, group_id: &str, mut_groups_fn: impl Fn(&mut GroupRevision)) -> FlowyResult<()> {
  251. self.mut_configuration(|configuration| {
  252. match configuration.groups.iter_mut().find(|group| group.id == group_id) {
  253. None => false,
  254. Some(group_rev) => {
  255. mut_groups_fn(group_rev);
  256. true
  257. }
  258. }
  259. })
  260. }
  261. }
  262. fn merge_groups(old_groups: Vec<GroupRevision>, new_groups: Vec<GroupRevision>) -> MergeGroupResult {
  263. let mut merge_result = MergeGroupResult::new();
  264. // if old_groups.is_empty() {
  265. // merge_result.all_group_revs.extend(new_groups.clone());
  266. // merge_result.all_group_revs.push(default_group);
  267. // merge_result.new_group_revs = new_groups;
  268. // return merge_result;
  269. // }
  270. // group_map is a helper map is used to filter out the new groups.
  271. let mut new_group_map: IndexMap<String, GroupRevision> = IndexMap::new();
  272. new_groups.into_iter().for_each(|group_rev| {
  273. new_group_map.insert(group_rev.id.clone(), group_rev);
  274. });
  275. // The group is ordered in old groups. Add them before adding the new groups
  276. for old in old_groups {
  277. if let Some(new) = new_group_map.remove(&old.id) {
  278. merge_result.all_group_revs.push(new.clone());
  279. if is_group_changed(&new, &old) {
  280. merge_result.updated_group_revs.push(new);
  281. }
  282. } else {
  283. merge_result.all_group_revs.push(old);
  284. }
  285. }
  286. // Find out the new groups
  287. new_group_map.reverse();
  288. let new_groups = new_group_map.into_values();
  289. for (_, group) in new_groups.into_iter().enumerate() {
  290. merge_result.all_group_revs.insert(0, group.clone());
  291. merge_result.new_group_revs.insert(0, group);
  292. }
  293. merge_result
  294. }
  295. fn is_group_changed(new: &GroupRevision, old: &GroupRevision) -> bool {
  296. if new.name != old.name {
  297. return true;
  298. }
  299. false
  300. }
  301. struct MergeGroupResult {
  302. // Contains the new groups and the updated groups
  303. all_group_revs: Vec<GroupRevision>,
  304. new_group_revs: Vec<GroupRevision>,
  305. updated_group_revs: Vec<GroupRevision>,
  306. deleted_group_revs: Vec<GroupRevision>,
  307. }
  308. impl MergeGroupResult {
  309. fn new() -> Self {
  310. Self {
  311. all_group_revs: vec![],
  312. new_group_revs: vec![],
  313. updated_group_revs: vec![],
  314. deleted_group_revs: vec![],
  315. }
  316. }
  317. }