grid_editor.rs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  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 database_model::*;
  7. use flowy_client_sync::client_database::DatabaseBuilder;
  8. use flowy_database::entities::*;
  9. use flowy_database::services::cell::ToCellChangesetString;
  10. use flowy_database::services::field::SelectOptionPB;
  11. use flowy_database::services::field::*;
  12. use flowy_database::services::grid_editor::{DatabaseRevisionEditor, GridRevisionSerde};
  13. use flowy_database::services::row::{CreateRowRevisionPayload, RowRevisionBuilder};
  14. use flowy_database::services::setting::GridSettingChangesetBuilder;
  15. use flowy_error::FlowyResult;
  16. use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
  17. use flowy_test::helper::ViewTest;
  18. use flowy_test::FlowySDKTest;
  19. use std::collections::HashMap;
  20. use std::sync::Arc;
  21. use std::time::Duration;
  22. use strum::EnumCount;
  23. use strum::IntoEnumIterator;
  24. use tokio::time::sleep;
  25. pub struct GridEditorTest {
  26. pub sdk: FlowySDKTest,
  27. pub view_id: String,
  28. pub editor: Arc<DatabaseRevisionEditor>,
  29. pub field_revs: Vec<Arc<FieldRevision>>,
  30. pub block_meta_revs: Vec<Arc<GridBlockMetaRevision>>,
  31. pub row_revs: Vec<Arc<RowRevision>>,
  32. pub field_count: usize,
  33. pub row_by_row_id: HashMap<String, RowPB>,
  34. }
  35. impl GridEditorTest {
  36. pub async fn new_table() -> Self {
  37. Self::new(DatabaseViewLayout::Grid).await
  38. }
  39. pub async fn new_board() -> Self {
  40. Self::new(DatabaseViewLayout::Board).await
  41. }
  42. pub async fn new(layout: DatabaseViewLayout) -> Self {
  43. let sdk = FlowySDKTest::default();
  44. let _ = sdk.init_user().await;
  45. let test = match layout {
  46. DatabaseViewLayout::Grid => {
  47. let build_context = make_test_grid();
  48. let view_data: Bytes = build_context.into();
  49. ViewTest::new_grid_view(&sdk, view_data.to_vec()).await
  50. },
  51. DatabaseViewLayout::Board => {
  52. let build_context = make_test_board();
  53. let view_data: Bytes = build_context.into();
  54. ViewTest::new_board_view(&sdk, view_data.to_vec()).await
  55. },
  56. DatabaseViewLayout::Calendar => {
  57. let build_context = make_test_calendar();
  58. let view_data: Bytes = build_context.into();
  59. ViewTest::new_calendar_view(&sdk, view_data.to_vec()).await
  60. },
  61. };
  62. let editor = sdk.grid_manager.open_database(&test.view.id).await.unwrap();
  63. let field_revs = editor.get_field_revs(None).await.unwrap();
  64. let block_meta_revs = editor.get_block_meta_revs().await.unwrap();
  65. let row_pbs = editor.get_all_row_revs(&test.view.id).await.unwrap();
  66. assert_eq!(block_meta_revs.len(), 1);
  67. // It seems like you should add the field in the make_test_grid() function.
  68. // Because we assert the initialize count of the fields is equal to FieldType::COUNT.
  69. assert_eq!(field_revs.len(), FieldType::COUNT);
  70. let grid_id = test.view.id;
  71. Self {
  72. sdk,
  73. view_id: grid_id,
  74. editor,
  75. field_revs,
  76. block_meta_revs,
  77. row_revs: row_pbs,
  78. field_count: FieldType::COUNT,
  79. row_by_row_id: HashMap::default(),
  80. }
  81. }
  82. pub async fn get_row_revs(&self) -> Vec<Arc<RowRevision>> {
  83. self.editor.get_all_row_revs(&self.view_id).await.unwrap()
  84. }
  85. pub async fn grid_filters(&self) -> Vec<FilterPB> {
  86. self.editor.get_all_filters().await.unwrap()
  87. }
  88. pub fn get_field_rev(&self, field_id: &str, field_type: FieldType) -> &Arc<FieldRevision> {
  89. self
  90. .field_revs
  91. .iter()
  92. .filter(|field_rev| {
  93. let t_field_type: FieldType = field_rev.ty.into();
  94. field_rev.id == field_id && t_field_type == field_type
  95. })
  96. .collect::<Vec<_>>()
  97. .pop()
  98. .unwrap()
  99. }
  100. /// returns the first `FieldRevision` in the build-in test grid.
  101. /// Not support duplicate `FieldType` in test grid yet.
  102. pub fn get_first_field_rev(&self, field_type: FieldType) -> &Arc<FieldRevision> {
  103. self
  104. .field_revs
  105. .iter()
  106. .filter(|field_rev| {
  107. let t_field_type: FieldType = field_rev.ty.into();
  108. t_field_type == field_type
  109. })
  110. .collect::<Vec<_>>()
  111. .pop()
  112. .unwrap()
  113. }
  114. pub fn get_multi_select_type_option(&self, field_id: &str) -> Vec<SelectOptionPB> {
  115. let field_type = FieldType::MultiSelect;
  116. let field_rev = self.get_field_rev(field_id, field_type.clone());
  117. let type_option = field_rev
  118. .get_type_option::<MultiSelectTypeOptionPB>(field_type.into())
  119. .unwrap();
  120. type_option.options
  121. }
  122. pub fn get_single_select_type_option(&self, field_id: &str) -> SingleSelectTypeOptionPB {
  123. let field_type = FieldType::SingleSelect;
  124. let field_rev = self.get_field_rev(field_id, field_type.clone());
  125. let type_option = field_rev
  126. .get_type_option::<SingleSelectTypeOptionPB>(field_type.into())
  127. .unwrap();
  128. type_option
  129. }
  130. pub fn get_checklist_type_option(&self, field_id: &str) -> ChecklistTypeOptionPB {
  131. let field_type = FieldType::Checklist;
  132. let field_rev = self.get_field_rev(field_id, field_type.clone());
  133. let type_option = field_rev
  134. .get_type_option::<ChecklistTypeOptionPB>(field_type.into())
  135. .unwrap();
  136. type_option
  137. }
  138. pub fn get_checkbox_type_option(&self, field_id: &str) -> CheckboxTypeOptionPB {
  139. let field_type = FieldType::Checkbox;
  140. let field_rev = self.get_field_rev(field_id, field_type.clone());
  141. let type_option = field_rev
  142. .get_type_option::<CheckboxTypeOptionPB>(field_type.into())
  143. .unwrap();
  144. type_option
  145. }
  146. pub fn block_id(&self) -> &str {
  147. &self.block_meta_revs.last().unwrap().block_id
  148. }
  149. pub async fn update_cell<T: ToCellChangesetString>(
  150. &mut self,
  151. field_id: &str,
  152. row_id: String,
  153. cell_changeset: T,
  154. ) {
  155. let field_rev = self
  156. .field_revs
  157. .iter()
  158. .find(|field_rev| field_rev.id == field_id)
  159. .unwrap();
  160. self
  161. .editor
  162. .update_cell_with_changeset(&row_id, &field_rev.id, cell_changeset)
  163. .await
  164. .unwrap();
  165. }
  166. pub(crate) async fn update_text_cell(&mut self, row_id: String, content: &str) {
  167. let field_rev = self
  168. .field_revs
  169. .iter()
  170. .find(|field_rev| {
  171. let field_type: FieldType = field_rev.ty.into();
  172. field_type == FieldType::RichText
  173. })
  174. .unwrap()
  175. .clone();
  176. self
  177. .update_cell(&field_rev.id, row_id, content.to_string())
  178. .await;
  179. }
  180. pub(crate) async fn update_single_select_cell(&mut self, row_id: String, option_id: &str) {
  181. let field_rev = self
  182. .field_revs
  183. .iter()
  184. .find(|field_rev| {
  185. let field_type: FieldType = field_rev.ty.into();
  186. field_type == FieldType::SingleSelect
  187. })
  188. .unwrap()
  189. .clone();
  190. let cell_changeset = SelectOptionCellChangeset::from_insert_option_id(&option_id);
  191. self
  192. .update_cell(&field_rev.id, row_id, cell_changeset)
  193. .await;
  194. }
  195. }
  196. pub const GOOGLE: &str = "Google";
  197. pub const FACEBOOK: &str = "Facebook";
  198. pub const TWITTER: &str = "Twitter";
  199. pub const COMPLETED: &str = "Completed";
  200. pub const PLANNED: &str = "Planned";
  201. pub const PAUSED: &str = "Paused";
  202. pub const FIRST_THING: &str = "Wake up at 6:00 am";
  203. pub const SECOND_THING: &str = "Get some coffee";
  204. pub const THIRD_THING: &str = "Start working";
  205. /// The build-in test data for grid. Currently, there are five rows in this grid, if you want to add
  206. /// more rows or alter the data in this grid. Some tests may fail. So you need to fix the failed tests.
  207. fn make_test_grid() -> BuildDatabaseContext {
  208. let mut grid_builder = DatabaseBuilder::new();
  209. // Iterate through the FieldType to create the corresponding Field.
  210. for field_type in FieldType::iter() {
  211. let field_type: FieldType = field_type;
  212. // The
  213. match field_type {
  214. FieldType::RichText => {
  215. let text_field = FieldBuilder::new(RichTextTypeOptionBuilder::default())
  216. .name("Name")
  217. .visibility(true)
  218. .primary(true)
  219. .build();
  220. grid_builder.add_field(text_field);
  221. },
  222. FieldType::Number => {
  223. // Number
  224. let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD);
  225. let number_field = FieldBuilder::new(number)
  226. .name("Price")
  227. .visibility(true)
  228. .build();
  229. grid_builder.add_field(number_field);
  230. },
  231. FieldType::DateTime => {
  232. // Date
  233. let date = DateTypeOptionBuilder::default()
  234. .date_format(DateFormat::US)
  235. .time_format(TimeFormat::TwentyFourHour);
  236. let date_field = FieldBuilder::new(date)
  237. .name("Time")
  238. .visibility(true)
  239. .build();
  240. grid_builder.add_field(date_field);
  241. },
  242. FieldType::SingleSelect => {
  243. // Single Select
  244. let single_select = SingleSelectTypeOptionBuilder::default()
  245. .add_option(SelectOptionPB::new(COMPLETED))
  246. .add_option(SelectOptionPB::new(PLANNED))
  247. .add_option(SelectOptionPB::new(PAUSED));
  248. let single_select_field = FieldBuilder::new(single_select)
  249. .name("Status")
  250. .visibility(true)
  251. .build();
  252. grid_builder.add_field(single_select_field);
  253. },
  254. FieldType::MultiSelect => {
  255. // MultiSelect
  256. let multi_select = MultiSelectTypeOptionBuilder::default()
  257. .add_option(SelectOptionPB::new(GOOGLE))
  258. .add_option(SelectOptionPB::new(FACEBOOK))
  259. .add_option(SelectOptionPB::new(TWITTER));
  260. let multi_select_field = FieldBuilder::new(multi_select)
  261. .name("Platform")
  262. .visibility(true)
  263. .build();
  264. grid_builder.add_field(multi_select_field);
  265. },
  266. FieldType::Checkbox => {
  267. // Checkbox
  268. let checkbox = CheckboxTypeOptionBuilder::default();
  269. let checkbox_field = FieldBuilder::new(checkbox)
  270. .name("is urgent")
  271. .visibility(true)
  272. .build();
  273. grid_builder.add_field(checkbox_field);
  274. },
  275. FieldType::URL => {
  276. // URL
  277. let url = URLTypeOptionBuilder::default();
  278. let url_field = FieldBuilder::new(url).name("link").visibility(true).build();
  279. grid_builder.add_field(url_field);
  280. },
  281. FieldType::Checklist => {
  282. let checklist = ChecklistTypeOptionBuilder::default()
  283. .add_option(SelectOptionPB::new(FIRST_THING))
  284. .add_option(SelectOptionPB::new(SECOND_THING))
  285. .add_option(SelectOptionPB::new(THIRD_THING));
  286. let checklist_field = FieldBuilder::new(checklist)
  287. .name("TODO")
  288. .visibility(true)
  289. .build();
  290. grid_builder.add_field(checklist_field);
  291. },
  292. }
  293. }
  294. for i in 0..6 {
  295. let block_id = grid_builder.block_id().to_owned();
  296. let field_revs = grid_builder.field_revs();
  297. let mut row_builder = GridRowTestBuilder::new(&block_id, field_revs);
  298. match i {
  299. 0 => {
  300. for field_type in FieldType::iter() {
  301. match field_type {
  302. FieldType::RichText => row_builder.insert_text_cell("A"),
  303. FieldType::Number => row_builder.insert_number_cell("1"),
  304. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  305. FieldType::MultiSelect => row_builder
  306. .insert_multi_select_cell(|mut options| vec![options.remove(0), options.remove(0)]),
  307. FieldType::Checklist => row_builder.insert_checklist_cell(|options| options),
  308. FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
  309. FieldType::URL => {
  310. row_builder.insert_url_cell("AppFlowy website - https://www.appflowy.io")
  311. },
  312. _ => "".to_owned(),
  313. };
  314. }
  315. },
  316. 1 => {
  317. for field_type in FieldType::iter() {
  318. match field_type {
  319. FieldType::RichText => row_builder.insert_text_cell(""),
  320. FieldType::Number => row_builder.insert_number_cell("2"),
  321. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  322. FieldType::MultiSelect => row_builder
  323. .insert_multi_select_cell(|mut options| vec![options.remove(0), options.remove(1)]),
  324. FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
  325. _ => "".to_owned(),
  326. };
  327. }
  328. },
  329. 2 => {
  330. for field_type in FieldType::iter() {
  331. match field_type {
  332. FieldType::RichText => row_builder.insert_text_cell("C"),
  333. FieldType::Number => row_builder.insert_number_cell("3"),
  334. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  335. FieldType::SingleSelect => {
  336. row_builder.insert_single_select_cell(|mut options| options.remove(0))
  337. },
  338. FieldType::MultiSelect => {
  339. row_builder.insert_multi_select_cell(|mut options| vec![options.remove(1)])
  340. },
  341. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  342. _ => "".to_owned(),
  343. };
  344. }
  345. },
  346. 3 => {
  347. for field_type in FieldType::iter() {
  348. match field_type {
  349. FieldType::RichText => row_builder.insert_text_cell("DA"),
  350. FieldType::Number => row_builder.insert_number_cell("4"),
  351. FieldType::DateTime => row_builder.insert_date_cell("1668704685"),
  352. FieldType::SingleSelect => {
  353. row_builder.insert_single_select_cell(|mut options| options.remove(0))
  354. },
  355. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  356. _ => "".to_owned(),
  357. };
  358. }
  359. },
  360. 4 => {
  361. for field_type in FieldType::iter() {
  362. match field_type {
  363. FieldType::RichText => row_builder.insert_text_cell("AE"),
  364. FieldType::Number => row_builder.insert_number_cell(""),
  365. FieldType::DateTime => row_builder.insert_date_cell("1668359085"),
  366. FieldType::SingleSelect => {
  367. row_builder.insert_single_select_cell(|mut options| options.remove(1))
  368. },
  369. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  370. _ => "".to_owned(),
  371. };
  372. }
  373. },
  374. 5 => {
  375. for field_type in FieldType::iter() {
  376. match field_type {
  377. FieldType::RichText => row_builder.insert_text_cell("AE"),
  378. FieldType::Number => row_builder.insert_number_cell("5"),
  379. FieldType::DateTime => row_builder.insert_date_cell("1671938394"),
  380. FieldType::SingleSelect => {
  381. row_builder.insert_single_select_cell(|mut options| options.remove(1))
  382. },
  383. FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
  384. _ => "".to_owned(),
  385. };
  386. }
  387. },
  388. _ => {},
  389. }
  390. let row_rev = row_builder.build();
  391. grid_builder.add_row(row_rev);
  392. }
  393. grid_builder.build()
  394. }
  395. // Kanban board unit test mock data
  396. fn make_test_board() -> BuildDatabaseContext {
  397. let mut grid_builder = DatabaseBuilder::new();
  398. // Iterate through the FieldType to create the corresponding Field.
  399. for field_type in FieldType::iter() {
  400. let field_type: FieldType = field_type;
  401. // The
  402. match field_type {
  403. FieldType::RichText => {
  404. let text_field = FieldBuilder::new(RichTextTypeOptionBuilder::default())
  405. .name("Name")
  406. .visibility(true)
  407. .primary(true)
  408. .build();
  409. grid_builder.add_field(text_field);
  410. },
  411. FieldType::Number => {
  412. // Number
  413. let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD);
  414. let number_field = FieldBuilder::new(number)
  415. .name("Price")
  416. .visibility(true)
  417. .build();
  418. grid_builder.add_field(number_field);
  419. },
  420. FieldType::DateTime => {
  421. // Date
  422. let date = DateTypeOptionBuilder::default()
  423. .date_format(DateFormat::US)
  424. .time_format(TimeFormat::TwentyFourHour);
  425. let date_field = FieldBuilder::new(date)
  426. .name("Time")
  427. .visibility(true)
  428. .build();
  429. grid_builder.add_field(date_field);
  430. },
  431. FieldType::SingleSelect => {
  432. // Single Select
  433. let single_select = SingleSelectTypeOptionBuilder::default()
  434. .add_option(SelectOptionPB::new(COMPLETED))
  435. .add_option(SelectOptionPB::new(PLANNED))
  436. .add_option(SelectOptionPB::new(PAUSED));
  437. let single_select_field = FieldBuilder::new(single_select)
  438. .name("Status")
  439. .visibility(true)
  440. .build();
  441. grid_builder.add_field(single_select_field);
  442. },
  443. FieldType::MultiSelect => {
  444. // MultiSelect
  445. let multi_select = MultiSelectTypeOptionBuilder::default()
  446. .add_option(SelectOptionPB::new(GOOGLE))
  447. .add_option(SelectOptionPB::new(FACEBOOK))
  448. .add_option(SelectOptionPB::new(TWITTER));
  449. let multi_select_field = FieldBuilder::new(multi_select)
  450. .name("Platform")
  451. .visibility(true)
  452. .build();
  453. grid_builder.add_field(multi_select_field);
  454. },
  455. FieldType::Checkbox => {
  456. // Checkbox
  457. let checkbox = CheckboxTypeOptionBuilder::default();
  458. let checkbox_field = FieldBuilder::new(checkbox)
  459. .name("is urgent")
  460. .visibility(true)
  461. .build();
  462. grid_builder.add_field(checkbox_field);
  463. },
  464. FieldType::URL => {
  465. // URL
  466. let url = URLTypeOptionBuilder::default();
  467. let url_field = FieldBuilder::new(url).name("link").visibility(true).build();
  468. grid_builder.add_field(url_field);
  469. },
  470. FieldType::Checklist => {
  471. let checklist = ChecklistTypeOptionBuilder::default()
  472. .add_option(SelectOptionPB::new(FIRST_THING))
  473. .add_option(SelectOptionPB::new(SECOND_THING))
  474. .add_option(SelectOptionPB::new(THIRD_THING));
  475. let checklist_field = FieldBuilder::new(checklist)
  476. .name("TODO")
  477. .visibility(true)
  478. .build();
  479. grid_builder.add_field(checklist_field);
  480. },
  481. }
  482. }
  483. // We have many assumptions base on the number of the rows, so do not change the number of the loop.
  484. for i in 0..5 {
  485. let block_id = grid_builder.block_id().to_owned();
  486. let field_revs = grid_builder.field_revs();
  487. let mut row_builder = GridRowTestBuilder::new(&block_id, field_revs);
  488. match i {
  489. 0 => {
  490. for field_type in FieldType::iter() {
  491. match field_type {
  492. FieldType::RichText => row_builder.insert_text_cell("A"),
  493. FieldType::Number => row_builder.insert_number_cell("1"),
  494. // 1647251762 => Mar 14,2022
  495. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  496. FieldType::SingleSelect => {
  497. row_builder.insert_single_select_cell(|mut options| options.remove(0))
  498. },
  499. FieldType::MultiSelect => row_builder
  500. .insert_multi_select_cell(|mut options| vec![options.remove(0), options.remove(0)]),
  501. FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
  502. FieldType::URL => row_builder.insert_url_cell("https://appflowy.io"),
  503. _ => "".to_owned(),
  504. };
  505. }
  506. },
  507. 1 => {
  508. for field_type in FieldType::iter() {
  509. match field_type {
  510. FieldType::RichText => row_builder.insert_text_cell("B"),
  511. FieldType::Number => row_builder.insert_number_cell("2"),
  512. // 1647251762 => Mar 14,2022
  513. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  514. FieldType::SingleSelect => {
  515. row_builder.insert_single_select_cell(|mut options| options.remove(0))
  516. },
  517. FieldType::MultiSelect => row_builder
  518. .insert_multi_select_cell(|mut options| vec![options.remove(0), options.remove(0)]),
  519. FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
  520. _ => "".to_owned(),
  521. };
  522. }
  523. },
  524. 2 => {
  525. for field_type in FieldType::iter() {
  526. match field_type {
  527. FieldType::RichText => row_builder.insert_text_cell("C"),
  528. FieldType::Number => row_builder.insert_number_cell("3"),
  529. // 1647251762 => Mar 14,2022
  530. FieldType::DateTime => row_builder.insert_date_cell("1647251762"),
  531. FieldType::SingleSelect => {
  532. row_builder.insert_single_select_cell(|mut options| options.remove(1))
  533. },
  534. FieldType::MultiSelect => {
  535. row_builder.insert_multi_select_cell(|mut options| vec![options.remove(0)])
  536. },
  537. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  538. FieldType::URL => {
  539. row_builder.insert_url_cell("https://github.com/AppFlowy-IO/AppFlowy")
  540. },
  541. _ => "".to_owned(),
  542. };
  543. }
  544. },
  545. 3 => {
  546. for field_type in FieldType::iter() {
  547. match field_type {
  548. FieldType::RichText => row_builder.insert_text_cell("DA"),
  549. FieldType::Number => row_builder.insert_number_cell("4"),
  550. FieldType::DateTime => row_builder.insert_date_cell("1668704685"),
  551. FieldType::SingleSelect => {
  552. row_builder.insert_single_select_cell(|mut options| options.remove(1))
  553. },
  554. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  555. FieldType::URL => row_builder.insert_url_cell("https://appflowy.io"),
  556. _ => "".to_owned(),
  557. };
  558. }
  559. },
  560. 4 => {
  561. for field_type in FieldType::iter() {
  562. match field_type {
  563. FieldType::RichText => row_builder.insert_text_cell("AE"),
  564. FieldType::Number => row_builder.insert_number_cell(""),
  565. FieldType::DateTime => row_builder.insert_date_cell("1668359085"),
  566. FieldType::SingleSelect => {
  567. row_builder.insert_single_select_cell(|mut options| options.remove(2))
  568. },
  569. FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
  570. _ => "".to_owned(),
  571. };
  572. }
  573. },
  574. _ => {},
  575. }
  576. let row_rev = row_builder.build();
  577. grid_builder.add_row(row_rev);
  578. }
  579. grid_builder.build()
  580. }
  581. // Calendar unit test mock data
  582. fn make_test_calendar() -> BuildDatabaseContext {
  583. todo!()
  584. }