configuration.rs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. use crate::services::group::{default_group_configuration, Group};
  2. use flowy_error::{FlowyError, FlowyResult};
  3. use flowy_grid_data_model::revision::{
  4. FieldRevision, FieldTypeRevision, GroupConfigurationContentSerde, GroupConfigurationRevision, GroupRecordRevision,
  5. };
  6. use std::marker::PhantomData;
  7. use indexmap::IndexMap;
  8. use lib_infra::future::AFFuture;
  9. use std::sync::Arc;
  10. pub trait GroupConfigurationReader: Send + Sync + 'static {
  11. fn get_group_configuration(
  12. &self,
  13. field_rev: Arc<FieldRevision>,
  14. ) -> AFFuture<Option<Arc<GroupConfigurationRevision>>>;
  15. }
  16. pub trait GroupConfigurationWriter: Send + Sync + 'static {
  17. fn save_group_configuration(
  18. &self,
  19. field_id: &str,
  20. field_type: FieldTypeRevision,
  21. group_configuration: GroupConfigurationRevision,
  22. ) -> AFFuture<FlowyResult<()>>;
  23. }
  24. pub struct GenericGroupConfiguration<C> {
  25. pub configuration: Arc<GroupConfigurationRevision>,
  26. configuration_content: PhantomData<C>,
  27. field_rev: Arc<FieldRevision>,
  28. groups_map: IndexMap<String, Group>,
  29. writer: Arc<dyn GroupConfigurationWriter>,
  30. }
  31. impl<C> GenericGroupConfiguration<C>
  32. where
  33. C: GroupConfigurationContentSerde,
  34. {
  35. #[tracing::instrument(level = "trace", skip_all, err)]
  36. pub async fn new(
  37. field_rev: Arc<FieldRevision>,
  38. reader: Arc<dyn GroupConfigurationReader>,
  39. writer: Arc<dyn GroupConfigurationWriter>,
  40. ) -> FlowyResult<Self> {
  41. let configuration = match reader.get_group_configuration(field_rev.clone()).await {
  42. None => {
  43. let default_group_configuration = default_group_configuration(&field_rev);
  44. writer
  45. .save_group_configuration(&field_rev.id, field_rev.ty, default_group_configuration.clone())
  46. .await?;
  47. Arc::new(default_group_configuration)
  48. }
  49. Some(configuration) => configuration,
  50. };
  51. // let configuration = C::from_configuration_content(&configuration_rev.content)?;
  52. Ok(Self {
  53. field_rev,
  54. groups_map: IndexMap::new(),
  55. writer,
  56. configuration,
  57. configuration_content: PhantomData,
  58. })
  59. }
  60. pub(crate) fn groups(&self) -> Vec<&Group> {
  61. self.groups_map.values().collect()
  62. }
  63. pub(crate) fn clone_groups(&self) -> Vec<Group> {
  64. self.groups_map.values().cloned().collect()
  65. }
  66. pub(crate) async fn merge_groups(&mut self, groups: Vec<Group>) -> FlowyResult<()> {
  67. let (group_revs, groups) = merge_groups(&self.configuration.groups, groups);
  68. self.mut_configuration(move |configuration| {
  69. configuration.groups = group_revs;
  70. true
  71. })?;
  72. groups.into_iter().for_each(|group| {
  73. self.groups_map.insert(group.id.clone(), group);
  74. });
  75. Ok(())
  76. }
  77. #[allow(dead_code)]
  78. pub(crate) async fn hide_group(&mut self, group_id: &str) -> FlowyResult<()> {
  79. self.mut_configuration_group(group_id, |group_rev| {
  80. group_rev.visible = false;
  81. })?;
  82. Ok(())
  83. }
  84. #[allow(dead_code)]
  85. pub(crate) async fn show_group(&mut self, group_id: &str) -> FlowyResult<()> {
  86. self.mut_configuration_group(group_id, |group_rev| {
  87. group_rev.visible = true;
  88. })?;
  89. Ok(())
  90. }
  91. pub(crate) fn with_mut_groups(&mut self, mut each: impl FnMut(&mut Group)) {
  92. self.groups_map.iter_mut().for_each(|(_, group)| {
  93. each(group);
  94. })
  95. }
  96. pub(crate) fn get_mut_group(&mut self, group_id: &str) -> Option<&mut Group> {
  97. self.groups_map.get_mut(group_id)
  98. }
  99. pub(crate) fn move_group(&mut self, from_id: &str, to_id: &str) -> FlowyResult<()> {
  100. let from_index = self.groups_map.get_index_of(from_id);
  101. let to_index = self.groups_map.get_index_of(to_id);
  102. match (from_index, to_index) {
  103. (Some(from_index), Some(to_index)) => {
  104. self.groups_map.swap_indices(from_index, to_index);
  105. self.mut_configuration(|configuration| {
  106. let from_index = configuration.groups.iter().position(|group| group.group_id == from_id);
  107. let to_index = configuration.groups.iter().position(|group| group.group_id == to_id);
  108. if let (Some(from), Some(to)) = (from_index, to_index) {
  109. configuration.groups.swap(from, to);
  110. }
  111. true
  112. })?;
  113. Ok(())
  114. }
  115. _ => Err(FlowyError::out_of_bounds()),
  116. }
  117. }
  118. // Returns the index and group specified by the group_id
  119. pub(crate) fn get_group(&self, group_id: &str) -> Option<(usize, &Group)> {
  120. match (self.groups_map.get_index_of(group_id), self.groups_map.get(group_id)) {
  121. (Some(index), Some(group)) => Some((index, group)),
  122. _ => None,
  123. }
  124. }
  125. pub fn save_configuration(&self) -> FlowyResult<()> {
  126. let configuration = (&*self.configuration).clone();
  127. let writer = self.writer.clone();
  128. let field_id = self.field_rev.id.clone();
  129. let field_type = self.field_rev.ty;
  130. tokio::spawn(async move {
  131. match writer
  132. .save_group_configuration(&field_id, field_type, configuration)
  133. .await
  134. {
  135. Ok(_) => {}
  136. Err(e) => {
  137. tracing::error!("Save group configuration failed: {}", e);
  138. }
  139. }
  140. });
  141. Ok(())
  142. }
  143. fn mut_configuration_group(
  144. &mut self,
  145. group_id: &str,
  146. mut_groups_fn: impl Fn(&mut GroupRecordRevision),
  147. ) -> FlowyResult<()> {
  148. self.mut_configuration(|configuration| {
  149. match configuration.groups.iter_mut().find(|group| group.group_id == group_id) {
  150. None => false,
  151. Some(group_rev) => {
  152. mut_groups_fn(group_rev);
  153. true
  154. }
  155. }
  156. })
  157. }
  158. fn mut_configuration(
  159. &mut self,
  160. mut_configuration_fn: impl FnOnce(&mut GroupConfigurationRevision) -> bool,
  161. ) -> FlowyResult<()> {
  162. let configuration = Arc::make_mut(&mut self.configuration);
  163. let is_changed = mut_configuration_fn(configuration);
  164. if is_changed {
  165. let _ = self.save_configuration()?;
  166. }
  167. Ok(())
  168. }
  169. }
  170. fn merge_groups(old_group_revs: &[GroupRecordRevision], groups: Vec<Group>) -> (Vec<GroupRecordRevision>, Vec<Group>) {
  171. if old_group_revs.is_empty() {
  172. let new_groups = groups
  173. .iter()
  174. .map(|group| GroupRecordRevision::new(group.id.clone()))
  175. .collect();
  176. return (new_groups, groups);
  177. }
  178. let mut group_map: IndexMap<String, Group> = IndexMap::new();
  179. groups.into_iter().for_each(|group| {
  180. group_map.insert(group.id.clone(), group);
  181. });
  182. // Inert
  183. let mut sorted_groups: Vec<Group> = vec![];
  184. for group_rev in old_group_revs {
  185. if let Some(group) = group_map.remove(&group_rev.group_id) {
  186. sorted_groups.push(group);
  187. }
  188. }
  189. sorted_groups.extend(group_map.into_values().collect::<Vec<Group>>());
  190. let new_group_revs = sorted_groups
  191. .iter()
  192. .map(|group| GroupRecordRevision::new(group.id.clone()))
  193. .collect::<Vec<GroupRecordRevision>>();
  194. tracing::trace!("group revs: {}, groups: {}", new_group_revs.len(), sorted_groups.len());
  195. (new_group_revs, sorted_groups)
  196. }