editor.rs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. use crate::dart_notification::{send_dart_notification, GridDartNotification};
  2. use crate::entities::*;
  3. use crate::services::filter::{FilterChangeset, FilterController, FilterTaskHandler, FilterType, UpdatedFilterType};
  4. use crate::services::group::{
  5. default_group_configuration, find_group_field, make_group_controller, Group, GroupConfigurationReader,
  6. GroupController, MoveGroupRowContext,
  7. };
  8. use crate::services::row::GridBlock;
  9. use crate::services::view_editor::changed_notifier::GridViewChangedNotifier;
  10. use crate::services::view_editor::trait_impl::*;
  11. use crate::services::view_editor::GridViewChangedReceiverRunner;
  12. use flowy_database::ConnectionPool;
  13. use flowy_error::FlowyResult;
  14. use flowy_http_model::revision::Revision;
  15. use flowy_revision::RevisionManager;
  16. use flowy_sync::client_grid::{make_grid_view_operations, GridViewRevisionChangeset, GridViewRevisionPad};
  17. use flowy_task::TaskDispatcher;
  18. use grid_rev_model::{
  19. gen_grid_filter_id, FieldRevision, FieldTypeRevision, FilterRevision, LayoutRevision, RowChangeset, RowRevision,
  20. };
  21. use lib_infra::async_trait::async_trait;
  22. use lib_infra::future::Fut;
  23. use lib_infra::ref_map::RefCountValue;
  24. use nanoid::nanoid;
  25. use std::future::Future;
  26. use std::sync::Arc;
  27. use tokio::sync::{broadcast, RwLock};
  28. pub trait GridViewEditorDelegate: Send + Sync + 'static {
  29. /// If the field_ids is None, then it will return all the field revisions
  30. fn get_field_revs(&self, field_ids: Option<Vec<String>>) -> Fut<Vec<Arc<FieldRevision>>>;
  31. fn get_field_rev(&self, field_id: &str) -> Fut<Option<Arc<FieldRevision>>>;
  32. fn index_of_row(&self, row_id: &str) -> Fut<Option<usize>>;
  33. fn get_row_rev(&self, row_id: &str) -> Fut<Option<(usize, Arc<RowRevision>)>>;
  34. fn get_row_revs(&self) -> Fut<Vec<Arc<RowRevision>>>;
  35. fn get_blocks(&self) -> Fut<Vec<GridBlock>>;
  36. fn get_task_scheduler(&self) -> Arc<RwLock<TaskDispatcher>>;
  37. }
  38. pub struct GridViewRevisionEditor {
  39. user_id: String,
  40. view_id: String,
  41. pad: Arc<RwLock<GridViewRevisionPad>>,
  42. rev_manager: Arc<RevisionManager<Arc<ConnectionPool>>>,
  43. delegate: Arc<dyn GridViewEditorDelegate>,
  44. group_controller: Arc<RwLock<Box<dyn GroupController>>>,
  45. filter_controller: Arc<RwLock<FilterController>>,
  46. pub notifier: GridViewChangedNotifier,
  47. }
  48. impl GridViewRevisionEditor {
  49. #[tracing::instrument(level = "trace", skip_all, err)]
  50. pub async fn new(
  51. user_id: &str,
  52. token: &str,
  53. view_id: String,
  54. delegate: Arc<dyn GridViewEditorDelegate>,
  55. mut rev_manager: RevisionManager<Arc<ConnectionPool>>,
  56. ) -> FlowyResult<Self> {
  57. let (notifier, _) = broadcast::channel(100);
  58. tokio::spawn(GridViewChangedReceiverRunner(Some(notifier.subscribe())).run());
  59. let cloud = Arc::new(GridViewRevisionCloudService {
  60. token: token.to_owned(),
  61. });
  62. let view_rev_pad = match rev_manager.initialize::<GridViewRevisionSerde>(Some(cloud)).await {
  63. Ok(pad) => pad,
  64. Err(err) => {
  65. // It shouldn't be here, because the snapshot should come to recue.
  66. tracing::error!("Deserialize grid view revisions failed: {}", err);
  67. let view = GridViewRevisionPad::new(view_id.to_owned(), view_id.to_owned(), LayoutRevision::Table);
  68. let bytes = make_grid_view_operations(&view).json_bytes();
  69. let reset_revision = Revision::initial_revision(&view_id, bytes);
  70. let _ = rev_manager.reset_object(vec![reset_revision]).await;
  71. view
  72. }
  73. };
  74. let view_rev_pad = Arc::new(RwLock::new(view_rev_pad));
  75. let rev_manager = Arc::new(rev_manager);
  76. let group_controller = new_group_controller(
  77. user_id.to_owned(),
  78. view_id.clone(),
  79. view_rev_pad.clone(),
  80. rev_manager.clone(),
  81. delegate.clone(),
  82. )
  83. .await?;
  84. let user_id = user_id.to_owned();
  85. let group_controller = Arc::new(RwLock::new(group_controller));
  86. let filter_controller =
  87. make_filter_controller(&view_id, delegate.clone(), notifier.clone(), view_rev_pad.clone()).await;
  88. Ok(Self {
  89. pad: view_rev_pad,
  90. user_id,
  91. view_id,
  92. rev_manager,
  93. delegate,
  94. group_controller,
  95. filter_controller,
  96. notifier,
  97. })
  98. }
  99. #[tracing::instrument(name = "close grid view editor", level = "trace", skip_all)]
  100. pub async fn close(&self) {
  101. self.rev_manager.generate_snapshot().await;
  102. self.rev_manager.close().await;
  103. self.filter_controller.read().await.close().await;
  104. }
  105. pub async fn filter_rows(&self, _block_id: &str, mut rows: Vec<Arc<RowRevision>>) -> Vec<Arc<RowRevision>> {
  106. self.filter_controller.write().await.filter_row_revs(&mut rows).await;
  107. rows
  108. }
  109. pub async fn duplicate_view_data(&self) -> FlowyResult<String> {
  110. let json_str = self.pad.read().await.json_str()?;
  111. Ok(json_str)
  112. }
  113. pub async fn will_create_view_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
  114. if params.group_id.is_none() {
  115. return;
  116. }
  117. let group_id = params.group_id.as_ref().unwrap();
  118. let _ = self
  119. .mut_group_controller(|group_controller, field_rev| {
  120. group_controller.will_create_row(row_rev, &field_rev, group_id);
  121. Ok(())
  122. })
  123. .await;
  124. }
  125. pub async fn did_create_view_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
  126. // Send the group notification if the current view has groups
  127. match params.group_id.as_ref() {
  128. None => {}
  129. Some(group_id) => {
  130. let index = match params.start_row_id {
  131. None => Some(0),
  132. Some(_) => None,
  133. };
  134. self.group_controller.write().await.did_create_row(row_pb, group_id);
  135. let inserted_row = InsertedRowPB {
  136. row: row_pb.clone(),
  137. index,
  138. is_new: true,
  139. };
  140. let changeset = GroupRowsNotificationPB::insert(group_id.clone(), vec![inserted_row]);
  141. self.notify_did_update_group_rows(changeset).await;
  142. }
  143. }
  144. }
  145. #[tracing::instrument(level = "trace", skip_all)]
  146. pub async fn did_delete_view_row(&self, row_rev: &RowRevision) {
  147. // Send the group notification if the current view has groups;
  148. let changesets = self
  149. .mut_group_controller(|group_controller, field_rev| {
  150. group_controller.did_delete_delete_row(row_rev, &field_rev)
  151. })
  152. .await;
  153. tracing::trace!("Delete row in view changeset: {:?}", changesets);
  154. if let Some(changesets) = changesets {
  155. for changeset in changesets {
  156. self.notify_did_update_group_rows(changeset).await;
  157. }
  158. }
  159. }
  160. pub async fn did_update_view_cell(&self, row_rev: &RowRevision) {
  161. let changesets = self
  162. .mut_group_controller(|group_controller, field_rev| {
  163. group_controller.did_update_group_row(row_rev, &field_rev)
  164. })
  165. .await;
  166. if let Some(changesets) = changesets {
  167. for changeset in changesets {
  168. self.notify_did_update_group_rows(changeset).await;
  169. }
  170. }
  171. let filter_controller = self.filter_controller.clone();
  172. let row_id = row_rev.id.clone();
  173. tokio::spawn(async move {
  174. filter_controller.write().await.did_receive_row_changed(&row_id).await;
  175. });
  176. }
  177. pub async fn move_view_group_row(
  178. &self,
  179. row_rev: &RowRevision,
  180. row_changeset: &mut RowChangeset,
  181. to_group_id: &str,
  182. to_row_id: Option<String>,
  183. ) -> Vec<GroupRowsNotificationPB> {
  184. let changesets = self
  185. .mut_group_controller(|group_controller, field_rev| {
  186. let move_row_context = MoveGroupRowContext {
  187. row_rev,
  188. row_changeset,
  189. field_rev: field_rev.as_ref(),
  190. to_group_id,
  191. to_row_id,
  192. };
  193. let changesets = group_controller.move_group_row(move_row_context)?;
  194. Ok(changesets)
  195. })
  196. .await;
  197. changesets.unwrap_or_default()
  198. }
  199. /// Only call once after grid view editor initialized
  200. #[tracing::instrument(level = "trace", skip(self))]
  201. pub async fn load_view_groups(&self) -> FlowyResult<Vec<GroupPB>> {
  202. let groups = self
  203. .group_controller
  204. .read()
  205. .await
  206. .groups()
  207. .into_iter()
  208. .cloned()
  209. .collect::<Vec<Group>>();
  210. tracing::trace!("Number of groups: {}", groups.len());
  211. Ok(groups.into_iter().map(GroupPB::from).collect())
  212. }
  213. #[tracing::instrument(level = "trace", skip(self), err)]
  214. pub async fn move_view_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
  215. let _ = self
  216. .group_controller
  217. .write()
  218. .await
  219. .move_group(&params.from_group_id, &params.to_group_id)?;
  220. match self.group_controller.read().await.get_group(&params.from_group_id) {
  221. None => tracing::warn!("Can not find the group with id: {}", params.from_group_id),
  222. Some((index, group)) => {
  223. let inserted_group = InsertedGroupPB {
  224. group: GroupPB::from(group),
  225. index: index as i32,
  226. };
  227. let changeset = GroupViewChangesetPB {
  228. view_id: self.view_id.clone(),
  229. inserted_groups: vec![inserted_group],
  230. deleted_groups: vec![params.from_group_id.clone()],
  231. update_groups: vec![],
  232. new_groups: vec![],
  233. };
  234. self.notify_did_update_view(changeset).await;
  235. }
  236. }
  237. Ok(())
  238. }
  239. pub async fn group_id(&self) -> String {
  240. self.group_controller.read().await.field_id().to_string()
  241. }
  242. pub async fn get_view_setting(&self) -> GridSettingPB {
  243. let field_revs = self.delegate.get_field_revs(None).await;
  244. let grid_setting = make_grid_setting(&*self.pad.read().await, &field_revs);
  245. grid_setting
  246. }
  247. pub async fn get_all_view_filters(&self) -> Vec<Arc<FilterRevision>> {
  248. let field_revs = self.delegate.get_field_revs(None).await;
  249. self.pad.read().await.get_all_filters(&field_revs)
  250. }
  251. pub async fn get_view_filters(&self, filter_type: &FilterType) -> Vec<Arc<FilterRevision>> {
  252. let field_type_rev: FieldTypeRevision = filter_type.field_type.clone().into();
  253. self.pad
  254. .read()
  255. .await
  256. .get_filters(&filter_type.field_id, &field_type_rev)
  257. }
  258. /// Initialize new group when grouping by a new field
  259. ///
  260. pub async fn initialize_new_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
  261. if let Some(field_rev) = self.delegate.get_field_rev(&params.field_id).await {
  262. let _ = self
  263. .modify(|pad| {
  264. let configuration = default_group_configuration(&field_rev);
  265. let changeset = pad.insert_or_update_group_configuration(
  266. &params.field_id,
  267. &params.field_type_rev,
  268. configuration,
  269. )?;
  270. Ok(changeset)
  271. })
  272. .await?;
  273. }
  274. if self.group_controller.read().await.field_id() != params.field_id {
  275. let _ = self.group_by_view_field(&params.field_id).await?;
  276. self.notify_did_update_setting().await;
  277. }
  278. Ok(())
  279. }
  280. pub async fn delete_view_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
  281. self.modify(|pad| {
  282. let changeset = pad.delete_group(&params.group_id, &params.field_id, &params.field_type_rev)?;
  283. Ok(changeset)
  284. })
  285. .await
  286. }
  287. #[tracing::instrument(level = "trace", skip(self), err)]
  288. pub async fn insert_view_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
  289. let filter_type = FilterType::from(&params);
  290. let is_exist = params.filter_id.is_some();
  291. let filter_id = match params.filter_id {
  292. None => gen_grid_filter_id(),
  293. Some(filter_id) => filter_id,
  294. };
  295. let filter_rev = FilterRevision {
  296. id: filter_id.clone(),
  297. field_id: params.field_id.clone(),
  298. field_type: params.field_type,
  299. condition: params.condition,
  300. content: params.content,
  301. };
  302. let mut filter_controller = self.filter_controller.write().await;
  303. let changeset = if is_exist {
  304. let old_filter_type = self
  305. .delegate
  306. .get_field_rev(&params.field_id)
  307. .await
  308. .map(|field| FilterType::from(&field));
  309. self.modify(|pad| {
  310. let changeset = pad.update_filter(&params.field_id, filter_rev)?;
  311. Ok(changeset)
  312. })
  313. .await?;
  314. filter_controller
  315. .did_receive_filter_changed(FilterChangeset::from_update(UpdatedFilterType::new(
  316. old_filter_type,
  317. filter_type,
  318. )))
  319. .await
  320. } else {
  321. self.modify(|pad| {
  322. let changeset = pad.insert_filter(&params.field_id, filter_rev)?;
  323. Ok(changeset)
  324. })
  325. .await?;
  326. filter_controller
  327. .did_receive_filter_changed(FilterChangeset::from_insert(filter_type))
  328. .await
  329. };
  330. if let Some(changeset) = changeset {
  331. self.notify_did_update_filter(changeset).await;
  332. }
  333. Ok(())
  334. }
  335. #[tracing::instrument(level = "trace", skip(self), err)]
  336. pub async fn delete_view_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
  337. let filter_type = params.filter_type;
  338. let field_type_rev = filter_type.field_type_rev();
  339. let changeset = self
  340. .filter_controller
  341. .write()
  342. .await
  343. .did_receive_filter_changed(FilterChangeset::from_delete(filter_type.clone()))
  344. .await;
  345. let _ = self
  346. .modify(|pad| {
  347. let changeset = pad.delete_filter(&params.filter_id, &filter_type.field_id, &field_type_rev)?;
  348. Ok(changeset)
  349. })
  350. .await?;
  351. if changeset.is_some() {
  352. self.notify_did_update_filter(changeset.unwrap()).await;
  353. }
  354. Ok(())
  355. }
  356. #[tracing::instrument(level = "trace", skip_all, err)]
  357. pub async fn did_update_view_field_type_option(
  358. &self,
  359. field_id: &str,
  360. old_field_rev: Option<Arc<FieldRevision>>,
  361. ) -> FlowyResult<()> {
  362. if let Some(field_rev) = self.delegate.get_field_rev(field_id).await {
  363. let old = old_field_rev.map(|old_field_rev| FilterType::from(&old_field_rev));
  364. let new = FilterType::from(&field_rev);
  365. let filter_type = UpdatedFilterType::new(old, new);
  366. let filter_changeset = FilterChangeset::from_update(filter_type);
  367. if let Some(changeset) = self
  368. .filter_controller
  369. .write()
  370. .await
  371. .did_receive_filter_changed(filter_changeset)
  372. .await
  373. {
  374. self.notify_did_update_filter(changeset).await;
  375. }
  376. }
  377. Ok(())
  378. }
  379. ///
  380. ///
  381. /// # Arguments
  382. ///
  383. /// * `field_id`:
  384. ///
  385. #[tracing::instrument(level = "debug", skip_all, err)]
  386. pub async fn group_by_view_field(&self, field_id: &str) -> FlowyResult<()> {
  387. if let Some(field_rev) = self.delegate.get_field_rev(field_id).await {
  388. let row_revs = self.delegate.get_row_revs().await;
  389. let new_group_controller = new_group_controller_with_field_rev(
  390. self.user_id.clone(),
  391. self.view_id.clone(),
  392. self.pad.clone(),
  393. self.rev_manager.clone(),
  394. field_rev,
  395. row_revs,
  396. )
  397. .await?;
  398. let new_groups = new_group_controller
  399. .groups()
  400. .into_iter()
  401. .map(|group| GroupPB::from(group.clone()))
  402. .collect();
  403. *self.group_controller.write().await = new_group_controller;
  404. let changeset = GroupViewChangesetPB {
  405. view_id: self.view_id.clone(),
  406. new_groups,
  407. ..Default::default()
  408. };
  409. debug_assert!(!changeset.is_empty());
  410. if !changeset.is_empty() {
  411. send_dart_notification(&changeset.view_id, GridDartNotification::DidGroupByNewField)
  412. .payload(changeset)
  413. .send();
  414. }
  415. }
  416. Ok(())
  417. }
  418. async fn notify_did_update_setting(&self) {
  419. let setting = self.get_view_setting().await;
  420. send_dart_notification(&self.view_id, GridDartNotification::DidUpdateGridSetting)
  421. .payload(setting)
  422. .send();
  423. }
  424. pub async fn notify_did_update_group_rows(&self, payload: GroupRowsNotificationPB) {
  425. send_dart_notification(&payload.group_id, GridDartNotification::DidUpdateGroup)
  426. .payload(payload)
  427. .send();
  428. }
  429. pub async fn notify_did_update_filter(&self, changeset: FilterChangesetNotificationPB) {
  430. send_dart_notification(&changeset.view_id, GridDartNotification::DidUpdateFilter)
  431. .payload(changeset)
  432. .send();
  433. }
  434. async fn notify_did_update_view(&self, changeset: GroupViewChangesetPB) {
  435. send_dart_notification(&self.view_id, GridDartNotification::DidUpdateGroupView)
  436. .payload(changeset)
  437. .send();
  438. }
  439. async fn modify<F>(&self, f: F) -> FlowyResult<()>
  440. where
  441. F: for<'a> FnOnce(&'a mut GridViewRevisionPad) -> FlowyResult<Option<GridViewRevisionChangeset>>,
  442. {
  443. let mut write_guard = self.pad.write().await;
  444. match f(&mut *write_guard)? {
  445. None => {}
  446. Some(change) => {
  447. let _ = apply_change(&self.user_id, self.rev_manager.clone(), change).await?;
  448. }
  449. }
  450. Ok(())
  451. }
  452. async fn mut_group_controller<F, T>(&self, f: F) -> Option<T>
  453. where
  454. F: FnOnce(&mut Box<dyn GroupController>, Arc<FieldRevision>) -> FlowyResult<T>,
  455. {
  456. let group_field_id = self.group_controller.read().await.field_id().to_owned();
  457. match self.delegate.get_field_rev(&group_field_id).await {
  458. None => None,
  459. Some(field_rev) => {
  460. let mut write_guard = self.group_controller.write().await;
  461. f(&mut write_guard, field_rev).ok()
  462. }
  463. }
  464. }
  465. #[allow(dead_code)]
  466. async fn async_mut_group_controller<F, O, T>(&self, f: F) -> Option<T>
  467. where
  468. F: FnOnce(Arc<RwLock<Box<dyn GroupController>>>, Arc<FieldRevision>) -> O,
  469. O: Future<Output = FlowyResult<T>> + Sync + 'static,
  470. {
  471. let group_field_id = self.group_controller.read().await.field_id().to_owned();
  472. match self.delegate.get_field_rev(&group_field_id).await {
  473. None => None,
  474. Some(field_rev) => {
  475. let _write_guard = self.group_controller.write().await;
  476. f(self.group_controller.clone(), field_rev).await.ok()
  477. }
  478. }
  479. }
  480. }
  481. #[async_trait]
  482. impl RefCountValue for GridViewRevisionEditor {
  483. async fn did_remove(&self) {
  484. self.close().await;
  485. }
  486. }
  487. async fn new_group_controller(
  488. user_id: String,
  489. view_id: String,
  490. view_rev_pad: Arc<RwLock<GridViewRevisionPad>>,
  491. rev_manager: Arc<RevisionManager<Arc<ConnectionPool>>>,
  492. delegate: Arc<dyn GridViewEditorDelegate>,
  493. ) -> FlowyResult<Box<dyn GroupController>> {
  494. let configuration_reader = GroupConfigurationReaderImpl(view_rev_pad.clone());
  495. let field_revs = delegate.get_field_revs(None).await;
  496. let row_revs = delegate.get_row_revs().await;
  497. let layout = view_rev_pad.read().await.layout();
  498. // Read the group field or find a new group field
  499. let field_rev = configuration_reader
  500. .get_configuration()
  501. .await
  502. .and_then(|configuration| {
  503. field_revs
  504. .iter()
  505. .find(|field_rev| field_rev.id == configuration.field_id)
  506. .cloned()
  507. })
  508. .unwrap_or_else(|| find_group_field(&field_revs, &layout).unwrap());
  509. new_group_controller_with_field_rev(user_id, view_id, view_rev_pad, rev_manager, field_rev, row_revs).await
  510. }
  511. /// Returns a [GroupController]
  512. ///
  513. async fn new_group_controller_with_field_rev(
  514. user_id: String,
  515. view_id: String,
  516. view_rev_pad: Arc<RwLock<GridViewRevisionPad>>,
  517. rev_manager: Arc<RevisionManager<Arc<ConnectionPool>>>,
  518. field_rev: Arc<FieldRevision>,
  519. row_revs: Vec<Arc<RowRevision>>,
  520. ) -> FlowyResult<Box<dyn GroupController>> {
  521. let configuration_reader = GroupConfigurationReaderImpl(view_rev_pad.clone());
  522. let configuration_writer = GroupConfigurationWriterImpl {
  523. user_id,
  524. rev_manager,
  525. view_pad: view_rev_pad,
  526. };
  527. make_group_controller(view_id, field_rev, row_revs, configuration_reader, configuration_writer).await
  528. }
  529. async fn make_filter_controller(
  530. view_id: &str,
  531. delegate: Arc<dyn GridViewEditorDelegate>,
  532. notifier: GridViewChangedNotifier,
  533. pad: Arc<RwLock<GridViewRevisionPad>>,
  534. ) -> Arc<RwLock<FilterController>> {
  535. let field_revs = delegate.get_field_revs(None).await;
  536. let filter_revs = pad.read().await.get_all_filters(&field_revs);
  537. let task_scheduler = delegate.get_task_scheduler();
  538. let filter_delegate = GridViewFilterDelegateImpl {
  539. editor_delegate: delegate.clone(),
  540. view_revision_pad: pad,
  541. };
  542. let handler_id = gen_handler_id();
  543. let filter_controller = FilterController::new(
  544. view_id,
  545. &handler_id,
  546. filter_delegate,
  547. task_scheduler.clone(),
  548. filter_revs,
  549. notifier,
  550. )
  551. .await;
  552. let filter_controller = Arc::new(RwLock::new(filter_controller));
  553. task_scheduler
  554. .write()
  555. .await
  556. .register_handler(FilterTaskHandler::new(handler_id, filter_controller.clone()));
  557. filter_controller
  558. }
  559. fn gen_handler_id() -> String {
  560. nanoid!(10)
  561. }
  562. #[cfg(test)]
  563. mod tests {
  564. use flowy_sync::client_grid::GridOperations;
  565. #[test]
  566. fn test() {
  567. let s1 = r#"[{"insert":"{\"view_id\":\"fTURELffPr\",\"grid_id\":\"fTURELffPr\",\"layout\":0,\"filters\":[],\"groups\":[]}"}]"#;
  568. let _delta_1 = GridOperations::from_json(s1).unwrap();
  569. let s2 = r#"[{"retain":195},{"insert":"{\\\"group_id\\\":\\\"wD9i\\\",\\\"visible\\\":true},{\\\"group_id\\\":\\\"xZtv\\\",\\\"visible\\\":true},{\\\"group_id\\\":\\\"tFV2\\\",\\\"visible\\\":true}"},{"retain":10}]"#;
  570. let _delta_2 = GridOperations::from_json(s2).unwrap();
  571. }
  572. }