grid_editor.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. #![allow(clippy::all)]
  2. #![allow(dead_code)]
  3. #![allow(unused_imports)]
  4. use crate::grid::block_test::util::GridRowTestBuilder;
  5. use bytes::Bytes;
  6. use flowy_error::FlowyResult;
  7. use flowy_grid::entities::*;
  8. use flowy_grid::services::field::SelectOptionPB;
  9. use flowy_grid::services::field::*;
  10. use flowy_grid::services::grid_editor::{GridRevisionEditor, GridRevisionSerde};
  11. use flowy_grid::services::row::{CreateRowRevisionPayload, RowRevisionBuilder};
  12. use flowy_grid::services::setting::GridSettingChangesetBuilder;
  13. use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
  14. use flowy_sync::client_grid::GridBuilder;
  15. use flowy_test::helper::ViewTest;
  16. use flowy_test::FlowySDKTest;
  17. use grid_rev_model::*;
  18. use std::collections::HashMap;
  19. use std::sync::Arc;
  20. use std::time::Duration;
  21. use strum::EnumCount;
  22. use strum::IntoEnumIterator;
  23. use tokio::time::sleep;
  24. pub struct GridEditorTest {
  25. pub sdk: FlowySDKTest,
  26. pub grid_id: String,
  27. pub editor: Arc<GridRevisionEditor>,
  28. pub field_revs: Vec<Arc<FieldRevision>>,
  29. pub block_meta_revs: Vec<Arc<GridBlockMetaRevision>>,
  30. pub row_revs: Vec<Arc<RowRevision>>,
  31. pub field_count: usize,
  32. pub row_order_by_row_id: HashMap<String, RowPB>,
  33. }
  34. impl GridEditorTest {
  35. pub async fn new_table() -> Self {
  36. Self::new(GridLayout::Table).await
  37. }
  38. pub async fn new_board() -> Self {
  39. Self::new(GridLayout::Board).await
  40. }
  41. pub async fn new(layout: GridLayout) -> Self {
  42. let sdk = FlowySDKTest::default();
  43. let _ = sdk.init_user().await;
  44. let test = match layout {
  45. GridLayout::Table => {
  46. let build_context = make_test_grid();
  47. let view_data: Bytes = build_context.into();
  48. ViewTest::new_grid_view(&sdk, view_data.to_vec()).await
  49. }
  50. GridLayout::Board => {
  51. let build_context = make_test_board();
  52. let view_data: Bytes = build_context.into();
  53. ViewTest::new_board_view(&sdk, view_data.to_vec()).await
  54. }
  55. };
  56. let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap();
  57. let field_revs = editor.get_field_revs(None).await.unwrap();
  58. let block_meta_revs = editor.get_block_meta_revs().await.unwrap();
  59. let row_revs = editor.get_blocks(None).await.unwrap().pop().unwrap().row_revs;
  60. assert_eq!(block_meta_revs.len(), 1);
  61. // It seems like you should add the field in the make_test_grid() function.
  62. // Because we assert the initialize count of the fields is equal to FieldType::COUNT.
  63. assert_eq!(field_revs.len(), FieldType::COUNT);
  64. let grid_id = test.view.id;
  65. Self {
  66. sdk,
  67. grid_id,
  68. editor,
  69. field_revs,
  70. block_meta_revs,
  71. row_revs,
  72. field_count: FieldType::COUNT,
  73. row_order_by_row_id: HashMap::default(),
  74. }
  75. }
  76. pub async fn get_row_revs(&self) -> Vec<Arc<RowRevision>> {
  77. self.editor.get_blocks(None).await.unwrap().pop().unwrap().row_revs
  78. }
  79. pub async fn grid_filters(&self) -> Vec<FilterPB> {
  80. self.editor.get_all_filters().await.unwrap()
  81. }
  82. pub fn get_field_rev(&self, field_type: FieldType) -> &Arc<FieldRevision> {
  83. self.field_revs
  84. .iter()
  85. .filter(|field_rev| {
  86. let t_field_type: FieldType = field_rev.ty.into();
  87. t_field_type == field_type
  88. })
  89. .collect::<Vec<_>>()
  90. .pop()
  91. .unwrap()
  92. }
  93. pub fn get_multi_select_type_option(&self) -> Vec<SelectOptionPB> {
  94. let field_type = FieldType::MultiSelect;
  95. let field_rev = self.get_field_rev(field_type.clone());
  96. let type_option = field_rev
  97. .get_type_option::<MultiSelectTypeOptionPB>(field_type.into())
  98. .unwrap();
  99. type_option.options
  100. }
  101. pub fn get_single_select_type_option(&self) -> Vec<SelectOptionPB> {
  102. let field_type = FieldType::SingleSelect;
  103. let field_rev = self.get_field_rev(field_type.clone());
  104. let type_option = field_rev
  105. .get_type_option::<SingleSelectTypeOptionPB>(field_type.into())
  106. .unwrap();
  107. type_option.options
  108. }
  109. pub fn block_id(&self) -> &str {
  110. &self.block_meta_revs.last().unwrap().block_id
  111. }
  112. }
  113. pub const GOOGLE: &str = "Google";
  114. pub const FACEBOOK: &str = "Facebook";
  115. pub const TWITTER: &str = "Twitter";
  116. pub const COMPLETED: &str = "Completed";
  117. pub const PLANNED: &str = "Planned";
  118. pub const PAUSED: &str = "Paused";
  119. // This grid is assumed to contain all the Fields.
  120. fn make_test_grid() -> BuildGridContext {
  121. let mut grid_builder = GridBuilder::new();
  122. // Iterate through the FieldType to create the corresponding Field.
  123. for field_type in FieldType::iter() {
  124. let field_type: FieldType = field_type;
  125. // The
  126. match field_type {
  127. FieldType::RichText => {
  128. let text_field = FieldBuilder::new(RichTextTypeOptionBuilder::default())
  129. .name("Name")
  130. .visibility(true)
  131. .primary(true)
  132. .build();
  133. grid_builder.add_field(text_field);
  134. }
  135. FieldType::Number => {
  136. // Number
  137. let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD);
  138. let number_field = FieldBuilder::new(number).name("Price").visibility(true).build();
  139. grid_builder.add_field(number_field);
  140. }
  141. FieldType::DateTime => {
  142. // Date
  143. let date = DateTypeOptionBuilder::default()
  144. .date_format(DateFormat::US)
  145. .time_format(TimeFormat::TwentyFourHour);
  146. let date_field = FieldBuilder::new(date).name("Time").visibility(true).build();
  147. grid_builder.add_field(date_field);
  148. }
  149. FieldType::SingleSelect => {
  150. // Single Select
  151. let single_select = SingleSelectTypeOptionBuilder::default()
  152. .add_option(SelectOptionPB::new(COMPLETED))
  153. .add_option(SelectOptionPB::new(PLANNED))
  154. .add_option(SelectOptionPB::new(PAUSED));
  155. let single_select_field = FieldBuilder::new(single_select).name("Status").visibility(true).build();
  156. grid_builder.add_field(single_select_field);
  157. }
  158. FieldType::MultiSelect => {
  159. // MultiSelect
  160. let multi_select = MultiSelectTypeOptionBuilder::default()
  161. .add_option(SelectOptionPB::new(GOOGLE))
  162. .add_option(SelectOptionPB::new(FACEBOOK))
  163. .add_option(SelectOptionPB::new(TWITTER));
  164. let multi_select_field = FieldBuilder::new(multi_select)
  165. .name("Platform")
  166. .visibility(true)
  167. .build();
  168. grid_builder.add_field(multi_select_field);
  169. }
  170. FieldType::Checkbox => {
  171. // Checkbox
  172. let checkbox = CheckboxTypeOptionBuilder::default();
  173. let checkbox_field = FieldBuilder::new(checkbox).name("is urgent").visibility(true).build();
  174. grid_builder.add_field(checkbox_field);
  175. }
  176. FieldType::URL => {
  177. // URL
  178. let url = URLTypeOptionBuilder::default();
  179. let url_field = FieldBuilder::new(url).name("link").visibility(true).build();
  180. grid_builder.add_field(url_field);
  181. }
  182. }
  183. }
  184. // We have many assumptions base on the number of the rows, so do not change the number of the loop.
  185. for i in 0..5 {
  186. let block_id = grid_builder.block_id().to_owned();
  187. let field_revs = grid_builder.field_revs();
  188. let mut row_builder = GridRowTestBuilder::new(&block_id, field_revs);
  189. match i {
  190. 0 => {
  191. for field_type in FieldType::iter() {
  192. match field_type {
  193. FieldType::RichText => row_builder.insert_text_cell("A"),
  194. FieldType::Number => row_builder.insert_number_cell("1"),
  195. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  196. FieldType::MultiSelect => row_builder
  197. .insert_multi_select_cell(|mut options| vec![options.remove(0), options.remove(0)]),
  198. FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
  199. _ => "".to_owned(),
  200. };
  201. }
  202. }
  203. 1 => {
  204. for field_type in FieldType::iter() {
  205. match field_type {
  206. FieldType::RichText => row_builder.insert_text_cell("B"),
  207. FieldType::Number => row_builder.insert_number_cell("2"),
  208. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  209. FieldType::MultiSelect => row_builder
  210. .insert_multi_select_cell(|mut options| vec![options.remove(0), options.remove(0)]),
  211. FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
  212. _ => "".to_owned(),
  213. };
  214. }
  215. }
  216. 2 => {
  217. for field_type in FieldType::iter() {
  218. match field_type {
  219. FieldType::RichText => row_builder.insert_text_cell("C"),
  220. FieldType::Number => row_builder.insert_number_cell("3"),
  221. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  222. FieldType::SingleSelect => {
  223. row_builder.insert_single_select_cell(|mut options| options.remove(0))
  224. }
  225. FieldType::MultiSelect => {
  226. row_builder.insert_multi_select_cell(|mut options| vec![options.remove(1)])
  227. }
  228. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  229. _ => "".to_owned(),
  230. };
  231. }
  232. }
  233. 3 => {
  234. for field_type in FieldType::iter() {
  235. match field_type {
  236. FieldType::RichText => row_builder.insert_text_cell("DA"),
  237. FieldType::Number => row_builder.insert_number_cell("4"),
  238. FieldType::DateTime => row_builder.insert_date_cell("1668704685"),
  239. FieldType::SingleSelect => {
  240. row_builder.insert_single_select_cell(|mut options| options.remove(0))
  241. }
  242. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  243. _ => "".to_owned(),
  244. };
  245. }
  246. }
  247. 4 => {
  248. for field_type in FieldType::iter() {
  249. match field_type {
  250. FieldType::RichText => row_builder.insert_text_cell("AE"),
  251. FieldType::Number => row_builder.insert_number_cell(""),
  252. FieldType::DateTime => row_builder.insert_date_cell("1668359085"),
  253. FieldType::SingleSelect => {
  254. row_builder.insert_single_select_cell(|mut options| options.remove(1))
  255. }
  256. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  257. _ => "".to_owned(),
  258. };
  259. }
  260. }
  261. _ => {}
  262. }
  263. let row_rev = row_builder.build();
  264. grid_builder.add_row(row_rev);
  265. }
  266. grid_builder.build()
  267. }
  268. fn make_test_board() -> BuildGridContext {
  269. let mut grid_builder = GridBuilder::new();
  270. // Iterate through the FieldType to create the corresponding Field.
  271. for field_type in FieldType::iter() {
  272. let field_type: FieldType = field_type;
  273. // The
  274. match field_type {
  275. FieldType::RichText => {
  276. let text_field = FieldBuilder::new(RichTextTypeOptionBuilder::default())
  277. .name("Name")
  278. .visibility(true)
  279. .primary(true)
  280. .build();
  281. grid_builder.add_field(text_field);
  282. }
  283. FieldType::Number => {
  284. // Number
  285. let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD);
  286. let number_field = FieldBuilder::new(number).name("Price").visibility(true).build();
  287. grid_builder.add_field(number_field);
  288. }
  289. FieldType::DateTime => {
  290. // Date
  291. let date = DateTypeOptionBuilder::default()
  292. .date_format(DateFormat::US)
  293. .time_format(TimeFormat::TwentyFourHour);
  294. let date_field = FieldBuilder::new(date).name("Time").visibility(true).build();
  295. grid_builder.add_field(date_field);
  296. }
  297. FieldType::SingleSelect => {
  298. // Single Select
  299. let single_select = SingleSelectTypeOptionBuilder::default()
  300. .add_option(SelectOptionPB::new(COMPLETED))
  301. .add_option(SelectOptionPB::new(PLANNED))
  302. .add_option(SelectOptionPB::new(PAUSED));
  303. let single_select_field = FieldBuilder::new(single_select).name("Status").visibility(true).build();
  304. grid_builder.add_field(single_select_field);
  305. }
  306. FieldType::MultiSelect => {
  307. // MultiSelect
  308. let multi_select = MultiSelectTypeOptionBuilder::default()
  309. .add_option(SelectOptionPB::new(GOOGLE))
  310. .add_option(SelectOptionPB::new(FACEBOOK))
  311. .add_option(SelectOptionPB::new(TWITTER));
  312. let multi_select_field = FieldBuilder::new(multi_select)
  313. .name("Platform")
  314. .visibility(true)
  315. .build();
  316. grid_builder.add_field(multi_select_field);
  317. }
  318. FieldType::Checkbox => {
  319. // Checkbox
  320. let checkbox = CheckboxTypeOptionBuilder::default();
  321. let checkbox_field = FieldBuilder::new(checkbox).name("is urgent").visibility(true).build();
  322. grid_builder.add_field(checkbox_field);
  323. }
  324. FieldType::URL => {
  325. // URL
  326. let url = URLTypeOptionBuilder::default();
  327. let url_field = FieldBuilder::new(url).name("link").visibility(true).build();
  328. grid_builder.add_field(url_field);
  329. }
  330. }
  331. }
  332. // We have many assumptions base on the number of the rows, so do not change the number of the loop.
  333. for i in 0..5 {
  334. let block_id = grid_builder.block_id().to_owned();
  335. let field_revs = grid_builder.field_revs();
  336. let mut row_builder = GridRowTestBuilder::new(&block_id, field_revs);
  337. match i {
  338. 0 => {
  339. for field_type in FieldType::iter() {
  340. match field_type {
  341. FieldType::RichText => row_builder.insert_text_cell("A"),
  342. FieldType::Number => row_builder.insert_number_cell("1"),
  343. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  344. FieldType::SingleSelect => {
  345. row_builder.insert_single_select_cell(|mut options| options.remove(0))
  346. }
  347. FieldType::MultiSelect => row_builder
  348. .insert_multi_select_cell(|mut options| vec![options.remove(0), options.remove(0)]),
  349. FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
  350. _ => "".to_owned(),
  351. };
  352. }
  353. }
  354. 1 => {
  355. for field_type in FieldType::iter() {
  356. match field_type {
  357. FieldType::RichText => row_builder.insert_text_cell("B"),
  358. FieldType::Number => row_builder.insert_number_cell("2"),
  359. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  360. FieldType::SingleSelect => {
  361. row_builder.insert_single_select_cell(|mut options| options.remove(0))
  362. }
  363. FieldType::MultiSelect => row_builder
  364. .insert_multi_select_cell(|mut options| vec![options.remove(0), options.remove(0)]),
  365. FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
  366. _ => "".to_owned(),
  367. };
  368. }
  369. }
  370. 2 => {
  371. for field_type in FieldType::iter() {
  372. match field_type {
  373. FieldType::RichText => row_builder.insert_text_cell("C"),
  374. FieldType::Number => row_builder.insert_number_cell("3"),
  375. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  376. FieldType::SingleSelect => {
  377. row_builder.insert_single_select_cell(|mut options| options.remove(1))
  378. }
  379. FieldType::MultiSelect => {
  380. row_builder.insert_multi_select_cell(|mut options| vec![options.remove(0)])
  381. }
  382. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  383. _ => "".to_owned(),
  384. };
  385. }
  386. }
  387. 3 => {
  388. for field_type in FieldType::iter() {
  389. match field_type {
  390. FieldType::RichText => row_builder.insert_text_cell("DA"),
  391. FieldType::Number => row_builder.insert_number_cell("4"),
  392. FieldType::DateTime => row_builder.insert_date_cell("1668704685"),
  393. FieldType::SingleSelect => {
  394. row_builder.insert_single_select_cell(|mut options| options.remove(1))
  395. }
  396. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  397. _ => "".to_owned(),
  398. };
  399. }
  400. }
  401. 4 => {
  402. for field_type in FieldType::iter() {
  403. match field_type {
  404. FieldType::RichText => row_builder.insert_text_cell("AE"),
  405. FieldType::Number => row_builder.insert_number_cell(""),
  406. FieldType::DateTime => row_builder.insert_date_cell("1668359085"),
  407. FieldType::SingleSelect => {
  408. row_builder.insert_single_select_cell(|mut options| options.remove(2))
  409. }
  410. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  411. _ => "".to_owned(),
  412. };
  413. }
  414. }
  415. _ => {}
  416. }
  417. let row_rev = row_builder.build();
  418. grid_builder.add_row(row_rev);
  419. }
  420. grid_builder.build()
  421. }